|
|
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 "briq/briq.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( vfd_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: char *s = malloc( len + 1 ); ! 74: ! 75: strncpy_nopad( s, addr, len ); ! 76: s[len]=0; ! 77: ! 78: printk( "%s", s ); ! 79: //vfd_draw_str( s ); ! 80: free( s ); ! 81: ! 82: PUSH( len ); ! 83: } ! 84: ! 85: NODE_METHODS( vfd_stdout ) = { ! 86: { "write", stdout_write }, ! 87: }; ! 88: ! 89: ! 90: /************************************************************************/ ! 91: /* tty */ ! 92: /************************************************************************/ ! 93: ! 94: DECLARE_NODE( tty, INSTALL_OPEN, 0, "/packages/terminal-emulator" ); ! 95: ! 96: /* ( addr len -- actual ) */ ! 97: static void ! 98: tty_read( void ) ! 99: { ! 100: int ch, len = POP(); ! 101: char *p = (char*)POP(); ! 102: int ret=0; ! 103: ! 104: if( len > 0 ) { ! 105: ret = 1; ! 106: ch = getchar(); ! 107: if( ch >= 0 ) { ! 108: *p = ch; ! 109: } else { ! 110: ret = 0; ! 111: } ! 112: } ! 113: PUSH( ret ); ! 114: } ! 115: ! 116: /* ( addr len -- actual ) */ ! 117: static void ! 118: tty_write( void ) ! 119: { ! 120: int i, len = POP(); ! 121: char *p = (char*)POP(); ! 122: for( i=0; i<len; i++ ) ! 123: putchar( *p++ ); ! 124: RET( len ); ! 125: } ! 126: ! 127: NODE_METHODS( tty ) = { ! 128: { "read", tty_read }, ! 129: { "write", tty_write }, ! 130: }; ! 131: ! 132: /************************************************************************/ ! 133: /* client interface 'quiesce' */ ! 134: /************************************************************************/ ! 135: ! 136: DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" ); ! 137: ! 138: /* ( -- ) */ ! 139: static void ! 140: ciface_quiesce( unsigned long args[], unsigned long ret[] ) ! 141: { ! 142: #if 0 ! 143: unsigned long msr; ! 144: /* This seems to be the correct thing to do - but I'm not sure */ ! 145: asm volatile("mfmsr %0" : "=r" (msr) : ); ! 146: msr &= ~(MSR_IR | MSR_DR); ! 147: asm volatile("mtmsr %0" :: "r" (msr) ); ! 148: #endif ! 149: printk("=============================================================\n\n"); ! 150: } ! 151: ! 152: /* ( -- ms ) */ ! 153: static void ! 154: ciface_milliseconds( unsigned long args[], unsigned long ret[] ) ! 155: { ! 156: extern unsigned long get_timer_freq(); ! 157: static unsigned long mticks=0, usecs=0; ! 158: unsigned long t; ! 159: ! 160: asm volatile("mftb %0" : "=r" (t) : ); ! 161: if( mticks ) ! 162: usecs += get_timer_freq() / 1000000 * ( t-mticks ); ! 163: mticks = t; ! 164: ! 165: PUSH( usecs/1000 ); ! 166: } ! 167: ! 168: ! 169: NODE_METHODS( ciface ) = { ! 170: { "quiesce", ciface_quiesce }, ! 171: { "milliseconds", ciface_milliseconds }, ! 172: }; ! 173: ! 174: ! 175: /************************************************************************/ ! 176: /* MMU/memory methods */ ! 177: /************************************************************************/ ! 178: ! 179: DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" ); ! 180: DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpu@0" ); ! 181: DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" ); ! 182: ! 183: ! 184: /* ( phys size align --- base ) */ ! 185: static void ! 186: mem_claim( void ) ! 187: { ! 188: int align = POP(); ! 189: int size = POP(); ! 190: int phys = POP(); ! 191: int ret = ofmem_claim_phys( phys, size, align ); ! 192: ! 193: if( ret == -1 ) { ! 194: printk("MEM: claim failure\n"); ! 195: throw( -13 ); ! 196: return; ! 197: } ! 198: PUSH( ret ); ! 199: } ! 200: ! 201: /* ( phys size --- ) */ ! 202: static void ! 203: mem_release( void ) ! 204: { ! 205: POP(); POP(); ! 206: } ! 207: ! 208: /* ( phys size align --- base ) */ ! 209: static void ! 210: mmu_claim( void ) ! 211: { ! 212: int align = POP(); ! 213: int size = POP(); ! 214: int phys = POP(); ! 215: int ret = ofmem_claim_virt( phys, size, align ); ! 216: ! 217: if( ret == -1 ) { ! 218: printk("MMU: CLAIM failure\n"); ! 219: throw( -13 ); ! 220: return; ! 221: } ! 222: PUSH( ret ); ! 223: } ! 224: ! 225: /* ( phys size --- ) */ ! 226: static void ! 227: mmu_release( void ) ! 228: { ! 229: POP(); POP(); ! 230: } ! 231: ! 232: /* ( phys virt size mode -- [ret???] ) */ ! 233: static void ! 234: mmu_map( void ) ! 235: { ! 236: int mode = POP(); ! 237: int size = POP(); ! 238: int virt = POP(); ! 239: int phys = POP(); ! 240: int ret; ! 241: ! 242: /* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */ ! 243: ret = ofmem_map( phys, virt, size, mode ); ! 244: ! 245: if( ret ) { ! 246: printk("MMU: map failure\n"); ! 247: throw( -13 ); ! 248: return; ! 249: } ! 250: } ! 251: ! 252: /* ( virt size -- ) */ ! 253: static void ! 254: mmu_unmap( void ) ! 255: { ! 256: POP(); POP(); ! 257: } ! 258: ! 259: /* ( virt -- false | phys mode true ) */ ! 260: static void ! 261: mmu_translate( void ) ! 262: { ! 263: ucell mode; ! 264: ucell virt = POP(); ! 265: ucell phys = ofmem_translate( virt, &mode ); ! 266: ! 267: if( phys == -1 ) { ! 268: PUSH( 0 ); ! 269: } else { ! 270: PUSH( phys ); ! 271: PUSH( mode ); ! 272: PUSH( -1 ); ! 273: } ! 274: } ! 275: ! 276: /* ( virt size align -- baseaddr|-1 ) */ ! 277: static void ! 278: ciface_claim( void ) ! 279: { ! 280: int align = POP(); ! 281: int size = POP(); ! 282: int virt = POP(); ! 283: int ret = ofmem_claim( virt, size, align ); ! 284: ! 285: /* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */ ! 286: PUSH( ret ); ! 287: } ! 288: ! 289: /* ( virt size -- ) */ ! 290: static void ! 291: ciface_release( void ) ! 292: { ! 293: POP(); ! 294: POP(); ! 295: } ! 296: ! 297: ! 298: NODE_METHODS( memory ) = { ! 299: { "claim", mem_claim }, ! 300: { "release", mem_release }, ! 301: }; ! 302: ! 303: NODE_METHODS( mmu ) = { ! 304: { "claim", mmu_claim }, ! 305: { "release", mmu_release }, ! 306: { "map", mmu_map }, ! 307: { "unmap", mmu_unmap }, ! 308: { "translate", mmu_translate }, ! 309: }; ! 310: ! 311: NODE_METHODS( mmu_ciface ) = { ! 312: { "cif-claim", ciface_claim }, ! 313: { "cif-release", ciface_release }, ! 314: }; ! 315: ! 316: ! 317: /************************************************************************/ ! 318: /* init */ ! 319: /************************************************************************/ ! 320: ! 321: void ! 322: node_methods_init( void ) ! 323: { ! 324: #ifdef CONFIG_RTAS ! 325: REGISTER_NODE( rtas ); ! 326: #endif ! 327: REGISTER_NODE( vfd_stdout ); ! 328: REGISTER_NODE( ciface ); ! 329: REGISTER_NODE( memory ); ! 330: REGISTER_NODE( mmu ); ! 331: REGISTER_NODE( mmu_ciface ); ! 332: REGISTER_NODE( tty ); ! 333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.