mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 13:09:48 +00:00
Latest changes from Andrew
This commit is contained in:
parent
0374a10562
commit
52edddb970
@ -28,6 +28,7 @@ COPYING.LIB
|
||||
ChangeLog
|
||||
Makefile.in
|
||||
README.psim
|
||||
PROBLEMS
|
||||
basics.h
|
||||
bits.c
|
||||
bits.h
|
||||
|
@ -1,3 +1,17 @@
|
||||
Tue Jan 9 15:10:27 1996 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* emul_bugapi.c (emul_bugapi_instruction_call) : Make format type
|
||||
correct.
|
||||
* emul_chirp.c (map_over_chirp_note) : Ditto
|
||||
* emul_chirp.c (chirp_emul_test) : Ditto
|
||||
* device_table.c (register_init): Ditto
|
||||
|
||||
Tue Jan 9 14:16:26 1996 Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
* configure.in: Make disable-sim-switch default. Switch only
|
||||
useful if using --enable-sim-opcode=ppc-opcode-stupid and then
|
||||
only marginally so.
|
||||
|
||||
Mon Jan 8 12:17:22 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* device_table.c (register_init): Make format type correct.
|
||||
|
@ -417,7 +417,7 @@ distclean realclean: clean
|
||||
rm -f TAGS Makefile config.cache config.status config.h stamp-h
|
||||
|
||||
maintainer-clean: distclean
|
||||
rm -f *~ ppc-config.h
|
||||
rm -f *~ *.log ppc-config.h core *.core
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
34
sim/ppc/PROBLEMS
Normal file
34
sim/ppc/PROBLEMS
Normal file
@ -0,0 +1,34 @@
|
||||
See the ChangeLog file looking for lines taged with the word FIXME.
|
||||
|
||||
COREFILE.C: The implementation of corefile.c (defined by
|
||||
corefile.h) isn't the best. It is intended to be functionaly
|
||||
correct rather than fast. One option being considered
|
||||
is to add a data cache to reduce the overhead of the most
|
||||
common case of data read/writes.
|
||||
|
||||
HTAB (page) code for OEA model untested. Some of the vm code
|
||||
instructions unimplemented.
|
||||
|
||||
Lacks PowerOpen (a.k.a. XCOFF a.k.a. AIX) and NT startups. The
|
||||
PowerOpen worked until I added the ELF one.
|
||||
|
||||
Missing VEA system calls.
|
||||
|
||||
Missing or commented out instructions.
|
||||
|
||||
64bit target untested.
|
||||
|
||||
64bit host broken. For instance use of scanf "%x", &long long.
|
||||
|
||||
Event code for pending events from within signal handlers not
|
||||
finished/tested.
|
||||
|
||||
Better and more devices.
|
||||
|
||||
PORTABILITY (Notes taken from Michael Meissner): Heavy use of the ##
|
||||
operator - fix using the clasic X/**/Y hack; Use of the signed
|
||||
keyword. In particular, signed char has no analogue in classic C
|
||||
(though most implementations of classic C use signed chars); Use of
|
||||
long long which restricts the target compiler to be GCC.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
PSIM - model of a PowerPC platform
|
||||
PSIM - model a PowerPC platform
|
||||
|
||||
Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>.
|
||||
|
||||
@ -18,15 +18,17 @@
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
This directory contains the program PSIM that implements a model of a
|
||||
PowerPC platform. PSIM can either be built standalone or as part of
|
||||
the debugger GDB.
|
||||
This directory contains the source code to the program PSIM that
|
||||
implements a model of a PowerPC platform. PSIM can either be built
|
||||
standalone or as part of the debugger GDB.
|
||||
|
||||
|
||||
What is PSIM?
|
||||
|
||||
PSIM is an ANSI C program that models a PowerPC platform.
|
||||
The platform it implements can vary from:
|
||||
PSIM is an ANSI C program that can be configured to model
|
||||
various PowerPC platforms.
|
||||
|
||||
The platform that is modeled can vary from:
|
||||
|
||||
o A user program environment (UEA) complete
|
||||
with emulated system calls
|
||||
@ -34,7 +36,17 @@ What is PSIM?
|
||||
to
|
||||
|
||||
o A hardware platform with several processors
|
||||
interacting with each other and modeled hardware.
|
||||
interacting with each other and various
|
||||
modeled hardware devices.
|
||||
|
||||
|
||||
Is the source code available?
|
||||
|
||||
Yes.
|
||||
|
||||
The source code to PSIM is available under the terms of
|
||||
the GNU Public Licence. This allows you to distribute
|
||||
the source code for free but with certain conditions.
|
||||
|
||||
|
||||
What motivated PSIM?
|
||||
@ -155,31 +167,40 @@ What features does PSIM have?
|
||||
|
||||
ENDIAN SUPORT
|
||||
|
||||
PSIM implements all of Big-endian, little-endian
|
||||
and PowerPC little endian (XOR endian).
|
||||
PSIM implements the PowerPC's big and little (xor
|
||||
endian) modes and correctly simulates code that
|
||||
switches between these two modes.
|
||||
|
||||
ISA models
|
||||
In addition, psim can model a true little-endian
|
||||
machine.
|
||||
|
||||
PSIM includes a model of UEA, VEA and OEA. This
|
||||
ISA models (Instruction Set Architecture)
|
||||
|
||||
PSIM includes a model of the UEA, VEA and OEA. This
|
||||
inclues the time base registers (VEA) and HTAB
|
||||
and BATS (OEA).
|
||||
|
||||
In addition, a preliminary model of the 64 bit
|
||||
PowerPC architecture is included.
|
||||
PowerPC architecture is implemented.
|
||||
|
||||
Hardware
|
||||
|
||||
PSIM's internals are based around the concept
|
||||
of a Device Tree. This tree intentionaly
|
||||
resembles that of the Device Tree found in
|
||||
OpenBoot firmware. Psim is flexable enough
|
||||
OpenBoot firmware. PSIM is flexable enough
|
||||
to allow the user to fully configure the
|
||||
actual hardware model from a device tree
|
||||
specification taken from a file.
|
||||
specification that is read in from a file.
|
||||
|
||||
A user can either run a program using one of
|
||||
PSIM's built in hardware models specify a
|
||||
custom hardware model that should be simulated.
|
||||
|
||||
A user is also able to quickly add a model
|
||||
of new hardware devices so that they can be
|
||||
included in a custom hardware model.
|
||||
|
||||
PSIM also contains several built in device
|
||||
trees.
|
||||
|
||||
Emulation
|
||||
|
||||
PSIM is able (UEA) to emulate UNIX calls
|
||||
@ -187,84 +208,97 @@ What features does PSIM have?
|
||||
the ROM rom calls found in common firmware
|
||||
(OpenBoot and BUGAPI).
|
||||
|
||||
floating point
|
||||
Floating point
|
||||
|
||||
Preliminary suport for floating point is included.
|
||||
Real kernels don't need floating point.
|
||||
|
||||
|
||||
Can PSIM model a CHRP a.k.a. PowerPC Platform machine?
|
||||
Is PSIM CHRP Compliant?
|
||||
|
||||
No. but that is now one of its main objectives. (Did you notice
|
||||
it was written PowerPC Platform instead of PowerPC platform?).
|
||||
No.
|
||||
|
||||
However, PSIM does include all the hooks that are needed to
|
||||
construct a model of a CHRP compliant platform.
|
||||
|
||||
That is:
|
||||
|
||||
o OpenBoot client software
|
||||
|
||||
o OpenPIC interrupt controller
|
||||
|
||||
o Hooks to implement a RTAS interface
|
||||
|
||||
o the ability to add a model of each of the
|
||||
hardware devices required by a CHRP compliant
|
||||
desktop.
|
||||
|
||||
|
||||
How do I build PSIM?
|
||||
|
||||
To build PSIM you will need the following:
|
||||
To build PSIM you will need the following files:
|
||||
|
||||
|
||||
gdb-4.15.tar.gz From your favorite GNU ftp site.
|
||||
I've also tested psim-951016 with
|
||||
gdb-4.15.1.
|
||||
gdb-4.15.1. If you would prefer
|
||||
a graphical development environment
|
||||
then PSIM can also be built with
|
||||
gdbtk.
|
||||
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/README.pim
|
||||
|
||||
This file.
|
||||
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/gdb-4.15+psim-951016.diff.gz
|
||||
|
||||
This contains a few minor patches to
|
||||
gdb-4.15 so that will include psim
|
||||
when it is built.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/gdb-4.15+psim-951016.tar.gz
|
||||
|
||||
This contains the psim files propper.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-test-951016.tar.gz
|
||||
|
||||
(Optional) A scattering of pre-compiled
|
||||
programs that run under the simulator.
|
||||
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/gdb-4.15+psim-951016.tar.gz
|
||||
|
||||
This contains the psim files proper.
|
||||
|
||||
|
||||
gcc Again available from your favorite
|
||||
GNU ftp site.
|
||||
|
||||
|
||||
patch Sun's patch behaves a little wierd
|
||||
and doesn't appear to like creating
|
||||
empty files.
|
||||
empty files. You may want to consider
|
||||
installing gnu's patch.
|
||||
|
||||
|
||||
Since PSIM is still being developed, from time to time, to meet
|
||||
a specific analysts needsfurther psim snap shots are occasionally
|
||||
made available. These snapshots may or may not work with GDB-4.15.
|
||||
Several of the more recent snapshots are:
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-951218.tar.gz
|
||||
|
||||
Hopefully merges in Michael stuff
|
||||
with mine, adds multiple emulations
|
||||
(OpenBoot and NetBSD), revamps
|
||||
inline stuff, rearanges devices so
|
||||
that phandls and ihandles can be
|
||||
implemented.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-951203.tar.gz
|
||||
|
||||
A good snapshot
|
||||
|
||||
This includes extensions from Michael
|
||||
Meissner that add monitoring of the
|
||||
PowerPC's register and bus architectures.
|
||||
In addition, I'm slowly building up a set of useful patches
|
||||
to gdb-4.15 that are useful. You will want to also apply
|
||||
these patches:
|
||||
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-test-951218.tar.gz
|
||||
ftp://ftp.ci.com.au/pub/clayton/gdb-4.15+attach.diff.gz
|
||||
|
||||
Prebuilt test programs for PSIM.
|
||||
Includes examples of UEA, VEA and
|
||||
OEA code.
|
||||
Requires gcc-2.7.2 and binutils-2.6
|
||||
to rebuild.
|
||||
Patch to gdb that allows the `attach'
|
||||
command to be used when connecting to a
|
||||
simulator.
|
||||
|
||||
See that file for more information.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/gdb-4.15+note.diff.gz
|
||||
|
||||
Patch to gdb's bfd that adds basic support
|
||||
for a .note section. OpenBoot makes
|
||||
use of a .note section when loading a
|
||||
boot image.
|
||||
|
||||
|
||||
Procedure:
|
||||
@ -294,6 +328,15 @@ How do I build PSIM?
|
||||
$ gunzip < ../gdb-4.15+psim-951016.tar.gz | tar tvf -
|
||||
$ gunzip < ../gdb-4.15+psim-951016.tar.gz | tar xvf -
|
||||
|
||||
You may also want to consider applying the `attach' and
|
||||
`note' patches that are available vis:
|
||||
|
||||
$ gunzip < ../gdb-4.15+attach.diff.gz | more
|
||||
$ gunzip < ../gdb-4.15+attach.diff.gz | patch -p
|
||||
|
||||
$ gunzip < ../gdb-4.15+note.diff.gz | more
|
||||
$ gunzip < ../gdb-4.15+note.diff.gz | patch -p
|
||||
|
||||
|
||||
3. Configure gdb
|
||||
|
||||
@ -329,24 +372,97 @@ How do I build PSIM?
|
||||
$ cp sim/ppc/run ~/bin/powerpc-unknown-eabisim-run
|
||||
|
||||
|
||||
Is there a more recent version of PSIM and if so, how would I build it?
|
||||
|
||||
A PSIM is an ongoing development, occasional snapshots
|
||||
(that include new features) are made available. Several of
|
||||
the more recent snapshots are:
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-951219.tar.gz
|
||||
|
||||
Hopefully merges in Michael stuff
|
||||
with mine, adds multiple emulations
|
||||
(OpenBoot and NetBSD), revamps
|
||||
inline stuff, rearanges devices so
|
||||
that phandls and ihandles can be
|
||||
implemented.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-951203.tar.gz
|
||||
|
||||
A good snapshot
|
||||
|
||||
This includes extensions from Michael
|
||||
Meissner that add monitoring of the
|
||||
PowerPC's register and bus architectures.
|
||||
|
||||
|
||||
To build/install one of these snapshots, you replace the
|
||||
current gdb/sim/ppc directory with the one in the update,
|
||||
re-configure and rebuild.
|
||||
|
||||
Procedure:
|
||||
|
||||
0. A starting point
|
||||
|
||||
$ cd gdb-4.15
|
||||
|
||||
|
||||
1. Remove the old psim directory
|
||||
|
||||
$ mv sim/ppc sim/old.ppc
|
||||
|
||||
|
||||
2. Unpack the new one
|
||||
|
||||
$ gunzip < ../psim-960105.tar.gz | tar tf -
|
||||
$ gunzip < ../psim-960105.tar.gz | tar tf -
|
||||
|
||||
|
||||
3. Reconfig/rebuild (as seen above):
|
||||
|
||||
$ CC=gcc ./configure --target=powerpc-unknown-eabisim
|
||||
$ make CC=gcc
|
||||
|
||||
|
||||
Are there any example programs that can be run on PSIM?
|
||||
|
||||
Psim has a simple test suite that is used to ensure
|
||||
that fixes do not introduce new bugs. This test suite
|
||||
like psim is updated:
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-test-951218.tar.gz
|
||||
|
||||
Prebuilt test programs for PSIM.
|
||||
Includes examples of UEA, VEA and
|
||||
OEA code.
|
||||
Requires gcc-2.7.2 and binutils-2.6
|
||||
to rebuild.
|
||||
|
||||
ftp://ftp.ci.com.au/pub/clayton/psim-test-951016.tar.gz
|
||||
|
||||
(Optional) A scattering of pre-compiled
|
||||
programs that run under the simulator.
|
||||
|
||||
|
||||
How do I use the simulator?
|
||||
|
||||
|
||||
(I assume that you've unpacked the psim-test archive).
|
||||
I assume that you've unpacked a psim-test archive.
|
||||
|
||||
|
||||
1. As a standalone program
|
||||
|
||||
Print out the users environment:
|
||||
|
||||
$ powerpc-unknown-eabisim-run envp
|
||||
$ powerpc-unknown-eabisim-run psim-test/uea/envp
|
||||
|
||||
Print out the arguments:
|
||||
|
||||
$ powerpc-unknown-eabisim-run argv a b c
|
||||
$ powerpc-unknown-eabisim-run psim-test/uea/argv a b c
|
||||
|
||||
Check that sbrk works:
|
||||
|
||||
$ powerpc-unknown-eabisim-run break
|
||||
$ powerpc-unknown-eabisim-run psim-test/uea/break
|
||||
|
||||
|
||||
2. Example of running GDB:
|
||||
@ -354,7 +470,7 @@ How do I use the simulator?
|
||||
The main thing to note is that before you can run the simulator
|
||||
you must enable it. The example below illustrates this:
|
||||
|
||||
$ powerpc-unknown-eabisim-gdb envp
|
||||
$ powerpc-unknown-eabisim-gdb psim-test/uea/envp
|
||||
(gdb) target sim
|
||||
(gdb) load
|
||||
(gdb) break main
|
||||
@ -364,6 +480,21 @@ How do I use the simulator?
|
||||
.
|
||||
|
||||
|
||||
3. Using a device tree as a description of a machine
|
||||
(I assume that you have applied the attach bug).
|
||||
|
||||
$ cd psim-test/tree
|
||||
$ powerpc-unknown-eabisim-gdb
|
||||
(gdb) target sim
|
||||
(gdb) attach device-tree
|
||||
(gdb) run
|
||||
|
||||
or
|
||||
|
||||
$ cd psim-test/tree
|
||||
$ powerpc-unknown-eabisim-run device-tree
|
||||
|
||||
|
||||
Where do I send bugs or report problems?
|
||||
|
||||
There is a mailing list (subscribe through majordomo@ci.com.au) (that
|
||||
@ -376,40 +507,10 @@ Where do I send bugs or report problems?
|
||||
that e-mail list.
|
||||
|
||||
|
||||
Are there any known problems?
|
||||
Does PSIM have any limitations or problems?
|
||||
|
||||
See the ChangeLog file looking for lines taged with the word FIXME.
|
||||
|
||||
COREFILE.C: The implementation of corefile.c (defined by
|
||||
corefile.h) isn't the best. It is intended to be functionaly
|
||||
correct rather than fast. One option being considered
|
||||
is to add a data cache to reduce the overhead of the most
|
||||
common case of data read/writes.
|
||||
|
||||
HTAB (page) code for OEA model untested. Some of the vm code
|
||||
instructions unimplemented.
|
||||
|
||||
Lacks PowerOpen (a.k.a. XCOFF a.k.a. AIX) and NT startups. The
|
||||
PowerOpen worked until I added the ELF one.
|
||||
|
||||
Missing VEA system calls.
|
||||
|
||||
Missing or commented out instructions.
|
||||
|
||||
64bit target untested.
|
||||
|
||||
64bit host broken. For instance use of scanf "%x", &long long.
|
||||
|
||||
Event code for pending events from within signal handlers not
|
||||
finished/tested.
|
||||
|
||||
Better and more devices.
|
||||
|
||||
PORTABILITY (Notes taken from Michael Meissner): Heavy use of the ##
|
||||
operator - fix using the clasic X/**/Y hack; Use of the signed
|
||||
keyword. In particular, signed char has no analogue in classic C
|
||||
(though most implementations of classic C use signed chars); Use of
|
||||
long long which restricts the target compiler to be GCC.
|
||||
See the file PROBLEMS (included in the distribution) for any
|
||||
outstanding issues.
|
||||
|
||||
|
||||
Who helped?
|
||||
|
@ -73,7 +73,7 @@ AC_ARG_ENABLE(sim-switch,
|
||||
esac
|
||||
if test x"$silent" != x"yes" && test x"$sim_switch" != x""; then
|
||||
echo "Setting switch flags = $sim_switch" 6>&1
|
||||
fi],[sim_switch="-s";
|
||||
fi],[sim_switch="";
|
||||
if test x"$silent" != x"yes"; then
|
||||
echo "Setting switch flags = $sim_switch" 6>&1
|
||||
fi])dnl
|
||||
|
@ -685,7 +685,7 @@ register_init(device *me,
|
||||
if (isdigit(name[0]) && name[1] == '.') {
|
||||
processor = atol(name);
|
||||
name += 2;
|
||||
DTRACE(register, ("%ld.%s=0x%lx\n", (long)name, processor, (unsigned long)value));
|
||||
DTRACE(register, ("%d.%s=0x%lx\n", processor, name, (unsigned long)value));
|
||||
}
|
||||
else {
|
||||
processor = -1;
|
||||
|
@ -156,15 +156,15 @@ emul_bugapi_create(device *root,
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_SYSTEM_CALL_ADDRESS,
|
||||
4, 0x1); /*emul-call*/
|
||||
4, emul_call_instruction);
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_SYSTEM_CALL_ADDRESS + 4,
|
||||
4, 0x4c000064); /*rfi*/
|
||||
4, emul_rfi_instruction);
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
OEA_STALL_CPU_LOOP_ADDRESS,
|
||||
4, 0x48000000); /*b .*/
|
||||
4, emul_loop_instruction);
|
||||
}
|
||||
{
|
||||
device *init_stack = device_tree_add_found(init, "", "stack");
|
||||
@ -204,7 +204,7 @@ emul_bugapi_instruction_call(cpu *processor,
|
||||
return 0;
|
||||
switch (call_id) {
|
||||
case _OUTCHR:
|
||||
printf_filtered("%c", cpu_registers(processor)->gpr[3]);
|
||||
printf_filtered("%c", (char)cpu_registers(processor)->gpr[3]);
|
||||
break;
|
||||
case _OUTLN:
|
||||
printf_filtered("\n");
|
||||
|
@ -74,11 +74,135 @@ struct _os_emul_data {
|
||||
unsigned_word catching_instruction_ea;
|
||||
cap *phandles;
|
||||
device *root;
|
||||
chirp_services *services;
|
||||
};
|
||||
|
||||
|
||||
/* Read in the argument list and make the most basic check that number
|
||||
of argumnets are consistent with what was expected */
|
||||
|
||||
static int
|
||||
chirp_read_args(void *args,
|
||||
int sizeof_args,
|
||||
int n_args,
|
||||
int n_returns,
|
||||
os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct base_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
} *base;
|
||||
emul_read_buffer(args, data->arguments,
|
||||
sizeof_args,
|
||||
processor, cia);
|
||||
base = (struct base_args*)args;
|
||||
if (T2H_4(base->n_args) != n_args || T2H_4(base->n_returns) != n_returns) {
|
||||
TRACE(trace_os_emul, ("invalid nr of args - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(base->n_args),
|
||||
(long)T2H_4(base->n_returns)));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* OpenBoot emulation functions */
|
||||
|
||||
/* client interface */
|
||||
|
||||
static int
|
||||
chirp_emul_test(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct test_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 name; /*string*/
|
||||
/*out*/
|
||||
unsigned32 missing;
|
||||
} args;
|
||||
char name[32];
|
||||
chirp_services *service = data->services;
|
||||
/* read in the arguments */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
return -1;
|
||||
emul_read_string(name, T2H_4(args.name), sizeof(name),
|
||||
processor, cia);
|
||||
TRACE(trace_os_emul, ("test - in - name=`%s'\n", name));
|
||||
/* see if we know about the service */
|
||||
while (service->name != NULL && strcmp(service->name, name) != 0) {
|
||||
service++;
|
||||
}
|
||||
if (service->name == NULL)
|
||||
args.missing = -1;
|
||||
else
|
||||
args.missing = 0;
|
||||
/* write the arguments back out */
|
||||
TRACE(trace_os_emul, ("test - out - missing=%ld\n",
|
||||
(long)args.missing));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Device tree */
|
||||
|
||||
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;
|
||||
/* read in the arguments */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
return -1;
|
||||
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))));
|
||||
/* find the peer */
|
||||
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);
|
||||
/* write the arguments back out */
|
||||
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_child(os_emul_data *data,
|
||||
cpu *processor,
|
||||
@ -95,21 +219,15 @@ chirp_emul_child(os_emul_data *data,
|
||||
} 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)));
|
||||
/* read the arguments in */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
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))));
|
||||
/* find a child */
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
child_dev = device_child(dev);
|
||||
@ -117,6 +235,7 @@ chirp_emul_child(os_emul_data *data,
|
||||
args.child_phandle = 0;
|
||||
else
|
||||
args.child_phandle = cap_external(data->phandles, child_dev);
|
||||
/* write the result out */
|
||||
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,
|
||||
@ -128,55 +247,101 @@ chirp_emul_child(os_emul_data *data,
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_exit(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
chirp_emul_parent(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)
|
||||
{
|
||||
struct finddevice_args {
|
||||
struct parent_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 device_specifier;
|
||||
/*out*/
|
||||
unsigned32 phandle;
|
||||
/*out*/
|
||||
unsigned32 parent_phandle;
|
||||
} args;
|
||||
char device_specifier[1024];
|
||||
device *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, ("finddevice - invalid nr - n_args=%ld, n_returns=%ld\n",
|
||||
(long)T2H_4(args.n_args),
|
||||
(long)T2H_4(args.n_returns)));
|
||||
device *parent_dev;
|
||||
/* read the args in */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
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",
|
||||
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))));
|
||||
/* find a parent */
|
||||
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);
|
||||
/* return the result */
|
||||
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_instance_to_package(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: instance-to-package unimplemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
/* read the args in */
|
||||
if (chirp_read_args(&args, sizeof(args), 2, 1, data, processor, cia))
|
||||
return -1;
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
/* find our prop and get its length */
|
||||
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);
|
||||
}
|
||||
/* return the result */
|
||||
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);
|
||||
@ -203,16 +368,9 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
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) != 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)));
|
||||
/* read in the args */
|
||||
if (chirp_read_args(&args, sizeof(args), 4, 1, data, processor, cia))
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
emul_read_string(name,
|
||||
T2H_4(args.name),
|
||||
@ -225,6 +383,7 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
name,
|
||||
(unsigned long)T2H_4(args.buf),
|
||||
(unsigned long)T2H_4(args.buflen)));
|
||||
/* get the property */
|
||||
if (dev == (device*)0)
|
||||
return -1;
|
||||
prop = device_find_property(dev, name);
|
||||
@ -248,6 +407,7 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* write back the result */
|
||||
TRACE(trace_os_emul, ("getprop - out - size=%ld\n",
|
||||
(unsigned long)T2H_4(args.size)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
@ -257,60 +417,105 @@ chirp_emul_getprop(os_emul_data *data,
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_getproplen(os_emul_data *data,
|
||||
chirp_emul_nextprop(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: nextprop not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_setprop(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: setprop not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_canon(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: canon not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_finddevice(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct getproplen_args {
|
||||
struct finddevice_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
unsigned32 phandle;
|
||||
unsigned32 name;
|
||||
unsigned32 device_specifier;
|
||||
/*out*/
|
||||
unsigned32 proplen;
|
||||
unsigned32 phandle;
|
||||
} args;
|
||||
char name[32];
|
||||
char device_specifier[1024];
|
||||
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)));
|
||||
/* get the args */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
dev = cap_internal(data->phandles, args.phandle);
|
||||
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));
|
||||
/* find the device */
|
||||
dev = device_tree_find_device(data->root,
|
||||
device_specifier);
|
||||
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",
|
||||
args.phandle = -1;
|
||||
else
|
||||
args.phandle = cap_external(data->phandles, dev);
|
||||
/* return its phandle */
|
||||
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)),
|
||||
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)));
|
||||
(dev == NULL ? "" : device_name(dev))));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_instance_to_path(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: instance_to_path not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_package_to_path(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: package_to_path not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_call_method(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: call-method implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Device I/O */
|
||||
|
||||
static int
|
||||
chirp_emul_open(os_emul_data *data,
|
||||
cpu *processor,
|
||||
@ -326,24 +531,19 @@ chirp_emul_open(os_emul_data *data,
|
||||
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)));
|
||||
/* read the args */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
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));
|
||||
/* open the device */
|
||||
printf_filtered("OpenBoot - open unimplemented for %s\n", name);
|
||||
args.ihandle = -1;
|
||||
/* return the ihandle result */
|
||||
TRACE(trace_os_emul, ("open - out - ihandle=0x%lx\n",
|
||||
(unsigned long)T2H_4(args.ihandle)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
@ -353,101 +553,11 @@ chirp_emul_open(os_emul_data *data,
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_parent(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
chirp_emul_close(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);
|
||||
error("chirp: close not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -469,31 +579,33 @@ chirp_emul_read(os_emul_data *data,
|
||||
} 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)));
|
||||
/* read the args */
|
||||
if (chirp_read_args(&args, sizeof(args), 3, 1, data, processor, cia))
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
TRACE(trace_os_emul, ("read - in - ihandle=0x%lx addr=0x%lx len=%ld\n",
|
||||
(unsigned long)args.ihandle,
|
||||
(unsigned long)T2H_4(args.addr),
|
||||
(unsigned long)T2H_4(args.len)));
|
||||
/* do the read */
|
||||
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)));
|
||||
actual = read(BE2H_4(args.ihandle), buf, actual);
|
||||
if (actual >= 0) {
|
||||
emul_write_buffer(buf,
|
||||
T2H_4(args.addr),
|
||||
actual,
|
||||
processor, cia);
|
||||
args.actual = H2T_4(actual);
|
||||
buf[actual] = '\0';
|
||||
}
|
||||
else {
|
||||
args.actual = 0;
|
||||
}
|
||||
/* return the result */
|
||||
TRACE(trace_os_emul, ("read - out - actual=%ld `%s'\n",
|
||||
(long)T2H_4(args.actual),
|
||||
(actual >= 0 ? buf : "")));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
@ -518,16 +630,9 @@ chirp_emul_write(os_emul_data *data,
|
||||
} 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)));
|
||||
/* get the args */
|
||||
if (chirp_read_args(&args, sizeof(args), 3, 1, data, processor, cia))
|
||||
return -1;
|
||||
}
|
||||
/* read in the arguments */
|
||||
actual = T2H_4(args.len);
|
||||
if (actual >= sizeof(buf))
|
||||
actual = sizeof(buf) - 1;
|
||||
@ -536,11 +641,15 @@ chirp_emul_write(os_emul_data *data,
|
||||
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);
|
||||
/* write it out */
|
||||
actual = write(BE2H_4(args.ihandle), buf, actual);
|
||||
if (actual < 0)
|
||||
args.actual = 0;
|
||||
else
|
||||
args.actual = H2T_4(actual);
|
||||
/* return the result */
|
||||
TRACE(trace_os_emul, ("write - out - actual=%ld\n",
|
||||
(long)T2H_4(args.actual)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
@ -549,18 +658,186 @@ chirp_emul_write(os_emul_data *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_seek(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: seek not implemented\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 },
|
||||
|
||||
/* memory */
|
||||
|
||||
static int
|
||||
chirp_emul_claim(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: claim not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_release(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: release not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Control transfer */
|
||||
|
||||
static int
|
||||
chirp_emul_boot(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: boot not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_enter(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: enter not implemented\n");
|
||||
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_chain(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: chain not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* user interface */
|
||||
|
||||
static int
|
||||
chirp_emul_interpret(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: interpret not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_set_callback(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: set_callback not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chirp_emul_set_symbol_lookup(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
error("chirp: set_symbol_lookup not implemented\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Time */
|
||||
|
||||
static int
|
||||
chirp_emul_milliseconds(os_emul_data *data,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
struct test_args {
|
||||
unsigned32 service;
|
||||
unsigned32 n_args;
|
||||
unsigned32 n_returns;
|
||||
/*in*/
|
||||
/*out*/
|
||||
unsigned32 ms;
|
||||
} args;
|
||||
unsigned64 time;
|
||||
/* read in the arguments */
|
||||
if (chirp_read_args(&args, sizeof(args), 1, 1, data, processor, cia))
|
||||
return -1;
|
||||
/* make up a number */
|
||||
time = event_queue_time(cpu_event_queue(processor)) / 1000000;
|
||||
args.ms = H2T_4(time);
|
||||
/* write the arguments back out */
|
||||
TRACE(trace_os_emul, ("milliseconds - out - ms=%ld\n",
|
||||
(unsigned long)T2H_4(args.ms)));
|
||||
emul_write_buffer(&args, data->arguments,
|
||||
sizeof(args),
|
||||
processor, cia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static chirp_services services[] = {
|
||||
|
||||
/* client interface */
|
||||
{ "test", chirp_emul_test },
|
||||
|
||||
/* device tree */
|
||||
{ "peer", chirp_emul_peer },
|
||||
{ "child", chirp_emul_child },
|
||||
{ "parent", chirp_emul_parent },
|
||||
{ "instance-to-package", chirp_emul_instance_to_package },
|
||||
{ "getproplen", chirp_emul_getproplen },
|
||||
{ "getprop", chirp_emul_getprop },
|
||||
{ "nextprop", chirp_emul_nextprop },
|
||||
{ "setprop", chirp_emul_setprop },
|
||||
{ "canon", chirp_emul_canon },
|
||||
{ "finddevice", chirp_emul_finddevice },
|
||||
{ "instance-to-path", chirp_emul_instance_to_path },
|
||||
{ "package-to-path", chirp_emul_package_to_path },
|
||||
{ "call-method", chirp_emul_call_method },
|
||||
|
||||
/* device I/O */
|
||||
{ "open", chirp_emul_open },
|
||||
{ "close", chirp_emul_close },
|
||||
{ "read", chirp_emul_read },
|
||||
{ "write", chirp_emul_write },
|
||||
{ "seek", chirp_emul_seek },
|
||||
{ "write", chirp_emul_write },
|
||||
|
||||
/* memory */
|
||||
{ "claim", chirp_emul_claim },
|
||||
{ "release", chirp_emul_release },
|
||||
|
||||
/* control transfer */
|
||||
{ "boot", chirp_emul_boot },
|
||||
{ "enter", chirp_emul_enter },
|
||||
{ "exit", chirp_emul_exit },
|
||||
{ "chain", chirp_emul_chain },
|
||||
|
||||
/* user interface */
|
||||
{ "interpret", chirp_emul_interpret },
|
||||
{ "set_callback", chirp_emul_set_callback },
|
||||
{ "set_symbol_lookup", chirp_emul_set_symbol_lookup },
|
||||
|
||||
/* time */
|
||||
{ "milliseconds", chirp_emul_milliseconds },
|
||||
|
||||
{ 0, /* sentinal */ },
|
||||
};
|
||||
|
||||
@ -613,18 +890,33 @@ map_over_chirp_note(bfd *image,
|
||||
return;
|
||||
note->found = 1;
|
||||
/* check the name field */
|
||||
if (head.namesz > sizeof(name))
|
||||
if (head.namesz > sizeof(name)) {
|
||||
printf_filtered("open-boot warning: note name too long (%ld)\n",
|
||||
(long)head.namesz);
|
||||
return;
|
||||
}
|
||||
if (!bfd_get_section_contents(image, sect,
|
||||
name, sizeof(head), head.namesz))
|
||||
name, sizeof(head), head.namesz)) {
|
||||
printf_filtered("open-boot warning: note name unreadable\n");
|
||||
return;
|
||||
if (strcmp(name, "PowerPC") != 0)
|
||||
}
|
||||
if (strcmp(name, "PowerPC") != 0) {
|
||||
printf_filtered("open-boot warning: note name (%s) not `PowerPC'\n",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
/* get the contents */
|
||||
if (!bfd_get_section_contents(image, sect,
|
||||
¬e->desc, sizeof(head) + head.namesz,
|
||||
head.descsz))
|
||||
if (head.descsz != sizeof(note->desc)) {
|
||||
printf_filtered("open-boot warning: note descriptor of wrong size\n");
|
||||
return;
|
||||
}
|
||||
if (!bfd_get_section_contents(image, sect,
|
||||
¬e->desc, /* page align start */
|
||||
((sizeof(head) + head.namesz) + 3) & ~3,
|
||||
head.descsz)) {
|
||||
printf_filtered("open-boot warning: note descriptor unreadable\n");
|
||||
return;
|
||||
}
|
||||
note->desc.real_mode = bfd_get_32(image, (void*)¬e->desc.real_mode);
|
||||
note->desc.real_base = bfd_get_32(image, (void*)¬e->desc.real_base);
|
||||
note->desc.real_size = bfd_get_32(image, (void*)¬e->desc.real_size);
|
||||
@ -753,18 +1045,25 @@ emul_chirp_create(device *root,
|
||||
device_add_integer_property(init_register,
|
||||
"r5",
|
||||
code_client_va);
|
||||
/* client interface */
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_client_va - code_va),
|
||||
4, 0x1); /*emul-call*/
|
||||
4, emul_call_instruction);
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_client_va - code_va) + 4,
|
||||
4, emul_blr_instruction);
|
||||
/* callback return address */
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_callback_va - code_va),
|
||||
4, 0x1); /*emul-call*/
|
||||
4, emul_call_instruction);
|
||||
/* loop to keep other processors busy */
|
||||
device_tree_add_found_uw_u_u(init, "",
|
||||
"data",
|
||||
code_ra + (code_loop_va - code_va),
|
||||
4, 0x48000000); /*b .*/
|
||||
4, emul_loop_instruction);
|
||||
device_add_integer_property(init_register,
|
||||
"msr",
|
||||
(msr_machine_check_enable
|
||||
@ -843,6 +1142,7 @@ emul_chirp_create(device *root,
|
||||
data->catching_instruction_ea = code_callback_va;
|
||||
data->phandles = cap_create("chirp");
|
||||
data->root = root;
|
||||
data->services = services;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -923,9 +1223,7 @@ emul_chirp_instruction_call(cpu *processor,
|
||||
|
||||
}
|
||||
|
||||
/* return to caller */
|
||||
cpu_registers(processor)->gpr[3] = result;
|
||||
cpu_restart(processor, emul_data->return_address);
|
||||
/* return to caller - instruction following this is a function return */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -16,16 +16,6 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
----
|
||||
|
||||
Code to output system call traces Copyright (C) 1991 Gordon Irlam.
|
||||
All rights reserved.
|
||||
|
||||
This tool is part of the Spa(7) package. The Spa(7) package
|
||||
may be redistributed and/or modified under the terms of the
|
||||
GNU General Public License Version 2 (GPL(7)) as published
|
||||
by the Free Software Foundation.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -39,33 +29,32 @@
|
||||
#endif
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC void
|
||||
emul_enter_call(emulation *emul,
|
||||
int call,
|
||||
int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
STATIC_INLINE_EMUL_GENERIC void
|
||||
emul_syscall_enter(emul_syscall *emul,
|
||||
int call,
|
||||
int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
printf_filtered("%d:0x%x:%s(",
|
||||
printf_filtered("%d:0x%lx:%s(",
|
||||
cpu_nr(processor) + 1,
|
||||
cia,
|
||||
emul->call_descriptor[call].name);
|
||||
(long)cia,
|
||||
emul->syscall_descriptor[call].name);
|
||||
}
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC void
|
||||
emul_exit_call(emulation *emul,
|
||||
int call,
|
||||
int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
STATIC_INLINE_EMUL_GENERIC void
|
||||
emul_syscall_exit(emul_syscall *emul,
|
||||
int call,
|
||||
int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
int status = cpu_registers(processor)->gpr[3];
|
||||
int error = cpu_registers(processor)->gpr[0];
|
||||
printf_filtered(")=%d", status);
|
||||
if (error > 0 && error < emul->nr_error_names)
|
||||
printf_filtered("[%s]",
|
||||
emul->error_names[cpu_registers(processor)->gpr[0]]);
|
||||
printf_filtered("[%s]", emul->error_names[error]);
|
||||
printf_filtered("\n");
|
||||
}
|
||||
|
||||
@ -117,12 +106,9 @@ emul_read_string(char *dest,
|
||||
if (addr == 0)
|
||||
return NULL;
|
||||
while (1) {
|
||||
if (vm_data_map_read_buffer(cpu_data_map(processor),
|
||||
&dest[nr_moved],
|
||||
addr + nr_moved,
|
||||
sizeof(dest[nr_moved]))
|
||||
!= sizeof(dest[nr_moved]))
|
||||
return NULL;
|
||||
dest[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
|
||||
addr + nr_moved,
|
||||
processor, cia);
|
||||
if (dest[nr_moved] == '\0' || nr_moved >= nr_bytes)
|
||||
break;
|
||||
nr_moved++;
|
||||
@ -145,24 +131,27 @@ emul_write_status(cpu *processor,
|
||||
}
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC unsigned_word
|
||||
emul_read_word(unsigned_word addr,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
return vm_data_map_read_word(cpu_data_map(processor),
|
||||
addr,
|
||||
processor, cia);
|
||||
}
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC void
|
||||
emul_write_word(unsigned_word addr,
|
||||
unsigned_word buf,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
int nr_moved;
|
||||
H2T(buf);
|
||||
nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
|
||||
&buf,
|
||||
addr,
|
||||
sizeof(buf),
|
||||
0/*violate_ro*/);
|
||||
if (nr_moved != sizeof(buf)) {
|
||||
printf_filtered("emul_write_word() write failed, %d out of %d written\n",
|
||||
nr_moved, sizeof(buf));
|
||||
cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
|
||||
}
|
||||
vm_data_map_write_word(cpu_data_map(processor),
|
||||
addr,
|
||||
buf,
|
||||
processor, cia);
|
||||
}
|
||||
|
||||
|
||||
@ -173,15 +162,12 @@ emul_write_buffer(const void *source,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
int nr_moved = vm_data_map_write_buffer(cpu_data_map(processor),
|
||||
source,
|
||||
addr,
|
||||
nr_bytes,
|
||||
0/*violate_ro*/);
|
||||
if (nr_moved != nr_bytes) {
|
||||
printf_filtered("emul_write_buffer() write failed %d out of %d written\n",
|
||||
nr_moved, nr_bytes);
|
||||
cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
|
||||
int nr_moved;
|
||||
for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
|
||||
vm_data_map_write_1(cpu_data_map(processor),
|
||||
addr + nr_moved,
|
||||
((const char*)source)[nr_moved],
|
||||
processor, cia);
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,38 +179,39 @@ emul_read_buffer(void *dest,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
int nr_moved = vm_data_map_read_buffer(cpu_data_map(processor),
|
||||
dest,
|
||||
addr,
|
||||
nr_bytes);
|
||||
if (nr_moved != nr_bytes) {
|
||||
printf_filtered("emul_read_buffer() read failed %d out of %d read\n",
|
||||
nr_moved, nr_bytes);
|
||||
cpu_halt(processor, cia, was_exited, 14/*EFAULT*/);
|
||||
int nr_moved;
|
||||
for (nr_moved = 0; nr_moved < nr_bytes; nr_moved++) {
|
||||
((char*)dest)[nr_moved] = vm_data_map_read_1(cpu_data_map(processor),
|
||||
addr + nr_moved,
|
||||
processor, cia);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC void
|
||||
emul_do_call(emulation *emul,
|
||||
unsigned call,
|
||||
const int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
emul_do_system_call(os_emul_data *emul_data,
|
||||
emul_syscall *emul,
|
||||
unsigned call,
|
||||
const int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
emul_call_handler *handler = NULL;
|
||||
emul_syscall_handler *handler = NULL;
|
||||
if (call >= emul->nr_system_calls)
|
||||
error("do_call() os_emul call %d out-of-range\n", call);
|
||||
|
||||
handler = emul->call_descriptor[call].handler;
|
||||
handler = emul->syscall_descriptor[call].handler;
|
||||
if (handler == NULL)
|
||||
error("do_call() unimplemented call %d\n", call);
|
||||
|
||||
ENTER_CALL;
|
||||
if (WITH_TRACE && ppc_trace[trace_os_emul])
|
||||
emul_syscall_enter(emul, call, arg0, processor, cia);
|
||||
|
||||
cpu_registers(processor)->gpr[0] = 0; /* default success */
|
||||
handler(emul, call, arg0, processor, cia);
|
||||
EXIT_CALL;
|
||||
handler(emul_data, call, arg0, processor, cia);
|
||||
|
||||
if (WITH_TRACE && ppc_trace[trace_os_emul])
|
||||
emul_syscall_exit(emul, call, arg0, processor, cia);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _SYSTEM_C_ */
|
||||
|
158
sim/ppc/emul_generic.h
Normal file
158
sim/ppc/emul_generic.h
Normal file
@ -0,0 +1,158 @@
|
||||
/* This file is part of the program psim.
|
||||
|
||||
Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _EMUL_GENERIC_H_
|
||||
#define _EMUL_GENERIC_H_
|
||||
|
||||
#include "cpu.h"
|
||||
#include "idecode.h"
|
||||
#include "os_emul.h"
|
||||
|
||||
#include "bfd.h"
|
||||
|
||||
#ifndef INLINE_EMUL_GENERIC
|
||||
#define INLINE_EMUL_GENERIC
|
||||
#endif
|
||||
|
||||
/* various PowerPC instructions for writing into memory */
|
||||
enum {
|
||||
emul_call_instruction = 0x1,
|
||||
emul_loop_instruction = 0x48000000, /* branch to . */
|
||||
emul_rfi_instruction = 0x4c000064,
|
||||
emul_blr_instruction = 0x4e800020,
|
||||
};
|
||||
|
||||
|
||||
/* emulation specific data */
|
||||
|
||||
typedef struct _os_emul_data os_emul_data;
|
||||
|
||||
typedef os_emul_data *(os_emul_create_handler)
|
||||
(device *tree,
|
||||
bfd *image,
|
||||
const char *emul_name);
|
||||
typedef void (os_emul_init_handler)
|
||||
(os_emul_data *emul_data,
|
||||
int nr_cpus);
|
||||
typedef void (os_emul_system_call_handler)
|
||||
(cpu *processor,
|
||||
unsigned_word cia,
|
||||
os_emul_data *emul_data);
|
||||
typedef int (os_emul_instruction_call_handler)
|
||||
(cpu *processor,
|
||||
unsigned_word cia,
|
||||
unsigned_word ra,
|
||||
os_emul_data *emul_data);
|
||||
|
||||
struct _os_emul {
|
||||
const char *name;
|
||||
os_emul_create_handler *create;
|
||||
os_emul_init_handler *init;
|
||||
os_emul_system_call_handler *system_call;
|
||||
os_emul_instruction_call_handler *instruction_call;
|
||||
os_emul_data *data;
|
||||
};
|
||||
|
||||
|
||||
/* One class of emulation - system call is pretty general, provide a
|
||||
common template for implementing this */
|
||||
|
||||
typedef struct _emul_syscall emul_syscall;
|
||||
typedef struct _emul_syscall_descriptor emul_syscall_descriptor;
|
||||
|
||||
typedef void (emul_syscall_handler)
|
||||
(os_emul_data *emul_data,
|
||||
unsigned call,
|
||||
const int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
struct _emul_syscall_descriptor {
|
||||
emul_syscall_handler *handler;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct _emul_syscall {
|
||||
emul_syscall_descriptor *syscall_descriptor;
|
||||
int nr_system_calls;
|
||||
char **error_names;
|
||||
int nr_error_names;
|
||||
char **signal_names;
|
||||
int nr_signal_names;
|
||||
};
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_do_system_call
|
||||
(os_emul_data *emul_data,
|
||||
emul_syscall *syscall,
|
||||
unsigned call,
|
||||
const int arg0,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
|
||||
INLINE_EMUL_GENERIC unsigned64 emul_read_gpr64
|
||||
(cpu *processor,
|
||||
int g);
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_write_gpr64
|
||||
(cpu *processor,
|
||||
int g,
|
||||
unsigned64 val);
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_write_status
|
||||
(cpu *processor,
|
||||
int status,
|
||||
int errno);
|
||||
|
||||
INLINE_EMUL_GENERIC char *emul_read_string
|
||||
(char *dest,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
INLINE_EMUL_GENERIC unsigned_word emul_read_word
|
||||
(unsigned_word addr,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_write_word
|
||||
(unsigned_word addr,
|
||||
unsigned_word buf,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_read_buffer
|
||||
(void *dest,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
INLINE_EMUL_GENERIC void emul_write_buffer
|
||||
(const void *source,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia);
|
||||
|
||||
#endif /* _EMUL_GENERIC_H_ */
|
Loading…
Reference in New Issue
Block a user