Wed May 24 14:37:31 1995 Steve Chamberlain <sac@slash.cygnus.com>

* New.
This commit is contained in:
Steve Chamberlain 1995-05-24 21:45:01 +00:00
parent 1ff71ed037
commit 2494eaf6fd
23 changed files with 5310 additions and 0 deletions

339
sim/arm/COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

120
sim/arm/Makefile.orig Normal file
View File

@ -0,0 +1,120 @@
# Makefile for ARMulator: ARM6 Instruction Emulator.
# Copyright (C) 1994 Advanced RISC Machines Ltd.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
# These variables can be overridden
#Default endianness of the processor (LITTLEEND or BIGEND)
ENDIAN=LITTLEEND
prefix=/usr/local
CC = gcc
CFLAGS = -O2 -D$(ENDIAN) $(CFL)
INSTALL_DIR = $(prefix)/bin
INSTALL=cp
# Everything else should be ok as it is.
OBJS = armcopro.o armemu26.o armemu32.o arminit.o armos.o \
armsupp.o main.o parent.o kid.o communicate.o gdbhost.o \
bag.o armrdi.o
SRCS = armcopro.c armemu.c arminit.c armos.c armvirt.c \
armsupp.c main.c parent.c kid.c communicate.c gdbhost.c \
bag.c armrdi.c
INCS = armdefs.h armemu.h armfpe.h armopts.h armos.h bag.h communicate.h \
dbg_conf.h dbg_cp.h dbg_hif.h dbg_rdi.h gdbhost.h
TARED = $(SRCS) $(INCS) README COPYING Makefile
MODEL = armvirt
VER=1.0
all: armul
install: all
$(INSTALL) armul $(INSTALL_DIR)
armul: $(OBJS) $(MODEL).o
$(CC) $(CFLAGS) $(OBJS) $(MODEL).o -o $@ -lm -lXext -lX11
clean:
rm -f *.o armul core
distclean: clean
rm -f *~
realclean: distclean
rm -f *.tar *.tar.gz
armul.tar.gz:
rm -rf armul-$(VER)
mkdir armul-$(VER)
cd armul-$(VER) ; \
for file in $(TARED) ; do \
ln ../$${file} . ; \
done
tar cf armul.tar armul-$(VER)
gzip armul.tar
mv armul.tar.gz armul-$(VER).tar.gz
# memory models
armvirt.o: armdefs.h armvirt.c
$(CC) $(CFLAGS) -c $*.c
# other objects
armos.o: armos.c armdefs.h armos.h armfpe.h
$(CC) $(CFLAGS) -c $*.c
armcopro.o: armcopro.c armdefs.h
$(CC) $(CFLAGS) -c $*.c
armemu26.o: armemu.c armdefs.h armemu.h
$(CC) $(CFLAGS) -o armemu26.o -c armemu.c
armemu32.o: armemu.c armdefs.h armemu.h
$(CC) $(CFLAGS) -o armemu32.o -DMODE32 -c armemu.c
arminit.o: arminit.c armdefs.h armemu.h
$(CC) $(CFLAGS) -c $*.c
armrdi.o: armrdi.c armdefs.h armemu.h armos.h dbg_cp.h dbg_conf.h dbg_rdi.h \
dbg_hif.h communicate.h
$(CC) $(CFLAGS) -c $*.c
armsupp.o: armsupp.c armdefs.h armemu.h
$(CC) $(CFLAGS) -c $*.c
kid.o: kid.c armdefs.h dbg_conf.h dbg_hif.h dbg_rdi.h gdbhost.h communicate.h
$(CC) $(CFLAGS) -c $*.c
main.o: main.c armdefs.h dbg_rdi.h dbg_conf.h
$(CC) $(CFLAGS) -c $*.c
communicate.o: communicate.c armdefs.h
$(CC) $(CFLAGS) -c $*.c
bag.o: bag.c bag.h
$(CC) $(CFLAGS) -c $*.c
gdbhost.o: gdbhost.c armdefs.h communicate.h dbg_rdi.h armos.h
$(CC) $(CFLAGS) -c $*.c
parent.o: parent.c armdefs.h dbg_rdi.h communicate.h
$(CC) $(CFLAGS) -c $*.c

27
sim/arm/README.Cygnus Normal file
View File

@ -0,0 +1,27 @@
This directory contains the standard release of the ARMulator from
Advanced RISC Machines, and was ftp'd from.
ftp.cl.cam.ac.uk:/arm/gnu
It likes to use TCP/IP between the simulator and the host, which is
nice, but is a pain to use under anything non-unix.
I've added created a new Makefile.in (the original in Makefile.orig)
to build a version of the simulator without the TCP/IP stuff, and a
wrapper.c to link directly into gdb and the run command.
It should be possible (barring major changes in the layout of
the armulator) to upgrade the simulator by copying all the files
out of a release into this directory and renaming the Makefile.
(Except that I changed armos.c to understand our fcntl flags
and made it possible to set breakpoints simply)
Steve
sac@cygnus.com
Mon May 15 12:03:28 PDT 1995

58
sim/arm/README.orig Normal file
View File

@ -0,0 +1,58 @@
This is the README file for ARMulator version 1.0, an ARM6 instruction
emulator.
Configuration:
The armulator has one configuration option, the default endianness
of the processor. This can be changed by building with ENDIAN=BIGEND
to produce a big-endian variant. The debugger can also select the
endianness at run-time.
Build instructions:
This program is known to compile using GCC 2.6.0 on a Sun4. Other
builds are untested. It almost certainly will not work on non-32bit
machines.
To build the program simply type make in the source directory,
followed by "make install"
Using the emulator:
The emulator runs as a separate process, and communicates with a
debugger via tcp. To start the emulator type
armul <socknum>
where socknum is any number between 1024 and 65535. If the socket is
already in use, armul will exit with an error.
This version of armul has been designed to work with gdb-4.13
with the ARM/RDP/RDI extensions added (available separately). To
connect gdb to the ARMulator, start gdb and type
target arm <hostname>:<socknum>
where hostname is the name of the machine on which the armulator
is running, and socknum is the socket number specified when armul
was started.
IMPORTANT:
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Advanced RISC Machines welcomes bug reports for this package,
but no undertaking can be made to provide support or reply to email.
Bugs should be sent to:
armgnu@armltd.co.uk

3
sim/arm/arm.mt Normal file
View File

@ -0,0 +1,3 @@
ALL=all-arm
CLEAN=clean-arm
DO_INSTALL=install-arm

1351
sim/arm/armfpe.h Normal file

File diff suppressed because it is too large Load Diff

30
sim/arm/armopts.h Normal file
View File

@ -0,0 +1,30 @@
/* armopts.h -- ARMulator configuration options: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Define one of ARM60 or ARM61 */
#ifndef ARM60
#ifndef ARM61
#define ARM60
#endif
#endif
/* define for a little endian ARMulator */
#ifndef LITTLEEND
#ifndef BIGEND
#define LITTLEEND
#endif
#endif

64
sim/arm/armos.h Normal file
View File

@ -0,0 +1,64 @@
/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/***************************************************************************\
* Define the initial layout of memory *
\***************************************************************************/
#define ADDRSUPERSTACK 0x800L /* supervisor stack space */
#define ADDRUSERSTACK 0x80000L /* default user stack start */
#define ADDRSOFTVECTORS 0x840L /* soft vectors are here */
#define ADDRCMDLINE 0xf00L /* command line is here after a SWI GetEnv */
#define ADDRSOFHANDLERS 0xad0L /* address and workspace for installed handlers */
#define SOFTVECTORCODE 0xb80L /* default handlers */
/***************************************************************************\
* SWI numbers *
\***************************************************************************/
#define SWI_WriteC 0x0
#define SWI_Write0 0x2
#define SWI_ReadC 0x4
#define SWI_CLI 0x5
#define SWI_GetEnv 0x10
#define SWI_Exit 0x11
#define SWI_EnterOS 0x16
#define SWI_GetErrno 0x60
#define SWI_Clock 0x61
#define SWI_Time 0x63
#define SWI_Remove 0x64
#define SWI_Rename 0x65
#define SWI_Open 0x66
#define SWI_Close 0x68
#define SWI_Write 0x69
#define SWI_Read 0x6a
#define SWI_Seek 0x6b
#define SWI_Flen 0x6c
#define SWI_IsTTY 0x6e
#define SWI_TmpNam 0x6f
#define SWI_InstallHandler 0x70
#define SWI_GenerateError 0x71
#define FPESTART 0x2000L
#define FPEEND 0x8000L
#define FPEOLDVECT FPESTART + 0x100L + 8L * 16L + 4L /* stack + 8 regs + fpsr */
#define FPENEWVECT(addr) 0xea000000L + ((addr) >> 2) - 3L /* branch from 4 to 0x2400 */
extern unsigned long fpecode[] ;
extern unsigned long fpesize ;

