1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #ifndef _EMUL_CHIRP_C_
23 #define _EMUL_CHIRP_C_
25 /* Note: this module is called via a table. There is no benefit in
28 #include "emul_generic.h"
29 #include "emul_chirp.h"
43 #ifndef STATIC_INLINE_EMUL_CHIRP
44 #define STATIC_INLINE_EMUL_CHIRP STATIC_INLINE
48 /* Descriptor of the open boot services being emulated */
50 typedef int (chirp_handler
)
54 typedef struct _chirp_services
{
56 chirp_handler
*handler
;
60 /* The OpenBoot emulation is, at any time either waiting for a client
61 request or waiting on a client callback */
68 struct _os_emul_data
{
69 chirp_emul_state state
;
70 unsigned_word return_address
;
71 unsigned_word arguments
;
72 chirp_services
*service
;
73 unsigned_word serving_instruction_ea
;
74 unsigned_word catching_instruction_ea
;
77 chirp_services
*services
;
81 /* Read in the argument list and make the most basic check that number
82 of argumnets are consistent with what was expected */
85 chirp_read_args(void *args
,
98 emul_read_buffer(args
, data
->arguments
,
101 base
= (struct base_args
*)args
;
102 if (T2H_4(base
->n_args
) != n_args
|| T2H_4(base
->n_returns
) != n_returns
) {
103 TRACE(trace_os_emul
, ("invalid nr of args - n_args=%ld, n_returns=%ld\n",
104 (long)T2H_4(base
->n_args
),
105 (long)T2H_4(base
->n_returns
)));
112 /* OpenBoot emulation functions */
114 /* client interface */
117 chirp_emul_test(os_emul_data
*data
,
124 unsigned32 n_returns
;
126 unsigned32 name
; /*string*/
131 chirp_services
*service
= data
->services
;
132 /* read in the arguments */
133 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
135 emul_read_string(name
, T2H_4(args
.name
), sizeof(name
),
137 TRACE(trace_os_emul
, ("test - in - name=`%s'\n", name
));
138 /* see if we know about the service */
139 while (service
->name
!= NULL
&& strcmp(service
->name
, name
) != 0) {
142 if (service
->name
== NULL
)
146 /* write the arguments back out */
147 TRACE(trace_os_emul
, ("test - out - missing=%ld\n",
148 (long)args
.missing
));
149 emul_write_buffer(&args
, data
->arguments
,
159 chirp_emul_peer(os_emul_data
*data
,
166 unsigned32 n_returns
;
170 unsigned32 sibling_phandle
;
173 device
*sibling_dev
= NULL
;
174 /* read in the arguments */
175 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
177 dev
= cap_internal(data
->phandles
, args
.phandle
);
178 TRACE(trace_os_emul
, ("peer - in - phandle=0x%lx(0x%lx`%s')\n",
179 (unsigned long)T2H_4(args
.phandle
),
181 (dev
== NULL
? "" : device_name(dev
))));
183 if (dev
== NULL
&& args
.phandle
!= 0)
185 if (args
.phandle
== 0)
186 sibling_dev
= data
->root
;
188 sibling_dev
= device_sibling(dev
);
189 if (sibling_dev
== NULL
)
190 args
.sibling_phandle
= 0;
192 args
.sibling_phandle
= cap_external(data
->phandles
, sibling_dev
);
193 /* write the arguments back out */
194 TRACE(trace_os_emul
, ("peer - out - sibling_phandle=0x%lx(0x%lx`%s')\n",
195 (unsigned long)T2H_4(args
.sibling_phandle
),
196 (unsigned long)sibling_dev
,
199 : device_name(sibling_dev
))));
200 emul_write_buffer(&args
, data
->arguments
,
207 chirp_emul_child(os_emul_data
*data
,
214 unsigned32 n_returns
;
218 unsigned32 child_phandle
;
222 /* read the arguments in */
223 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
225 dev
= cap_internal(data
->phandles
, args
.phandle
);
226 TRACE(trace_os_emul
, ("child - in - phandle=0x%lx(0x%lx`%s')\n",
227 (unsigned long)T2H_4(args
.phandle
),
229 (dev
== NULL
? "" : device_name(dev
))));
231 if (dev
== (device
*)0)
233 child_dev
= device_child(dev
);
234 if (child_dev
== NULL
)
235 args
.child_phandle
= 0;
237 args
.child_phandle
= cap_external(data
->phandles
, child_dev
);
238 /* write the result out */
239 TRACE(trace_os_emul
, ("child - out - child_phandle=0x%lx(0x%lx`%s')\n",
240 (unsigned long)T2H_4(args
.child_phandle
),
241 (unsigned long)child_dev
,
242 (child_dev
== NULL
? "" : device_name(child_dev
))));
243 emul_write_buffer(&args
, data
->arguments
,
250 chirp_emul_parent(os_emul_data
*data
,
257 unsigned32 n_returns
;
261 unsigned32 parent_phandle
;
265 /* read the args in */
266 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
268 dev
= cap_internal(data
->phandles
, args
.phandle
);
269 TRACE(trace_os_emul
, ("parent - in - phandle=0x%lx(0x%lx`%s')\n",
270 (unsigned long)T2H_4(args
.phandle
),
272 (dev
== NULL
? "" : device_name(dev
))));
274 if (dev
== (device
*)0)
276 parent_dev
= device_parent(dev
);
277 if (parent_dev
== NULL
)
278 args
.parent_phandle
= 0;
280 args
.parent_phandle
= cap_external(data
->phandles
, parent_dev
);
281 /* return the result */
282 TRACE(trace_os_emul
, ("parent - out - parent_phandle=0x%lx(0x%lx`%s')\n",
283 (unsigned long)T2H_4(args
.parent_phandle
),
284 (unsigned long)parent_dev
,
285 (parent_dev
== NULL
? "" : device_name(parent_dev
))));
286 emul_write_buffer(&args
, data
->arguments
,
293 chirp_emul_instance_to_package(os_emul_data
*data
,
297 error("chirp: instance-to-package unimplemented\n");
302 chirp_emul_getproplen(os_emul_data
*data
,
306 struct getproplen_args
{
309 unsigned32 n_returns
;
318 const device_property
*prop
;
319 /* read the args in */
320 if (chirp_read_args(&args
, sizeof(args
), 2, 1, data
, processor
, cia
))
322 dev
= cap_internal(data
->phandles
, args
.phandle
);
323 /* find our prop and get its length */
324 if (dev
== (device
*)0)
326 emul_read_string(name
,
330 TRACE(trace_os_emul
, ("getproplen - in - phandle=0x%lx(0x%lx`%s') name=`%s'\n",
331 (unsigned long)T2H_4(args
.phandle
),
333 (dev
== NULL
? "" : device_name(dev
)),
335 prop
= device_find_property(dev
, name
);
336 if (prop
== (device_property
*)0) {
340 args
.proplen
= H2T_4(prop
->sizeof_array
);
342 /* return the result */
343 TRACE(trace_os_emul
, ("getproplen - out - proplen=%ld\n",
344 (unsigned long)T2H_4(args
.proplen
)));
345 emul_write_buffer(&args
, data
->arguments
,
352 chirp_emul_getprop(os_emul_data
*data
,
356 struct getprop_args
{
359 unsigned32 n_returns
;
370 const device_property
*prop
;
371 /* read in the args */
372 if (chirp_read_args(&args
, sizeof(args
), 4, 1, data
, processor
, cia
))
374 dev
= cap_internal(data
->phandles
, args
.phandle
);
375 emul_read_string(name
,
379 TRACE(trace_os_emul
, ("getprop - in - phandle=0x%lx(0x%lx`%s') name=`%s' buf=0x%lx buflen=%ld\n",
380 (unsigned long)T2H_4(args
.phandle
),
382 (dev
== NULL
? "" : device_name(dev
)),
384 (unsigned long)T2H_4(args
.buf
),
385 (unsigned long)T2H_4(args
.buflen
)));
386 /* get the property */
387 if (dev
== (device
*)0)
389 prop
= device_find_property(dev
, name
);
390 if (prop
== (device_property
*)0) {
394 int size
= T2H_4(args
.buflen
);
395 if (size
> prop
->sizeof_array
)
396 size
= prop
->sizeof_array
;
397 emul_write_buffer(prop
->array
, T2H_4(args
.buf
),
400 args
.size
= H2T_4(size
);
402 switch (prop
->type
) {
403 case string_property
:
404 TRACE(trace_os_emul
, ("getprop - value=`%s' (string)\n",
405 (char*)prop
->array
));
410 /* write back the result */
411 TRACE(trace_os_emul
, ("getprop - out - size=%ld\n",
412 (unsigned long)T2H_4(args
.size
)));
413 emul_write_buffer(&args
, data
->arguments
,
420 chirp_emul_nextprop(os_emul_data
*data
,
424 error("chirp: nextprop not implemented\n");
429 chirp_emul_setprop(os_emul_data
*data
,
433 error("chirp: setprop not implemented\n");
438 chirp_emul_canon(os_emul_data
*data
,
442 error("chirp: canon not implemented\n");
447 chirp_emul_finddevice(os_emul_data
*data
,
451 struct finddevice_args
{
454 unsigned32 n_returns
;
456 unsigned32 device_specifier
;
460 char device_specifier
[1024];
463 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
465 emul_read_string(device_specifier
,
466 T2H_4(args
.device_specifier
),
467 sizeof(device_specifier
),
469 TRACE(trace_os_emul
, ("finddevice - in - device_specifier=`%s'\n",
471 /* find the device */
472 dev
= device_tree_find_device(data
->root
,
474 if (dev
== (device
*)0)
477 args
.phandle
= cap_external(data
->phandles
, dev
);
478 /* return its phandle */
479 TRACE(trace_os_emul
, ("finddevice - out - phandle=0x%lx(0x%lx`%s')\n",
480 (unsigned long)T2H_4(args
.phandle
),
482 (dev
== NULL
? "" : device_name(dev
))));
483 emul_write_buffer(&args
, data
->arguments
,
490 chirp_emul_instance_to_path(os_emul_data
*data
,
494 error("chirp: instance_to_path not implemented\n");
499 chirp_emul_package_to_path(os_emul_data
*data
,
503 error("chirp: package_to_path not implemented\n");
508 chirp_emul_call_method(os_emul_data
*data
,
512 error("chirp: call-method implemented\n");
520 chirp_emul_open(os_emul_data
*data
,
527 unsigned32 n_returns
;
529 unsigned32 device_specifier
;
535 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
537 emul_read_string(name
,
538 T2H_4(args
.device_specifier
),
541 TRACE(trace_os_emul
, ("open - in - device_specifier=`%s'\n",
543 /* open the device */
544 printf_filtered("OpenBoot - open unimplemented for %s\n", name
);
546 /* return the ihandle result */
547 TRACE(trace_os_emul
, ("open - out - ihandle=0x%lx\n",
548 (unsigned long)T2H_4(args
.ihandle
)));
549 emul_write_buffer(&args
, data
->arguments
,
556 chirp_emul_close(os_emul_data
*data
,
560 error("chirp: close not implemented\n");
565 chirp_emul_read(os_emul_data
*data
,
572 unsigned32 n_returns
;
583 if (chirp_read_args(&args
, sizeof(args
), 3, 1, data
, processor
, cia
))
585 TRACE(trace_os_emul
, ("read - in - ihandle=0x%lx addr=0x%lx len=%ld\n",
586 (unsigned long)args
.ihandle
,
587 (unsigned long)T2H_4(args
.addr
),
588 (unsigned long)T2H_4(args
.len
)));
590 actual
= T2H_4(args
.len
);
591 if (actual
>= sizeof(buf
))
592 actual
= sizeof(buf
) - 1;
593 actual
= read(BE2H_4(args
.ihandle
), buf
, actual
);
595 emul_write_buffer(buf
,
599 args
.actual
= H2T_4(actual
);
605 /* return the result */
606 TRACE(trace_os_emul
, ("read - out - actual=%ld `%s'\n",
607 (long)T2H_4(args
.actual
),
608 (actual
>= 0 ? buf
: "")));
609 emul_write_buffer(&args
, data
->arguments
,
616 chirp_emul_write(os_emul_data
*data
,
623 unsigned32 n_returns
;
634 if (chirp_read_args(&args
, sizeof(args
), 3, 1, data
, processor
, cia
))
636 actual
= T2H_4(args
.len
);
637 if (actual
>= sizeof(buf
))
638 actual
= sizeof(buf
) - 1;
639 emul_read_buffer(buf
,
644 TRACE(trace_os_emul
, ("write - in - ihandle=0x%lx `%s' (%ld)\n",
645 (unsigned long)args
.ihandle
, buf
, (long)actual
));
647 actual
= write(BE2H_4(args
.ihandle
), buf
, actual
);
651 args
.actual
= H2T_4(actual
);
652 /* return the result */
653 TRACE(trace_os_emul
, ("write - out - actual=%ld\n",
654 (long)T2H_4(args
.actual
)));
655 emul_write_buffer(&args
, data
->arguments
,
662 chirp_emul_seek(os_emul_data
*data
,
666 error("chirp: seek not implemented\n");
674 chirp_emul_claim(os_emul_data
*data
,
678 error("chirp: claim not implemented\n");
683 chirp_emul_release(os_emul_data
*data
,
687 error("chirp: release not implemented\n");
692 /* Control transfer */
695 chirp_emul_boot(os_emul_data
*data
,
699 error("chirp: boot not implemented\n");
704 chirp_emul_enter(os_emul_data
*data
,
708 error("chirp: enter not implemented\n");
713 chirp_emul_exit(os_emul_data
*data
,
717 cpu_halt(processor
, cia
, was_exited
, 0); /* always succeeds */
722 chirp_emul_chain(os_emul_data
*data
,
726 error("chirp: chain not implemented\n");
734 chirp_emul_interpret(os_emul_data
*data
,
738 error("chirp: interpret not implemented\n");
743 chirp_emul_set_callback(os_emul_data
*data
,
747 error("chirp: set_callback not implemented\n");
752 chirp_emul_set_symbol_lookup(os_emul_data
*data
,
756 error("chirp: set_symbol_lookup not implemented\n");
764 chirp_emul_milliseconds(os_emul_data
*data
,
771 unsigned32 n_returns
;
777 /* read in the arguments */
778 if (chirp_read_args(&args
, sizeof(args
), 1, 1, data
, processor
, cia
))
780 /* make up a number */
781 time
= event_queue_time(cpu_event_queue(processor
)) / 1000000;
782 args
.ms
= H2T_4(time
);
783 /* write the arguments back out */
784 TRACE(trace_os_emul
, ("milliseconds - out - ms=%ld\n",
785 (unsigned long)T2H_4(args
.ms
)));
786 emul_write_buffer(&args
, data
->arguments
,
795 static chirp_services services
[] = {
797 /* client interface */
798 { "test", chirp_emul_test
},
801 { "peer", chirp_emul_peer
},
802 { "child", chirp_emul_child
},
803 { "parent", chirp_emul_parent
},
804 { "instance-to-package", chirp_emul_instance_to_package
},
805 { "getproplen", chirp_emul_getproplen
},
806 { "getprop", chirp_emul_getprop
},
807 { "nextprop", chirp_emul_nextprop
},
808 { "setprop", chirp_emul_setprop
},
809 { "canon", chirp_emul_canon
},
810 { "finddevice", chirp_emul_finddevice
},
811 { "instance-to-path", chirp_emul_instance_to_path
},
812 { "package-to-path", chirp_emul_package_to_path
},
813 { "call-method", chirp_emul_call_method
},
816 { "open", chirp_emul_open
},
817 { "close", chirp_emul_close
},
818 { "read", chirp_emul_read
},
819 { "write", chirp_emul_write
},
820 { "seek", chirp_emul_seek
},
821 { "write", chirp_emul_write
},
824 { "claim", chirp_emul_claim
},
825 { "release", chirp_emul_release
},
827 /* control transfer */
828 { "boot", chirp_emul_boot
},
829 { "enter", chirp_emul_enter
},
830 { "exit", chirp_emul_exit
},
831 { "chain", chirp_emul_chain
},
834 { "interpret", chirp_emul_interpret
},
835 { "set_callback", chirp_emul_set_callback
},
836 { "set_symbol_lookup", chirp_emul_set_symbol_lookup
},
839 { "milliseconds", chirp_emul_milliseconds
},
841 { 0, /* sentinal */ },
847 /* Any starting address greater than this is assumed to be an Chirp
850 #ifndef CHIRP_START_ADDRESS
851 #define CHIRP_START_ADDRESS 0x80000000
854 typedef struct _chirp_note_desc
{
862 typedef struct _chirp_note
{
863 chirp_note_desc desc
;
867 typedef struct _chirp_note_head
{
874 map_over_chirp_note(bfd
*image
,
878 chirp_note
*note
= (chirp_note
*)obj
;
879 if (strcmp(sect
->name
, ".note") == 0) {
880 chirp_note_head head
;
883 if (!bfd_get_section_contents(image
, sect
,
884 &head
, 0, sizeof(head
)))
886 head
.namesz
= bfd_get_32(image
, (void*)&head
.namesz
);
887 head
.descsz
= bfd_get_32(image
, (void*)&head
.descsz
);
888 head
.type
= bfd_get_32(image
, (void*)&head
.type
);
889 if (head
.type
!= 0x1275)
892 /* check the name field */
893 if (head
.namesz
> sizeof(name
)) {
894 printf_filtered("open-boot warning: note name too long (%ld)\n",
898 if (!bfd_get_section_contents(image
, sect
,
899 name
, sizeof(head
), head
.namesz
)) {
900 printf_filtered("open-boot warning: note name unreadable\n");
903 if (strcmp(name
, "PowerPC") != 0) {
904 printf_filtered("open-boot warning: note name (%s) not `PowerPC'\n",
908 /* get the contents */
909 if (head
.descsz
!= sizeof(note
->desc
)) {
910 printf_filtered("open-boot warning: note descriptor of wrong size\n");
913 if (!bfd_get_section_contents(image
, sect
,
914 ¬e
->desc
, /* page align start */
915 ((sizeof(head
) + head
.namesz
) + 3) & ~3,
917 printf_filtered("open-boot warning: note descriptor unreadable\n");
920 note
->desc
.real_mode
= bfd_get_32(image
, (void*)¬e
->desc
.real_mode
);
921 note
->desc
.real_base
= bfd_get_32(image
, (void*)¬e
->desc
.real_base
);
922 note
->desc
.real_size
= bfd_get_32(image
, (void*)¬e
->desc
.real_size
);
923 note
->desc
.virt_base
= bfd_get_32(image
, (void*)¬e
->desc
.virt_base
);
924 note
->desc
.virt_size
= bfd_get_32(image
, (void*)¬e
->desc
.virt_size
);
930 static os_emul_data
*
931 emul_chirp_create(device
*root
,
939 /* Sanity check that this really is the chosen emulation */
940 if (name
== NULL
&& image
== NULL
)
943 && strcmp(name
, "ob") != 0
944 && strcmp(name
, "ieee1274") != 0
945 && strcmp(name
, "chrp") != 0
946 && strcmp(name
, "chirp") != 0
947 && strcmp(name
, "openboot") != 0)
950 /* look for an elf note section */
951 memset(¬e
, 0, sizeof(note
));
953 bfd_map_over_sections(image
, map_over_chirp_note
, ¬e
);
954 if (name
== NULL
&& image
!= NULL
&& !note
.found
)
958 device_add_string_property(root
,
963 const unsigned_word memory_size
= 0x200000;
966 const unsigned nr_page_table_entry_groups
= (memory_size
< 0x800000
967 ? 1024 /* min allowed */
968 : (memory_size
/ 4096 / 2));
969 const unsigned sizeof_htab
= nr_page_table_entry_groups
* 64;
970 const unsigned_word htab_ra
= memory_size
- sizeof_htab
;
972 /* a page for firmware calls */
973 const unsigned_word sizeof_code
= 4096;
974 const unsigned_word code_ra
= htab_ra
- sizeof_code
;
977 const unsigned sizeof_stack
= 32 * 1024;
978 const unsigned_word stack_ra
= code_ra
- sizeof_stack
;
980 /* the firmware's home */
981 const int real_mode
= 0;
982 /* const unsigned_word real_base = stack_ra; */
983 /* const unsigned real_size = memory_size - real_base; */
984 const unsigned_word virt_base
= CHIRP_START_ADDRESS
;
985 /* const unsigned virt_size = real_size;*/
987 /* the virtual addresses */
988 const unsigned_word stack_va
= virt_base
;
989 const unsigned_word code_va
= stack_va
+ sizeof_stack
;
990 const unsigned_word code_client_va
= code_va
;
991 const unsigned_word code_callback_va
= code_client_va
+ 16;
992 const unsigned_word code_loop_va
= code_callback_va
+ 16;
993 const unsigned_word htab_va
= code_va
+ sizeof_code
;
995 #ifdef bfd_big_endian /* new bfd */
996 big_endian
= bfd_big_endian(image
);
998 big_endian
= image
->xvec
->byteorder_big_p
;
1003 device
*options
= device_tree_add_found(root
, "/", "options");
1004 device_add_integer_property(options
,
1007 device_add_boolean_property(options
,
1010 device_add_string_property(options
,
1013 device_add_boolean_property(options
,
1014 "strict-alignment?",
1015 (WITH_ALIGNMENT
== STRICT_ALIGNMENT
1017 device_add_boolean_property(options
,
1019 WITH_FLOATING_POINT
);
1020 device_add_string_property(options
,
1026 device_tree_add_found_uw_u_u(root
, "/", "memory",
1027 0, memory_size
, access_read_write_exec
);
1029 /* initialization */
1031 device
*init
= device_tree_add_found(root
, "/", "init");
1033 device
*init_register
= device_tree_add_found(init
, "", "register");
1034 device_add_integer_property(init_register
,
1037 device_add_integer_property(init_register
,
1039 bfd_get_start_address(image
));
1040 device_add_integer_property(init_register
,
1042 stack_va
+ sizeof_stack
- 16);
1044 /* init the code callback along with a loop for the unused cpu's */
1045 device_add_integer_property(init_register
,
1048 /* client interface */
1049 device_tree_add_found_uw_u_u(init
, "",
1051 code_ra
+ (code_client_va
- code_va
),
1052 4, emul_call_instruction
);
1053 device_tree_add_found_uw_u_u(init
, "",
1055 code_ra
+ (code_client_va
- code_va
) + 4,
1056 4, emul_blr_instruction
);
1057 /* callback return address */
1058 device_tree_add_found_uw_u_u(init
, "",
1060 code_ra
+ (code_callback_va
- code_va
),
1061 4, emul_call_instruction
);
1062 /* loop to keep other processors busy */
1063 device_tree_add_found_uw_u_u(init
, "",
1065 code_ra
+ (code_loop_va
- code_va
),
1066 4, emul_loop_instruction
);
1067 device_add_integer_property(init_register
,
1069 (msr_machine_check_enable
1072 : (msr_instruction_relocate
1073 | msr_data_relocate
))
1076 : (msr_little_endian_mode
1077 | msr_interrupt_little_endian_mode
1079 device_add_integer_property(init_register
,
1083 | ((sizeof_htab
- 1) >> 16)));
1085 device_add_integer_property(init_register
,
1088 device_add_integer_property(init_register
,
1092 { /* hash table and vm */
1093 device
*htab_root
= device_tree_add_found_uw_u(init
, "", "htab",
1094 htab_ra
, sizeof_htab
);
1095 device_tree_add_found_uw_uw_u_u_u(htab_root
, "", "pte",
1096 stack_ra
, stack_va
, sizeof_stack
,
1097 0x7/*wimg*/, 0x2/*pp*/);
1098 device_tree_add_found_uw_uw_u_u_u(htab_root
, "", "pte",
1099 code_ra
, code_va
, sizeof_code
,
1100 0x7/*wimg*/, 0x2/*pp*/);
1101 device_tree_add_found_uw_uw_u_u_u(htab_root
, "", "pte",
1102 htab_ra
, htab_va
, sizeof_htab
,
1103 0x7/*wimg*/, 0x2/*pp*/);
1104 device_tree_add_found_uw_u_u_c(htab_root
, "", "pte",
1106 0x7/*wimg*/, 0x2/*pp*/,
1107 bfd_get_filename (image
));
1112 { /* chosen options */
1113 device
*chosen
= device_tree_add_found(root
, "/", "chosen");
1114 device_add_string_property(chosen
,
1117 device_add_integer_property(chosen
,
1119 0); /* FIXME: ihandle of stdin */
1120 device_add_integer_property(chosen
,
1122 1); /* FIXME: ihandle of stdout */
1123 device_add_string_property(chosen
,
1126 device_add_string_property(chosen
,
1130 device_add_integer_property(chosen
,
1132 0); /* FIXME: ihandle of memory */
1133 device_add_integer_property(chosen
,
1139 /* FIXME - should come from the device tree */
1140 data
= ZALLOC(os_emul_data
);
1141 data
->serving_instruction_ea
= code_client_va
;
1142 data
->catching_instruction_ea
= code_callback_va
;
1143 data
->phandles
= cap_create("chirp");
1145 data
->services
= services
;
1151 emul_chirp_init(os_emul_data
*emul_data
,
1154 emul_data
->state
= serving
;
1155 cap_init(emul_data
->phandles
);
1159 emul_chirp_instruction_call(cpu
*processor
,
1162 os_emul_data
*emul_data
)
1164 unsigned_word service_name_addr
;
1165 unsigned_word result
;
1166 char service_buf
[32];
1168 chirp_services
*service
;
1170 switch (emul_data
->state
) {
1173 /* we are waiting on an OpenBoot request from the client program
1174 via the client interface */
1175 if (cia
!= emul_data
->serving_instruction_ea
)
1177 emul_data
->return_address
= LR
;
1178 emul_data
->arguments
= cpu_registers(processor
)->gpr
[3];
1179 /* try to determine what to do */
1180 service_name_addr
= emul_read_word(cpu_registers(processor
)->gpr
[3],
1182 service_name
= emul_read_string(service_buf
, service_name_addr
,
1183 sizeof(service_buf
), processor
, cia
);
1184 TRACE(trace_os_emul
, ("%s called from 0x%lx with args 0x%lx\n",
1186 (unsigned long)emul_data
->return_address
,
1187 (unsigned long)emul_data
->arguments
));
1190 while (service
->name
!= NULL
&& strcmp(service
->name
, service_name
) != 0)
1192 if (service
->name
== NULL
) {
1193 error("OpenBoot service `%s' not found\n", service_name
);
1194 TRACE(trace_os_emul
, ("%s not found\n", service_name
));
1195 cpu_registers(processor
)->gpr
[3] = 0;
1196 cpu_restart(processor
, emul_data
->return_address
);
1198 emul_data
->service
= service
;
1200 result
= service
->handler(emul_data
, processor
, cia
);
1204 /* We were handling a client request but encountered a page fault
1205 (or other exception). The fault needs to be passed back to the
1206 client using the the client suplied call back interface */
1207 error("emul_chirp_instruction_call() faulting unimplemented\n");
1212 /* Have called the client (via the callback interface) because
1213 some fault (hash table miss) occured. The client has finished
1214 handling this and is now returning */
1215 error("emul_chirp_instruction_call() catching unimplemented\n");
1220 error("emul_chirp_instruction_call() unknown internal state\n");
1226 /* return to caller - instruction following this is a function return */
1230 const os_emul emul_chirp
= {
1234 NULL
, /*system_call*/
1235 emul_chirp_instruction_call
,