This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[Patch, moxie, sim] Use common memory infrastructure & introduce device tree source
- From: Anthony Green <green at moxielogic dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 10 Sep 2009 17:59:56 -0400
- Subject: [Patch, moxie, sim] Use common memory infrastructure & introduce device tree source
I am committing the following patch which serves two main purposes.
The first purpose is to use the common sim infrastructure for simulated
memory instead of our own simple solution. This lets us define
non-contiguous blocks of simulated memory, which is very useful.
The second purpose is to introduce a device tree blob for the simulated
target. The device tree is a mechanism to describe embedded hardware to
system software such as a boot loader or an operating system kernel.
Here's a reprint from the 2008 Linux Symposium describing how the device
tree is used to describe Power hardware to the Linux kernel.
http://ols.fedoraproject.org/OLS/Reprints-2008/likely2-reprint.pdf
The moxie Linux kernel port currently boots on both GDB and qemu
simulators, however they use different mechanisms to interact with the
console. The gdb port uses software interrupts to escape to the
simulator. The qemu port uses a simulated memory mapped UART device.
The device tree allows us to describe these differences in target
hardware to the system software so we can have a single image that will
boot on any compatible target.
This patch includes a simple device tree description of the gdb
simulator (RAM location and extent, etc). The Makefile now invokes the
GPL device tree compiler (dtc, found in many places on the web) to
generate a device tree blob (.dtb file). We install this file
under /usr/share and the simulator is modified to load the blob into
simulated memory at start-up and point special register 3 at it. The
kernel always expects to find a device tree blob reference in special
register 3 at startup. The kernel then decodes this blob, detects that
it is running on gdb, and uses software interrupt mechanism for console
IO.
The Linux kernel is not the only consumer of this emerging standard.
U-Boot and other firmwares are adopting it as well. Integrating support
for device tree blobs into the moxie GDB simulator will make it easier
to develop, test and debug many types of system software ports.
AG
2009-09-10 Anthony Green <green@moxielogic.com>
* Makefile.in (install-dtb): New target.
(moxie-gdb.dtb): New target.
(SIM_CFLAGS): Define DTB macro on command line.
(SIM_OBJS): Use common infrastructure.
(dtbdir): Define install location for dtb file.
* sim-main.h: New file.
* moxie-gdb.dts: New file.
* configure.ac: Check for dtc. Install dtb file. Remove some old
cruft.
* configure: Regenerate.
* interp.c: Many changes to use common memory infrastructure.
(load_dtb): New function.
(sim_create_inferior): Call it.
Index: sim/moxie/Makefile.in
===================================================================
RCS file: /cvs/src/src/sim/moxie/Makefile.in,v
retrieving revision 1.1
diff -u -r1.1 Makefile.in
--- sim/moxie/Makefile.in 1 May 2009 03:03:41 -0000 1.1
+++ sim/moxie/Makefile.in 10 Sep 2009 21:44:28 -0000
@@ -18,12 +18,29 @@
## COMMON_PRE_CONFIG_FRAG
-SIM_OBJS = interp.o sim-load.o
+dtbdir = @datadir@/gdb-`sed q ${srcdir}/../../gdb/version.in`/dtb
+
+SIM_OBJS = interp.o sim-load.o sim-io.o sim-config.o sim-utils.o \
+sim-options.o sim-module.o sim-core.o sim-endian.o sim-trace.o \
+sim-engine.o sim-fpu.o sim-bits.o sim-profile.o sim-events.o \
+sim-memopt.o
+
SIM_EXTRA_LIBS = -lm -lz
SIM_EXTRA_CLEAN = moxie-clean
+SIM_EXTRA_INSTALL = install-dtb
+SIM_CFLAGS = -DDTB="\"$(dtbdir)/moxie-gdb.dtb\""
## COMMON_POST_CONFIG_FRAG
+all: interp.o moxie-gdb.dtb
+
interp.o: interp.c
+moxie-gdb.dtb: moxie-gdb.dts
+ dtc -O dtb -o moxie-gdb.dtb ${srcdir}/moxie-gdb.dts
+
+install-dtb: moxie-gdb.dtb
+ $(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(dtbdir)
+ $(INSTALL_DATA) moxie-gdb.dtb $(DESTDIR)$(dtbdir)/moxie-gdb.dtb
+
moxie-clean:
Index: sim/moxie/configure.ac
===================================================================
RCS file: /cvs/src/src/sim/moxie/configure.ac,v
retrieving revision 1.1
diff -u -r1.1 configure.ac
--- sim/moxie/configure.ac 1 May 2009 03:03:41 -0000 1.1
+++ sim/moxie/configure.ac 10 Sep 2009 21:44:30 -0000
@@ -3,12 +3,20 @@
AC_INIT(Makefile.in)
AC_CONFIG_HEADER(config.h:config.in)
+AC_CHECK_TOOL(DTC, dtc)
+
sinclude(../common/aclocal.m4)
# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around
# it by inlining the macro's contents.
sinclude(../common/common.m4)
+SIM_AC_OPTION_ENDIAN(BIG_ENDIAN)
+SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT)
+SIM_AC_OPTION_HOSTENDIAN
+SIM_AC_OPTION_ENVIRONMENT
+SIM_AC_OPTION_INLINE()
+
AC_CHECK_HEADERS(unistd.h)
SIM_AC_OUTPUT
Index: sim/moxie/interp.c
===================================================================
RCS file: /cvs/src/src/sim/moxie/interp.c,v
retrieving revision 1.4
diff -u -r1.4 interp.c
--- sim/moxie/interp.c 31 Jul 2009 11:40:16 -0000 1.4
+++ sim/moxie/interp.c 10 Sep 2009 21:44:30 -0000
@@ -28,6 +28,9 @@
#include "libiberty.h"
#include "gdb/remote-sim.h"
+#include "sim-main.h"
+#include "sim-base.h"
+
typedef int word;
typedef unsigned int uword;
@@ -39,10 +42,11 @@
instruction. */
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
-#define EXTRACT_WORD(addr) (((addr)[0] << 24) \
- + ((addr)[1] << 16) \
- + ((addr)[2] << 8) \
- + ((addr)[3]))
+#define EXTRACT_WORD(addr) \
+ ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
unsigned long
moxie_extract_unsigned_integer (addr, len)
@@ -111,8 +115,6 @@
word sregs[256]; /* special registers */
word cc; /* the condition code reg */
int exception;
- unsigned long msize;
- unsigned char * memory;
unsigned long long insts; /* instruction counter */
};
@@ -132,65 +134,20 @@
static SIM_OPEN_KIND sim_kind;
static int issue_messages = 0;
-/* Default to a 16 Mbyte (== 2^23) memory space. */
-static int sim_memory_size = 24;
-
-#define MEM_SIZE_FLOOR 64
void
-sim_size (power)
- int power;
+sim_size (int s)
{
- sim_memory_size = power;
- cpu.asregs.msize = 1 << sim_memory_size;
-
- if (cpu.asregs.memory)
- free (cpu.asregs.memory);
-
- /* Watch out for the '0 count' problem. There's probably a better
- way.. e.g., why do we use 64 here? */
- if (cpu.asregs.msize < 64) /* Ensure a boundary. */
- cpu.asregs.memory = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
- else
- cpu.asregs.memory = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
-
- if (!cpu.asregs.memory)
- {
- if (issue_messages)
- fprintf (stderr,
- "Not enough VM for simulation of %d bytes of RAM\n",
- cpu.asregs.msize);
-
- cpu.asregs.msize = 1;
- cpu.asregs.memory = (unsigned char *) calloc (1, 1);
- }
}
static void
-init_pointers ()
-{
- if (cpu.asregs.msize != (1 << sim_memory_size))
- sim_size (sim_memory_size);
-}
-
-
-static void
set_initial_gprs ()
{
int i;
long space;
- unsigned long memsize;
- init_pointers ();
-
/* Set up machine just out of reset. */
cpu.asregs.regs[PC_REGNO] = 0;
- memsize = cpu.asregs.msize / (1024 * 1024);
-
- if (issue_messages > 1)
- fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
- memsize, cpu.asregs.msize - 1);
-
/* Clean out the register contents. */
for (i = 0; i < NUM_MOXIE_REGS; i++)
cpu.asregs.regs[i] = 0;
@@ -207,168 +164,61 @@
/* Write a 1 byte value to memory. */
static void INLINE
-wbat (pc, x, v)
- word pc, x, v;
+wbat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- {
- unsigned char * p = cpu.asregs.memory + x;
- *p = v;
- }
- }
+ address_word cia = CIA_GET (scpu);
+
+ sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
}
/* Write a 2 byte value to memory. */
static void INLINE
-wsat (pc, x, v)
- word pc, x, v;
+wsat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "short word write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "short word write to unaligned memory address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- p[0] = v >> 8;
- p[1] = v;
- }
- }
+ address_word cia = CIA_GET (scpu);
+
+ sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
}
/* Write a 4 byte value to memory. */
static void INLINE
-wlat (pc, x, v)
- word pc, x, v;
+wlat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "word write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- p[0] = v >> 24;
- p[1] = v >> 16;
- p[2] = v >> 8;
- p[3] = v;
- }
- }
+ address_word cia = CIA_GET (scpu);
+
+ sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
}
/* Read 2 bytes from memory. */
static int INLINE
-rsat (pc, x)
- word pc, x;
+rsat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "short word read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "short word read from unaligned address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- return 0;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- return (p[0] << 8) | p[1];
- }
- }
+ address_word cia = CIA_GET (scpu);
+
+ return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
}
/* Read 1 byte from memory. */
static int INLINE
-rbat (pc, x)
- word pc, x;
+rbat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- unsigned char * p = cpu.asregs.memory + x;
- return *p;
- }
+ address_word cia = CIA_GET (scpu);
+
+ return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
}
/* Read 4 bytes from memory. */
static int INLINE
-rlat (pc, x)
- word pc, x;
+rlat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "word read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- if ((x & 3) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- return 0;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- return (EXTRACT_WORD(p));
- }
- }
+ address_word cia = CIA_GET (scpu);
+
+ return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
}
#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
@@ -407,12 +257,13 @@
unsigned long long insts;
unsigned short inst;
void (* sigsave)();
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+ address_word cia = CIA_GET (scpu);
sigsave = signal (SIGINT, interrupt);
cpu.asregs.exception = step ? SIGTRAP: 0;
pc = cpu.asregs.regs[PC_REGNO];
insts = cpu.asregs.insts;
- unsigned char *memory = cpu.asregs.memory;
/* Run instructions here. */
do
@@ -420,7 +271,8 @@
opc = pc;
/* Fetch the instruction at pc. */
- inst = (memory[pc] << 8) + memory[pc + 1];
+ inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
+ + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
/* Decode instruction. */
if (inst & (1 << 15))
@@ -568,7 +420,7 @@
{
int reg = (inst >> 4) & 0xf;
TRACE("ldi.l");
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int val = EXTRACT_WORD(pc+2);
cpu.asregs.regs[reg] = val;
pc += 4;
}
@@ -583,7 +435,7 @@
break;
case 0x03: /* jsra */
{
- unsigned int fn = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int fn = EXTRACT_WORD(pc+2);
unsigned int sp = cpu.asregs.regs[1];
TRACE("jsra");
/* Save a slot for the static chain. */
@@ -591,11 +443,11 @@
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 6);
+ wlat (scpu, opc, sp, pc + 6);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the pc and $fp. */
cpu.asregs.regs[1] = sp;
@@ -610,11 +462,11 @@
TRACE("ret");
/* Pop the frame pointer. */
- cpu.asregs.regs[0] = rlat (opc, sp);
+ cpu.asregs.regs[0] = rlat (scpu, opc, sp);
sp += 4;
/* Pop the return address. */
- pc = rlat (opc, sp) - 2;
+ pc = rlat (scpu, opc, sp) - 2;
sp += 4;
/* Skip over the static chain slot. */
@@ -640,7 +492,7 @@
int b = inst & 0xf;
int sp = cpu.asregs.regs[a] - 4;
TRACE("push");
- wlat (opc, sp, cpu.asregs.regs[b]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[b]);
cpu.asregs.regs[a] = sp;
}
break;
@@ -650,25 +502,25 @@
int b = inst & 0xf;
int sp = cpu.asregs.regs[a];
TRACE("pop");
- cpu.asregs.regs[b] = rlat (opc, sp);
+ cpu.asregs.regs[b] = rlat (scpu, opc, sp);
cpu.asregs.regs[a] = sp + 4;
}
break;
case 0x08: /* lda.l */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("lda.l");
- cpu.asregs.regs[reg] = rlat (opc, addr);
+ cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
pc += 4;
}
break;
case 0x09: /* sta.l */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("sta.l");
- wlat (opc, addr, cpu.asregs.regs[reg]);
+ wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
@@ -679,7 +531,7 @@
int xv;
TRACE("ld.l");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rlat (opc, xv);
+ cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
}
break;
case 0x0b: /* st.l */
@@ -687,28 +539,28 @@
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
TRACE("st.l");
- wlat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+ wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x0c: /* ldo.l */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("ldo.l");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rlat(opc, addr);
+ cpu.asregs.regs[a] = rlat (scpu, opc, addr);
pc += 4;
}
break;
case 0x0d: /* sto.l */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("sto.l");
addr += cpu.asregs.regs[a];
- wlat(opc, addr, cpu.asregs.regs[b]);
+ wlat (scpu, opc, addr, cpu.asregs.regs[b]);
pc += 4;
}
break;
@@ -763,11 +615,11 @@
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 2);
+ wlat (scpu, opc, sp, pc + 2);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the fp & pc. */
cpu.asregs.regs[1] = sp;
@@ -777,7 +629,7 @@
break;
case 0x1a: /* jmpa */
{
- unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int tgt = EXTRACT_WORD(pc+2);
TRACE("jmpa");
pc = tgt - 2;
}
@@ -786,7 +638,7 @@
{
int reg = (inst >> 4) & 0xf;
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int val = EXTRACT_WORD(pc+2);
TRACE("ldi.b");
cpu.asregs.regs[reg] = val;
pc += 4;
@@ -799,15 +651,15 @@
int xv;
TRACE("ld.b");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rbat (opc, xv);
+ cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
}
break;
case 0x1d: /* lda.b */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("lda.b");
- cpu.asregs.regs[reg] = rbat (opc, addr);
+ cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
pc += 4;
}
break;
@@ -816,15 +668,15 @@
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
TRACE("st.b");
- wbat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+ wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x1f: /* sta.b */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("sta.b");
- wbat (opc, addr, cpu.asregs.regs[reg]);
+ wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
@@ -832,7 +684,7 @@
{
int reg = (inst >> 4) & 0xf;
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int val = EXTRACT_WORD(pc+2);
TRACE("ldi.s");
cpu.asregs.regs[reg] = val;
pc += 4;
@@ -845,15 +697,15 @@
int xv;
TRACE("ld.s");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rsat (opc, xv);
+ cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
}
break;
case 0x22: /* lda.s */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("lda.s");
- cpu.asregs.regs[reg] = rsat (opc, addr);
+ cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
pc += 4;
}
break;
@@ -862,15 +714,15 @@
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
TRACE("st.s");
- wsat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+ wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x24: /* sta.s */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
TRACE("sta.s");
- wsat (opc, addr, cpu.asregs.regs[reg]);
+ wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
@@ -984,8 +836,11 @@
break;
case 0x30: /* swi */
{
- unsigned int inum = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int inum = EXTRACT_WORD(pc+2);
TRACE("swi");
+ /* Set the special registers appropriately. */
+ cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
+ cpu.asregs.sregs[3] = inum;
switch (inum)
{
case 0x1: /* SYS_exit */
@@ -995,10 +850,12 @@
}
case 0x2: /* SYS_open */
{
- char *fname = &memory[cpu.asregs.regs[2]];
+ char fname[1024];
int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
int perm = (int) cpu.asregs.regs[4];
int fd = open (fname, mode, perm);
+ sim_core_read_buffer (sd, scpu, read_map, fname,
+ cpu.asregs.regs[2], 1024);
/* FIXME - set errno */
cpu.asregs.regs[2] = fd;
break;
@@ -1006,17 +863,24 @@
case 0x4: /* SYS_read */
{
int fd = cpu.asregs.regs[2];
- char *buf = &memory[cpu.asregs.regs[3]];
unsigned len = (unsigned) cpu.asregs.regs[4];
+ char *buf = malloc (len);
cpu.asregs.regs[2] = read (fd, buf, len);
+ sim_core_write_buffer (sd, scpu, write_map, buf,
+ cpu.asregs.regs[3], len);
+ free (buf);
break;
}
case 0x5: /* SYS_write */
{
- char *str = &memory[cpu.asregs.regs[3]];
+ char *str;
/* String length is at 0x12($fp) */
unsigned count, len = (unsigned) cpu.asregs.regs[4];
+ str = malloc (len);
+ sim_core_read_buffer (sd, scpu, read_map, str,
+ cpu.asregs.regs[3], len);
count = write (cpu.asregs.regs[2], str, len);
+ free (str);
cpu.asregs.regs[2] = count;
break;
}
@@ -1024,18 +888,17 @@
{
unsigned int handler = cpu.asregs.sregs[1];
unsigned int sp = cpu.asregs.regs[1];
- cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
/* Save a slot for the static chain. */
sp -= 4;
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 6);
+ wlat (scpu, opc, sp, pc + 6);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the fp & pc. */
cpu.asregs.regs[1] = sp;
@@ -1095,45 +958,45 @@
break;
case 0x36: /* ldo.b */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("ldo.b");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rbat(opc, addr);
+ cpu.asregs.regs[a] = rbat (scpu, opc, addr);
pc += 4;
}
break;
case 0x37: /* sto.b */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("sto.b");
addr += cpu.asregs.regs[a];
- wbat(opc, addr, cpu.asregs.regs[b]);
+ wbat (scpu, opc, addr, cpu.asregs.regs[b]);
pc += 4;
}
break;
case 0x38: /* ldo.s */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("ldo.s");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rsat(opc, addr);
+ cpu.asregs.regs[a] = rsat (scpu, opc, addr);
pc += 4;
}
break;
case 0x39: /* sto.s */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
TRACE("sto.s");
addr += cpu.asregs.regs[a];
- wsat(opc, addr, cpu.asregs.regs[b]);
+ wsat (scpu, opc, addr, cpu.asregs.regs[b]);
pc += 4;
}
break;
@@ -1164,11 +1027,10 @@
unsigned char * buffer;
int size;
{
- int i;
- init_pointers ();
-
- memcpy (& cpu.asregs.memory[addr], buffer, size);
-
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+
+ sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
+
return size;
}
@@ -1179,10 +1041,9 @@
unsigned char * buffer;
int size;
{
- int i;
- init_pointers ();
-
- memcpy (buffer, & cpu.asregs.memory[addr], size);
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+
+ sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
return size;
}
@@ -1195,8 +1056,6 @@
unsigned char * memory;
int length;
{
- init_pointers ();
-
if (rn < NUM_MOXIE_REGS && rn >= 0)
{
if (length == 4)
@@ -1221,8 +1080,6 @@
unsigned char * memory;
int length;
{
- init_pointers ();
-
if (rn < NUM_MOXIE_REGS && rn >= 0)
{
if (length == 4)
@@ -1301,21 +1158,25 @@
struct bfd * abfd;
char ** argv;
{
- int osize = sim_memory_size;
+ SIM_DESC sd = sim_state_alloc (kind, cb);
+ printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+ return 0;
+
+ sim_do_command(sd," memory region 0x00000000,0x4000000") ;
+ sim_do_command(sd," memory region 0xE0000000,0x10000") ;
+
myname = argv[0];
callback = cb;
if (kind == SIM_OPEN_STANDALONE)
issue_messages = 1;
- /* Discard and reacquire memory -- start with a clean slate. */
- sim_size (1); /* small */
- sim_size (osize); /* and back again */
-
set_initial_gprs (); /* Reset the GPR registers. */
- /* Fudge our descriptor for now. */
- return (SIM_DESC) 1;
+ return sd;
}
void
@@ -1326,6 +1187,35 @@
/* nothing to do */
}
+
+/* Load the device tree blob. */
+
+static void
+load_dtb (SIM_DESC sd, const char *filename)
+{
+ int size = 0;
+ FILE *f = fopen (filename, "rb");
+ char *buf;
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+ if (f == NULL)
+ {
+ printf ("WARNING: ``%s'' could not be opened.\n", filename);
+ return;
+ }
+ fseek (f, 0, SEEK_END);
+ size = ftell(f);
+ fseek (f, 0, SEEK_SET);
+ buf = alloca (size);
+ if (size != fread (buf, 1, size, f))
+ {
+ printf ("ERROR: error reading ``%s''.\n", filename);
+ return;
+ }
+ sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
+ cpu.asregs.sregs[9] = 0xE0000000;
+ fclose (f);
+}
+
SIM_RC
sim_load (sd, prog, abfd, from_tty)
SIM_DESC sd;
@@ -1389,6 +1279,7 @@
{
char ** avp;
int l, argc, i, tp;
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
/* Set the initial register set. */
l = issue_messages;
@@ -1412,8 +1303,8 @@
0x0000???? zero word
0x0000???? start of data pointed to by argv */
- wlat (0, 0, 0);
- wlat (0, 4, argc);
+ wlat (scpu, 0, 0, 0);
+ wlat (scpu, 0, 4, argc);
/* tp is the offset of our first argv data. */
tp = 4 + 4 + argc * 4 + 4;
@@ -1421,14 +1312,17 @@
for (i = 0; i < argc; i++)
{
/* Set the argv value. */
- wlat (0, 4 + 4 + i * 4, tp);
+ wlat (scpu, 0, 4 + 4 + i * 4, tp);
/* Store the string. */
- strcpy (&cpu.asregs.memory[tp], argv[i]);
+ sim_core_write_buffer (sd, scpu, write_map, argv[i],
+ tp, strlen(argv[i])+1);
tp += strlen (argv[i]) + 1;
}
- wlat (0, 4 + 4 + i * 4, 0);
+ wlat (scpu, 0, 4 + 4 + i * 4, 0);
+
+ load_dtb (sd, DTB);
return SIM_RC_OK;
}
@@ -1446,26 +1340,10 @@
SIM_DESC sd;
char * cmd;
{
- /* Nothing there yet; it's all an error. */
-
- if (cmd != NULL)
- {
- char ** simargv = buildargv (cmd);
- if (strcmp (simargv[0], "verbose") == 0)
- {
- issue_messages = 2;
- }
- else
- {
- fprintf (stderr,"Error: \"%s\" is not a valid moxie simulator command.\n",
+ if (sim_args_command (sd, cmd) != SIM_RC_OK)
+ sim_io_printf (sd,
+ "Error: \"%s\" is not a valid moxie simulator command.\n",
cmd);
- }
- }
- else
- {
- fprintf (stderr, "moxie sim commands: \n");
- fprintf (stderr, " verbose\n");
- }
}
void
Index: sim/moxie/moxie-gdb.dts
===================================================================
RCS file: sim/moxie/moxie-gdb.dts
diff -N sim/moxie/moxie-gdb.dts
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/moxie/moxie-gdb.dts 10 Sep 2009 21:44:30 -0000
@@ -0,0 +1,49 @@
+/*
+ * GDB Simulator device tree.
+ *
+ * (C) Copyright 2009 Anthony Green
+ *
+ * Anthony Green <green@moxielogic.com>
+ *
+ * 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
+ *
+ */
+
+/dts-v1/;
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "gdb,moxie-elf-gdb";
+ model = "testing";
+ DDR2_SDRAM: memory@00000000 {
+ device_type = "memory";
+ reg = < 0x00000000 0x04000000 >;
+ } ;
+ chosen {
+ bootargs = "lpj=1000 console=earlyser0";
+ } ;
+ cpus {
+ #address-cells = <1>;
+ #cpus = <0x1>;
+ #size-cells = <0>;
+ moxie_0: cpu@0 {
+ compatible = "moxie,moxie-0.99";
+ device_type = "cpu";
+ model = "moxie,0.99";
+ reg = <0>;
+ } ;
+ } ;
+} ;
Index: sim/moxie/sim-main.h
===================================================================
RCS file: sim/moxie/sim-main.h
diff -N sim/moxie/sim-main.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sim/moxie/sim-main.h 10 Sep 2009 21:44:30 -0000
@@ -0,0 +1,63 @@
+/* Moxie Simulator definition.
+ Copyright (C) 2009
+ Free Software Foundation, Inc.
+ Contributed by Anthony Green <green@moxielogic.com>
+
+This file is part of GDB, the GNU debugger.
+
+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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SIM_MAIN_H
+#define SIM_MAIN_H
+
+#define SIM_HAVE_BIENDIAN
+
+#include "sim-basics.h"
+
+typedef address_word sim_cia;
+
+#include "sim-base.h"
+#include "bfd.h"
+
+#define PCIDX 17
+
+struct _sim_cpu {
+
+ /* The following are internal simulator state variables: */
+#define CIA_GET(CPU) ((CPU)->registers[PCIDX] + 0)
+#define CIA_SET(CPU,CIA) ((CPU)->registers[PCIDX] = (CIA))
+
+/* To keep this default simulator simple, and fast, we use a direct
+ vector of registers. The internal simulator engine then uses
+ manifests to access the correct slot. */
+
+ unsigned_word registers[19];
+
+ sim_cpu_base base;
+};
+
+struct sim_state {
+
+ sim_cpu cpu[MAX_NR_PROCESSORS];
+#if (WITH_SMP)
+#define STATE_CPU(sd,n) (&(sd)->cpu[n])
+#else
+#define STATE_CPU(sd,n) (&(sd)->cpu[0])
+#endif
+
+ sim_state_base base;
+};
+
+#endif
+