1042
sim/arm/armrdi.c Normal file

File diff suppressed because it is too large Load Diff

42
sim/arm/bag.h Normal file
View File

@ -0,0 +1,42 @@
/* bag.h -- ARMulator support code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/********************************************************************/
/* bag.h: */
/* Header file for bag.c */
/* Offers a data structure for storing and getting pairs of number. */
/* The numbers are stored together, put one can be looked up by */
/* quoting the other. If a new pair is entered and one of the */
/* numbers is a repeat of a previous pair, then the previos pair */
/* is deleted. */
/********************************************************************/
typedef enum {
NO_ERROR,
DELETED_OLD_PAIR,
NO_SUCH_PAIR,
} Bag_error;
void BAG_putpair(long first, long second);
void BAG_newbag(void);
Bag_error BAG_killpair_byfirst(long first);
Bag_error BAG_killpair_bysecond(long second);
Bag_error BAG_getfirst(long *first, long second);
Bag_error BAG_getsecond(long first, long *second);

221
sim/arm/communicate.c Normal file
View File

@ -0,0 +1,221 @@
/* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/**************************************************************************/
/* Functions to read and write characters or groups of characters */
/* down sockets or pipes. Those that return a value return -1 on failure */
/* and 0 on success. */
/**************************************************************************/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "armdefs.h"
/* The socket to the debugger */
int debugsock;
/* The maximum number of file descriptors */
extern int nfds;
/* The socket handle */
extern int sockethandle;
/* Read and Write routines down a pipe or socket */
/****************************************************************/
/* Read an individual character. */
/* All other read functions rely on this one. */
/* It waits 15 seconds until there is a character available: if */
/* no character is available, then it timeouts and returns -1. */
/****************************************************************/
int MYread_char(int sock, unsigned char *c) {
int i;
fd_set readfds;
struct timeval timeout= {15, 0};
struct sockaddr_in isa;
retry:
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
i = select(nfds, &readfds,
(fd_set *) 0,
(fd_set *) 0,
&timeout);
if (i < 0) {
perror("select");
exit(1);
}
if (!i) {
fprintf(stderr, "read: Timeout\n");
return -1;
}
if ((i = read(sock, c, 1)) < 1) {
if (!i && sock == debugsock) {
fprintf(stderr, "Connection with debugger severed.\n");
/* This shouldn't be necessary for a detached armulator, but
the armulator cannot be cold started a second time, so
this is probably preferable to locking up. */
return -1;
fprintf(stderr, "Waiting for connection from debugger...");
debugsock = accept(sockethandle, &isa, &i);
if (debugsock < 0) { /* Now we are in serious trouble... */
perror("accept");
return -1;
}
fprintf(stderr, " done.\nConnection Established.\n");
sock = debugsock;
goto retry;
}
perror("read");
return -1;
}
#ifdef DEBUG
if (sock == debugsock) fprintf(stderr, "<%02x ", *c);
#endif
return 0;
}
/****************************************************************/
/* Read an individual character. */
/* It waits until there is a character available. Returns -1 if */
/* an error occurs. */
/****************************************************************/
int MYread_charwait(int sock, unsigned char *c) {
int i;
fd_set readfds;
struct sockaddr_in isa;
retry:
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
i = select(nfds, &readfds,
(fd_set *) 0,
(fd_set *) 0,
(struct timeval *) 0);
if (i < 0) {
perror("select");
exit(-1);
}
if ((i = read(sock, c, 1)) < 1) {
if (!i && sock == debugsock) {
fprintf(stderr, "Connection with debugger severed.\n");
return -1;
fprintf(stderr, "Waiting for connection from debugger...");
debugsock = accept(sockethandle, &isa, &i);
if (debugsock < 0) { /* Now we are in serious trouble... */
perror("accept");
return -1;
}
fprintf(stderr, " done.\nConnection Established.\n");
sock = debugsock;
goto retry;
}
perror("read");
return -1;
}
#ifdef DEBUG
if (sock == debugsock) fprintf(stderr, "<%02x ", *c);
#endif
return 0;
}
void MYwrite_char(int sock, unsigned char c) {
if (write(sock, &c, 1) < 1)
perror("write");
#ifdef DEBUG
if (sock == debugsock) fprintf(stderr, ">%02x ", c);
#endif
}
int MYread_word(int sock, ARMword *here) {
unsigned char a, b, c, d;
if (MYread_char(sock, &a) < 0) return -1;
if (MYread_char(sock, &b) < 0) return -1;
if (MYread_char(sock, &c) < 0) return -1;
if (MYread_char(sock, &d) < 0) return -1;
*here = a | b << 8 | c << 16 | d << 24;
return 0;
}
void MYwrite_word(int sock, ARMword i) {
MYwrite_char(sock, i & 0xff);
MYwrite_char(sock, (i & 0xff00) >> 8);
MYwrite_char(sock, (i & 0xff0000) >> 16);
MYwrite_char(sock, (i & 0xff000000) >> 24);
}
void MYwrite_string(int sock, char *s) {
int i;
for (i = 0; MYwrite_char(sock, s[i]), s[i]; i++);
}
int MYread_FPword(int sock, char *putinhere) {
int i;
for (i = 0; i < 16; i++)
if (MYread_char(sock, &putinhere[i]) < 0) return -1;
return 0;
}
void MYwrite_FPword(int sock, char *fromhere) {
int i;
for (i = 0; i < 16; i++)
MYwrite_char(sock, fromhere[i]);
}
/* Takes n bytes from source and those n bytes */
/* down to dest */
int passon(int source, int dest, int n) {
char *p;
int i;
p = (char *) malloc(n);
if (!p) {
perror("Out of memory\n");
exit(1);
}
if (n) {
for (i = 0; i < n; i++)
if (MYread_char(source, &p[i]) < 0) return -1;
#ifdef DEBUG
if (dest == debugsock)
for (i = 0; i < n; i++) fprintf(stderr, ")%02x ", (unsigned char) p[i]);
#endif
write(dest, p, n);
}
free(p);
return 0;
}

37
sim/arm/communicate.h Normal file
View File

@ -0,0 +1,37 @@
/* communicate.h -- ARMulator comms support defns: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
int MYread_char(int sock, unsigned char *c);
void MYwrite_char(int sock, unsigned char c);
int MYread_word(int sock, ARMword *here);
void MYwrite_word(int sock, ARMword i);
void MYwrite_string(int sock, char *s);
int MYread_FPword(int sock, char *putinhere);
void MYwrite_FPword(int sock, char *fromhere);
int passon(int source, int dest, int n);
int wait_for_osreply(ARMword *reply); /* from kid.c */
#define OS_SendNothing 0x0
#define OS_SendChar 0x1
#define OS_SendWord 0x2
#define OS_SendString 0x3
/* The pipes between the two processes */
extern int mumkid[2];
extern int kidmum[2];

35
sim/arm/configure.in Normal file
View File

