1 |
/* |
/* |
2 |
* Copyright (C) 2005-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2005-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: of.c,v 1.18 2006/02/16 05:57:10 debug Exp $ |
* $Id: of.c,v 1.23 2007/03/24 06:40:16 debug Exp $ |
29 |
* |
* |
30 |
* OpenFirmware emulation. |
* OpenFirmware emulation. |
31 |
* |
* |
163 |
{ |
{ |
164 |
if (strcmp(arg[0], "set-colors") == 0) { |
if (strcmp(arg[0], "set-colors") == 0) { |
165 |
/* Used by OpenBSD/macppc: */ |
/* Used by OpenBSD/macppc: */ |
166 |
struct vfb_data *v = cpu->machine->of_data->vfb_data; |
struct vfb_data *v = cpu->machine->md.of_data->vfb_data; |
167 |
int color = OF_GET_ARG(3); |
int color = OF_GET_ARG(3); |
168 |
uint64_t ptr = OF_GET_ARG(4); |
uint64_t ptr = OF_GET_ARG(4); |
169 |
unsigned char rgb[3]; |
unsigned char rgb[3]; |
199 |
|
|
200 |
OF_SERVICE(child) |
OF_SERVICE(child) |
201 |
{ |
{ |
202 |
struct of_device *od = cpu->machine->of_data->of_devices; |
struct of_device *od = cpu->machine->md.of_data->of_devices; |
203 |
int handle = OF_GET_ARG(0); |
int handle = OF_GET_ARG(0); |
204 |
OF_FIND(od, od->parent == handle); |
OF_FIND(od, od->parent == handle); |
205 |
store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->handle); |
store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->handle); |
216 |
|
|
217 |
OF_SERVICE(finddevice) |
OF_SERVICE(finddevice) |
218 |
{ |
{ |
219 |
int h = find_device_handle(cpu->machine->of_data, arg[0]); |
int h = find_device_handle(cpu->machine->md.of_data, arg[0]); |
220 |
store_32bit_word(cpu, base + retofs, h); |
store_32bit_word(cpu, base + retofs, h); |
221 |
return h>0? 0 : -1; |
return h>0? 0 : -1; |
222 |
} |
} |
224 |
|
|
225 |
OF_SERVICE(getprop) |
OF_SERVICE(getprop) |
226 |
{ |
{ |
227 |
struct of_device *od = cpu->machine->of_data->of_devices; |
struct of_device *od = cpu->machine->md.of_data->of_devices; |
228 |
struct of_device_property *pr; |
struct of_device_property *pr; |
229 |
int handle = OF_GET_ARG(0), i, len_returned = 0; |
int handle = OF_GET_ARG(0), i, len_returned = 0; |
230 |
uint64_t buf = OF_GET_ARG(2); |
uint64_t buf = OF_GET_ARG(2); |
271 |
|
|
272 |
OF_SERVICE(getproplen) |
OF_SERVICE(getproplen) |
273 |
{ |
{ |
274 |
struct of_device *od = cpu->machine->of_data->of_devices; |
struct of_device *od = cpu->machine->md.of_data->of_devices; |
275 |
struct of_device_property *pr; |
struct of_device_property *pr; |
276 |
int handle = OF_GET_ARG(0); |
int handle = OF_GET_ARG(0); |
277 |
|
|
348 |
|
|
349 |
OF_SERVICE(parent) |
OF_SERVICE(parent) |
350 |
{ |
{ |
351 |
struct of_device *od = cpu->machine->of_data->of_devices; |
struct of_device *od = cpu->machine->md.of_data->of_devices; |
352 |
int handle = OF_GET_ARG(0); |
int handle = OF_GET_ARG(0); |
353 |
OF_FIND(od, od->handle == handle); |
OF_FIND(od, od->handle == handle); |
354 |
store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->parent); |
store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->parent); |
358 |
|
|
359 |
OF_SERVICE(peer) |
OF_SERVICE(peer) |
360 |
{ |
{ |
361 |
struct of_device *od = cpu->machine->of_data->of_devices; |
struct of_device *od = cpu->machine->md.of_data->of_devices; |
362 |
int handle = OF_GET_ARG(0), parent = 0, peer = 0, seen_self = 1; |
int handle = OF_GET_ARG(0), parent = 0, peer = 0, seen_self = 1; |
363 |
|
|
364 |
if (handle == 0) { |
if (handle == 0) { |
375 |
parent = od->parent; |
parent = od->parent; |
376 |
seen_self = 0; |
seen_self = 0; |
377 |
|
|
378 |
od = cpu->machine->of_data->of_devices; |
od = cpu->machine->md.of_data->of_devices; |
379 |
|
|
380 |
while (od != NULL) { |
while (od != NULL) { |
381 |
if (od->parent == parent) { |
if (od->parent == parent) { |
497 |
bad: |
bad: |
498 |
fatal("of_add_device(): out of memory\n"); |
fatal("of_add_device(): out of memory\n"); |
499 |
exit(1); |
exit(1); |
500 |
|
|
501 |
|
return NULL; /* Silences a compiler warning */ |
502 |
} |
} |
503 |
|
|
504 |
|
|
691 |
*/ |
*/ |
692 |
void of_emul_init_isa(struct machine *machine) |
void of_emul_init_isa(struct machine *machine) |
693 |
{ |
{ |
694 |
struct of_data *ofd = machine->of_data; |
struct of_data *ofd = machine->md.of_data; |
695 |
unsigned char *isa_ranges; |
unsigned char *isa_ranges; |
696 |
|
|
697 |
of_add_device(ofd, "isa", "/"); |
of_add_device(ofd, "isa", "/"); |
722 |
*/ |
*/ |
723 |
void of_emul_init_adb(struct machine *machine) |
void of_emul_init_adb(struct machine *machine) |
724 |
{ |
{ |
725 |
struct of_data *ofd = machine->of_data; |
struct of_data *ofd = machine->md.of_data; |
726 |
unsigned char *adb_interrupts, *adb_reg; |
unsigned char *adb_interrupts, *adb_reg; |
727 |
|
|
728 |
adb_interrupts = malloc(4 * sizeof(uint32_t)); |
adb_interrupts = malloc(4 * sizeof(uint32_t)); |
762 |
*/ |
*/ |
763 |
void of_emul_init_zs(struct machine *machine) |
void of_emul_init_zs(struct machine *machine) |
764 |
{ |
{ |
765 |
struct of_data *ofd = machine->of_data; |
struct of_data *ofd = machine->md.of_data; |
766 |
unsigned char *zs_interrupts, *zs_reg; |
unsigned char *zs_interrupts, *zs_reg; |
767 |
|
|
768 |
zs_reg = malloc(6 * sizeof(uint32_t)); |
zs_reg = malloc(6 * sizeof(uint32_t)); |
838 |
*/ |
*/ |
839 |
void of_emul_init_uninorth(struct machine *machine) |
void of_emul_init_uninorth(struct machine *machine) |
840 |
{ |
{ |
841 |
struct of_data *ofd = machine->of_data; |
struct of_data *ofd = machine->md.of_data; |
842 |
unsigned char *uninorth_reg, *uninorth_bus_range, *uninorth_ranges; |
unsigned char *uninorth_reg, *uninorth_bus_range, *uninorth_ranges; |
843 |
unsigned char *macio_aa, *ata_interrupts, *ata_reg; |
unsigned char *macio_aa, *ata_interrupts, *ata_reg; |
844 |
struct of_device *ic; |
struct of_device *ic; |
904 |
|
|
905 |
if (diskimage_exist(machine, 0, DISKIMAGE_IDE) || |
if (diskimage_exist(machine, 0, DISKIMAGE_IDE) || |
906 |
diskimage_exist(machine, 1, DISKIMAGE_IDE)) { |
diskimage_exist(machine, 1, DISKIMAGE_IDE)) { |
907 |
|
char tmpstr[400]; |
908 |
of_add_device(ofd, "ata", "/bandit/gc"); |
of_add_device(ofd, "ata", "/bandit/gc"); |
909 |
of_add_prop_str(machine, ofd, "/bandit/gc/ata", "name", "ata"); |
of_add_prop_str(machine, ofd, "/bandit/gc/ata", "name", "ata"); |
910 |
of_add_prop_str(machine, ofd, "/bandit/gc/ata", "compatible", |
of_add_prop_str(machine, ofd, "/bandit/gc/ata", "compatible", |
927 |
of_store_32bit_in_host(ata_reg + 28, 0); |
of_store_32bit_in_host(ata_reg + 28, 0); |
928 |
of_add_prop(ofd, "/bandit/gc/ata", "reg", ata_reg, |
of_add_prop(ofd, "/bandit/gc/ata", "reg", ata_reg, |
929 |
8*sizeof(uint32_t), 0); |
8*sizeof(uint32_t), 0); |
930 |
device_add(machine, "wdc addr=0xf3020000 irq=21 " |
|
931 |
"addr_mult=0x10"); |
snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0xf3020000 " |
932 |
|
"irq=%s.cpu[%i].gc.lo.21 addr_mult=0x10", machine->path, |
933 |
|
machine->bootstrap_cpu); |
934 |
|
device_add(machine, tmpstr); |
935 |
} |
} |
936 |
|
|
937 |
return; |
return; |
1063 |
if (verbose >= 2) |
if (verbose >= 2) |
1064 |
of_dump_all(ofd); |
of_dump_all(ofd); |
1065 |
|
|
1066 |
machine->of_data = ofd; |
machine->md.of_data = ofd; |
1067 |
return ofd; |
return ofd; |
1068 |
|
|
1069 |
bad: |
bad: |
1070 |
fatal("of_emul_init(): out of memory\n"); |
fatal("of_emul_init(): out of memory\n"); |
1071 |
exit(1); |
exit(1); |
1072 |
|
|
1073 |
|
return NULL; /* Silences a compiler warning */ |
1074 |
} |
} |
1075 |
|
|
1076 |
|
|
1086 |
char *arg[OF_N_MAX_ARGS]; |
char *arg[OF_N_MAX_ARGS]; |
1087 |
uint64_t base, ptr; |
uint64_t base, ptr; |
1088 |
struct of_service *os; |
struct of_service *os; |
1089 |
struct of_data *of_data = cpu->machine->of_data; |
struct of_data *of_data = cpu->machine->md.of_data; |
1090 |
|
|
1091 |
if (of_data == NULL) { |
if (of_data == NULL) { |
1092 |
fatal("of_emul(): no of_data struct?\n"); |
fatal("of_emul(): no of_data struct?\n"); |
1170 |
fatal("[ of: unimplemented service \"%s\" with %i input " |
fatal("[ of: unimplemented service \"%s\" with %i input " |
1171 |
"args and %i output values ]\n", service, nargs, nret); |
"args and %i output values ]\n", service, nargs, nret); |
1172 |
cpu->running = 0; |
cpu->running = 0; |
|
cpu->dead = 1; |
|
1173 |
} |
} |
1174 |
|
|
1175 |
for (i=0; i<nargs; i++) |
for (i=0; i<nargs; i++) |