|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13:
14: #include <of.h>
15: #include <rtas.h>
16: #include <string.h>
17: #include <netdriver_int.h>
18: #include <fileio.h>
1.1.1.2 ! root 19: #include <stdint.h>
1.1 root 20:
21: extern void call_client_interface(of_arg_t *);
22:
23: static int ofmod_init(void);
24: static int ofmod_term(void);
25: static int ofmod_open(snk_fileio_t*, const char* name, int flags);
26: static int ofmod_read(char *buffer, int len);
27: static int ofmod_write(char *buffer, int len);
28: static int ofmod_ioctl(int request, void *data);
29:
30: snk_module_t of_module = {
31: .version = 1,
32: .type = MOD_TYPE_OTHER,
33: .running = 1,
34: .link_addr = (char*) 1,
35: .init = ofmod_init,
36: .term = ofmod_term,
37: .open = ofmod_open,
38: .write = ofmod_write,
39: .read = ofmod_read,
40: .ioctl = ofmod_ioctl
41: };
42:
43: static ihandle_t fd_ihandle_array[FILEIO_MAX];
44: static int claim_rc = 0;
45: static void* client_start;
46: static size_t client_size;
47:
48: extern inline int
49: of_0_1(const char *serv)
50: {
51: of_arg_t arg = {
52: p32cast serv,
53: 0, 1,
54: { 0 }
55: };
56:
57: call_client_interface(&arg);
58:
59: return arg.args[0];
60: }
61:
62: extern inline void
63: of_1_0(const char *serv, int arg0)
64: {
65: of_arg_t arg = {
66: p32cast serv,
67: 1, 0,
68: {arg0, 0}
69: };
70:
71: call_client_interface(&arg);
72: }
73:
74: extern inline unsigned int
75: of_1_1(const char *serv, int arg0)
76: {
77: of_arg_t arg = {
78: p32cast serv,
79: 1, 1,
80: {arg0, 0}
81: };
82:
83: call_client_interface(&arg);
84: return arg.args[1];
85: }
86:
87: extern inline unsigned int
88: of_1_2(const char *serv, int arg0, int *ret0)
89: {
90: of_arg_t arg = {
91: p32cast serv,
92: 1, 2,
93: {arg0, 0, 0}
94: };
95:
96: call_client_interface(&arg);
97: *ret0 = arg.args[2];
98: return arg.args[1];
99: }
100:
101: extern inline void
102: of_2_0(const char *serv, int arg0, int arg1)
103: {
104: of_arg_t arg = {
105: p32cast serv,
106: 2, 0,
107: {arg0, arg1, 0}
108: };
109:
110: call_client_interface(&arg);
111: }
112:
113: extern inline unsigned int
114: of_2_1(const char *serv, int arg0, int arg1)
115: {
116: of_arg_t arg = {
117: p32cast serv,
118: 2, 1,
119: {arg0, arg1, 0}
120: };
121:
122: call_client_interface(&arg);
123: return arg.args[2];
124: }
125:
126: extern inline unsigned int
127: of_2_2(const char *serv, int arg0, int arg1, int *ret0)
128: {
129: of_arg_t arg = {
130: p32cast serv,
131: 2, 2,
132: {arg0, arg1, 0, 0}
133: };
134:
135: call_client_interface(&arg);
136: *ret0 = arg.args[3];
137: return arg.args[2];
138: }
139:
140: extern inline unsigned int
141: of_2_3(const char *serv, int arg0, int arg1, int *ret0, int *ret1)
142: {
143: of_arg_t arg = {
144: p32cast serv,
145: 2, 3,
146: {arg0, arg1, 0, 0, 0}
147: };
148:
149: call_client_interface(&arg);
150: *ret0 = arg.args[3];
151: *ret1 = arg.args[4];
152: return arg.args[2];
153: }
154:
155: extern inline void
156: of_3_0(const char *serv, int arg0, int arg1, int arg2)
157: {
158: of_arg_t arg = {
159: p32cast serv,
160: 3, 0,
161: {arg0, arg1, arg2, 0}
162: };
163:
164: call_client_interface(&arg);
165: return;
166: }
167:
168: extern inline unsigned int
169: of_3_1(const char *serv, int arg0, int arg1, int arg2)
170: {
171: of_arg_t arg = {
172: p32cast serv,
173: 3, 1,
174: {arg0, arg1, arg2, 0}
175: };
176:
177: call_client_interface(&arg);
178: return arg.args[3];
179: }
180:
181: extern inline unsigned int
182: of_3_2(const char *serv, int arg0, int arg1, int arg2, int *ret0)
183: {
184: of_arg_t arg = {
185: p32cast serv,
186: 3, 2,
187: {arg0, arg1, arg2, 0, 0}
188: };
189:
190: call_client_interface(&arg);
191: *ret0 = arg.args[4];
192: return arg.args[3];
193: }
194:
195: extern inline unsigned int
196: of_3_3(const char *serv, int arg0, int arg1, int arg2, int *ret0, int *ret1)
197: {
198: of_arg_t arg = {
199: p32cast serv,
200: 3, 3,
201: {arg0, arg1, arg2, 0, 0, 0}
202: };
203:
204: call_client_interface(&arg);
205: *ret0 = arg.args[4];
206: *ret1 = arg.args[5];
207: return arg.args[3];
208: }
209:
210: extern inline unsigned int
211: of_4_1(const char *serv, int arg0, int arg1, int arg2, int arg3)
212: {
213: of_arg_t arg = {
214: p32cast serv,
215: 4, 1,
216: {arg0, arg1, arg2, arg3, 0}
217: };
218:
219: call_client_interface(&arg);
220: return arg.args[4];
221: }
222:
223: int
224: of_interpret_1(void *s, void *ret)
225: {
226: return of_1_2("interpret", p32cast s, ret);
227: }
228:
229: void
230: of_close(ihandle_t ihandle)
231: {
232: of_1_0("close", ihandle);
233: }
234:
235: int
236: of_write(ihandle_t ihandle, void *s, int len)
237: {
238: return of_3_1("write", ihandle, p32cast s, len);
239: }
240:
241: int
242: of_read(ihandle_t ihandle, void *s, int len)
243: {
244: return of_3_1("read", ihandle, p32cast s, len);
245: }
246:
247: int
248: of_seek(ihandle_t ihandle, int poshi, int poslo)
249: {
250: return of_3_1("seek", ihandle, poshi, poslo);
251: }
252:
253: int
254: of_getprop(phandle_t phandle, const char *name, void *buf, int len)
255: {
256: return of_4_1("getprop", phandle, p32cast name, p32cast buf, len);
257: }
258:
259: phandle_t
260: of_peer(phandle_t phandle)
261: {
262: return (phandle_t) of_1_1("peer", phandle);
263: }
264:
265: phandle_t
266: of_child(phandle_t phandle)
267: {
268: return (phandle_t) of_1_1("child", phandle);
269: }
270:
271: phandle_t
272: of_parent(phandle_t phandle)
273: {
274: return (phandle_t) of_1_1("parent", phandle);
275: }
276:
277: phandle_t
278: of_finddevice(const char *name)
279: {
280: return (phandle_t) of_1_1("finddevice", p32cast name);
281: }
282:
283: ihandle_t
284: of_open(const char *name)
285: {
286: return (ihandle_t) of_1_1("open", p32cast name);
287: }
288:
289: void *
290: of_claim(void *start, unsigned int size, unsigned int align)
291: {
292: return(void *)(long)(size_t)of_3_1("claim", p32cast start, size, align);
293: }
294:
295: void
296: of_release(void *start, unsigned int size)
297: {
298: (void) of_2_0("release", p32cast start, size);
299: }
300:
301: unsigned int
302: romfs_lookup(const char *name, void **addr)
303: {
304: unsigned int high, low;
305: unsigned int i = of_2_3("ibm,romfs-lookup", p32cast name, strlen(name),
306: (int *) &high, (int *) &low);
307: *addr = (void*)(((unsigned long) high << 32) | (unsigned long) low);
308: return i;
309: }
310:
311: void *
312: of_call_method_3(const char *name, ihandle_t ihandle, int arg0)
313: {
314: int entry, rc;
315: rc = of_3_2("call-method", p32cast name, ihandle, arg0, &entry);
316: return rc != 0 ? 0 : (void *) (long) entry;
317: }
318:
319: int
320: vpd_read(unsigned int offset, unsigned int length, char *data)
321: {
322: int result;
323: long tmp = (long) data;
324: result = of_3_1("rtas-read-vpd", offset, length, (int) tmp);
325: return result;
326: }
327:
328: int
329: vpd_write(unsigned int offset, unsigned int length, char *data)
330: {
331: int result;
332: long tmp = (long) data;
333: result = of_3_1("rtas-write-vpd", offset, length, (int) tmp);
334: return result;
335: }
336:
337: static void
338: ipmi_oem_led_set(int type, int instance, int state)
339: {
340: return of_3_0("set-led", type, instance, state);
341: }
342:
343: int
344: write_mm_log(char *data, unsigned int length, unsigned short type)
345: {
346: long tmp = (long) data;
347:
348: ipmi_oem_led_set(2, 0, 1);
349: return of_3_1("write-mm-log", (int) tmp, length, type);
350: }
351:
352: int
353: of_yield(void)
354: {
355: return of_0_1("yield");
356: }
357:
358: void *
359: of_set_callback(void *addr)
360: {
361: return (void *) (long) (size_t) of_1_1("set-callback", p32cast addr);
362: }
363:
364: void
365: bootmsg_warning(short id, const char *str, short lvl)
366: {
367: (void) of_3_0("bootmsg-warning", id, lvl, p32cast str);
368: }
369:
370: void
371: bootmsg_error(short id, const char *str)
372: {
373: (void) of_2_0("bootmsg-error", id, p32cast str);
374: }
375:
376: void
377: bootmsg_debugcp(short id, const char *str, short lvl)
378: {
379: (void) of_3_0("bootmsg-debugcp", id, lvl, p32cast str);
380: }
381:
382: void
383: bootmsg_cp(short id)
384: {
385: (void) of_1_0("bootmsg-cp", id);
386: }
387:
388:
389: static long
390: of_fileio_read(snk_fileio_t *fileio, char *buf, long len)
391: {
392: if(!fileio)
393: return -1;
394: return of_read( * (ihandle_t*) fileio->data, buf, len );
395: }
396:
397: static long
398: of_fileio_write(snk_fileio_t *fileio, char *buf, long len)
399: {
400: if(!fileio)
401: return -1;
402: return of_write( * (ihandle_t*) fileio->data, buf, len );
403: }
404:
405: static int
406: of_fileio_close(snk_fileio_t *fileio)
407: {
408: if(!fileio)
409: return -1;
410:
411: fileio->type = FILEIO_TYPE_EMPTY;
412: of_close( * (ihandle_t*) fileio->data );
413: return 0;
414: }
415:
416:
417: #define CONFIG_SPACE 0
418: #define IO_SPACE 1
419: #define MEM_SPACE 2
420:
421: #define ASSIGNED_ADDRESS_PROPERTY 0
422: #define REG_PROPERTY 1
423:
424: #define DEBUG_TRANSLATE_ADDRESS 0
425: #if DEBUG_TRANSLATE_ADDRESS != 0
426: #define DEBUG_TR(str...) printk(str)
427: #else
428: #define DEBUG_TR(str...)
429: #endif
430:
431: /**
432: * pci_address_type tries to find the type for which a
433: * mapping should be done. This is PCI specific and is done by
434: * looking at the first 32bit of the phys-addr in
435: * assigned-addresses
436: *
437: * @param node the node of the device which requests
438: * translatation
439: * @param address the address which needs to be translated
440: * @param prop_type the type of the property to search in (either REG_PROPERTY or ASSIGNED_ADDRESS_PROPERTY)
441: * @return the corresponding type (config, i/o, mem)
442: */
443: static int
444: pci_address_type(phandle_t node, uint64_t address, uint8_t prop_type)
445: {
446: char *prop_name = "assigned-addresses";
447: if (prop_type == REG_PROPERTY)
448: prop_name = "reg";
449: /* #address-cells */
450: const unsigned int nac = 3; //PCI
451: /* #size-cells */
452: const unsigned int nsc = 2; //PCI
453: /* up to 11 pairs of (phys-addr(3) size(2)) */
454: unsigned char buf[11 * (nac + nsc) * sizeof(int)];
455: unsigned int *assigned_ptr;
456: int result = -1;
457: int len;
458: len = of_getprop(node, prop_name, buf, 11 * (nac + nsc) * sizeof(int));
459: assigned_ptr = (unsigned int *) &buf[0];
460: while (len > 0) {
461: if ((prop_type == REG_PROPERTY)
462: && ((assigned_ptr[0] & 0xFF) != 0)) {
463: //BARs and Expansion ROM must be in assigned-addresses... so in reg
464: // we only look for those without config space offset set...
465: assigned_ptr += (nac + nsc);
466: len -= (nac + nsc) * sizeof(int);
467: continue;
468: }
469: DEBUG_TR("%s %x size %x\n", prop_name, assigned_ptr[2],
470: assigned_ptr[4]);
471: if (address >= assigned_ptr[2]
472: && address <= assigned_ptr[2] + assigned_ptr[4]) {
473: DEBUG_TR("found a match\n");
474: result = (assigned_ptr[0] & 0x03000000) >> 24;
475: break;
476: }
477: assigned_ptr += (nac + nsc);
478: len -= (nac + nsc) * sizeof(int);
479: }
480: /* this can only handle 32bit memory space and should be
481: * removed as soon as translations for 64bit are available */
482: return (result == 3) ? MEM_SPACE : result;
483: }
484:
485: /**
486: * this is a hack which returns the lower 64 bit of any number of cells
487: * all the higher bits will silently discarded
488: * right now this works pretty good as long 64 bit addresses is all we want
489: *
490: * @param addr a pointer to the first address cell
491: * @param nc number of cells addr points to
492: * @return the lower 64 bit to which addr points
493: */
494: static uint64_t
495: get_dt_address(uint32_t *addr, uint32_t nc)
496: {
497: uint64_t result = 0;
498: while (nc--)
499: result = (result << 32) | *(addr++);
500: return result;
501: }
502:
503: /**
504: * this functions tries to find a mapping for the given address
505: * it assumes that if we have #address-cells == 3 that we are trying
506: * to do a PCI translation
507: *
508: * @param addr a pointer to the address that should be translated
509: * if a translation has been found the address will
510: * be modified
511: * @param type this is required for PCI devices to find the
512: * correct translation
513: * @param ranges this is one "range" containing the translation
514: * information (one range = nac + pnac + nsc)
515: * @param nac the OF property #address-cells
516: * @param nsc the OF property #size-cells
517: * @param pnac the OF property #address-cells from the parent node
518: * @return -1 if no translation was possible; else 0
519: */
520: static int
521: map_one_range(uint64_t *addr, int type, uint32_t *ranges, uint32_t nac,
522: uint32_t nsc, uint32_t pnac)
523: {
524: long offset;
525: /* cm - child mapping */
526: /* pm - parent mapping */
527: uint64_t cm, size, pm;
528: /* only check for the type if nac == 3 (PCI) */
529: DEBUG_TR("type %x, nac %x\n", ranges[0], nac);
530: if (((ranges[0] & 0x03000000) >> 24) != type && nac == 3)
531: return -1;
532: /* okay, it is the same type let's see if we find a mapping */
533: size = get_dt_address(ranges + nac + pnac, nsc);
534: if (nac == 3) /* skip type if PCI */
535: cm = get_dt_address(ranges + 1, nac - 1);
536: else
537: cm = get_dt_address(ranges, nac);
538:
539: DEBUG_TR("\t\tchild_mapping %lx\n", cm);
540: DEBUG_TR("\t\tsize %lx\n", size);
541: DEBUG_TR("\t\t*address %lx\n", (uint64_t) * addr);
542: if (cm + size <= (uint64_t) * addr || cm > (uint64_t) * addr)
543: /* it is not inside the mapping range */
544: return -1;
545: /* get the offset */
546: offset = *addr - cm;
547: /* and add the offset on the parent mapping */
548: if (pnac == 3) /* skip type if PCI */
549: pm = get_dt_address(ranges + nac + 1, pnac - 1);
550: else
551: pm = get_dt_address(ranges + nac, pnac);
552: DEBUG_TR("\t\tparent_mapping %lx\n", pm);
553: *addr = pm + offset;
554: DEBUG_TR("\t\t*address %lx\n", *addr);
555: return 0;
556: }
557:
558: /**
559: * translate_address_dev tries to translate the device specific address
560: * to a host specific address by walking up in the device tree
561: *
562: * @param address a pointer to a 64 bit value which will be
563: * translated
564: * @param current_node phandle of the device from which the
565: * translation will be started
566: */
567: void
568: translate_address_dev(uint64_t *addr, phandle_t current_node)
569: {
570: unsigned char buf[1024];
571: phandle_t parent;
572: unsigned int pnac;
573: unsigned int nac;
574: unsigned int nsc;
575: int addr_type;
576: int len;
577: unsigned int *ranges;
578: unsigned int one_range;
579: DEBUG_TR("translate address %lx, node: %lx\n", *addr, current_node);
580: of_getprop(current_node, "name", buf, 400);
581: DEBUG_TR("current node: %s\n", buf);
582: addr_type =
583: pci_address_type(current_node, *addr, ASSIGNED_ADDRESS_PROPERTY);
584: if (addr_type == -1) {
585: // check in "reg" property if not found in "assigned-addresses"
586: addr_type = pci_address_type(current_node, *addr, REG_PROPERTY);
587: }
588: DEBUG_TR("address_type %x\n", addr_type);
589: current_node = of_parent(current_node);
590: while (1) {
591: parent = of_parent(current_node);
592: if (!parent) {
593: DEBUG_TR("reached root node...\n");
594: break;
595: }
596: of_getprop(current_node, "#address-cells", &nac, 4);
597: of_getprop(current_node, "#size-cells", &nsc, 4);
598: of_getprop(parent, "#address-cells", &pnac, 4);
599: one_range = nac + pnac + nsc;
600: len = of_getprop(current_node, "ranges", buf, 400);
601: if (len < 0) {
602: DEBUG_TR("no 'ranges' property; not translatable\n");
603: return;
604: }
605: ranges = (unsigned int *) &buf[0];
606: while (len > 0) {
607: if (!map_one_range
608: ((uint64_t *) addr, addr_type, ranges, nac, nsc,
609: pnac))
610: /* after a successful mapping we stop
611: * going through the ranges */
612: break;
613: ranges += one_range;
614: len -= one_range * sizeof(int);
615: }
616: DEBUG_TR("address %lx\n", *addr);
617: of_getprop(current_node, "name", buf, 400);
618: DEBUG_TR("current node: %s\n", buf);
619: DEBUG_TR("\t#address-cells: %x\n", nac);
620: DEBUG_TR("\t#size-cells: %x\n", nsc);
621: of_getprop(parent, "name", buf, 400);
622: DEBUG_TR("parent node: %s\n", buf);
623: DEBUG_TR("\t#address-cells: %x\n", pnac);
624: current_node = parent;
625: }
626: }
627:
628: static phandle_t
629: get_boot_device(void)
630: {
631: char buf[1024];
632: phandle_t dev = of_finddevice("/chosen");
633:
634: if (dev == -1) {
635: dev = of_finddevice("/aliases");
636: if (dev == -1)
637: return dev;
638: of_getprop(dev, "net", buf, 1024);
639: } else
640: of_getprop(dev, "bootpath", buf, 1024);
641:
642: return of_finddevice(buf);
643: }
644:
645: /**
646: * translate_address tries to translate the device specific address
647: * of the boot device to a host specific address
648: *
649: * @param address a pointer to a 64 bit value which will be
650: * translated
651: */
652: void
653: translate_address(unsigned long *addr)
654: {
655: translate_address_dev((uint64_t*) addr, get_boot_device());
656: }
657:
658: /**
659: * get_puid walks up in the device tree until it finds a parent
660: * node without a reg property. get_puid is assuming that if the
661: * parent node has no reg property it has found the pci host bridge
662: *
663: * this is not the correct way to find PHBs but it seems to work
664: * for all our systems
665: *
666: * @param node the device for which to find the puid
667: *
668: * @return the puid or 0
669: */
670: uint64_t
671: get_puid(phandle_t node)
672: {
673: uint64_t puid = 0;
674: uint64_t tmp = 0;
1.1.1.2 ! root 675: phandle_t curr_node, last_node;
! 676:
! 677: curr_node = last_node = of_parent(node);
! 678:
! 679: while (curr_node) {
1.1 root 680: puid = tmp;
681: if (of_getprop(curr_node, "reg", &tmp, 8) < 8) {
682: /* if the found PHB is not directly under
683: * root we need to translate the found address */
1.1.1.2 ! root 684: translate_address_dev(&puid, last_node);
1.1 root 685: return puid;
686: }
1.1.1.2 ! root 687: last_node = curr_node;
1.1 root 688: curr_node = of_parent(curr_node);
689: }
1.1.1.2 ! root 690:
1.1 root 691: return 0;
692: }
693:
694: static int set_vio_config(vio_config_t * vio_config, phandle_t net)
695: {
696: of_getprop(net, "reg", &vio_config->reg, 4);
697: of_getprop(net, "compatible", &vio_config->compat, 64);
698:
699: return 0;
700: }
701:
702: /* Fill in the pci config structure from the device tree */
703: static int set_pci_config(pci_config_t * pci_config, phandle_t net)
704: {
705: unsigned char buf[400];
706: int len, bar_nr;
707: unsigned int *assigned_ptr;
708:
709: of_getprop(net, "vendor-id", &pci_config->vendor_id, 4);
710: of_getprop(net, "device-id", &pci_config->device_id, 4);
711: of_getprop(net, "revision-id", &pci_config->revision_id, 4);
712: of_getprop(net, "class-code", &pci_config->class_code, 4);
713: of_getprop(net, "interrupts", &pci_config->interrupt_line, 4);
714:
715: len = of_getprop(net, "assigned-addresses", buf, 400);
716: if (len <= 0)
717: return -1;
718:
719: assigned_ptr = (unsigned int *) &buf[0];
720: pci_config->bus = (assigned_ptr[0] & 0x00ff0000) >> 16;
721: pci_config->devfn = (assigned_ptr[0] & 0x0000ff00) >> 8;
722:
723: while (len > 0) {
724: /* Fixme 64 bit bars */
725: bar_nr = ((assigned_ptr[0] & 0xff) - 0x10) / 4;
726: pci_config->bars[bar_nr].type =
727: (assigned_ptr[0] & 0x0f000000) >> 24;
728: pci_config->bars[bar_nr].addr = assigned_ptr[2];
729: pci_config->bars[bar_nr].size = assigned_ptr[4];
730: assigned_ptr += 5;
731: len -= 5 * sizeof(int);
732: }
733:
734: pci_config->puid = get_puid(net);
735:
736: return 0;
737: }
738:
739: static int set_config(snk_kernel_t * snk_kernel_interface)
740: {
741: phandle_t parent, net = get_boot_device();
742: char compat[64];
743:
744: if (net == -1)
745: return -1;
746:
747: parent = of_parent(net);
748: of_getprop(parent, "compatible", compat, 64);
749: if (!strcmp(compat, "IBM,vdevice"))
750: return set_vio_config(&snk_kernel_interface->vio_conf, net);
751: return set_pci_config(&snk_kernel_interface->pci_conf, net);
752: }
753:
754: void
755: get_mac(char *mac)
756: {
1.1.1.2 ! root 757: uint8_t localmac[8];
! 758: int len;
! 759:
1.1 root 760: phandle_t net = get_boot_device();
761:
762: if (net == -1)
763: return;
764:
1.1.1.2 ! root 765: len = of_getprop(net, "local-mac-address", localmac, 8);
! 766:
! 767: if (len == 8) {
! 768: /* Some bad FDT nodes like veth use a 8-byte wide
! 769: * property instead of 6-byte wide MACs... :-( */
! 770: memcpy(mac, &localmac[2], 6);
! 771: }
! 772: else {
! 773: memcpy(mac, localmac, 6);
! 774: }
1.1 root 775: }
776:
777: static void
778: get_timebase(unsigned int *timebase)
779: {
780: phandle_t cpu;
781: phandle_t cpus = of_finddevice("/cpus");
782:
783: if (cpus == -1)
784: return;
785:
786: cpu = of_child(cpus);
787:
788: if (cpu == -1)
789: return;
790:
791: of_getprop(cpu, "timebase-frequency", timebase, 4);
792: }
793:
794: int
795: glue_init(snk_kernel_t * snk_kernel_interface, unsigned int * timebase,
796: size_t _client_start, size_t _client_size)
797: {
798: phandle_t chosen = of_finddevice("/chosen");
799:
800: client_start = (void *) (long) _client_start;
801: client_size = _client_size;
802:
803: if (chosen == -1)
804: return -1;
805:
806: fd_array[0].type = FILEIO_TYPE_USED;
807: fd_array[0].read = of_fileio_read;
808: fd_array[0].write = of_fileio_write;
809: fd_array[0].ioctl = 0;
810: fd_array[0].close = of_fileio_close;
811: fd_array[0].data = &fd_ihandle_array[0];
812: of_getprop(chosen, "stdin", fd_array[0].data, sizeof(ihandle_t));
813:
814: fd_array[1].type = FILEIO_TYPE_USED;
815: fd_array[1].read = of_fileio_read;
816: fd_array[1].write = of_fileio_write;
817: fd_array[1].ioctl = 0;
818: fd_array[1].close = of_fileio_close;
819: fd_array[1].data = &fd_ihandle_array[1];
820: of_getprop(chosen, "stdout", fd_array[1].data, sizeof(ihandle_t));
821:
822: if (of_write(fd_ihandle_array[1], " ", 1) < 0)
823: return -2;
824:
825: /* Setup Kernel Struct */
826: if (set_config(snk_kernel_interface) == -1) {
827: snk_kernel_interface->print(" No net device found \n");
828: }
829:
830: get_timebase(timebase);
831: rtas_init();
832:
833: snk_kernel_interface->k_romfs_lookup = romfs_lookup;
834: snk_kernel_interface->translate_addr = translate_address;
835: snk_kernel_interface->pci_config_read = rtas_pci_config_read;
836: snk_kernel_interface->pci_config_write = rtas_pci_config_write;
837: claim_rc=(int)(long)of_claim(client_start, client_size, 0);
838:
839: return 0;
840: }
841:
842: void
843: glue_release(void)
844: {
845: if (claim_rc >= 0) {
846: of_release(client_start, client_size);
847: }
848: }
849:
850: static int
851: ofmod_init(void)
852: {
853: of_module.running = 1;
854: return 0;
855: }
856:
857: static int
858: ofmod_term(void)
859: {
860: of_module.running = 0;
861: return 0;
862: }
863:
864: static int
865: ofmod_open(snk_fileio_t *fileio, const char* name, int flags)
866: {
867: if ((fd_ihandle_array[fileio->idx] = of_open (name)) == 0)
868: {
869: /* this module can not open this file */
870: return -1;
871: }
872:
873: fileio->type = FILEIO_TYPE_USED;
874: fileio->read = of_fileio_read;
875: fileio->write = of_fileio_write;
876: fileio->close = of_fileio_close;
877: fileio->data = &fd_ihandle_array[fileio->idx];
878: return 0;
879: }
880:
881: static int
882: ofmod_read(char *buffer, int len)
883: {
884: return len;
885: }
886:
887: static int
888: ofmod_write(char *buffer, int len)
889: {
890: return len;
891: }
892:
893: static int
894: ofmod_ioctl(int request, void *data)
895: {
896: return 0;
897: }
898:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.