@ -0,0 +1,35 @@
# This file is a shell script that supplies the information necessary
# to tailor a template configure script into the configure script
# appropriate for this directory. For more information, check any
# existing configure script.
srctrigger=bag.c
srcname="arm sim"
# per-host:
. ${srcdir}/../../bfd/configure.host
# Set up to make a link between the host's include file and "sysdep.h".
files="../../bfd/hosts/${my_host}.h"
links="sysdep.h"
if [ ! -f ${srcdir}/${files} ] ; then
files=../../bfd/hosts/std-host.h
echo "[${srcname} has no specific support for host ${host} -- using std-host]"
fi
host_makefile_frag=
if [ -f ${srcdir}/../../bfd/config/${my_host}.mh ] ; then
host_makefile_frag=../../bfd/config/${my_host}.mh
fi
# per-target:
case "${target}" in
arm-*-*) sim_target=arm ;;
esac
target_makefile_frag=${sim_target}.mt

48
sim/arm/dbg_conf.h Normal file
View File

@ -0,0 +1,48 @@
/* dbg_conf.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef Dbg_Conf__h
#define Dbg_Conf__h
typedef struct Dbg_ConfigBlock {
int bytesex;
long memorysize;
int serialport; /*) remote connection parameters */
int seriallinespeed; /*) (serial connection) */
int parallelport; /*) ditto */
int parallellinespeed; /*) (parallel connection) */
int processor; /* processor the armulator is to emulate (eg ARM60) */
int rditype; /* armulator / remote processor */
int drivertype; /* parallel / serial / etc */
char const *configtoload;
int flags;
} Dbg_ConfigBlock;
#define Dbg_ConfigFlag_Reset 1
typedef struct Dbg_HostosInterface Dbg_HostosInterface;
/* This structure allows access by the (host-independent) C-library support
module of armulator or pisd (armos.c) to host-dependent functions for
which there is no host-independent interface. Its contents are unknown
to the debugger toolbox.
The assumption is that, in a windowed system, fputc(stderr) for example
may not achieve the desired effect of the character appearing in some
window.
*/
#endif

62
sim/arm/dbg_cp.h Normal file
View File

@ -0,0 +1,62 @@
/* dbg_cp.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef Dbg_CP__h
#define Dbg_CP__h
#define Dbg_Access_Readable 1
#define Dbg_Access_Writable 2
#define Dbg_Access_CPDT 4 /* else CPRT */
typedef struct {
unsigned short rmin, rmax;
/* a single description can be used for a range of registers with
the same properties *accessed via CPDT instructions*
*/
unsigned char nbytes; /* size of register */
unsigned char access; /* see above (Access_xxx) */
union {
struct { /* CPDT instructions do not allow the coprocessor much freedom:
only bit 22 ('N') and 12-15 ('CRd') are free for the
coprocessor to use as it sees fit.
*/
unsigned char nbit;
unsigned char rdbits;
} cpdt;
struct { /* CPRT instructions have much more latitude. The bits fixed
by the ARM are 24..31 (condition mask & opcode)
20 (direction)
8..15 (cpnum, arm register)
4 (CPRT not CPDO)
leaving 14 bits free to the coprocessor (fortunately
falling within two bytes).
*/
unsigned char read_b0, read_b1,
write_b0, write_b1;
} cprt;
} accessinst;
} Dbg_CoProRegDesc;
struct Dbg_CoProDesc {
int entries;
Dbg_CoProRegDesc regdesc[1/* really nentries */];
};
#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + (n-1)*sizeof(Dbg_CoProRegDesc))
#endif

47
sim/arm/dbg_hif.h Normal file
View File

