+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
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) \
$(ASSERT_CFLAGS) \
$(RESERVED_CFLAGS) \
$(MONITOR_CFLAGS) \
- $(FUNC_CFLAGS) \
$(MODEL_CFLAGS)
STD_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)
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 \
cpu.h \
$(BASICS_H) \
$(REGISTERS_H) \
- device_tree.h \
+ device.h \
corefile.h \
vm.h \
events.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) \
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
# 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
# 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)
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)
# 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
-
-corefile.o: corefile.c corefile.h $(BASICS_H) device_tree.h
+ device.h corefile.h interrupts.h itable.h mon.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) $<
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
};
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_create(const char *name,
device *parent)
{
return NULL;
}
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_create_from(const char *name,
void *data,
const device_callbacks *callbacks,
}
-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)
}
}
-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,
addr, nr_bytes, access, who);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_detach_address(device *me,
const char *name,
attach_type attach,
addr, nr_bytes, access, who);
}
-unsigned INLINE_DEVICE
+INLINE_DEVICE\
+(unsigned)
device_io_read_buffer(device *me,
void *dest,
int space,
processor, cia);
}
-unsigned INLINE_DEVICE
+INLINE_DEVICE\
+(unsigned)
device_io_write_buffer(device *me,
const void *source,
int space,
processor, cia);
}
-unsigned INLINE_DEVICE
+INLINE_DEVICE\
+(unsigned)
device_dma_read_buffer(device *me,
void *dest,
int space,
addr, nr_bytes);
}
-unsigned INLINE_DEVICE
+INLINE_DEVICE\
+(unsigned)
device_dma_write_buffer(device *me,
const void *source,
int space,
violate_read_only_section);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_attach_interrupt(device *me,
device *who,
int interrupt_line,
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,
me->callback->detach_interrupt(me, who, interrupt_line, name);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_interrupt(device *me,
device *who,
int interrupt_line,
processor, cia);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_interrupt_ack(device *me,
int interrupt_line,
int interrupt_status)
me->callback->interrupt_ack(me, interrupt_line, interrupt_status);
}
-void EXTERN_DEVICE
+EXTERN_DEVICE\
+(void)
device_ioctl(device *me,
psim *system,
cpu *processor,
/* 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,
return new_value;
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_add_array_property(device *me,
const char *property,
const void *array,
array_property, array, sizeof_array);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_add_integer_property(device *me,
const char *property,
signed32 integer)
&integer, sizeof(integer));
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_add_boolean_property(device *me,
const char *property,
int boolean)
&new_boolean, sizeof(new_boolean));
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_add_null_property(device *me,
const char *property)
{
NULL, 0);
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_add_string_property(device *me,
const char *property,
const char *string)
string, strlen(string) + 1);
}
-const device_property INLINE_DEVICE *
+INLINE_DEVICE\
+(const device_property *)
device_find_property(device *me,
const char *property)
{
return (device_property*)0;
}
-const char INLINE_DEVICE *
+INLINE_DEVICE\
+(const char *)
device_find_next_property(device *me,
const char *property)
{
return NULL;
}
-const device_property INLINE_DEVICE *
+INLINE_DEVICE\
+(const device_property *)
device_find_array_property(device *me,
const char *property)
{
return node;
}
-signed_word INLINE_DEVICE
+INLINE_DEVICE\
+(signed_word)
device_find_integer_property(device *me,
const char *property)
{
return integer;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
device_find_boolean_property(device *me,
const char *property)
{
return boolean;
}
-const char INLINE_DEVICE *
+INLINE_DEVICE\
+(const char *)
device_find_string_property(device *me,
const char *property)
{
/* 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)
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,
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
/* grow the device tree */
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_tree_add_device(device *root,
const char *prefix,
device *new_sub_tree)
return new_sub_tree;
}
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_tree_find_device(device *root,
const char *path)
{
/* init all the devices */
-void STATIC_INLINE_DEVICE
+STATIC_INLINE_DEVICE\
+(void)
device_tree_init_device(device *root,
void *data)
{
}
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_tree_init(device *root,
psim *system)
{
/* 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,
/* dump out a device node and addresses */
-void INLINE_DEVICE
+INLINE_DEVICE\
+(void)
device_tree_dump(device *device,
void *ignore_data_argument)
{
/* lookup/create a device various formats */
-void STATIC_INLINE_DEVICE
+STATIC_INLINE_DEVICE\
+(void)
u_strcat(char *buf,
unsigned_word uw)
{
}
}
-void STATIC_INLINE_DEVICE
+STATIC_INLINE_DEVICE\
+(void)
c_strcat(char *buf,
const char *c)
{
*end = '\0';
}
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_tree_add_found(device *root,
const char *prefix,
const char *name)
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);
}
}
-device INLINE_DEVICE *
+INLINE_DEVICE\
+(device *)
device_tree_add_found_c(device *root,
const char *prefix,
const char *name,
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,
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,
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,
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,
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,
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,
START = END + 1; \
} while (0)
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_c(const char *name,
char *c1,
unsigned c1size)
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_c_uw_u(const char *name,
char *c1,
unsigned c1size,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw(const char *name,
unsigned_word *uw1)
{
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_c(const char *name,
unsigned_word *uw1,
char *c2,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_u(const char *name,
unsigned_word *uw1,
unsigned *u2)
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_u_u(const char *name,
unsigned_word *uw1,
unsigned *u2,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_u_u_c(const char *name,
unsigned_word *uw1,
unsigned *u2,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_uw(const char *name,
unsigned_word *uw1,
unsigned_word *uw2)
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_uw_u(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_uw_u_u_c(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
SCAN_END;
}
-int INLINE_DEVICE
+INLINE_DEVICE\
+(int)
scand_uw_uw_u_u_u(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
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,
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,
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,
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,
/* 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);
(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,
/* 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);
/* 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);
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);
/* 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);
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);
/* 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);
*/
-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);
*/
-void INLINE_DEVICE device_attach_address
+INLINE_DEVICE(void) device_attach_address
(device *me,
const char *name,
attach_type attach,
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,
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,
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,
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,
*/
-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,
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);
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,
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
\f
/* 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,
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,
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,
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
+#include <ctype.h>
#include "device_table.h"
/* 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,
{
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);
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));
}
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);
(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,
/* 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);
}
#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 */
/* 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,
/* 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;
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");
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);
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");
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 = {
/* 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);
request or waiting on a client callback */
typedef enum {
serving,
+ faulting,
catching,
} chirp_emul_state;
/* 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)
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)
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;
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
-chirp_emul_write(os_emul_data *data,
+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 write_args {
+ 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;
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, ("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);
+ if (actual >= sizeof(buf))
+ actual = sizeof(buf) - 1;
emul_read_buffer(buf,
T2H_4(args.addr),
actual,
processor, cia);
- /* write it out */
- write(BE2H_4(args.ihandle), buf, actual);
+ 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 unsigned_word
-chirp_emul_exit(os_emul_data *data,
- cpu *processor,
- unsigned_word cia)
+static int
+chirp_emul_write(os_emul_data *data,
+ cpu *processor,
+ unsigned_word cia)
{
- error("chirp_emul_exit not implemnented\n");
+ struct write_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, ("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) - 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;
}
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 */ },
};
{
os_emul_data *data;
chirp_note note;
+ int big_endian;
/* Sanity check that this really is the chosen emulation */
if (name == NULL && image == NULL)
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;
/* 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;
/* 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");
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);
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
? 0
: (msr_instruction_relocate
| msr_data_relocate))
- | (image->xvec->byteorder_big_p
+ | (big_endian
? 0
: (msr_little_endian_mode
| msr_interrupt_little_endian_mode
{ /* 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;
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;
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;
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 */