mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-26 05:20:30 +00:00
Latest cagney update
This commit is contained in:
parent
436d414327
commit
979c3c25fd
@ -1,3 +1,114 @@
|
||||
Mon Jan 8 12:17:22 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* device_table.c (register_init): Make format type correct.
|
||||
|
||||
Wed Jan 3 19:21:46 1996 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* emul_bugapi.c (emul_bugapi_create): Add nodes to init the
|
||||
system-call trap to the emul instruction call instruction (Along
|
||||
with an rfi and infinate loop).
|
||||
|
||||
* emul_bugapi.c (emul_bugapi_instruction_call): Expand to include
|
||||
a few real PPC bug calls. Test with simple hello world.
|
||||
|
||||
Tue Jan 2 20:51:19 1996 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
||||
|
||||
* device.h, device.c (device_child, device_sibling): New
|
||||
functions. Return corresponding device value.
|
||||
|
||||
* emul_chirp.c (chirp_emul_child, chirp_emul_peer,
|
||||
chirp_emul_parent): New functions - emulate corresponding OpenBoot
|
||||
interfaces.
|
||||
|
||||
* device_table.c (register_init): Extend properties attached to
|
||||
register init node to allow a specific processor's register to be
|
||||
specified.
|
||||
|
||||
* emul_chirp.c (emul_chirp_create): Init SMP correctly - the
|
||||
initial PC for all processors is an infinate loop but then, for
|
||||
processor zero, is quickly changed to be the correct code starting
|
||||
address.
|
||||
|
||||
* emul_chirp.c (emul_chirp_create): Add fake bootpath
|
||||
et.al. properties to tree.
|
||||
|
||||
* emul_chirp.c (chirp_emul_getproplen): New function. Emulate the
|
||||
getproplen OpenBoot call.
|
||||
|
||||
* emul_chirp.c (emul_chirp_instruction_call): Document other
|
||||
possible chirp emulation internal states.
|
||||
|
||||
* emul_chirp.c (emul_chirp_instruction_call): Trace failed lookups
|
||||
as well as successful ones.
|
||||
|
||||
* emul_chirp.c (emul_chirp_open): New function - handle open
|
||||
client call.
|
||||
|
||||
* Makefile.in (maintainer-clean): Proper rule that eliminates more
|
||||
junk.
|
||||
|
||||
Tue Dec 19 13:00:11 1995 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* emul_chirp.c (chirp_emul_exit): Full out call.
|
||||
|
||||
* device_table.c (htab_map_page): Wasn't handling byte swap when
|
||||
creating entries in the hash table.
|
||||
|
||||
* device.c (device_tree_find_node): Allow primative wild-card match
|
||||
of device names with the path.
|
||||
|
||||
FIXME: As mentioned earlier, the device stuff needs work to bring
|
||||
it into line with OpenBoot. Part of this work is rewriting the
|
||||
find_node function so that it behaves as specified in p1275.
|
||||
|
||||
Mon Dec 18 19:58:56 1995 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* emul_chrp.c (chirp_emul_write, chirp_emul_finddevice): add
|
||||
better tracing.
|
||||
|
||||
* emul_chrp.c: Change return type of emul functions to int. Emul
|
||||
functions either return -1 or zero so unsigned was a bit
|
||||
dangerous.
|
||||
|
||||
* inline.h (*), igen.c, dgen.c, *: Update INLINE macros so that
|
||||
they are paramaterised with the type of the function. Gets around
|
||||
the problem of `static' needing to come first with `attribute'
|
||||
comming last. Format declarations and definitions so that emacs
|
||||
doesn't get confused.
|
||||
|
||||
Fri Dec 15 17:06:44 1995 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* std-config.h (PSIM_INLINE): Add missing inline configuration
|
||||
control for the main loop.
|
||||
|
||||
* mon.c (mon_print_info): If monitoring disabled still print out
|
||||
the number seconds used.
|
||||
|
||||
* psim.c (run_until_stop): Don't monitor the cache misses when
|
||||
monitoring is disabled.
|
||||
|
||||
* configure.in (sim_mon, sim_monitor): Correct typo - sim_mon ->
|
||||
sim_monitor for shell variable (or should that have been the other
|
||||
way around?).
|
||||
|
||||
* vm.c (vm_synchronize_context): Fix wrong test for unsuported
|
||||
change in endian-mode.
|
||||
|
||||
* std-config.h (WITH_REGPARM), inline.h (IDECODE_INLINE,
|
||||
SEMANTICS_INLINE): Add -DWITH_REGPARM=<n> option. Enables the
|
||||
__attribute__((__regparm(WITH_REGPARM))) for some functions.
|
||||
configure with --enable-sim-cflags="-DWITH_REGPARAM=3" (say).
|
||||
Unfortunatly it tickles a bug (gcc?) and can't be used.
|
||||
|
||||
Mon Dec 18 13:36:06 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* device.c (device_tree_add_device): Make trace fprintf arguments
|
||||
type correct.
|
||||
* device_table.c (htab_decode_hash_table): Ditto.
|
||||
(htab_map_binary): Ditto.
|
||||
(htab_init_callback): Ditto.
|
||||
* vm.c (om_virtual_to_real): Ditto.
|
||||
|
||||
Sat Dec 16 09:54:18 1995 Michael Meissner <meissner@wogglebug.tiac.net>
|
||||
|
||||
* emul_netbsd.c (emul_netbsd_create): Deal with new BFD that
|
||||
|
@ -83,8 +83,7 @@ TRACE_CFLAGS = @sim_trace@
|
||||
ASSERT_CFLAGS = @sim_assert@
|
||||
RESERVED_CFLAGS = @sim_reserved@
|
||||
MONITOR_CFLAGS = @sim_monitor@
|
||||
FUNC_CFLAGS = @sim_func@
|
||||
MODEL_CFLAGS = @sim_model@ @sim_default_model@
|
||||
MODEL_CFLAGS = @sim_model@ @sim_default_model@ @sim_model_issue@
|
||||
WARNING_CFLAGS = @sim_warnings@
|
||||
CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
|
||||
$(ENDIAN_CFLAGS) \
|
||||
@ -101,7 +100,6 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
|
||||
$(ASSERT_CFLAGS) \
|
||||
$(RESERVED_CFLAGS) \
|
||||
$(MONITOR_CFLAGS) \
|
||||
$(FUNC_CFLAGS) \
|
||||
$(MODEL_CFLAGS)
|
||||
|
||||
STD_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)
|
||||
@ -139,14 +137,15 @@ all: run $(TARGETLIB) $(GDB_OBJ)
|
||||
|
||||
|
||||
BASICS_H = \
|
||||
basics.h \
|
||||
config.h \
|
||||
ppc-config.h \
|
||||
inline.h \
|
||||
sim_callbacks.h \
|
||||
debug.h filter_filename.h \
|
||||
words.h \
|
||||
sim-endian.h \
|
||||
debug.h \
|
||||
filter_filename.h \
|
||||
bits.h \
|
||||
sim_callbacks.h
|
||||
sim-endian.h
|
||||
|
||||
PSIM_H = \
|
||||
psim.h \
|
||||
@ -167,7 +166,7 @@ CPU_H = \
|
||||
cpu.h \
|
||||
$(BASICS_H) \
|
||||
$(REGISTERS_H) \
|
||||
device_tree.h \
|
||||
device.h \
|
||||
corefile.h \
|
||||
vm.h \
|
||||
events.h \
|
||||
@ -176,9 +175,13 @@ CPU_H = \
|
||||
icache.h \
|
||||
itable.h \
|
||||
mon.h \
|
||||
function_unit.h \
|
||||
model.h
|
||||
|
||||
DEVICE_TABLE_H = \
|
||||
$(BASICS_H) \
|
||||
device_table.h \
|
||||
device.h
|
||||
|
||||
EMUL_GENERIC_H = \
|
||||
$(CPU_H) \
|
||||
$(IDECODE_H) \
|
||||
@ -213,16 +216,18 @@ LIB_SRC = \
|
||||
vm.c \
|
||||
vm_n.h \
|
||||
corefile.c \
|
||||
function_unit.c \
|
||||
events.c \
|
||||
os_emul.c \
|
||||
emul_generic.c \
|
||||
emul_netbsd.c \
|
||||
emul_chirp.c \
|
||||
emul_bugapi.c \
|
||||
registers.c \
|
||||
cpu.c \
|
||||
interrupts.c \
|
||||
devices.c \
|
||||
device_tree.c \
|
||||
device.c \
|
||||
device_table.c \
|
||||
cap.c \
|
||||
mon.c \
|
||||
options.c
|
||||
|
||||
@ -235,29 +240,31 @@ MAIN_SRC = \
|
||||
# first
|
||||
LIB_OBJ = \
|
||||
debug.o \
|
||||
options.o \
|
||||
filter_filename.o \
|
||||
bits.o \
|
||||
sim-endian.o \
|
||||
os_emul.o \
|
||||
emul_generic.o \
|
||||
emul_netbsd.o \
|
||||
emul_chirp.o \
|
||||
emul_bugapi.o \
|
||||
registers.o \
|
||||
vm.o \
|
||||
corefile.o \
|
||||
model.o \
|
||||
function_unit.o \
|
||||
spreg.o \
|
||||
cpu.o \
|
||||
interrupts.o \
|
||||
events.o \
|
||||
devices.o \
|
||||
device_tree.o \
|
||||
cap.o \
|
||||
device.o \
|
||||
device_table.o \
|
||||
itable.o \
|
||||
mon.o \
|
||||
semantics.o \
|
||||
idecode.o \
|
||||
psim.o
|
||||
psim.o \
|
||||
options.o
|
||||
|
||||
|
||||
GDB_OBJ = sim_calls.o
|
||||
@ -278,7 +285,6 @@ $(TARGETLIB): tmp-igen tmp-dgen $(LIB_OBJ) $(GDB_OBJ)
|
||||
# Given that inlines are turned on now, rebuild psim whenever
|
||||
# anything changes.
|
||||
psim.o: psim.c psim.h $(CPU_H) $(IDECODE_H) $(INLINE) $(LIB_SRC) $(BUILT_SRC)
|
||||
$(CC) -c $(NOWARN_CFLAGS) $<
|
||||
|
||||
bits.o: bits.c $(BASICS_H)
|
||||
|
||||
@ -287,9 +293,12 @@ filter_filename.o: filter_filename.c filter_filename.h config.h ppc-config.h
|
||||
|
||||
sim-endian.o: sim-endian.c sim-endian-n.h $(BASICS_H)
|
||||
|
||||
os_emul.o: os_emul.c $(EMUL_GENERIC_H)
|
||||
os_emul.o: os_emul.c emul_netbsd.h emul_chirp.h emul_bugapi.h $(EMUL_GENERIC_H)
|
||||
emul_generic.o: emul_generic.c $(EMUL_GENERIC_H)
|
||||
|
||||
emul_netbsd.o: emul_netbsd.c emul_netbsd.h $(EMUL_GENERIC_H)
|
||||
emul_chirp.o: emul_chirp.c emul_chirp.h cap.h $(EMUL_GENERIC_H)
|
||||
emul_bugapi.o: emul_bugapi.c emul_bugapi.h $(EMUL_GENERIC_H)
|
||||
|
||||
registers.o: registers.c $(REGISTERS_H) $(BASICS_H)
|
||||
|
||||
@ -303,26 +312,25 @@ idecode.o: idecode.c $(CPU_H) $(IDECODE_H) semantics.h
|
||||
# double.o: double.c dp-bit.c
|
||||
|
||||
vm.o: vm.c vm.h vm_n.h $(BASICS_H) $(REGISTERS_H) \
|
||||
device_tree.h corefile.h interrupts.h itable.h mon.h
|
||||
device.h corefile.h interrupts.h itable.h mon.h
|
||||
|
||||
corefile.o: corefile.c corefile.h $(BASICS_H) device_tree.h
|
||||
|
||||
function_unit.o: function_unit.c $(CPU_H)
|
||||
corefile.o: corefile.c corefile.h corefile-n.h $(BASICS_H) device.h
|
||||
|
||||
model.o: model.c $(CPU_H)
|
||||
|
||||
events.o: events.c events.h $(BASICS_H)
|
||||
|
||||
sim_calls.o: sim_calls.c $(CPU_H) $(PSIM_H) ../../gdb/tm.h devices.h options.h
|
||||
sim_calls.o: sim_calls.c $(PSIM_H) itable.h ../../gdb/tm.h options.h
|
||||
|
||||
spreg.o: spreg.h spreg.c words.h
|
||||
spreg.o: spreg.h spreg.c $(BASICS_H)
|
||||
|
||||
main.o: main.c $(PSIM_H) function_unit.h itable.h options.h
|
||||
main.o: main.c $(PSIM_H) itable.h options.h
|
||||
|
||||
devices.o: devices.c devices.h $(CPU_H) \
|
||||
device_tree.h events.h
|
||||
device.o: device.c $(DEVICE_TABLE_H)
|
||||
|
||||
device_tree.o: device_tree.c device_tree.h devices.h $(BASICS_H)
|
||||
device_table.o: device_table.c $(DEVICE_TABLE_H) events.h
|
||||
|
||||
cap.o: cap.c cap.h $(BASICS_H)
|
||||
|
||||
semantics.o: semantics.c semantics.h $(CPU_H) $(IDECODE_H)
|
||||
$(CC) -c $(NOWARN_CFLAGS) $<
|
||||
@ -405,9 +413,12 @@ TAGS: $(BUILT_SRC)
|
||||
clean mostlyclean:
|
||||
rm -f tmp-* *.[oasi] core psim run igen dgen config.log $(BUILT_SRC_WO_CONFIG)
|
||||
|
||||
distclean maintainer-clean realclean: clean
|
||||
distclean realclean: clean
|
||||
rm -f TAGS Makefile config.cache config.status config.h stamp-h
|
||||
|
||||
maintainer-clean: distclean
|
||||
rm -f *~ ppc-config.h
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
199
sim/ppc/device.c
199
sim/ppc/device.c
@ -67,7 +67,8 @@ struct _device {
|
||||
};
|
||||
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_create(const char *name,
|
||||
device *parent)
|
||||
{
|
||||
@ -90,7 +91,8 @@ device_create(const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_create_from(const char *name,
|
||||
void *data,
|
||||
const device_callbacks *callbacks,
|
||||
@ -105,25 +107,43 @@ device_create_from(const char *name,
|
||||
}
|
||||
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_parent(device *me)
|
||||
{
|
||||
return me->parent;
|
||||
}
|
||||
|
||||
const char INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_sibling(device *me)
|
||||
{
|
||||
return me->sibling;
|
||||
}
|
||||
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_child(device *me)
|
||||
{
|
||||
return me->children;
|
||||
}
|
||||
|
||||
INLINE_DEVICE\
|
||||
(const char *)
|
||||
device_name(device *me)
|
||||
{
|
||||
return me->name;
|
||||
}
|
||||
|
||||
void INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(void *)
|
||||
device_data(device *me)
|
||||
{
|
||||
return me->data;
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_traverse_properties(device *me,
|
||||
device_traverse_property_function *traverse,
|
||||
void *data)
|
||||
@ -135,14 +155,16 @@ device_traverse_properties(device *me,
|
||||
}
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_init(device *me,
|
||||
psim *system)
|
||||
{
|
||||
me->callback->init(me, system);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_attach_address(device *me,
|
||||
const char *name,
|
||||
attach_type attach,
|
||||
@ -156,7 +178,8 @@ device_attach_address(device *me,
|
||||
addr, nr_bytes, access, who);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_detach_address(device *me,
|
||||
const char *name,
|
||||
attach_type attach,
|
||||
@ -170,7 +193,8 @@ device_detach_address(device *me,
|
||||
addr, nr_bytes, access, who);
|
||||
}
|
||||
|
||||
unsigned INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(unsigned)
|
||||
device_io_read_buffer(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
@ -184,7 +208,8 @@ device_io_read_buffer(device *me,
|
||||
processor, cia);
|
||||
}
|
||||
|
||||
unsigned INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(unsigned)
|
||||
device_io_write_buffer(device *me,
|
||||
const void *source,
|
||||
int space,
|
||||
@ -198,7 +223,8 @@ device_io_write_buffer(device *me,
|
||||
processor, cia);
|
||||
}
|
||||
|
||||
unsigned INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(unsigned)
|
||||
device_dma_read_buffer(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
@ -209,7 +235,8 @@ device_dma_read_buffer(device *me,
|
||||
addr, nr_bytes);
|
||||
}
|
||||
|
||||
unsigned INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(unsigned)
|
||||
device_dma_write_buffer(device *me,
|
||||
const void *source,
|
||||
int space,
|
||||
@ -222,7 +249,8 @@ device_dma_write_buffer(device *me,
|
||||
violate_read_only_section);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_attach_interrupt(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
@ -231,7 +259,8 @@ device_attach_interrupt(device *me,
|
||||
me->callback->attach_interrupt(me, who, interrupt_line, name);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_detach_interrupt(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
@ -240,7 +269,8 @@ device_detach_interrupt(device *me,
|
||||
me->callback->detach_interrupt(me, who, interrupt_line, name);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_interrupt(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
@ -252,7 +282,8 @@ device_interrupt(device *me,
|
||||
processor, cia);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_interrupt_ack(device *me,
|
||||
int interrupt_line,
|
||||
int interrupt_status)
|
||||
@ -260,7 +291,8 @@ device_interrupt_ack(device *me,
|
||||
me->callback->interrupt_ack(me, interrupt_line, interrupt_status);
|
||||
}
|
||||
|
||||
void EXTERN_DEVICE
|
||||
EXTERN_DEVICE\
|
||||
(void)
|
||||
device_ioctl(device *me,
|
||||
psim *system,
|
||||
cpu *processor,
|
||||
@ -276,7 +308,8 @@ device_ioctl(device *me,
|
||||
|
||||
/* Manipulate properties attached to devices */
|
||||
|
||||
device_property STATIC_INLINE_DEVICE *
|
||||
STATIC_INLINE_DEVICE\
|
||||
(device_property *)
|
||||
device_add_property(device *me,
|
||||
const char *property,
|
||||
device_property_type type,
|
||||
@ -311,7 +344,8 @@ device_add_property(device *me,
|
||||
return new_value;
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_add_array_property(device *me,
|
||||
const char *property,
|
||||
const void *array,
|
||||
@ -324,7 +358,8 @@ device_add_array_property(device *me,
|
||||
array_property, array, sizeof_array);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_add_integer_property(device *me,
|
||||
const char *property,
|
||||
signed32 integer)
|
||||
@ -337,7 +372,8 @@ device_add_integer_property(device *me,
|
||||
&integer, sizeof(integer));
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_add_boolean_property(device *me,
|
||||
const char *property,
|
||||
int boolean)
|
||||
@ -350,7 +386,8 @@ device_add_boolean_property(device *me,
|
||||
&new_boolean, sizeof(new_boolean));
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_add_null_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -361,7 +398,8 @@ device_add_null_property(device *me,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_add_string_property(device *me,
|
||||
const char *property,
|
||||
const char *string)
|
||||
@ -374,7 +412,8 @@ device_add_string_property(device *me,
|
||||
string, strlen(string) + 1);
|
||||
}
|
||||
|
||||
const device_property INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(const device_property *)
|
||||
device_find_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -389,7 +428,8 @@ device_find_property(device *me,
|
||||
return (device_property*)0;
|
||||
}
|
||||
|
||||
const char INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(const char *)
|
||||
device_find_next_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -413,7 +453,8 @@ device_find_next_property(device *me,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const device_property INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(const device_property *)
|
||||
device_find_array_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -429,7 +470,8 @@ device_find_array_property(device *me,
|
||||
return node;
|
||||
}
|
||||
|
||||
signed_word INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(signed_word)
|
||||
device_find_integer_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -449,7 +491,8 @@ device_find_integer_property(device *me,
|
||||
return integer;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
device_find_boolean_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -468,7 +511,8 @@ device_find_boolean_property(device *me,
|
||||
return boolean;
|
||||
}
|
||||
|
||||
const char INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(const char *)
|
||||
device_find_string_property(device *me,
|
||||
const char *property)
|
||||
{
|
||||
@ -490,7 +534,8 @@ device_find_string_property(device *me,
|
||||
|
||||
/* determine the full name of the device. If buf is specified it is
|
||||
stored in there. Failing that, a safe area of memory is allocated */
|
||||
const char STATIC_INLINE_DEVICE *
|
||||
STATIC_INLINE_DEVICE\
|
||||
(const char *)
|
||||
device_tree_full_name(device *leaf,
|
||||
char *buf,
|
||||
unsigned sizeof_buf)
|
||||
@ -530,7 +575,8 @@ typedef enum {
|
||||
device_tree_abort = 3,
|
||||
} device_tree_action;
|
||||
|
||||
device STATIC_INLINE_DEVICE *
|
||||
STATIC_INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_find_node(device *root,
|
||||
const char *path,
|
||||
const char *full_path,
|
||||
@ -605,7 +651,9 @@ device_tree_find_node(device *root,
|
||||
child != NULL;
|
||||
child = child->sibling) {
|
||||
if (strncmp(name, child->name, strlen_name) == 0
|
||||
&& strlen(child->name) == strlen_name) {
|
||||
&& strlen(child->name) >= strlen_name
|
||||
&& (child->name[strlen_name] == '\0'
|
||||
|| child->name[strlen_name] == '@')) {
|
||||
if (*path == '\0')
|
||||
return child;
|
||||
else
|
||||
@ -634,7 +682,8 @@ device_tree_find_node(device *root,
|
||||
|
||||
/* grow the device tree */
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_device(device *root,
|
||||
const char *prefix,
|
||||
device *new_sub_tree)
|
||||
@ -662,7 +711,8 @@ device_tree_add_device(device *root,
|
||||
return new_sub_tree;
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_find_device(device *root,
|
||||
const char *path)
|
||||
{
|
||||
@ -680,7 +730,8 @@ device_tree_find_device(device *root,
|
||||
|
||||
/* init all the devices */
|
||||
|
||||
void STATIC_INLINE_DEVICE
|
||||
STATIC_INLINE_DEVICE\
|
||||
(void)
|
||||
device_tree_init_device(device *root,
|
||||
void *data)
|
||||
{
|
||||
@ -693,7 +744,8 @@ device_tree_init_device(device *root,
|
||||
}
|
||||
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_tree_init(device *root,
|
||||
psim *system)
|
||||
{
|
||||
@ -707,7 +759,8 @@ device_tree_init(device *root,
|
||||
|
||||
/* traverse a device tree applying prefix/postfix functions to it */
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_tree_traverse(device *root,
|
||||
device_tree_traverse_function *prefix,
|
||||
device_tree_traverse_function *postfix,
|
||||
@ -726,7 +779,8 @@ device_tree_traverse(device *root,
|
||||
|
||||
/* dump out a device node and addresses */
|
||||
|
||||
void INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(void)
|
||||
device_tree_dump(device *device,
|
||||
void *ignore_data_argument)
|
||||
{
|
||||
@ -742,7 +796,8 @@ device_tree_dump(device *device,
|
||||
|
||||
/* lookup/create a device various formats */
|
||||
|
||||
void STATIC_INLINE_DEVICE
|
||||
STATIC_INLINE_DEVICE\
|
||||
(void)
|
||||
u_strcat(char *buf,
|
||||
unsigned_word uw)
|
||||
{
|
||||
@ -759,7 +814,8 @@ u_strcat(char *buf,
|
||||
}
|
||||
}
|
||||
|
||||
void STATIC_INLINE_DEVICE
|
||||
STATIC_INLINE_DEVICE\
|
||||
(void)
|
||||
c_strcat(char *buf,
|
||||
const char *c)
|
||||
{
|
||||
@ -772,7 +828,8 @@ c_strcat(char *buf,
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found(device *root,
|
||||
const char *prefix,
|
||||
const char *name)
|
||||
@ -781,8 +838,8 @@ device_tree_add_found(device *root,
|
||||
device *new_device;
|
||||
device *new_node;
|
||||
TRACE(trace_device_tree,
|
||||
("device_tree_add_found(root=0x%lx, prefix=%s, name=%x)\n",
|
||||
(long)root, prefix, name));
|
||||
("device_tree_add_found(root=0x%lx, prefix=%s, name=%lx)\n",
|
||||
(unsigned long)root, prefix, (unsigned long)name));
|
||||
parent = device_tree_find_node(root, prefix, prefix,
|
||||
device_tree_abort);
|
||||
new_device = device_tree_find_device(parent, name);
|
||||
@ -796,7 +853,8 @@ device_tree_add_found(device *root,
|
||||
}
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_c(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -811,7 +869,8 @@ device_tree_add_found_c(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_c_uw(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -829,7 +888,8 @@ device_tree_add_found_c_uw(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_uw_u(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -847,7 +907,8 @@ device_tree_add_found_uw_u(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_uw_u_u(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -868,7 +929,8 @@ device_tree_add_found_uw_u_u(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_uw_u_u_c(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -892,7 +954,8 @@ device_tree_add_found_uw_u_u_c(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_uw_uw_u_u_c(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -919,7 +982,8 @@ device_tree_add_found_uw_uw_u_u_c(device *root,
|
||||
return device_tree_add_found(root, prefix, buf);
|
||||
}
|
||||
|
||||
device INLINE_DEVICE *
|
||||
INLINE_DEVICE\
|
||||
(device *)
|
||||
device_tree_add_found_uw_uw_u_u_u(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -1007,7 +1071,8 @@ do { \
|
||||
START = END + 1; \
|
||||
} while (0)
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_c(const char *name,
|
||||
char *c1,
|
||||
unsigned c1size)
|
||||
@ -1017,7 +1082,8 @@ scand_c(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_c_uw_u(const char *name,
|
||||
char *c1,
|
||||
unsigned c1size,
|
||||
@ -1031,7 +1097,8 @@ scand_c_uw_u(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw(const char *name,
|
||||
unsigned_word *uw1)
|
||||
{
|
||||
@ -1040,7 +1107,8 @@ scand_uw(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_c(const char *name,
|
||||
unsigned_word *uw1,
|
||||
char *c2,
|
||||
@ -1052,7 +1120,8 @@ scand_uw_c(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_u(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2)
|
||||
@ -1063,7 +1132,8 @@ scand_uw_u(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_u_u(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2,
|
||||
@ -1076,7 +1146,8 @@ scand_uw_u_u(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_u_u_c(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2,
|
||||
@ -1092,7 +1163,8 @@ scand_uw_u_u_c(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_uw(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2)
|
||||
@ -1103,7 +1175,8 @@ scand_uw_uw(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_uw_u(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
@ -1116,7 +1189,8 @@ scand_uw_uw_u(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_uw_u_u_c(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
@ -1134,7 +1208,8 @@ scand_uw_uw_u_u_c(const char *name,
|
||||
SCAN_END;
|
||||
}
|
||||
|
||||
int INLINE_DEVICE
|
||||
INLINE_DEVICE\
|
||||
(int)
|
||||
scand_uw_uw_u_u_u(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
|
137
sim/ppc/device.h
137
sim/ppc/device.h
@ -39,50 +39,56 @@
|
||||
All the devices in this model live in a tree. The following allow
|
||||
the location/manipulation of this tree */
|
||||
|
||||
device INLINE_DEVICE *device_parent
|
||||
INLINE_DEVICE(device *) device_parent
|
||||
(device *me);
|
||||
|
||||
const char INLINE_DEVICE *device_name
|
||||
INLINE_DEVICE(device *) device_sibling
|
||||
(device *me);
|
||||
|
||||
void INLINE_DEVICE *device_data
|
||||
INLINE_DEVICE(device *) device_child
|
||||
(device *me);
|
||||
|
||||
INLINE_DEVICE(const char *) device_name
|
||||
(device *me);
|
||||
|
||||
INLINE_DEVICE(void *) device_data
|
||||
(device *me);
|
||||
|
||||
|
||||
/* Grow the device tree adding either a specific device or
|
||||
alternativly a device found in the device table */
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_device
|
||||
INLINE_DEVICE(device *)device_tree_add_device
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
device *new_sub_tree);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found
|
||||
INLINE_DEVICE(device *) device_tree_add_found
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_c
|
||||
INLINE_DEVICE(device *) device_tree_add_found_c
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
const char *c1);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_c_uw
|
||||
INLINE_DEVICE(device *) device_tree_add_found_c_uw
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
const char *c1,
|
||||
unsigned_word uw2);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_uw_u
|
||||
INLINE_DEVICE(device *) device_tree_add_found_uw_u
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
unsigned_word uw1,
|
||||
unsigned u2);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_uw_u_u
|
||||
INLINE_DEVICE(device *) device_tree_add_found_uw_u_u
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -90,7 +96,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_u_u
|
||||
unsigned u2,
|
||||
unsigned u3);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_uw_u_u_c
|
||||
INLINE_DEVICE(device *) device_tree_add_found_uw_u_u_c
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -99,7 +105,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_u_u_c
|
||||
unsigned u3,
|
||||
const char *c4);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c
|
||||
INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_c
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -109,7 +115,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c
|
||||
unsigned u4,
|
||||
const char *c5);
|
||||
|
||||
device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u
|
||||
INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_u
|
||||
(device *root,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
@ -123,7 +129,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u
|
||||
/* Query the device tree, null is returned if the specified device is
|
||||
not found */
|
||||
|
||||
device INLINE_DEVICE *device_tree_find_device
|
||||
INLINE_DEVICE(device *) device_tree_find_device
|
||||
(device *root,
|
||||
const char *path);
|
||||
|
||||
@ -135,7 +141,7 @@ typedef void (device_tree_traverse_function)
|
||||
(device *device,
|
||||
void *data);
|
||||
|
||||
void INLINE_DEVICE device_tree_traverse
|
||||
INLINE_DEVICE(void) device_tree_traverse
|
||||
(device *root,
|
||||
device_tree_traverse_function *prefix,
|
||||
device_tree_traverse_function *postfix,
|
||||
@ -145,7 +151,7 @@ void INLINE_DEVICE device_tree_traverse
|
||||
/* dump a node, this can be passed to the device_tree_traverse()
|
||||
function to dump out the entire device tree */
|
||||
|
||||
void INLINE_DEVICE device_tree_dump
|
||||
INLINE_DEVICE(void) device_tree_dump
|
||||
(device *device,
|
||||
void *ignore_data_argument);
|
||||
|
||||
@ -181,7 +187,7 @@ struct _device_property {
|
||||
|
||||
/* Basic operations used by software */
|
||||
|
||||
const char INLINE_DEVICE *device_find_next_property
|
||||
INLINE_DEVICE(const char *) device_find_next_property
|
||||
(device *me,
|
||||
const char *previous);
|
||||
|
||||
@ -189,27 +195,27 @@ const char INLINE_DEVICE *device_find_next_property
|
||||
No such external function, all properties, when added are explictly
|
||||
typed */
|
||||
|
||||
void INLINE_DEVICE device_add_array_property
|
||||
INLINE_DEVICE(void) device_add_array_property
|
||||
(device *me,
|
||||
const char *property,
|
||||
const void *array,
|
||||
int sizeof_array);
|
||||
|
||||
void INLINE_DEVICE device_add_integer_property
|
||||
INLINE_DEVICE(void) device_add_integer_property
|
||||
(device *me,
|
||||
const char *property,
|
||||
signed_word integer);
|
||||
|
||||
void INLINE_DEVICE device_add_boolean_property
|
||||
INLINE_DEVICE(void) device_add_boolean_property
|
||||
(device *me,
|
||||
const char *property,
|
||||
int bool);
|
||||
|
||||
void INLINE_DEVICE device_add_null_property
|
||||
INLINE_DEVICE(void) device_add_null_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
void INLINE_DEVICE device_add_string_property
|
||||
INLINE_DEVICE(void) device_add_string_property
|
||||
(device *me,
|
||||
const char *property,
|
||||
const char *string);
|
||||
@ -218,7 +224,7 @@ void INLINE_DEVICE device_add_string_property
|
||||
/* Locate a property returning its description. Return NULL if the
|
||||
named property is not found */
|
||||
|
||||
const device_property INLINE_DEVICE *device_find_property
|
||||
INLINE_DEVICE(const device_property *) device_find_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
@ -230,7 +236,7 @@ typedef void (device_traverse_property_function)
|
||||
const char *name,
|
||||
void *data);
|
||||
|
||||
void INLINE_DEVICE device_traverse_properties
|
||||
INLINE_DEVICE(void) device_traverse_properties
|
||||
(device *me,
|
||||
device_traverse_property_function *traverse,
|
||||
void *data);
|
||||
@ -239,19 +245,19 @@ void INLINE_DEVICE device_traverse_properties
|
||||
/* Similar to above except that the property *must* be in the device
|
||||
tree and *must* be of the specified type. */
|
||||
|
||||
const device_property INLINE_DEVICE *device_find_array_property
|
||||
INLINE_DEVICE(const device_property *) device_find_array_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
signed_word INLINE_DEVICE device_find_integer_property
|
||||
INLINE_DEVICE(signed_word) device_find_integer_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
const char INLINE_DEVICE *device_find_string_property
|
||||
INLINE_DEVICE(const char *) device_find_string_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
int INLINE_DEVICE device_find_boolean_property
|
||||
INLINE_DEVICE(int) device_find_boolean_property
|
||||
(device *me,
|
||||
const char *property);
|
||||
|
||||
@ -302,26 +308,26 @@ typedef enum _attach_type {
|
||||
|
||||
*/
|
||||
|
||||
device INLINE_DEVICE *device_create
|
||||
INLINE_DEVICE(device *) device_create
|
||||
(const char *name,
|
||||
device *parent);
|
||||
|
||||
/* some external functions want to create things */
|
||||
typedef struct _device_callbacks device_callbacks;
|
||||
|
||||
device INLINE_DEVICE *device_create_from
|
||||
INLINE_DEVICE(device *) device_create_from
|
||||
(const char *name,
|
||||
void *data,
|
||||
const device_callbacks *callbacks,
|
||||
device *parent);
|
||||
|
||||
void INLINE_DEVICE device_init
|
||||
INLINE_DEVICE(void) device_init
|
||||
(device *me,
|
||||
psim *system);
|
||||
|
||||
/* initialize the entire tree */
|
||||
|
||||
void INLINE_DEVICE device_tree_init
|
||||
INLINE_DEVICE(void) device_tree_init
|
||||
(device *root,
|
||||
psim *system);
|
||||
|
||||
@ -403,7 +409,7 @@ void INLINE_DEVICE device_tree_init
|
||||
|
||||
*/
|
||||
|
||||
void INLINE_DEVICE device_attach_address
|
||||
INLINE_DEVICE(void) device_attach_address
|
||||
(device *me,
|
||||
const char *name,
|
||||
attach_type attach,
|
||||
@ -413,7 +419,7 @@ void INLINE_DEVICE device_attach_address
|
||||
access_type access,
|
||||
device *who); /*callback/default*/
|
||||
|
||||
void INLINE_DEVICE device_detach_address
|
||||
INLINE_DEVICE(void) device_detach_address
|
||||
(device *me,
|
||||
const char *name,
|
||||
attach_type attach,
|
||||
@ -423,7 +429,7 @@ void INLINE_DEVICE device_detach_address
|
||||
access_type access,
|
||||
device *who); /*callback/default*/
|
||||
|
||||
unsigned INLINE_DEVICE device_io_read_buffer
|
||||
INLINE_DEVICE(unsigned) device_io_read_buffer
|
||||
(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
@ -432,7 +438,7 @@ unsigned INLINE_DEVICE device_io_read_buffer
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
unsigned INLINE_DEVICE device_io_write_buffer
|
||||
INLINE_DEVICE(unsigned) device_io_write_buffer
|
||||
(device *me,
|
||||
const void *source,
|
||||
int space,
|
||||
@ -441,14 +447,14 @@ unsigned INLINE_DEVICE device_io_write_buffer
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
unsigned INLINE_DEVICE device_dma_read_buffer
|
||||
INLINE_DEVICE(unsigned) device_dma_read_buffer
|
||||
(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes);
|
||||
|
||||
unsigned INLINE_DEVICE device_dma_write_buffer
|
||||
INLINE_DEVICE(unsigned) device_dma_write_buffer
|
||||
(device *me,
|
||||
const void *source,
|
||||
int space,
|
||||
@ -476,19 +482,19 @@ unsigned INLINE_DEVICE device_dma_write_buffer
|
||||
|
||||
*/
|
||||
|
||||
void INLINE_DEVICE device_attach_interrupt
|
||||
INLINE_DEVICE(void) device_attach_interrupt
|
||||
(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
const char *name);
|
||||
|
||||
void INLINE_DEVICE device_detach_interrupt
|
||||
INLINE_DEVICE(void) device_detach_interrupt
|
||||
(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
const char *name);
|
||||
|
||||
void INLINE_DEVICE device_interrupt
|
||||
INLINE_DEVICE(void) device_interrupt
|
||||
(device *me,
|
||||
device *who,
|
||||
int interrupt_line,
|
||||
@ -496,7 +502,7 @@ void INLINE_DEVICE device_interrupt
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
void INLINE_DEVICE device_interrupt_ack
|
||||
INLINE_DEVICE(void) device_interrupt_ack
|
||||
(device *me,
|
||||
int interrupt_line,
|
||||
int interrupt_status);
|
||||
@ -507,7 +513,8 @@ void INLINE_DEVICE device_interrupt_ack
|
||||
Very simply, a catch all for any thing that turns up that until now
|
||||
either hasn't been thought of or doesn't justify an extra function. */
|
||||
|
||||
void EXTERN_DEVICE device_ioctl
|
||||
EXTERN_DEVICE\
|
||||
(void) device_ioctl
|
||||
(device *me,
|
||||
psim *system,
|
||||
cpu *processor,
|
||||
@ -526,32 +533,32 @@ void EXTERN_DEVICE device_ioctl
|
||||
level software interface to the devices */
|
||||
|
||||
#if 0
|
||||
device_instance INLINE_DEVICE *device_instance_open
|
||||
INLINE_DEVICE(device_instance *)device_instance_open
|
||||
(device *me,
|
||||
const char *device_specifier);
|
||||
|
||||
void INLINE_DEVICE device_instance_close
|
||||
INLINE_DEVICE(void) device_instance_close
|
||||
(device_instance *instance);
|
||||
|
||||
int INLINE_DEVICE device_instance_read
|
||||
INLINE_DEVICE(int) device_instance_read
|
||||
(device_instance *instance,
|
||||
void *addr,
|
||||
unsigned_word len);
|
||||
|
||||
int INLINE_DEVICE device_instance_write
|
||||
INLINE_DEVICE(int) device_instance_write
|
||||
(device_instance *instance,
|
||||
const void *addr,
|
||||
unsigned_word len);
|
||||
|
||||
int INLINE_DEVICE device_instance_seek
|
||||
INLINE_DEVICE(int) device_instance_seek
|
||||
(device_instance *instance,
|
||||
unsigned_word pos_hi,
|
||||
unsigned_word pos_lo);
|
||||
|
||||
device INLINE_DEVICE *device_instance_device
|
||||
INLINE_DEVICE(device *) device_instance_device
|
||||
(device_instance *instance);
|
||||
|
||||
const char INLINE_DEVICE *device_instance_name
|
||||
INLINE_DEVICE(const char *) device_instance_name
|
||||
(device_instance *instance);
|
||||
#endif
|
||||
|
||||
@ -560,56 +567,46 @@ const char INLINE_DEVICE *device_instance_name
|
||||
|
||||
/* Device dregs... */
|
||||
|
||||
/* Parse a device name */
|
||||
|
||||
void INLINE_DEVICE device_tree_parse_name
|
||||
(const char *name,
|
||||
const char **driver_name,
|
||||
const char **unit_address,
|
||||
const char **device_arguments,
|
||||
const char **end);
|
||||
|
||||
|
||||
/* Parse a device name, various formats:
|
||||
|
||||
uw: unsigned_word
|
||||
u: unsigned
|
||||
c: string */
|
||||
|
||||
int INLINE_DEVICE scand_c
|
||||
INLINE_DEVICE(int) scand_c
|
||||
(const char *name,
|
||||
char *c1,
|
||||
unsigned c1size);
|
||||
|
||||
int INLINE_DEVICE scand_c_uw_u
|
||||
INLINE_DEVICE(int) scand_c_uw_u
|
||||
(const char *name,
|
||||
char *c1,
|
||||
unsigned c1size,
|
||||
unsigned_word *uw2,
|
||||
unsigned *u3);
|
||||
|
||||
int INLINE_DEVICE scand_uw
|
||||
INLINE_DEVICE(int) scand_uw
|
||||
(const char *name,
|
||||
unsigned_word *uw1);
|
||||
|
||||
int INLINE_DEVICE scand_uw_c
|
||||
INLINE_DEVICE(int) scand_uw_c
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
char *c2,
|
||||
unsigned c2size);
|
||||
|
||||
int INLINE_DEVICE scand_uw_u
|
||||
INLINE_DEVICE(int) scand_uw_u
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2);
|
||||
|
||||
int INLINE_DEVICE scand_uw_u_u
|
||||
INLINE_DEVICE(int) scand_uw_u_u
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2,
|
||||
unsigned *u3);
|
||||
|
||||
int INLINE_DEVICE scand_uw_u_u_c
|
||||
INLINE_DEVICE(int) scand_uw_u_u_c
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned *u2,
|
||||
@ -617,18 +614,18 @@ int INLINE_DEVICE scand_uw_u_u_c
|
||||
char *c4,
|
||||
unsigned c4size);
|
||||
|
||||
int INLINE_DEVICE scand_uw_uw
|
||||
INLINE_DEVICE(int) scand_uw_uw
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2);
|
||||
|
||||
int INLINE_DEVICE scand_uw_uw_u
|
||||
INLINE_DEVICE(int) scand_uw_uw_u
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
unsigned *u3);
|
||||
|
||||
int INLINE_DEVICE scand_uw_uw_u_u_c
|
||||
INLINE_DEVICE(int) scand_uw_uw_u_u_c
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
@ -637,7 +634,7 @@ int INLINE_DEVICE scand_uw_uw_u_u_c
|
||||
char *c5,
|
||||
unsigned c5size);
|
||||
|
||||
int INLINE_DEVICE scand_uw_uw_u_u_u
|
||||
INLINE_DEVICE(int) scand_uw_uw_u_u_u
|
||||
(const char *name,
|
||||
unsigned_word *uw1,
|
||||
unsigned_word *uw2,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "device_table.h"
|
||||
|
||||
@ -668,7 +669,10 @@ static device_callbacks const halt_callbacks = {
|
||||
/* Register init device: register
|
||||
|
||||
Properties attached to the register device specify the name/value
|
||||
initialization pair for cpu registers. */
|
||||
initialization pair for cpu registers.
|
||||
|
||||
FIXME: A specific processor can be initialized by creating a
|
||||
property with a name like `0.pc'. */
|
||||
|
||||
static void
|
||||
register_init(device *me,
|
||||
@ -677,8 +681,17 @@ register_init(device *me,
|
||||
{
|
||||
psim *system = (psim*)data;
|
||||
unsigned32 value = device_find_integer_property(me, name);
|
||||
DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
|
||||
psim_write_register(system, -1, /* all processors */
|
||||
int processor;
|
||||
if (isdigit(name[0]) && name[1] == '.') {
|
||||
processor = atol(name);
|
||||
name += 2;
|
||||
DTRACE(register, ("%ld.%s=0x%lx\n", (long)name, processor, (unsigned long)value));
|
||||
}
|
||||
else {
|
||||
processor = -1;
|
||||
DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
|
||||
}
|
||||
psim_write_register(system, processor, /* all processors */
|
||||
&value,
|
||||
name,
|
||||
cooked_transfer);
|
||||
@ -1221,8 +1234,8 @@ htab_decode_hash_table(device *parent,
|
||||
error("devices/%s - htaborg 0x%x not aligned to htabmask 0x%x\n",
|
||||
device_name(parent), *htaborg, *htabmask);
|
||||
}
|
||||
DTRACE(htab, ("htab - htaborg=0x%x htabmask=0x%x\n",
|
||||
*htaborg, *htabmask));
|
||||
DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
|
||||
(unsigned long)*htaborg, (unsigned long)*htabmask));
|
||||
}
|
||||
|
||||
|
||||
@ -1246,34 +1259,38 @@ htab_map_page(device *me,
|
||||
unsigned32 pteg = (htaborg | (hash & htabmask));
|
||||
int pti;
|
||||
for (pti = 0; pti < 8; pti++, pteg += 8) {
|
||||
unsigned32 pte0;
|
||||
unsigned32 current_target_pte0;
|
||||
unsigned32 current_pte0;
|
||||
if (device_dma_read_buffer(device_parent(me),
|
||||
&pte0,
|
||||
¤t_target_pte0,
|
||||
0, /*space*/
|
||||
pteg,
|
||||
sizeof(pte0)) != 4)
|
||||
sizeof(current_target_pte0)) != 4)
|
||||
error("htab_init_callback() failed to read a pte at 0x%x\n",
|
||||
pteg);
|
||||
if (!MASKED32(pte0, 0, 0)) {
|
||||
current_pte0 = T2H_4(current_target_pte0);
|
||||
if (!MASKED32(current_pte0, 0, 0)) {
|
||||
/* empty pte fill it */
|
||||
unsigned32 pte0 = (MASK32(0, 0)
|
||||
| INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
|
||||
| INSERTED32(h, 25, 25)
|
||||
| INSERTED32(EXTRACTED32(page, 0, 5), 26, 31));
|
||||
unsigned32 target_pte0 = H2T_4(pte0);
|
||||
unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
|
||||
| INSERTED32(wimg, 25, 28)
|
||||
| INSERTED32(pp, 30, 31));
|
||||
unsigned32 target_pte1 = H2T_4(pte1);
|
||||
if (device_dma_write_buffer(device_parent(me),
|
||||
&pte0,
|
||||
&target_pte0,
|
||||
0, /*space*/
|
||||
pteg,
|
||||
sizeof(pte0),
|
||||
sizeof(target_pte0),
|
||||
1/*ro?*/) != 4
|
||||
|| device_dma_write_buffer(device_parent(me),
|
||||
&pte1,
|
||||
&target_pte1,
|
||||
0, /*space*/
|
||||
pteg + 4,
|
||||
sizeof(pte1),
|
||||
sizeof(target_pte1),
|
||||
1/*ro?*/) != 4)
|
||||
error("htab_init_callback() failed to write a pte a 0x%x\n",
|
||||
pteg);
|
||||
@ -1459,9 +1476,13 @@ htab_map_binary(device *me,
|
||||
(sizes.text_bound - sizes.text_base));
|
||||
|
||||
DTRACE(htab, ("text map - base=0x%lx bound=0x%lx ra=0x%lx\n",
|
||||
sizes.text_base, sizes.text_bound, sizes.text_ra));
|
||||
(unsigned long)sizes.text_base,
|
||||
(unsigned long)sizes.text_bound,
|
||||
(unsigned long)sizes.text_ra));
|
||||
DTRACE(htab, ("data map - base=0x%lx bound=0x%lx ra=0x%lx\n",
|
||||
sizes.data_base, sizes.data_bound, sizes.data_ra));
|
||||
(unsigned long)sizes.data_base,
|
||||
(unsigned long)sizes.data_bound,
|
||||
(unsigned long)sizes.data_ra));
|
||||
|
||||
/* set up virtual memory maps for each of the regions */
|
||||
htab_map_region(me, sizes.text_ra, sizes.text_base,
|
||||
@ -1500,15 +1521,22 @@ htab_init_callback(device *me,
|
||||
/* handle a normal mapping definition */
|
||||
if (scand_uw_uw_u_u_u(device_name(me), &pte_ra, &pte_va, &pte_nr_bytes,
|
||||
&pte_wimg, &pte_pp) == 5) {
|
||||
DTRACE(htab, ("pte - ra=0x%x, wimg=%d, pp=%d, va=0x%x, nr_bytes=%d\n",
|
||||
pte_ra, pte_wimg, pte_pp, pte_va, pte_nr_bytes));
|
||||
DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
|
||||
(unsigned long)pte_ra,
|
||||
(long)pte_wimg,
|
||||
(long)pte_pp,
|
||||
(unsigned long)pte_va,
|
||||
(long)pte_nr_bytes));
|
||||
htab_map_region(me, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp,
|
||||
htaborg, htabmask);
|
||||
}
|
||||
else if (scand_uw_u_u_c(device_name(me), &pte_ra, &pte_wimg, &pte_pp,
|
||||
file_name, sizeof(file_name)) == 4) {
|
||||
DTRACE(htab, ("pte - ra=0x%x, wimg=%d, pp=%d, binary=%s\n",
|
||||
pte_ra, pte_wimg, pte_pp, file_name));
|
||||
DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, binary=%s\n",
|
||||
(unsigned long)pte_ra,
|
||||
(unsigned long)pte_wimg,
|
||||
(long)pte_pp,
|
||||
file_name));
|
||||
htab_map_binary(me, pte_ra, pte_wimg, pte_pp, file_name,
|
||||
htaborg, htabmask);
|
||||
}
|
||||
|
@ -23,6 +23,27 @@
|
||||
#define _EMUL_BUGAPI_C_
|
||||
|
||||
|
||||
/* from bug.S - Dale Rahn */
|
||||
#define _INCHR 0x00
|
||||
#define _INSTAT 0x01
|
||||
#define _INLN 0x02
|
||||
#define _READSTR 0x03
|
||||
#define _READLN 0x04
|
||||
#define _OUTCHR 0x20
|
||||
#define _OUTSTR 0x21
|
||||
#define _OUTLN 0x22
|
||||
#define _DSKRD 0x10
|
||||
#define _DSKWR 0x11
|
||||
#define _DSKCFIG 0x12
|
||||
#define _DSKFMT 0x14
|
||||
#define _DSKCTRL 0x15
|
||||
#define _WRITE 0x23
|
||||
#define _WRITELN 0x24
|
||||
#define _DELAY 0x43
|
||||
#define _RTC_RD 0x53
|
||||
#define _RETURN 0x63
|
||||
#define _BRD_ID 0x70
|
||||
|
||||
/* Note: this module is called via a table. There is no benefit in
|
||||
making it inline */
|
||||
|
||||
@ -32,13 +53,27 @@
|
||||
/* Any starting address less than this is assumed to be an OEA program
|
||||
rather than VEA. */
|
||||
#ifndef OEA_START_ADDRESS
|
||||
#define OEA_START_ADDRESS 4096
|
||||
#define OEA_START_ADDRESS 0x4000
|
||||
#endif
|
||||
|
||||
#ifndef OEA_MEMORY_SIZE
|
||||
#define OEA_MEMORY_SIZE 0x100000
|
||||
#endif
|
||||
|
||||
/* All but CPU 0 are put into an infinate loop, this loop instruction
|
||||
is stored at the address below */
|
||||
#ifndef OEA_STALL_CPU_LOOP_ADDRESS
|
||||
#define OEA_STALL_CPU_LOOP_ADDRESS 0x00c10
|
||||
#endif
|
||||
|
||||
/* At initiallization, the system call exception branches to the BUG
|
||||
emulation code */
|
||||
|
||||
#ifndef OEA_SYSTEM_CALL_ADDRESS
|
||||
#define OEA_SYSTEM_CALL_ADDRESS 0x00c00
|
||||
#endif
|
||||
|
||||
|
||||
static os_emul_data *
|
||||
emul_bugapi_create(device *root,
|
||||
bfd *image,
|
||||
@ -47,9 +82,11 @@ emul_bugapi_create(device *root,
|
||||
|
||||
/* check it really is for us */
|
||||
if (name != NULL
|
||||
&& strcmp(name, "bugapi") != 0)
|
||||
&& strcmp(name, "bugapi") != 0
|
||||
&& strcmp(name, "bug") != 0)
|
||||
return NULL;
|
||||
if (image != NULL
|
||||
&& name == NULL
|
||||
&& bfd_get_start_address(image) > OEA_START_ADDRESS)
|
||||
return NULL;
|
||||
|
||||
@ -58,8 +95,12 @@ emul_bugapi_create(device *root,
|
||||
const memory_size = OEA_MEMORY_SIZE;
|
||||
const elf_binary = (image != NULL
|
||||
&& image->xvec->flavour == bfd_target_elf_flavour);
|
||||
const little_endian = (image != NULL
|
||||
&& !image->xvec->byteorder_big_p);
|
||||
#ifdef bfd_little_endian /* new bfd */
|
||||
const little_endian = (image != NULL && bfd_little_endian(image));
|
||||
#else
|
||||
const little_endian = (image != NULL &&
|
||||
!image->xvec->byteorder_big_p);
|
||||
#endif
|
||||
|
||||
{ /* options */
|
||||
device *options = device_tree_add_found(root, "/", "options");
|
||||
@ -75,7 +116,7 @@ emul_bugapi_create(device *root,
|
||||
device_add_boolean_property(options,
|
||||
"strict-alignment?",
|
||||
(WITH_ALIGNMENT == STRICT_ALIGNMENT
|
||||
|| !image->xvec->byteorder_big_p));
|
||||
|| little_endian));
|
||||
device_add_boolean_property(options,
|
||||
"floating-point?",
|
||||
WITH_FLOATING_POINT);
|
||||
@ -98,15 +139,32 @@ emul_bugapi_create(device *root,
|
||||
device *init_register = device_tree_add_found(init, "", "register");
|
||||
device_add_integer_property(init_register,
|
||||
"pc",
|
||||
0);
|
||||
OEA_STALL_CPU_LOOP_ADDRESS);
|
||||
device_add_integer_property(init_register,
|
||||
"0.pc",
|
||||
bfd_get_start_address(image));
|
||||
device_add_integer_property(init_register,
|
||||
"sp",
|
||||
memory_size-16);
|
||||
device_add_integer_property(init_register,
|
||||
"msr",
|
||||
(little_endian
|
||||
? msr_little_endian_mode
|
||||
: 0));
|
||||
(msr_recoverable_interrupt
|
||||
| (little_endian
|
||||
? msr_little_endian_mode
|
||||
: 0)
|
||||
));
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_SYSTEM_CALL_ADDRESS,
|
||||
4, 0x1); /*emul-call*/
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_SYSTEM_CALL_ADDRESS + 4,
|
||||
4, 0x4c000064); /*rfi*/
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_STALL_CPU_LOOP_ADDRESS,
|
||||
4, 0x48000000); /*b .*/
|
||||
}
|
||||
{
|
||||
device *init_stack = device_tree_add_found(init, "", "stack");
|
||||
@ -140,8 +198,28 @@ emul_bugapi_instruction_call(cpu *processor,
|
||||
unsigned_word ra,
|
||||
os_emul_data *emul_data)
|
||||
{
|
||||
error("emul_bugapi_instruction_call() not implemented\n");
|
||||
const int call_id = cpu_registers(processor)->gpr[10];
|
||||
/* check that this isn't an invalid instruction */
|
||||
if (cia != OEA_SYSTEM_CALL_ADDRESS)
|
||||
return 0;
|
||||
switch (call_id) {
|
||||
case _OUTCHR:
|
||||
printf_filtered("%c", cpu_registers(processor)->gpr[3]);
|
||||
break;
|
||||
case _OUTLN:
|
||||
printf_filtered("\n");
|
||||
break;
|
||||
case _RETURN:
|
||||
cpu_halt(processor, cia, was_exited, 0); /* always succeeds */
|
||||
break;
|
||||
default:
|
||||
error("emul-bugapi: unimplemented bugapi call 0x%x from address 0x%lx\n",
|
||||
call_id, SRR0);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
/* the instruction following this one is a RFI. Thus by just
|
||||
continuing the return from system call is performed */
|
||||
}
|
||||
|
||||
const os_emul emul_bugapi = {
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
/* Descriptor of the open boot services being emulated */
|
||||
|
||||
typedef unsigned_word (chirp_handler)
|
||||
typedef int (chirp_handler)
|
||||
(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
@ -61,6 +61,7 @@ typedef struct _chirp_services {
|
||||
request or waiting on a client callback */
|
||||
typedef enum {
|
||||
serving,
|
||||
faulting,
|
||||
catching,
|
||||
} chirp_emul_state;
|
||||
|
||||
@ -78,7 +79,64 @@ struct _os_emul_data {
|
||||
|
||||
/* OpenBoot emulation functions */
|
||||
|
||||
static unsigned_word
|
||||
static int
|
||||
chirp_emul_child(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct child_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 phandle;
|
||||
/*out*/
|
||||
unsigned32 child_phandle;
|
||||
} args;
|
||||
device *dev;
|
||||
device *child_dev;
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("child - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
TRACE(trace_os_emul, ("child - in - phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev))));
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
child_dev = device_child(dev);
|
||||
if (child_dev == NULL)
|
||||
args.child_phandle = 0;
|
||||
else
|
||||
args.child_phandle = cap_external(data->phandles, child_dev);
|
||||
TRACE(trace_os_emul, ("child - out - child_phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.child_phandle),
|
||||
(unsigned long)child_dev,
|
||||
(child_dev == NULL ? "" : device_name(child_dev))));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_exit(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
cpu_halt(processor, cia, was_exited, 0); /* always succeeds */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_finddevice(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
@ -97,25 +155,35 @@ chirp_emul_finddevice(os_emul_data *data,
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1)
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("finddevice - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
emul_read_string(device_specifier,
|
||||
T2H_4(args.device_specifier),
|
||||
sizeof(device_specifier),
|
||||
processor, cia);
|
||||
TRACE(trace_os_emul, ("finddevice - in - device_specifier=`%s'\n",
|
||||
device_specifier));
|
||||
dev = device_tree_find_device(data->root,
|
||||
device_specifier);
|
||||
if (dev == (device*)0)
|
||||
args.phandle = -1;
|
||||
else
|
||||
args.phandle = cap_external(data->phandles, dev);
|
||||
TRACE(trace_os_emul, ("finddevice - out - phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev))));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned_word
|
||||
static int
|
||||
chirp_emul_getprop(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
@ -138,16 +206,27 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 4 || T2H_4(args.n_returns) != 1)
|
||||
if (T2H_4(args.n_args) != 4 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("getprop - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
emul_read_string(name,
|
||||
T2H_4(args.name),
|
||||
sizeof(name),
|
||||
processor, cia);
|
||||
TRACE(trace_os_emul, ("getprop - in - phandle=0x%lx(0x%lx`%s') name=`%s' buf=0x%lx buflen=%ld\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev)),
|
||||
name,
|
||||
(unsigned long)T2H_4(args.buf),
|
||||
(unsigned long)T2H_4(args.buflen)));
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
prop = device_find_property(dev, name);
|
||||
if (prop == (device_property*)0) {
|
||||
args.size = -1;
|
||||
@ -161,13 +240,267 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
processor, cia);
|
||||
args.size = H2T_4(size);
|
||||
}
|
||||
switch (prop->type) {
|
||||
case string_property:
|
||||
TRACE(trace_os_emul, ("getprop - value=`%s' (string)\n",
|
||||
(char*)prop->array));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
TRACE(trace_os_emul, ("getprop - out - size=%ld\n",
|
||||
(unsigned long)T2H_4(args.size)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned_word
|
||||
static int
|
||||
chirp_emul_getproplen(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct getproplen_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 phandle;
|
||||
unsigned32 name;
|
||||
/*out*/
|
||||
unsigned32 proplen;
|
||||
} args;
|
||||
char name[32];
|
||||
device *dev;
|
||||
const device_property *prop;
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 2 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("getproplen - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
emul_read_string(name,
|
||||
T2H_4(args.name),
|
||||
sizeof(name),
|
||||
processor, cia);
|
||||
TRACE(trace_os_emul, ("getproplen - in - phandle=0x%lx(0x%lx`%s') name=`%s'\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev)),
|
||||
name));
|
||||
prop = device_find_property(dev, name);
|
||||
if (prop == (device_property*)0) {
|
||||
args.proplen = -1;
|
||||
}
|
||||
else {
|
||||
args.proplen = H2T_4(prop->sizeof_array);
|
||||
}
|
||||
TRACE(trace_os_emul, ("getproplen - out - proplen=%ld\n",
|
||||
(unsigned long)T2H_4(args.proplen)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_open(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct open_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 device_specifier;
|
||||
/*out*/
|
||||
unsigned32 ihandle;
|
||||
} args;
|
||||
char name[1024];
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("open - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
emul_read_string(name,
|
||||
T2H_4(args.device_specifier),
|
||||
sizeof(name),
|
||||
processor, cia);
|
||||
TRACE(trace_os_emul, ("open - in - device_specifier=`%s'\n",
|
||||
name));
|
||||
printf_filtered("OpenBoot - open unimplemented for %s\n", name);
|
||||
args.ihandle = -1;
|
||||
TRACE(trace_os_emul, ("open - out - ihandle=0x%lx\n",
|
||||
(unsigned long)T2H_4(args.ihandle)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_parent(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct parent_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 phandle;
|
||||
/*out*/
|
||||
unsigned32 parent_phandle;
|
||||
} args;
|
||||
device *dev;
|
||||
device *parent_dev;
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("parent - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
TRACE(trace_os_emul, ("parent - in - phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev))));
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
parent_dev = device_parent(dev);
|
||||
if (parent_dev == NULL)
|
||||
args.parent_phandle = 0;
|
||||
else
|
||||
args.parent_phandle = cap_external(data->phandles, parent_dev);
|
||||
TRACE(trace_os_emul, ("parent - out - parent_phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.parent_phandle),
|
||||
(unsigned long)parent_dev,
|
||||
(parent_dev == NULL ? "" : device_name(parent_dev))));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_peer(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct peer_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 phandle;
|
||||
/*out*/
|
||||
unsigned32 sibling_phandle;
|
||||
} args;
|
||||
device *dev;
|
||||
device *sibling_dev = NULL;
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("peer - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
TRACE(trace_os_emul, ("peer - in - phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.phandle),
|
||||
(unsigned long)dev,
|
||||
(dev == NULL ? "" : device_name(dev))));
|
||||
if (dev == NULL && args.phandle != 0)
|
||||
return -1;
|
||||
if (args.phandle == 0)
|
||||
sibling_dev = data->root;
|
||||
else
|
||||
sibling_dev = device_sibling(dev);
|
||||
if (sibling_dev == NULL)
|
||||
args.sibling_phandle = 0;
|
||||
else
|
||||
args.sibling_phandle = cap_external(data->phandles, sibling_dev);
|
||||
TRACE(trace_os_emul, ("peer - out - sibling_phandle=0x%lx(0x%lx`%s')\n",
|
||||
(unsigned long)T2H_4(args.sibling_phandle),
|
||||
(unsigned long)sibling_dev,
|
||||
(sibling_dev == NULL ? "" : device_name(sibling_dev))));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_read(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct read_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 ihandle;
|
||||
unsigned32 addr;
|
||||
unsigned32 len;
|
||||
/*out*/
|
||||
unsigned32 actual;
|
||||
} args;
|
||||
char buf[1024];
|
||||
int actual;
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("read - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
actual = T2H_4(args.len);
|
||||
if (actual >= sizeof(buf))
|
||||
actual = sizeof(buf) - 1;
|
||||
emul_read_buffer(buf,
|
||||
T2H_4(args.addr),
|
||||
actual,
|
||||
processor, cia);
|
||||
buf[actual] = '\0';
|
||||
/* read it in */
|
||||
TRACE(trace_os_emul, ("read - in - ihandle=0x%lx `%s' (%ld)\n",
|
||||
(unsigned long)args.ihandle, buf, (long)actual));
|
||||
read(BE2H_4(args.ihandle), buf, actual);
|
||||
args.actual = H2T_4(actual);
|
||||
TRACE(trace_os_emul, ("read - out - actual=%ld\n",
|
||||
(long)T2H_4(args.actual)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_write(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
@ -188,40 +521,46 @@ chirp_emul_write(os_emul_data *data,
|
||||
emul_read_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1)
|
||||
if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1) {
|
||||
TRACE(trace_os_emul, ("write - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
actual = T2H_4(args.len);
|
||||
if (actual > sizeof(buf))
|
||||
actual = sizeof(buf);
|
||||
if (actual >= sizeof(buf))
|
||||
actual = sizeof(buf) - 1;
|
||||
emul_read_buffer(buf,
|
||||
T2H_4(args.addr),
|
||||
actual,
|
||||
processor, cia);
|
||||
buf[actual] = '\0';
|
||||
/* write it out */
|
||||
TRACE(trace_os_emul, ("write - in - ihandle=0x%lx `%s' (%ld)\n",
|
||||
(unsigned long)args.ihandle, buf, (long)actual));
|
||||
write(BE2H_4(args.ihandle), buf, actual);
|
||||
args.actual = H2T_4(actual);
|
||||
TRACE(trace_os_emul, ("write - out - actual=%ld\n",
|
||||
(long)T2H_4(args.actual)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned_word
|
||||
chirp_emul_exit(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp_emul_exit not implemnented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
chirp_services services[] = {
|
||||
{ "child", chirp_emul_child },
|
||||
{ "exit", chirp_emul_exit },
|
||||
{ "finddevice", chirp_emul_finddevice },
|
||||
{ "getprop", chirp_emul_getprop },
|
||||
{ "getproplen", chirp_emul_getproplen },
|
||||
{ "open", chirp_emul_open },
|
||||
{ "parent", chirp_emul_parent },
|
||||
{ "peer", chirp_emul_peer },
|
||||
{ "read", chirp_emul_read },
|
||||
{ "write", chirp_emul_write },
|
||||
{ "exit", chirp_emul_exit },
|
||||
{ 0, /* sentinal */ },
|
||||
};
|
||||
|
||||
@ -303,6 +642,7 @@ emul_chirp_create(device *root,
|
||||
{
|
||||
os_emul_data *data;
|
||||
chirp_note note;
|
||||
int big_endian;
|
||||
|
||||
/* Sanity check that this really is the chosen emulation */
|
||||
if (name == NULL && image == NULL)
|
||||
@ -322,6 +662,11 @@ emul_chirp_create(device *root,
|
||||
if (name == NULL && image != NULL && !note.found)
|
||||
return NULL;
|
||||
|
||||
/* the root node */
|
||||
device_add_string_property(root,
|
||||
"name",
|
||||
"gpl,clayton");
|
||||
|
||||
{
|
||||
const unsigned_word memory_size = 0x200000;
|
||||
|
||||
@ -335,7 +680,7 @@ emul_chirp_create(device *root,
|
||||
/* a page for firmware calls */
|
||||
const unsigned_word sizeof_code = 4096;
|
||||
const unsigned_word code_ra = htab_ra - sizeof_code;
|
||||
|
||||
|
||||
/* the stack */
|
||||
const unsigned sizeof_stack = 32 * 1024;
|
||||
const unsigned_word stack_ra = code_ra - sizeof_stack;
|
||||
@ -350,8 +695,17 @@ emul_chirp_create(device *root,
|
||||
/* the virtual addresses */
|
||||
const unsigned_word stack_va = virt_base;
|
||||
const unsigned_word code_va = stack_va + sizeof_stack;
|
||||
const unsigned_word code_client_va = code_va;
|
||||
const unsigned_word code_callback_va = code_client_va + 16;
|
||||
const unsigned_word code_loop_va = code_callback_va + 16;
|
||||
const unsigned_word htab_va = code_va + sizeof_code;
|
||||
|
||||
|
||||
#ifdef bfd_big_endian /* new bfd */
|
||||
big_endian = bfd_big_endian(image);
|
||||
#else
|
||||
big_endian = image->xvec->byteorder_big_p;
|
||||
#endif
|
||||
|
||||
/* options */
|
||||
{
|
||||
device *options = device_tree_add_found(root, "/", "options");
|
||||
@ -360,14 +714,14 @@ emul_chirp_create(device *root,
|
||||
MAX_NR_PROCESSORS);
|
||||
device_add_boolean_property(options,
|
||||
"little-endian?",
|
||||
!image->xvec->byteorder_big_p);
|
||||
!big_endian);
|
||||
device_add_string_property(options,
|
||||
"env",
|
||||
"operating");
|
||||
device_add_boolean_property(options,
|
||||
"strict-alignment?",
|
||||
(WITH_ALIGNMENT == STRICT_ALIGNMENT
|
||||
|| !image->xvec->byteorder_big_p));
|
||||
|| !big_endian));
|
||||
device_add_boolean_property(options,
|
||||
"floating-point?",
|
||||
WITH_FLOATING_POINT);
|
||||
@ -387,17 +741,30 @@ emul_chirp_create(device *root,
|
||||
device *init_register = device_tree_add_found(init, "", "register");
|
||||
device_add_integer_property(init_register,
|
||||
"pc",
|
||||
code_loop_va);
|
||||
device_add_integer_property(init_register,
|
||||
"0.pc",
|
||||
bfd_get_start_address(image));
|
||||
device_add_integer_property(init_register,
|
||||
"sp",
|
||||
stack_va + sizeof_stack - 16);
|
||||
|
||||
/* init the code callback */
|
||||
/* init the code callback along with a loop for the unused cpu's */
|
||||
device_add_integer_property(init_register,
|
||||
"r5",
|
||||
code_va);
|
||||
device_tree_add_found_uw_u_u(init, "", "data", code_ra, 4, 0x1);
|
||||
device_tree_add_found_uw_u_u(init, "", "data", code_ra+16, 4, 0x1);
|
||||
code_client_va);
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_client_va - code_va),
|
||||
4, 0x1); /*emul-call*/
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_callback_va - code_va),
|
||||
4, 0x1); /*emul-call*/
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_loop_va - code_va),
|
||||
4, 0x48000000); /*b .*/
|
||||
device_add_integer_property(init_register,
|
||||
"msr",
|
||||
(msr_machine_check_enable
|
||||
@ -405,7 +772,7 @@ emul_chirp_create(device *root,
|
||||
? 0
|
||||
: (msr_instruction_relocate
|
||||
| msr_data_relocate))
|
||||
| (image->xvec->byteorder_big_p
|
||||
| (big_endian
|
||||
? 0
|
||||
: (msr_little_endian_mode
|
||||
| msr_interrupt_little_endian_mode
|
||||
@ -445,15 +812,35 @@ emul_chirp_create(device *root,
|
||||
|
||||
{ /* chosen options */
|
||||
device *chosen = device_tree_add_found(root, "/", "chosen");
|
||||
device_add_string_property(chosen,
|
||||
"name",
|
||||
"chosen");
|
||||
device_add_integer_property(chosen,
|
||||
"stdin",
|
||||
0); /* FIXME: ihandle of stdin */
|
||||
device_add_integer_property(chosen,
|
||||
"stdout",
|
||||
1);
|
||||
1); /* FIXME: ihandle of stdout */
|
||||
device_add_string_property(chosen,
|
||||
"bootpath",
|
||||
"/disk@0:\\boot");
|
||||
device_add_string_property(chosen,
|
||||
"bootargs",
|
||||
"");
|
||||
#if 0
|
||||
device_add_integer_property(chosen,
|
||||
"memory",
|
||||
0); /* FIXME: ihandle of memory */
|
||||
device_add_integer_property(chosen,
|
||||
"mmu",
|
||||
0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIXME - should come from the device tree */
|
||||
data = ZALLOC(os_emul_data);
|
||||
data->serving_instruction_ea = CHIRP_START_ADDRESS + sizeof_stack;;
|
||||
data->catching_instruction_ea = CHIRP_START_ADDRESS + sizeof_stack + 16;
|
||||
data->serving_instruction_ea = code_client_va;
|
||||
data->catching_instruction_ea = code_callback_va;
|
||||
data->phandles = cap_create("chirp");
|
||||
data->root = root;
|
||||
return data;
|
||||
@ -470,9 +857,9 @@ emul_chirp_init(os_emul_data *emul_data,
|
||||
|
||||
static int
|
||||
emul_chirp_instruction_call(cpu *processor,
|
||||
unsigned_word cia,
|
||||
unsigned_word ra,
|
||||
os_emul_data *emul_data)
|
||||
unsigned_word cia,
|
||||
unsigned_word ra,
|
||||
os_emul_data *emul_data)
|
||||
{
|
||||
unsigned_word service_name_addr;
|
||||
unsigned_word result;
|
||||
@ -481,8 +868,10 @@ emul_chirp_instruction_call(cpu *processor,
|
||||
chirp_services *service;
|
||||
|
||||
switch (emul_data->state) {
|
||||
|
||||
case serving:
|
||||
/* verify then capture the current request */
|
||||
/* we are waiting on an OpenBoot request from the client program
|
||||
via the client interface */
|
||||
if (cia != emul_data->serving_instruction_ea)
|
||||
return 0;
|
||||
emul_data->return_address = LR;
|
||||
@ -492,24 +881,46 @@ emul_chirp_instruction_call(cpu *processor,
|
||||
processor, cia);
|
||||
service_name = emul_read_string(service_buf, service_name_addr,
|
||||
sizeof(service_buf), processor, cia);
|
||||
TRACE(trace_os_emul, ("%s called from 0x%lx with args 0x%lx\n",
|
||||
service_name,
|
||||
(unsigned long)emul_data->return_address,
|
||||
(unsigned long)emul_data->arguments));
|
||||
/* look it up */
|
||||
service = services;
|
||||
while (service->name != NULL && strcmp(service->name, service_name) != 0)
|
||||
service++;
|
||||
if (service->name == NULL) {
|
||||
error("OpenBoot service `%s' not found\n", service_name);
|
||||
TRACE(trace_os_emul, ("%s not found\n", service_name));
|
||||
cpu_registers(processor)->gpr[3] = 0;
|
||||
cpu_restart(processor, emul_data->return_address);
|
||||
}
|
||||
emul_data->service = service;
|
||||
TRACE(trace_os_emul, ("%s called from 0x%lx\n",
|
||||
service->name, emul_data->return_address));
|
||||
/* call upon it */
|
||||
result = service->handler(emul_data, processor, cia);
|
||||
break;
|
||||
|
||||
case faulting:
|
||||
/* We were handling a client request but encountered a page fault
|
||||
(or other exception). The fault needs to be passed back to the
|
||||
client using the the client suplied call back interface */
|
||||
error("emul_chirp_instruction_call() faulting unimplemented\n");
|
||||
result = -1;
|
||||
break;
|
||||
|
||||
case catching:
|
||||
/* Have called the client (via the callback interface) because
|
||||
some fault (hash table miss) occured. The client has finished
|
||||
handling this and is now returning */
|
||||
error("emul_chirp_instruction_call() catching unimplemented\n");
|
||||
result = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("emul_chirp_instruction_call() unknown internal state\n");
|
||||
result = -1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* return to caller */
|
||||
|
Loading…
Reference in New Issue
Block a user