@ -0,0 +1,47 @@
/* dbg_hif.h -- ARMulator debug interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef __STDC__
# include <stdarg.h>
#else
# include <varargs.h>
#endif
typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap);
typedef void Hif_DbgPause(void *arg);
typedef void Hif_WriteC(void *arg, int c);
typedef int Hif_ReadC(void *arg);
typedef int Hif_Write(void *arg, char const *buffer, int len);
typedef char *Hif_GetS(void *arg, char *buffer, int len);
typedef void Hif_RDIResetProc(void *arg);
struct Dbg_HostosInterface {
Hif_DbgPrint *dbgprint;
Hif_DbgPause *dbgpause;
void *dbgarg;
Hif_WriteC *writec;
Hif_ReadC *readc;
Hif_Write *write;
Hif_GetS *gets;
void *hostosarg;
Hif_RDIResetProc *reset;
void *resetarg;
};

323
sim/arm/dbg_rdi.h Normal file
View File

@ -0,0 +1,323 @@
/* dbg_rdi.h -- ARMulator RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef dbg_rdi__h
#define dbg_rdi__h
/***************************************************************************\
* Error Codes *
\***************************************************************************/
#define RDIError_NoError 0
#define RDIError_Reset 1
#define RDIError_UndefinedInstruction 2
#define RDIError_SoftwareInterrupt 3
#define RDIError_PrefetchAbort 4
#define RDIError_DataAbort 5
#define RDIError_AddressException 6
#define RDIError_IRQ 7
#define RDIError_FIQ 8
#define RDIError_Error 9
#define RDIError_BranchThrough0 10
#define RDIError_NotInitialised 128
#define RDIError_UnableToInitialise 129
#define RDIError_WrongByteSex 130
#define RDIError_UnableToTerminate 131
#define RDIError_BadInstruction 132
#define RDIError_IllegalInstruction 133
#define RDIError_BadCPUStateSetting 134
#define RDIError_UnknownCoPro 135
#define RDIError_UnknownCoProState 136
#define RDIError_BadCoProState 137
#define RDIError_BadPointType 138
#define RDIError_UnimplementedType 139
#define RDIError_BadPointSize 140
#define RDIError_UnimplementedSize 141
#define RDIError_NoMorePoints 142
#define RDIError_BreakpointReached 143
#define RDIError_WatchpointAccessed 144
#define RDIError_NoSuchPoint 145
#define RDIError_ProgramFinishedInStep 146
#define RDIError_UserInterrupt 147
#define RDIError_CantSetPoint 148
#define RDIError_IncompatibleRDILevels 149
#define RDIError_CantLoadConfig 150
#define RDIError_BadConfigData 151
#define RDIError_NoSuchConfig 152
#define RDIError_BufferFull 153
#define RDIError_OutOfStore 154
#define RDIError_NotInDownload 155
#define RDIError_PointInUse 156
#define RDIError_BadImageFormat 157
#define RDIError_TargetRunning 158
#define RDIError_LittleEndian 240
#define RDIError_BigEndian 241
#define RDIError_SoftInitialiseError 242
#define RDIError_InsufficientPrivilege 253
#define RDIError_UnimplementedMessage 254
#define RDIError_UndefinedMessage 255
/***************************************************************************\
* RDP Message Numbers *
\***************************************************************************/
#define RDP_Start (unsigned char)0x0
#define RDP_End (unsigned char)0x1
#define RDP_Read (unsigned char)0x2
#define RDP_Write (unsigned char)0x3
#define RDP_CPUread (unsigned char)0x4
#define RDP_CPUwrite (unsigned char)0x5
#define RDP_CPread (unsigned char)0x6
#define RDP_CPwrite (unsigned char)0x7
#define RDP_SetBreak (unsigned char)0xa
#define RDP_ClearBreak (unsigned char)0xb
#define RDP_SetWatch (unsigned char)0xc
#define RDP_ClearWatch (unsigned char)0xd
#define RDP_Execute (unsigned char)0x10
#define RDP_Step (unsigned char)0x11
#define RDP_Info (unsigned char)0x12
#define RDP_OSOpReply (unsigned char)0x13
#define RDP_AddConfig (unsigned char)0x14
#define RDP_LoadConfigData (unsigned char)0x15
#define RDP_SelectConfig (unsigned char)0x16
#define RDP_LoadAgent (unsigned char)0x17
#define RDP_Stopped (unsigned char)0x20
#define RDP_OSOp (unsigned char)0x21
#define RDP_Fatal (unsigned char)0x5e
#define RDP_Return (unsigned char)0x5f
#define RDP_Reset (unsigned char)0x7f
/***************************************************************************\
* Other RDI values *
\***************************************************************************/
#define RDISex_Little 0 /* the byte sex of the debuggee */
#define RDISex_Big 1
#define RDISex_DontCare 2
#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
#define RDIPoint_GT 1
#define RDIPoint_GE 2
#define RDIPoint_LT 3
#define RDIPoint_LE 4
#define RDIPoint_IN 5
#define RDIPoint_OUT 6
#define RDIPoint_MASK 7
#define RDIPoint_Inquiry 64 /* ORRed with point type in extended RDP */
#define RDIPoint_Handle 128 /* messages */
#define RDIWatch_ByteRead 1 /* types of data accesses to watch for */
#define RDIWatch_HalfRead 2
#define RDIWatch_WordRead 4
#define RDIWatch_ByteWrite 8
#define RDIWatch_HalfWrite 16
#define RDIWatch_WordWrite 32
#define RDIReg_R15 (1L << 15) /* mask values for CPU */
#define RDIReg_PC (1L << 16)
#define RDIReg_CPSR (1L << 17)
#define RDIReg_SPSR (1L << 18)
#define RDINumCPURegs 19
#define RDINumCPRegs 10 /* current maximum */
#define RDIMode_Curr 255
/* Bits set in return value from RDIInfo_Target */
#define RDITarget_LogSpeed 0x0f
#define RDITarget_HW 0x10 /* else emulator */
#define RDITarget_AgentMaxLevel 0xe0
#define RDITarget_AgentLevelShift 5
#define RDITarget_DebuggerMinLevel 0x700
#define RDITarget_DebuggerLevelShift 8
#define RDITarget_CanReloadAgent 0x800
#define RDITarget_CanInquireLoadSize 0x1000
/* Bits set in return value from RDIInfo_Step */
#define RDIStep_Multiple 1
#define RDIStep_PCChange 2
#define RDIStep_Single 4
/* Bits set in return value from RDIInfo_Points */
#define RDIPointCapability_Comparison 1
#define RDIPointCapability_Range 2
/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
#define RDIPointCapability_Mask 256
#define RDIPointCapability_Status 512 /* Point status enquiries available */
/* RDI_Info subcodes */
#define RDIInfo_Target 0
#define RDIInfo_Points 1
#define RDIInfo_Step 2
#define RDIInfo_MMU 3
#define RDIInfo_DownLoad 4 /* Inquires whether configuration download
and selection is available.
*/
#define RDIInfo_SemiHosting 5 /* Inquires whether RDISemiHosting_* RDI_Info
calls are available.
*/
#define RDIInfo_CoPro 6 /* Inquires whether CoPro RDI_Info calls are
available.
*/
#define RDIInfo_Icebreaker 7
/* The next two are only to be used if the value returned by RDIInfo_Points */
/* has RDIPointCapability_Status set. */
#define RDIPointStatus_Watch 0x80
#define RDIPointStatus_Break 0x81
#define RDISignal_Stop 0x100
#define RDIVector_Catch 0x180
/* The next four are only to be used if RDIInfo_Semihosting returned no error */
#define RDISemiHosting_SetState 0x181
#define RDISemiHosting_GetState 0x182
#define RDISemiHosting_SetVector 0x183
#define RDISemiHosting_GetVector 0x184
/* The next two are only to be used if RDIInfo_Icebreaker returned no error */
#define RDIIcebreaker_GetLocks 0x185
#define RDIIcebreaker_SetLocks 0x186
/* Only if RDIInfo_Target returned RDITarget_CanInquireLoadSize */
#define RDIInfo_GetLoadSize 0x187
#define RDICycles 0x200
#define RDICycles_Size 48
#define RDIErrorP 0x201
#define RDISet_Cmdline 0x300
#define RDISet_RDILevel 0x301
#define RDISet_Thread 0x302
/* The next two are only to be used if RDIInfo_CoPro returned no error */
#define RDIInfo_DescribeCoPro 0x400
#define RDIInfo_RequestCoProDesc 0x401
#define RDIInfo_Log 0x800
#define RDIInfo_SetLog 0x801
typedef unsigned long PointHandle;
typedef unsigned long ThreadHandle;
#define RDINoPointHandle ((PointHandle)-1L)
#define RDINoHandle ((ThreadHandle)-1L)
struct Dbg_ConfigBlock;
struct Dbg_HostosInterface;
struct Dbg_MCState;
typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config,
struct Dbg_HostosInterface const *i,
struct Dbg_MCState *dbg_state);
typedef int rdi_close_proc(void);
typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes);
typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes);
typedef int rdi_CPUread_proc(unsigned mode, unsigned long mask, ARMword *state);
typedef int rdi_CPUwrite_proc(unsigned mode, unsigned long mask, ARMword const *state);
typedef int rdi_CPread_proc(unsigned CPnum, unsigned long mask, ARMword *state);
typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned long mask, ARMword const *state);
typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound,
PointHandle *handle);
typedef int rdi_clearbreak_proc(PointHandle handle);
typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype,
ARMword bound, PointHandle *handle);
typedef int rdi_clearwatch_proc(PointHandle handle);
typedef int rdi_execute_proc(PointHandle *handle);
typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle);
typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2);
typedef int rdi_pointinq_proc(ARMword *address, unsigned type,
unsigned datatype, ARMword *bound);
typedef enum {
RDI_ConfigCPU,
RDI_ConfigSystem
} RDI_ConfigAspect;
typedef enum {
RDI_MatchAny,
RDI_MatchExactly,
RDI_MatchNoEarlier
} RDI_ConfigMatchType;
typedef int rdi_addconfig_proc(unsigned long nbytes);
typedef int rdi_loadconfigdata_proc(unsigned long nbytes, char const *data);
typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name,
RDI_ConfigMatchType matchtype, unsigned versionreq,
unsigned *versionp);
typedef char *getbufferproc(void *getbarg, unsigned long *sizep);
typedef int rdi_loadagentproc(ARMword dest, unsigned long size, getbufferproc *getb, void *getbarg);
typedef struct {
int itemmax;
char const * const *names;
} RDI_NameList;
typedef RDI_NameList const *rdi_namelistproc(void);
typedef int rdi_errmessproc(char *buf, int buflen, int errno);
struct RDIProcVec {
char rditypename[12];
rdi_open_proc *open;
rdi_close_proc *close;
rdi_read_proc *read;
rdi_write_proc *write;
rdi_CPUread_proc *CPUread;
rdi_CPUwrite_proc *CPUwrite;
rdi_CPread_proc *CPread;
rdi_CPwrite_proc *CPwrite;
rdi_setbreak_proc *setbreak;
rdi_clearbreak_proc *clearbreak;
rdi_setwatch_proc *setwatch;
rdi_clearwatch_proc *clearwatch;
rdi_execute_proc *execute;
rdi_step_proc *step;
rdi_info_proc *info;
/* V2 RDI */
rdi_pointinq_proc *pointinquiry;
/* These three useable only if RDIInfo_DownLoad returns no error */
rdi_addconfig_proc *addconfig;
rdi_loadconfigdata_proc *loadconfigdata;
rdi_selectconfig_proc *selectconfig;
rdi_namelistproc *drivernames;
rdi_namelistproc *cpunames;
rdi_errmessproc *errmess;
/* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
rdi_loadagentproc *loadagent;
};
#endif

107
sim/arm/gdbhost.c Normal file
View File

@ -0,0 +1,107 @@
/* gdbhost.c -- ARMulator RDP to gdb comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/***********************************************************/
/* Functions that communicate info back to the debugger... */
/***********************************************************/
#include <stdio.h>
#include <stdarg.h>
#include "armdefs.h"
#include "communicate.h"
#include "dbg_rdi.h"
#include "armos.h"
#define OS_SendNothing 0x0
#define OS_SendChar 0x1
#define OS_SendWord 0x2
#define OS_SendString 0x3
/* Defined in kid.c */
extern int wait_for_osreply(ARMword *reply);
/* A pipe for handling SWI return values that goes straight from the */
/* parent to the ARMulator host interface, bypassing the childs RDP */
/* to RDI interpreter */
int DebuggerARMul[2];
/* The pipes between the two processes */
int mumkid[2];
int kidmum[2];
void myprint (void *arg, const char *format, va_list ap)
{
#ifdef DEBUG
fprintf (stderr, "Host: myprint\n");
#endif
vfprintf (stderr, format, ap);
}
/* Waits for a keypress on the debuggers' keyboard */
void mypause (void *arg)
{
#ifdef DEBUG
fprintf (stderr, "Host: mypause\n");
#endif
} /* I do love exciting functions */
void mywritec(void *arg, int c)
{
#ifdef DEBUG
fprintf(stderr, "Mywrite : %c\n", c);
#endif
MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */
MYwrite_word(kidmum[1], SWI_WriteC); /* Print... */
MYwrite_char(kidmum[1], OS_SendChar); /* ...a single character */
MYwrite_char(kidmum[1], (unsigned char) c);
wait_for_osreply((ARMword *) 0);
}
int myreadc(void *arg)
{
char c;
ARMword x;
#ifdef DEBUG
fprintf(stderr, "Host: myreadc\n");
#endif
MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */
MYwrite_word(kidmum[1], SWI_ReadC); /* Read... */
MYwrite_char(kidmum[1], OS_SendNothing);
c = wait_for_osreply(&x);
return (x);
}
int mywrite(void *arg, char const *buffer, int len)
{
#ifdef DEBUG
fprintf(stderr, "Host: mywrite\n");
#endif
return 0;
}
char *mygets(void *arg, char *buffer, int len)
{
#ifdef DEBUG
fprintf(stderr, "Host: mygets\n");
#endif
return buffer;
}

23
sim/arm/gdbhost.h Normal file
View File

@ -0,0 +1,23 @@
/* gdbhost.h -- ARMulator to gdb interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
void myprint(void *arg, const char *format, va_list ap);
void mypause(void *arg);
void mywritec(void *arg, int c);
int myreadc(void *arg);
int mywrite(void *arg, char const *buffer, int len);
char *mygets(void *arg, char *buffer, int len);

510
sim/arm/kid.c Normal file
View File

@ -0,0 +1,510 @@
/* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*****************************************************************/
/* The child process continues here... */
/* It waits on a pipe from the parent and translates the RDP */
/* messages into RDI calls to the ARMulator passing RDP replies */
/* back up a pipe to the parent. */
/*****************************************************************/
#include <sys/types.h>
#include <signal.h>
#include "armdefs.h"
#include "dbg_conf.h"
#include "dbg_hif.h"
#include "dbg_rdi.h"
#include "gdbhost.h"
#include "communicate.h"
/* The pipes between the two processes */
extern int mumkid[2];
extern int kidmum[2];
/* The maximum number of file descriptors */
extern int nfds;
/* The machine name */
#define MAXHOSTNAMELENGTH 64
extern char localhost[MAXHOSTNAMELENGTH + 1];
/* The socket number */
extern unsigned int socketnumber;
/* RDI interface */
extern const struct RDIProcVec armul_rdi;
static int MYrdp_level = 0;
static int rdi_state = 0;
/**************************************************************/
/* Signal handler that terminates excecution in the ARMulator */
/**************************************************************/
void kid_handlesignal(int sig) {
#ifdef DEBUG
fprintf(stderr, "Terminate ARMulator excecution\n");
#endif
if (sig != SIGUSR1) {
fprintf(stderr, "Unsupported signal.\n");
return;
}
armul_rdi.info(RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
}
/********************************************************************/
/* Waits on a pipe from the socket demon for RDP and */
/* acts as an RDP to RDI interpreter on the front of the ARMulator. */
/********************************************************************/
void kid() {
char *p, *q;
int i, j, k;
long outofthebag;
unsigned char c, d, message;
ARMword x, y, z;
struct sigaction action;
PointHandle point;
Dbg_ConfigBlock config;
Dbg_HostosInterface hostif;
struct Dbg_MCState *MCState;
char command_line[256];
struct fd_set readfds;
/* Setup a signal handler for SIGUSR1 */
action.sa_handler = kid_handlesignal;
action.sa_mask = 0;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, (struct sigaction *) 0);
while (1)
{
/* Wait for ever */
FD_ZERO(&readfds);
FD_SET(mumkid[0], &readfds);
i = select(nfds, &readfds,
(fd_set *) 0,
(fd_set *) 0,
(struct timeval *) 0);
if (i < 0) {
perror("select");
}
if (read(mumkid[0], &message, 1) < 1) {
perror("read");
}
switch (message) {
case RDP_Start :
/* Open and/or Initialise */
BAG_newbag();
MYread_char(mumkid[0], &c); /* type */
MYread_word(mumkid[0], &x); /* memorysize */
if (c & 0x2) MYread_char(mumkid[0], &d); /* speed */
config.processor = 0;
config.memorysize = x;
config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
if (c & 0x8) config.bytesex = RDISex_DontCare;
hostif.dbgprint = myprint;
hostif.dbgpause = mypause;
hostif.dbgarg = stdout;
hostif.writec = mywritec;
hostif.readc = myreadc;
hostif.write = mywrite;
hostif.gets = mygets;
hostif.reset = mypause; /* do nothing */
hostif.resetarg = "Do I love resetting or what!\n";
if (rdi_state)
{
/* we have restarted, so kill off the existing run. */
/* armul_rdi.close(); */
}
i = armul_rdi.open(c & 0x3, &config, &hostif, MCState);
rdi_state = 1;
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
x = ~0x4;
armul_rdi.info(RDIVector_Catch, &x, 0);
break;
case RDP_End :
/* Close and Finalise */
i = armul_rdi.close();
rdi_state = 0;
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_Read :
/* Read Memory Address */
MYread_word(mumkid[0], &x); /* address */
MYread_word(mumkid[0], &y); /* nbytes */
p = (char *) malloc(y);
i = armul_rdi.read(x, p, (unsigned *) &y);
MYwrite_char(kidmum[1], RDP_Return);
for (k = 0; k < y; k++)
MYwrite_char(kidmum[1], p[k]);
free(p);
MYwrite_char(kidmum[1], (unsigned char) i);
if (i)
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
break;
case RDP_Write :
/* Write Memory Address */
MYread_word(mumkid[0], &x); /* address */
MYread_word(mumkid[0], &y); /* nbytes */
p = (char *) malloc(y);
for (k = 0; k < y; k++)
MYread_char(mumkid[0], &p[k]);
i = armul_rdi.write(p, x, (unsigned *) &y);
free(p);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
if (i)
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
break;
case RDP_CPUread :
/* Read CPU State */
MYread_char(mumkid[0], &c); /* mode */
MYread_word(mumkid[0], &x); /* mask */
p = (char *) malloc(4 * RDINumCPURegs);
i = armul_rdi.CPUread(c, x, (ARMword *) p);
MYwrite_char(kidmum[1], RDP_Return);
for (k = 1, j = 0; k != 0x80000000; k *= 2)
if (k & x) MYwrite_word(kidmum[1], ((ARMword *) p)[j++]);
free(p);
if (i) MYwrite_char(kidmum[1], (unsigned char) j);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_CPUwrite :
/* Write CPU State */
MYread_char(mumkid[0], &c); /* mode */
MYread_word(mumkid[0], &x); /* mask */
p = (char *) malloc(4 * RDINumCPURegs);
for (k = 1, j = 0; k != 0x80000000; k *= 2)
if (k & x) MYread_word(mumkid[0], &(((ARMword *) p)[j++]));
i = armul_rdi.CPUwrite(c, x, (ARMword *) p);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
free(p);
break;
case RDP_CPread :
/* Read Co-Processor State */
MYread_char(mumkid[0], &c); /* CPnum */
MYread_word(mumkid[0], &x); /* mask */
p = q = (char *) malloc(16 * RDINumCPRegs);
i = armul_rdi.CPread(c, x, (ARMword *) p);
MYwrite_char(kidmum[1], RDP_Return);
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
if (k & x) {
if ((c == 1 || c == 2) && k <= 128) {
MYwrite_FPword(kidmum[1], q);
q += 16;
}
else {
MYwrite_word(kidmum[1], *q);
q += 4;
}
}
free(p);
if (i) MYwrite_char(kidmum[1], (unsigned char) j);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_CPwrite :
/* Write Co-Processor State */
MYread_char(mumkid[0], &c); /* CPnum */
MYread_word(mumkid[0], &x); /* mask */
p = q = (char *) malloc(16 * RDINumCPURegs);
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
if (k & x) {
if ((c == 1 || c == 2) && k <= 128) {
MYread_FPword(kidmum[1], q);
q += 16;
}
else {
MYread_word(mumkid[0], (ARMword *) q);
q += 4;
}
}
i = armul_rdi.CPwrite(c, x, (ARMword *) p);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
free(p);
break;
case RDP_SetBreak :
/* Set Breakpoint */
MYread_word(mumkid[0], &x); /* address */
MYread_char(mumkid[0], &c); /* type */
if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */
i = armul_rdi.setbreak(x, c, y, &point);
if (!MYrdp_level) BAG_putpair((long) x, (long) point);
MYwrite_char(kidmum[1], RDP_Return);
if (MYrdp_level) MYwrite_word(kidmum[1], point);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_ClearBreak :
/* Clear Breakpoint */
MYread_word(mumkid[0], &point); /* PointHandle */
if (!MYrdp_level) {
BAG_getsecond((long) point, &outofthebag); /* swap pointhandle for address */
BAG_killpair_byfirst(outofthebag);
point = outofthebag;
}
i = armul_rdi.clearbreak(point);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_SetWatch :
/* Set Watchpoint */
MYread_word(mumkid[0], &x); /* address */
MYread_char(mumkid[0], &c); /* type */
MYread_char(mumkid[0], &d); /* datatype */
if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */
i = armul_rdi.setwatch(x, c, d, y, &point);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_word(kidmum[1], point);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_ClearWatch :
/* Clear Watchpoint */
MYread_word(mumkid[0], &point); /* PointHandle */
i = armul_rdi.clearwatch(point);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_Execute :
/* Excecute */
MYread_char(mumkid[0], &c); /* return */
#ifdef DEBUG
fprintf(stderr, "Starting execution\n");
#endif
i = armul_rdi.execute(&point);
#ifdef DEBUG
fprintf(stderr, "Completed execution\n");
#endif
MYwrite_char(kidmum[1], RDP_Return);
if (c & 0x80) MYwrite_word(kidmum[1], point);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_Step :
/* Step */
MYread_char(mumkid[0], &c); /* return */
MYread_word(mumkid[0], &x); /* ninstr */
point = 0x87654321;
i = armul_rdi.step(x, &point);
MYwrite_char(kidmum[1], RDP_Return);
if (c & 0x80) MYwrite_word(kidmum[1], point);
MYwrite_char(kidmum[1], (unsigned char) i);
break;
case RDP_Info:
/* Info */
MYread_word (mumkid[0], &x);
switch (x)
{
case RDIInfo_Target:
i = armul_rdi.info (RDIInfo_Target, &y, &z);
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_word (kidmum[1], y); /* Loads of info... */
MYwrite_word (kidmum[1], z); /* Model */
MYwrite_char (kidmum[1], (unsigned char) i);
break;
case RDISet_RDILevel:
MYread_word (mumkid[0], &x); /* arg1, debug level */
i = armul_rdi.info (RDISet_RDILevel, &x, 0);
if (i == RDIError_NoError)
MYrdp_level = x;
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_char (kidmum[1], (unsigned char) i);
break;
case RDISet_Cmdline:
for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
; /* String */
i = armul_rdi.info (RDISet_Cmdline,
(unsigned long *) command_line, 0);
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_char (kidmum[1], (unsigned char) i);
break;
case RDIInfo_Step:
i = armul_rdi.info (RDIInfo_Step, &x, 0);
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_word (kidmum[1], x);
MYwrite_char (kidmum[1], (unsigned char) i);
break;
case RDIVector_Catch:
MYread_word (mumkid[0], &x);
i = armul_rdi.info (RDIVector_Catch, &x, 0);
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_char (kidmum[1], i);
break;
case RDIInfo_Points:
i = armul_rdi.info (RDIInfo_Points, &x, 0);
MYwrite_char (kidmum[1], RDP_Return);
MYwrite_word (kidmum[1], x);
MYwrite_char (kidmum[1], (unsigned char) i);
break;
default:
fprintf (stderr, "Unsupported info code %d\n", x);
break;
}
break;
case RDP_OSOpReply:
/* OS Operation Reply */
MYwrite_char (kidmum[1], RDP_Fatal);
break;
case RDP_Reset:
/* Reset */
for (i = 0; i < 50; i++)
MYwrite_char(kidmum[1], RDP_Reset);
p = (char *) malloc(MAXHOSTNAMELENGTH + 5 + 20);
sprintf(p, "Running on %s:%d\n", localhost, socketnumber);
MYwrite_string(kidmum[1], p);
free(p);
break;
default:
fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
/* Hmm.. bad RDP operation */
break;
}
}
}
/* Handles memory read operations until an OS Operation Reply Message is */
/* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
/* in 'putinr0' with the data if appropriate. */
int wait_for_osreply(ARMword *reply)
{
char *p, *q;
int i, j, k;
unsigned char c, d, message;
ARMword x, y, z;
struct sigaction action;
PointHandle point;
Dbg_ConfigBlock config;
Dbg_HostosInterface hostif;
struct Dbg_MCState *MCState;
char command_line[256];
struct fd_set readfds;
#ifdef DEBUG
fprintf(stderr, "wait_for_osreply ().\n");
#endif
/* Setup a signal handler for SIGUSR1 */
action.sa_handler = kid_handlesignal;
action.sa_mask = 0;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, (struct sigaction *) 0);
while (1)
{
/* Wait for ever */
FD_ZERO(&readfds);
FD_SET(mumkid[0], &readfds);
i = select(nfds, &readfds,
(fd_set *) 0,
(fd_set *) 0,
(struct timeval *) 0);
if (i < 0) {
perror("select");
}
if (read(mumkid[0], &message, 1) < 1) {
perror("read");
}
switch (message) {
case RDP_Read :
/* Read Memory Address */
MYread_word(mumkid[0], &x); /* address */
MYread_word(mumkid[0], &y); /* nbytes */
p = (char *) malloc(y);
i = armul_rdi.read(x, p, (unsigned *) &y);
MYwrite_char(kidmum[1], RDP_Return);
for (k = 0; k < y; k++)
MYwrite_char(kidmum[1], p[k]);
free(p);
MYwrite_char(kidmum[1], (unsigned char) i);
if (i)
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
break;
case RDP_Write :
/* Write Memory Address */
MYread_word(mumkid[0], &x); /* address */
MYread_word(mumkid[0], &y); /* nbytes */
p = (char *) malloc(y);
for (k = 0; k < y; k++)
MYread_char(mumkid[0], &p[k]);
i = armul_rdi.write(p, x, (unsigned *) &y);
free(p);
MYwrite_char(kidmum[1], RDP_Return);
MYwrite_char(kidmum[1], (unsigned char) i);
if (i)
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
break;
case RDP_OSOpReply :
/* OS Operation Reply */
MYread_char(mumkid[0], &c);
if (c == 1) MYread_char(mumkid[0], (char *) reply);
if (c == 2) MYread_word(mumkid[0], reply);
return c;
break;
default :
fprintf(stderr, "HELP! Unaccounted-for message during OS request. \n");
MYwrite_char(kidmum[1], RDP_Fatal);
}
}
}

