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