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