183
sim/arm/main.c Normal file
View File

@ -0,0 +1,183 @@
/* main.c -- top level of ARMulator: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/**********************************************************************/
/* Forks the ARMulator and hangs on a socket passing on RDP messages */
/* down a pipe to the ARMulator which translates them into RDI calls. */
/**********************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include "armdefs.h"
#include "dbg_rdi.h"
#include "dbg_conf.h"
#define MAXHOSTNAMELENGTH 64
/* Read and write routines down sockets and pipes */
void MYread_chars(int sock, void *p, int n);
unsigned char MYread_char(int sock);
ARMword MYread_word(int sock);
void MYread_FPword(int sock, char *putinhere);
void MYwrite_word(int sock, ARMword i);
void MYwrite_string(int sock, char *s);
void MYwrite_FPword(int sock, char *fromhere);
void MYwrite_char(int sock, unsigned char c);
void passon(int source, int dest, int n);
/* Mother and child processes */
void parent (void);
void kid(void);
/* The child process id. */
pid_t child;
/* The socket to the debugger */
int debugsock;
/* The pipes between the two processes */
int mumkid[2];
int kidmum[2];
/* A pipe for handling SWI return values that goes straight from the */
/* parent to the ARMulator host interface, bypassing the childs RDP */
/* to RDI interpreter */
int DebuggerARMul[2];
/* The maximum number of file descriptors */
int nfds;
/* The socket handle */
int sockethandle;
/* The machine name */
char localhost[MAXHOSTNAMELENGTH + 1];
/* The socket number */
unsigned int socketnumber;
/**************************************************************/
/* Takes one argument: the socket number. */
/* Opens a socket to the debugger, and once opened spawns the */
/* ARMulator and sets up a couple of pipes. */
/**************************************************************/
int main(int argc, char *argv[]) {
int i;
struct sockaddr_in devil, isa;
struct hostent *hp;
if (argc == 1) {
fprintf(stderr, "No socket number\n");
return 1;
}
sscanf(argv[1], "%d", &socketnumber);
if (!socketnumber || socketnumber > 0xffff) {
fprintf(stderr, "Invalid socket number: %d\n", socketnumber);
return 1;
}
gethostname(localhost, MAXHOSTNAMELENGTH);
hp = gethostbyname(localhost);
if (!hp) {
fprintf(stderr, "Cannot get local host info\n");
return 1;
}
/* Open a socket */
sockethandle = socket(hp->h_addrtype, SOCK_STREAM, 0);
if (sockethandle < 0) {
perror("socket");
return 1;
}
devil.sin_family = hp->h_addrtype;
devil.sin_port = htons(socketnumber);
devil.sin_addr.s_addr = 0;
for(i = 0; i < sizeof(devil.sin_zero); i++) devil.sin_zero[i] = '\000';
memcpy(&devil.sin_addr, hp->h_addr_list[0], hp->h_length);
if (bind(sockethandle, &devil, sizeof(devil)) < 0) {
perror("bind");
return 1;
}
/* May only accept one debugger at once */
if (listen(sockethandle, 0)) {
perror("listen");
return 1;
}
fprintf(stderr, "Waiting for connection from debugger...");
debugsock = accept(sockethandle, &isa, &i);
if (debugsock < 0) {
perror("accept");
return 1;
}
fprintf(stderr, " done.\nConnection Established.\n");
nfds = getdtablesize();
if (pipe(mumkid)) {
perror("pipe");
return 1;
}
if (pipe(kidmum)) {
perror("pipe");
return 1;
}
if (pipe(DebuggerARMul)) {
perror("pipe");
return 1;
}
#ifdef DEBUG
fprintf(stderr, "Created pipes ok\n");
#endif
child = fork();
#ifdef DEBUG
fprintf(stderr, "fork() ok\n");
#endif
if (child == 0) kid ();
if (child != -1) parent ();
perror("fork");
return 1;
}

