Latest cagney update

This commit is contained in:
Michael Meissner 1996-01-08 18:01:17 +00:00
parent 436d414327
commit 979c3c25fd
7 changed files with 941 additions and 230 deletions

View File

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

View File

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

View File

@ -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,

View File

@ -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,

View File

@ -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,
&current_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);
}

View File

@ -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 = {

View File

@ -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 */