483
sim/arm/parent.c Normal file
View File

@ -0,0 +1,483 @@
/* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*****************************************************************/
/* The Parent process continues here... */
/* It waits on the socket and passes on RDP messages down a pipe */
/* to the ARMulator RDP to RDI interpreter. */
/*****************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include "time.h"
#include "armdefs.h"
#include "dbg_rdi.h"
#include "communicate.h"
/* The socket to the debugger */
extern int debugsock;
/* The pipes between the two processes */
extern int mumkid[2];
extern int kidmum[2];
/* A pipe for handling SWI return values that goes straight from the */
/* parent to the ARMulator host interface, bypassing the child's RDP */
/* to RDI interpreter */
extern int DebuggerARMul[2];
/* The maximum number of file descriptors */
extern int nfds;
/* The child process id. */
extern pid_t child;
void
parent ()
{
int i, j, k;
unsigned char message, CPnum, exreturn;
ARMword mask, nbytes, messagetype;
unsigned char c, d;
ARMword x, y;
int virgin = 1;
struct fd_set readfds;
#ifdef DEBUG
fprintf (stderr, "parent ()...\n");
#endif
panic_error:
if (!virgin)
{
#ifdef DEBUG
fprintf(stderr, "Arghh! What is going on?\n");
#endif
kill (child, SIGHUP);
MYwrite_char(debugsock, RDP_Reset);
}
virgin = 0;
while (1)
{
/* Wait either for the ARMulator or the debugger */
FD_ZERO (&readfds);
FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
#ifdef DEBUG
fprintf (stderr, "Waiting for ARMulator or debugger... ");
#endif
while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
{
perror ("select");
}
#ifdef DEBUG
fprintf(stderr, "(%d/2)", i);
#endif
if (FD_ISSET (debugsock, &readfds)) {
#ifdef DEBUG
fprintf (stderr, "->debugger\n");
#endif
/* Inside this rather large if statement with simply pass on a complete
message to the ARMulator. The reason we need to pass messages on one
at a time is that we have to know whether the message is an OSOpReply
or an info(stop), so that we can take different action in those
cases. */
if (MYread_char (debugsock, &message))
goto panic_error;
switch (message)
{
case RDP_Start:
/* Open and/or Initialise */
#ifdef DEBUG
fprintf (stderr, "RDP Open\n");
#endif
if (MYread_char(debugsock, &c)) /* type */
goto panic_error;
if (MYread_word(debugsock, &x)) /* memory size */
goto panic_error;
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], c);
MYwrite_word (mumkid[1], x);
if (c & 0x2)
{
passon (debugsock, mumkid[1], 1); /* speed */
}
break;
case RDP_End:
/* Close and Finalise */
#ifdef DEBUG
fprintf(stderr, "RDP Close\n");
#endif
MYwrite_char (mumkid[1], message);
break;
case RDP_Read:
/* Read Memory Address */
#ifdef DEBUG
fprintf (stderr, "RDP Read Memory\n");
#endif
MYwrite_char (mumkid[1], message);
if (passon (debugsock, mumkid[1], 4))
goto panic_error; /* address */
if (MYread_word(debugsock, &nbytes))
goto panic_error; /* nbytes */
MYwrite_word (mumkid[1], nbytes);
break;
case RDP_Write :
/* Write Memory Address */
#ifdef DEBUG
fprintf (stderr, "RDP Write Memory\n");
#endif
if (MYread_word (debugsock, &x))
goto panic_error; /* address */
if (MYread_word (debugsock, &y))
goto panic_error; /* nbytes */
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], x);
MYwrite_word (mumkid[1], y);
passon (debugsock, mumkid[1], y); /* actual data */
break;
case RDP_CPUread:
/* Read CPU State */
#ifdef DEBUG
fprintf (stderr, "RDP Read CPU\n");
#endif
if (MYread_char(debugsock, &c))
goto panic_error; /* mode */
if (MYread_word (debugsock, &mask))
goto panic_error; /* mask */
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], c);
MYwrite_word (mumkid[1], mask);
break;
case RDP_CPUwrite :
/* Write CPU State */
#ifdef DEBUG
fprintf (stderr, "RDP Write CPU\n");
#endif
if (MYread_char (debugsock, &c))
goto panic_error; /* mode */
if (MYread_word (debugsock, &x))
goto panic_error; /* mask */
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], c);
MYwrite_word (mumkid[1], x);
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
if ((k & x)
&& passon(debugsock, mumkid[1], 4))
goto panic_error;
break;
case RDP_CPread:
/* Read Co-Processor State */
#ifdef DEBUG
fprintf (stderr, "RDP Read CP state\n");
#endif
if (MYread_char (debugsock, &CPnum))
goto panic_error;
if (MYread_word (debugsock, &mask))
goto panic_error;
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], CPnum);
MYwrite_word (mumkid[1], mask);
break;
case RDP_CPwrite:
/* Write Co-Processor State */
#ifdef DEBUG
fprintf(stderr, "RDP Write CP state\n");
#endif
if (MYread_char (debugsock, &CPnum))
goto panic_error;
if (MYread_word (debugsock, &mask))
goto panic_error;
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], c);
MYwrite_char (mumkid[1], x);
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
if (k & x)
{
if ((c == 1 || c == 2) && k <= 128)
{
/* FP register = 12 bytes + 4 bytes format */
if (passon(debugsock, mumkid[1], 16))
goto panic_error;
}
else
{
/* Normal register = 4 bytes */
if (passon(debugsock, mumkid[1], 4))
goto panic_error;
}
}
break;
case RDP_SetBreak:
/* Set Breakpoint */
#ifdef DEBUG
fprintf (stderr, "RDP Set Breakpoint\n");
#endif
if (MYread_word (debugsock, &x))
goto panic_error; /* address */
if (MYread_char (debugsock, &c))
goto panic_error; /* type */
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], x);
MYwrite_char (mumkid[1], c);
if (((c & 0xf) >= 5)
&& passon(debugsock, mumkid[1], 4))
goto panic_error; /* bound */
break;
case RDP_ClearBreak:
/* Clear Breakpoint */
#ifdef DEBUG
fprintf (stderr, "RDP Clear Breakpoint\n");
#endif
MYwrite_char (mumkid[1], message);
if (passon (debugsock, mumkid[1], 4))
goto panic_error; /* point */
break;
case RDP_SetWatch:
/* Set Watchpoint */
#ifdef DEBUG
fprintf (stderr, "RDP Set Watchpoint\n");
#endif
if (MYread_word (debugsock, &x))
goto panic_error; /* address */
if (MYread_char(debugsock, &c))
goto panic_error; /* type */
if (MYread_char (debugsock, &d))
goto panic_error; /* datatype */
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], x);
MYwrite_char (mumkid[1], c);
MYwrite_char (mumkid[1], d);
if (((c & 0xf) >= 5)
&& passon(debugsock, mumkid[1], 4))
goto panic_error; /* bound */
break;
case RDP_ClearWatch:
/* Clear Watchpoint */
#ifdef DEBUG
fprintf (stderr, "RDP Clear Watchpoint\n");
#endif
MYwrite_char (mumkid[1], message);
if (passon (debugsock, mumkid[1], 4))
goto panic_error; /* point */
break;
case RDP_Execute:
/* Excecute */
#ifdef DEBUG
fprintf (stderr, "RDP Execute\n");
#endif
/* LEAVE THIS ONE 'TIL LATER... */
/* NEED TO WORK THINGS OUT */
/* NO ASCYNCHROUS RUNNING */
if (MYread_char(debugsock, &c))
goto panic_error; /* return */
/* Remember incase bit 7 is set and we have to send back a word */
exreturn = c;
MYwrite_char(mumkid[1], message);
MYwrite_char(mumkid[1], c);
break;
case RDP_Step:
/* Step */
#ifdef DEBUG
fprintf (stderr, "RDP Step\n");
#endif
if (MYread_char(debugsock, &c))
goto panic_error; /* return */
if (MYread_word(debugsock, &x))
goto panic_error; /* ninstr */
MYwrite_char (mumkid[1], message);
MYwrite_char (mumkid[1], c);
MYwrite_word (mumkid[1], x);
break;
case RDP_Info:
/* Info */
#ifdef DEBUG
fprintf (stderr, "RDP Info\n");
#endif
/* INFO TARGET, SET RDI LEVEL */
if (MYread_word (debugsock, &messagetype))
goto panic_error; /* info */
switch (messagetype)
{
case RDIInfo_Target:
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
break;
case RDISet_RDILevel:
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
if (passon (debugsock, mumkid[1], 1))
goto panic_error; /* argument */
break;
case RDISet_Cmdline:
/* Got to pass on a string argument */
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
do
{
if (MYread_char (debugsock, &c))
goto panic_error;
MYwrite_char (mumkid[1], c);
} while (c);
break;
case RDISignal_Stop:
kill (child, SIGUSR1);
MYwrite_char (debugsock, RDP_Return);
MYwrite_char (debugsock, RDIError_UserInterrupt);
break;
case RDIVector_Catch:
MYread_word (debugsock, &x);
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
MYwrite_word (mumkid[1], x);
break;
case RDIInfo_Step:
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
break;
case RDIInfo_Points:
MYwrite_char (mumkid[1], message);
MYwrite_word (mumkid[1], messagetype);
break;
default:
fprintf (stderr, "Unrecognized RDIInfo request %d\n",
messagetype);
goto panic_error;
}
break;
case RDP_OSOpReply:
/* OS Operation Reply */
#ifdef DEBUG
fprintf (stderr, "RDP OS Reply\n");
#endif
MYwrite_char (mumkid[1], message);
if (MYread_char (debugsock, &message))
goto panic_error;
MYwrite_char (mumkid[1], message);
switch(message)
{
case 0: /* return value i.e. nothing else.*/
break;
case 1: /* returns a byte... */
if (MYread_char(debugsock, &c))
goto panic_error;
MYwrite_char (mumkid[1], c);
break;
case 2: /* returns a word... */
if (MYread_word(debugsock, &x))
goto panic_error;
MYwrite_word (mumkid[1], x);
break;
}
break;
case RDP_Reset:
/* Reset */
#ifdef DEBUG
fprintf (stderr, "RDP Reset\n");
#endif
MYwrite_char (mumkid[1], message);
break;
default:
/* Hmm.. bad RDP operation */
fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
MYwrite_char (debugsock, RDP_Return);
MYwrite_char (debugsock, RDIError_UnimplementedMessage);
break;
}
}
if (FD_ISSET (kidmum[0], &readfds))
{
#ifdef DEBUG
fprintf (stderr, "->ARMulator\n");
#endif
/* Anything we get from the ARMulator has to go to the debugger... */
/* It is that simple! */
passon (kidmum[0], debugsock, 1);
}
}
}

155
sim/arm/run.c Normal file
View File

@ -0,0 +1,155 @@
/* run front end support for ARM
Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of ARM SIM
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Steve Chamberlain
sac@cygnus.com */
#include <stdio.h>
#include <varargs.h>
#include "bfd.h"
#include "sysdep.h"
#include "remote-sim.h"
void usage();
extern int optind;
extern char *optarg;
int target_byte_order;
int
main (ac, av)
int ac;
char **av;
{
bfd *abfd;
bfd_vma start_address;
asection *s;
int i;
int verbose = 0;
int trace = 0;
char *name = "";
while ((i = getopt (ac, av, "m:p:s:tv")) != EOF)
switch (i)
{
case 'm':
sim_size (atoi (optarg));
break;
case 'p':
sim_set_profile (atoi (optarg));
break;
case 's':
sim_set_profile_size (atoi (optarg));
break;
case 't':
trace = 1;
break;
case 'v':
verbose = 1;
break;
default:
usage();
}
ac -= optind;
av += optind;
if (ac != 1)
usage();
name = *av;
if (verbose)
{
printf ("run %s\n", name);
}
abfd = bfd_openr (name, 0);
if (abfd)
{
if (bfd_check_format (abfd, bfd_object))
{
for (s = abfd->sections; s; s = s->next)
{
unsigned char *buffer = malloc (bfd_section_size (abfd, s));
bfd_get_section_contents (abfd,
s,
buffer,
0,
bfd_section_size (abfd, s));
sim_write (s->vma, buffer, bfd_section_size (abfd, s));
}
start_address = bfd_get_start_address (abfd);
sim_create_inferior (start_address, NULL, NULL);
target_byte_order = abfd->xvec->byteorder_big_p ? 4321 : 1234;
if (trace)
{
int done = 0;
while (!done)
{
done = sim_trace ();
}
}
else
{
sim_resume (0, 0);
}
if (verbose)
sim_info (0);
/* Assume we left through the exit system call,
in which case r5 has the exit code */
{
unsigned char b[4];
sim_fetch_register (5, b);
return b[3];
}
}
}
return 1;
}
void
usage()
{
fprintf (stderr, "usage: run [-tv] program\n");
exit (1);
}
/* Callbacks used by the simulator proper. */
void
printf_filtered (va_alist)
va_dcl
{
va_list args;
char *format;
va_start (args);
format = va_arg (args, char *);
vfprintf (stdout, format, args);
va_end (args);
}