[Vm-dev] [commit][3046] add files to make the GdbArmPlugin unde linux; can' t actually add them to 'cross' because of permissions so this is best we can do for now

commits at squeakvm.org commits at squeakvm.org
Wed Jul 16 23:23:03 UTC 2014


Revision: 3046
Author:   rowledge
Date:     2014-07-16 16:23:03 -0700 (Wed, 16 Jul 2014)
Log Message:
-----------
add files to make the GdbArmPlugin unde linux; can't actually add them to 'cross' because of permissions so this is best we can do for now

Added Paths:
-----------
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/README
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
    branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,74 @@
+/* heavily based on BochsIA32Plugin.h */
+/* Bochs seems to use error code 1 for execution errors.
+ * So we use > 1 for various errors
+ */
+
+/* TPR - added MemoryWriteBoundsError */
+#define NoError 0
+#define ExecutionError 1
+#define BadCPUInstance 2
+#define MemoryLoadBoundsError 3
+#define MemoryWriteBoundsError 4
+#define InstructionPrefetchError 5
+#define PanicError 6
+#define UnsupportedOperationError 7
+#define SomethingLoggedError 8
+
+// TPR - The library is compiled with TFlag, therefore, we also need to set it.
+#define MODET
+
+#if !defined(ulong)
+typedef unsigned long ulong;
+#endif
+
+extern ulong	minReadAddress, minWriteAddress;
+extern int gdb_log_printf(void* stream, const char * format, ...);
+
+
+/*
+ * Answer a pointer to a new ARMulator CPU (an instance of typedef ARMul_State)
+ */
+extern void *newCPU();
+/*
+ * reset the cpu to register contents 0, protected 32-bit mode.
+ */
+extern int   resetCPU(void *cpu);
+/*
+ * Single-step *cpu (an ARMul_state instance) using memory as its memory.
+ * Answer 0 on success, or an integer error code if something went awry.
+ */
+extern int  singleStepCPUInSizeMinAddrReadWrite(void *cpu, void *memory,
+					ulong byteSize, ulong minReadAddr, ulong minWriteAddr);
+/*
+ * Run *cpu (an ARMul_state instance) using memory as its memory.
+ * Answer an integer error code when the processor hits some exception.
+ * Answer 0 when it is interrupted.
+ */
+extern int	runCPUInSizeMinAddrReadWrite(void *cpu, void *memory,
+					ulong byteSize, ulong minReadAddr, ulong minWriteAddr);
+/*
+ * Flush any icache entries from start to end
+ */
+extern void	flushICacheFromTo(void *cpu, ulong strt, ulong nd);
+/*
+ * force runCPUInSize to exit asap.  Used by interrupts.
+ */
+extern void	forceStopRunning();
+/*
+ * The previous entry in the interruptCheckChain so forceStopRunning can chain.
+ */
+extern void (*prevInterruptCheckChain)();
+/*
+ * Disassemble the instruction at address in memory, writing the output to the
+ * log.
+ */
+extern int disassembleForAtInSize(void *cpu, ulong laddr,
+									void *memory, ulong byteSize);
+/*
+ * The saved error if the previous singleStepIn failed.
+ */
+extern int   errorAcorn();
+/*
+ * The current log (if singleStep failed with SomethingLoggedError).
+ */
+extern char *getlog(long *len);


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/GdbARMPlugin.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,81 @@
+Building the GdbARMPlugin
+------------------------------
+
+Build the normal VM on your Platform. Consult Cog/{cygwinbuild|unixbuild|macbuild}/HowToBuild 
+for additional information.
+When generating sources, update to the latest 
+versions of Cog and VMMaker.oscog.
+You might want/need to change VMMaker 
+class>generateSqueakCogVM to point to the right 
+directories and remove FT2Plugin from the plugin-
+list (even if skipped, generates a messageNotUnderstood). 
+You can also change VMMaker>plugins:do: removing 
+the return in the false block, in order to skip 
+when a plugin is not found, instead of aborting 
+the generation process.
+
+Building on Windows
+------------------------------
+(so far tried with Windows 7 64bit unsing mingw/MSYS 32bit)
+
+Besides the normal build environment, you need the package gettext.
+Also, downgrade your mingwrt package to 3.20 (not 3.20-2) by unpacking
+the respective -dev tarball into your mingw-folder.
+
+When compiling the Squeak VM you need a version 3 gcc/g++. 
+For configuration of gdb, you need a version 4 gcc (you don't need 
+to switch g++). For switching between compilers in mingw, 
+you may use 
+	mingw-get install/remove gcc/gcc-v3/g++/gcc-v3-g++.
+
+Compile gdb/bfd and gdb/opcodes with a gcc 4.*.
+	cd <gdb>/bfd
+	./configure --enable-targets=arm-linux
+	make
+	cd <gdb>/opcodes
+	./configure --enable-targets=arm-linux
+	make
+Then switch to gcc-v3.
+	cd <gdb>/bfd
+	make clean && make
+	cd <gdb>/opcodes
+	make clean && make
+	
+For libsim.a, the gcc version is not important.
+	cd sim/common
+	./configure
+	cd ../arm
+	./configure && make libsim.a
+
+Change Makefile.win32 to point to your gdb folder.
+Then copy the plugin files to your svn-checkout, 
+for example changing <plugin>/Makefile and running it.
+Change <cog>/cygwinbuild/plugins.ext to include GdbARMPlugin.
+Change to gcc 3, then build the VM (again).
+
+Building on Linux
+------------------------------
+(so far tried on Ubuntu 12.04 LTS 32bit)
+
+Download the gdb sources (http://ftp.gnu.org/gnu/gdb) and 
+unpack them. Change Makefile and Makefile.unix, setting 
+GDBBUILDFOLDER to the correct place.
+
+Compile libopcodes.a:
+	cd GDBBUILDFOLDER
+	./configure --enable-targets=arm-linux
+Making gdb takes quite some time. It may fail, as long as 
+it generates <gdb>/bfd/bfd.h and <gdb>/opcodes/libopcodes.a.
+	make
+Compile libsim.a
+	cd sim/common
+	./configure
+	cd ../arm
+	./configure
+	make
+Ensure libsim.a exists in <gdb>/sim/arm.
+
+Make the plugin which just copies the plugin-files 
+to the appropriate directories. Then change 
+Cog/unixbuild/bld/plugins.ext to include GdbARMPlugin.
+Build the VM (again).


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/HowToBuild
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,26 @@
+# edit this to suit your system; it really ought to use relative paths
+# or some other convenience
+GDBBUILDFOLDER = /home/tim/Documents/Raspbian-Cog/gdb-arm/gdb-7.6
+
+CC      = gcc
+CFLAGS  = -I$(GBDBUILDFOLDER)/bfd 
+LDFLAGS = $(GDBBUILDFOLDER)/sim/arm/libsim.a $(GDBBUILDFOLDER)/opcodes/libopcodes.a -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI -L$(GDBBUILDFOLDER)/bfd/ 
+SHAREDLIBRARYFLAGS = 
+
+all:
+# another test on linux:
+#	$(CC) $(CFLAGS) armulmem.c -c -I$(GDBBUILDFOLDER)/sim/arm/ -I$(GDBBUILDFOLDER)/include/
+#	$(CC) $(CFLAGS) sqGdbARMPlugin.c -c -fPIC -I$(GDBBUILDFOLDER)/sim/arm/ -I$(GDBBUILDFOLDER)/include/ -I$(GDBBUILDFOLDER)/bfd/ 
+#	$(CC) -shared $(SHAREDLIBRARYFLAGS) -o GdbARMPlugin.dll sqGdbARMPlugin.o armulmem.o $(LDFLAGS)
+
+	mkdir -p ../cog/platforms/Cross/plugins/GdbARMPlugin
+	mkdir -p ../cog/platforms/win32/plugins/GdbARMPlugin
+	mkdir -p ../cog/platforms/unix/plugins/GdbARMPlugin
+
+	cp sqGdbARMPlugin.c GdbARMPlugin.h armulmem.c ../cog/platforms/Cross/plugins/GdbARMPlugin/
+	cp Makefile.win32 ../cog/platforms/win32/plugins/GdbARMPlugin/Makefile
+	cp Makefile.unix ../cog/platforms/unix/plugins/GdbARMPlugin/Makefile.inc
+#unix
+#	cd ../cog/unixbuild/bld; make install #prefix=
+#windows
+	cd ../cog/cygwinbuild/;make


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,12 @@
+# edit this to suit your system; it really ought to use relative paths
+# or some other convenience
+GDBBUILDFOLDER	= /mnt/hgfs/tim/Documents/Squeak/Raspbian-Cog/gdb-arm/gdb-7.6
+XCFLAGS		= -m32 -DNEED_UI_LOOP_HOOK
+
+XINCLUDES	+= -I$(GDBBUILDFOLDER)/sim/arm
+XINCLUDES	:= -I$(GDBBUILDFOLDER)/bfd $(XINCLUDES)
+
+XLDFLAGS=	$(GDBBUILDFOLDER)/sim/arm/libsim.a \
+		$(GDBBUILDFOLDER)/opcodes/libopcodes.a \
+		-lbfd -liberty \
+		-Wl,-wrap,ARMul_OSHandleSWI


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.unix
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,13 @@
+GDBBUILDFOLDER = /d/Programming/cog/gdb
+
+LINK_WITH_GPP := yes
+EXTRALIBS:= -L$(GDBBUILDFOLDER)/opcodes \
+			-L$(GDBBUILDFOLDER)/sim/arm \
+			-lsim -lopcodes -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI
+
+include ../../Makefile.plugin
+
+INCLUDES:= $(INCLUDES) -I$(GDBBUILDFOLDER)/sim/arm
+
+# Copy libgcc_s_dw2-1.dll, libiconv-2.dll and libintl-8.dll from your MinGW/bin 
+# folder to the VM folder, to make it work on other Windows (7?) systems


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/Makefile.win32
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/README
===================================================================
Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,508 @@
+/*
+  This file is a compy of armvirt.c, which is part of the ARMulator distributed e.g. with gdb and skyeye.
+  In order to overwrite GetWord and PutWord, I (lars wasserman) had to copy the whole file and alter the Make to use it instead of the default ARM armvirt.c.
+  Also changed: ReLoadInstr.
+  TPR - changed the errors returned in PutWord & GetWord to discriminate between read & write bounds errors for better simulation
+  TPR - changed Get/PutWord to ensure address used is an actual word address ie bottom two bits are zeros. Without that, fetching bytes becomes... fun
+*/
+#include "GdbARMPlugin.h"
+
+/*  armvirt.c -- ARMulator virtual memory interace:  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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* This file contains a complete ARMulator memory model, modelling a
+"virtual memory" system. A much simpler model can be found in armfast.c,
+and that model goes faster too, but has a fixed amount of memory. This
+model's memory has 64K pages, allocated on demand from a 64K entry page
+table. The routines PutWord and GetWord implement this. Pages are never
+freed as they might be needed again. A single area of memory may be
+defined to generate aborts. */
+
+#include "armopts.h"
+#include "armos.h"
+#include "armdefs.h"
+#include "ansidecl.h"
+
+#ifdef VALIDATE			/* for running the validate suite */
+#define TUBE 48 * 1024 * 1024	/* write a char on the screen */
+#define ABORTS 1
+#endif
+
+/* #define ABORTS */
+
+#ifdef ABORTS			/* the memory system will abort */
+/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
+   For the new test suite Abort between 8 Mbytes and 26 Mbytes */
+/* #define LOWABORT 32 * 1024
+#define HIGHABORT 32 * 1024 * 1024 */
+#define LOWABORT 8 * 1024 * 1024
+#define HIGHABORT 26 * 1024 * 1024
+
+#endif
+
+#define NUMPAGES 64 * 1024
+#define PAGESIZE 64 * 1024
+#define PAGEBITS 16
+#define OFFSETBITS 0xffff
+
+int SWI_vector_installed = FALSE;
+
+#include <stdio.h>
+
+/***************************************************************************\
+*        Get a Word from Memory          *
+\***************************************************************************/
+
+static ARMword
+GetWord (ARMul_State * state, ARMword address, int check)
+{
+  if(address < minReadAddress || address + 4 > (state->MemSize))
+  {
+    //raise memory access error
+    state->EndCondition = MemoryLoadBoundsError;
+    state->Emulate = FALSE;
+    gdb_log_printf(NULL, "Illegal memory read at %#p. ", address);
+    return 0;
+  }
+  else
+  {
+    return *((ARMword*) (state->MemDataPtr + (address & ~3)));
+  }
+}
+
+/***************************************************************************\
+*        Put a Word into Memory          *
+\***************************************************************************/
+
+static void
+PutWord (ARMul_State * state, ARMword address, ARMword data, int check)
+{
+  if(address < minWriteAddress || address + 4 > (state->MemSize))
+  {
+    state->Emulate = FALSE;
+    state->EndCondition = MemoryWriteBoundsError;
+    gdb_log_printf(NULL, "Illegal memory write at %#p. ", address);
+  } 
+  else
+  {
+    *((ARMword*) (state->MemDataPtr + (address & ~3))) = data;
+  }
+}
+
+/***************************************************************************\
+*                   ReLoad Instruction                                     *
+\***************************************************************************/
+
+ARMword
+ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
+{
+#ifdef ABORTS
+  if (address >= LOWABORT && address < HIGHABORT)
+    {
+      ARMul_PREFETCHABORT (address);
+      return ARMul_ABORTWORD;
+    }
+  else
+    {
+      ARMul_CLEARABORT;
+    }
+#endif
+
+  if (address < minReadAddress 
+  	  || address >= (state->MemSize) 
+  	  || (address >= minWriteAddress && minWriteAddress != 0))
+  {
+  	  // Custom SWI, defined in the wrapper of ARMul_OSHandleSWI
+  	  return 0xEF000000 | 0x200000;
+  	  //      ^ SWI         ^ SWI number
+  }
+  
+  if ((isize == 2) && (address & 0x2))
+    {
+      /* We return the next two halfwords: */
+      ARMword lo = GetWord (state, address, FALSE);
+      ARMword hi = GetWord (state, address + 4, FALSE);
+
+      if (state->bigendSig == HIGH)
+	return (lo << 16) | (hi >> 16);
+      else
+	return ((hi & 0xFFFF) << 16) | (lo >> 16);
+    }
+
+  return GetWord (state, address, TRUE);
+}
+
+/***************************************************************************\
+*                      Initialise the memory interface                      *
+\***************************************************************************/
+
+unsigned
+ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
+{
+  ARMword **pagetable;
+  unsigned page;
+
+  if (initmemsize)
+    state->MemSize = initmemsize;
+
+  pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES);
+
+  if (pagetable == NULL)
+    return FALSE;
+
+  for (page = 0; page < NUMPAGES; page++)
+    *(pagetable + page) = NULL;
+
+  state->MemDataPtr = (unsigned char *) pagetable;
+
+  ARMul_ConsolePrint (state, ", 4 Gb memory");
+
+  return TRUE;
+}
+
+/***************************************************************************\
+*                         Remove the memory interface                       *
+\***************************************************************************/
+
+void
+ARMul_MemoryExit (ARMul_State * state)
+{
+  ARMword page;
+  ARMword **pagetable;
+  ARMword *pageptr;
+
+  pagetable = (ARMword **) state->MemDataPtr;
+  for (page = 0; page < NUMPAGES; page++)
+    {
+      pageptr = *(pagetable + page);
+      if (pageptr != NULL)
+	free ((char *) pageptr);
+    }
+  free ((char *) pagetable);
+  return;
+}
+
+/***************************************************************************\
+*                   Load Instruction, Sequential Cycle                      *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
+{
+  state->NumScycles++;
+
+#ifdef HOURGLASS
+  if ((state->NumScycles & HOURGLASS_RATE) == 0)
+    {
+      HOURGLASS;
+    }
+#endif
+
+  return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+*                 Load Instruction, Non Sequential Cycle                    *
+\***************************************************************************/
+
+ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
+{
+  state->NumNcycles++;
+
+  return ARMul_ReLoadInstr (state, address, isize);
+}
+
+/***************************************************************************\
+*                      Read Word (but don't tell anyone!)                   *
+\***************************************************************************/
+
+ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
+{
+#ifdef ABORTS
+  if (address >= LOWABORT && address < HIGHABORT)
+    {
+      ARMul_DATAABORT (address);
+      return ARMul_ABORTWORD;
+    }
+  else
+    {
+      ARMul_CLEARABORT;
+    }
+#endif
+
+  return GetWord (state, address, TRUE);
+}
+
+/***************************************************************************\
+*                        Load Word, Sequential Cycle                        *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
+{
+  state->NumScycles++;
+
+  return ARMul_ReadWord (state, address);
+}
+
+/***************************************************************************\
+*                      Load Word, Non Sequential Cycle                      *
+\***************************************************************************/
+
+ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
+{
+  state->NumNcycles++;
+
+  return ARMul_ReadWord (state, address);
+}
+
+/***************************************************************************\
+*                     Load Halfword, (Non Sequential Cycle)                 *
+\***************************************************************************/
+
+ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
+{
+  ARMword temp, offset;
+
+  state->NumNcycles++;
+
+  temp = ARMul_ReadWord (state, address);
+  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;	/* bit offset into the word */
+
+  return (temp >> offset) & 0xffff;
+}
+
+/***************************************************************************\
+*                      Read Byte (but don't tell anyone!)                   *
+\***************************************************************************/
+
+ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
+{
+  ARMword temp, offset;
+
+  temp = ARMul_ReadWord (state, address);
+  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;	/* bit offset into the word */
+
+  return (temp >> offset & 0xffL);
+}
+
+/***************************************************************************\
+*                     Load Byte, (Non Sequential Cycle)                     *
+\***************************************************************************/
+
+ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
+{
+  state->NumNcycles++;
+
+  return ARMul_ReadByte (state, address);
+}
+
+/***************************************************************************\
+*                     Write Word (but don't tell anyone!)                   *
+\***************************************************************************/
+
+void
+ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
+{
+#ifdef ABORTS
+  if (address >= LOWABORT && address < HIGHABORT)
+    {
+      ARMul_DATAABORT (address);
+      return;
+    }
+  else
+    {
+      ARMul_CLEARABORT;
+    }
+#endif
+
+  PutWord (state, address, data, TRUE);
+}
+
+/***************************************************************************\
+*                       Store Word, Sequential Cycle                        *
+\***************************************************************************/
+
+void
+ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
+{
+  state->NumScycles++;
+
+  ARMul_WriteWord (state, address, data);
+}
+
+/***************************************************************************\
+*                       Store Word, Non Sequential Cycle                        *
+\***************************************************************************/
+
+void
+ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
+{
+  state->NumNcycles++;
+
+  ARMul_WriteWord (state, address, data);
+}
+
+/***************************************************************************\
+*                    Store HalfWord, (Non Sequential Cycle)                 *
+\***************************************************************************/
+
+void
+ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
+{
+  ARMword temp, offset;
+
+  state->NumNcycles++;
+
+#ifdef VALIDATE
+  if (address == TUBE)
+    {
+      if (data == 4)
+	state->Emulate = FALSE;
+      else
+	(void) putc ((char) data, stderr);	/* Write Char */
+      return;
+    }
+#endif
+
+  temp = ARMul_ReadWord (state, address);
+  offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;	/* bit offset into the word */
+
+  PutWord (state, address,
+	   (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset),
+	   TRUE);
+}
+
+/***************************************************************************\
+*                     Write Byte (but don't tell anyone!)                   *
+\***************************************************************************/
+
+void
+ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
+{
+  ARMword temp, offset;
+
+  temp = ARMul_ReadWord (state, address);
+  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;	/* bit offset into the word */
+
+  PutWord (state, address,
+	   (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
+	   TRUE);
+}
+
+/***************************************************************************\
+*                    Store Byte, (Non Sequential Cycle)                     *
+\***************************************************************************/
+
+void
+ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
+{
+  state->NumNcycles++;
+
+#ifdef VALIDATE
+  if (address == TUBE)
+    {
+      if (data == 4)
+	state->Emulate = FALSE;
+      else
+	(void) putc ((char) data, stderr);	/* Write Char */
+      return;
+    }
+#endif
+
+  ARMul_WriteByte (state, address, data);
+}
+
+/***************************************************************************\
+*                   Swap Word, (Two Non Sequential Cycles)                  *
+\***************************************************************************/
+
+ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
+{
+  ARMword temp;
+
+  state->NumNcycles++;
+
+  temp = ARMul_ReadWord (state, address);
+
+  state->NumNcycles++;
+
+  PutWord (state, address, data, TRUE);
+
+  return temp;
+}
+
+/***************************************************************************\
+*                   Swap Byte, (Two Non Sequential Cycles)                  *
+\***************************************************************************/
+
+ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
+{
+  ARMword temp;
+
+  temp = ARMul_LoadByte (state, address);
+  ARMul_StoreByte (state, address, data);
+
+  return temp;
+}
+
+/***************************************************************************\
+*                             Count I Cycles                                *
+\***************************************************************************/
+
+void
+ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
+{
+  state->NumIcycles += number;
+  ARMul_CLEARABORT;
+}
+
+/***************************************************************************\
+*                             Count C Cycles                                *
+\***************************************************************************/
+
+void
+ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
+{
+  state->NumCcycles += number;
+  ARMul_CLEARABORT;
+}
+
+
+/* Read a byte.  Do not check for alignment or access errors.  */
+
+ARMword
+ARMul_SafeReadByte (ARMul_State * state, ARMword address)
+{
+  ARMword temp, offset;
+
+  temp = GetWord (state, address, FALSE);
+  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
+
+  return (temp >> offset & 0xffL);
+}
+
+void
+ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data)
+{
+  ARMword temp, offset;
+
+  temp = GetWord (state, address, FALSE);
+  offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
+
+  PutWord (state, address,
+	   (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
+	   FALSE);
+}


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/armulmem.c
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c
===================================================================
--- branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c	                        (rev 0)
+++ branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c	2014-07-16 23:23:03 UTC (rev 3046)
@@ -0,0 +1,215 @@
+#define COG 1
+#define FOR_COG_PLUGIN 1
+
+#include "GdbARMPlugin.h"
+//disassembler
+#include <gdbconfig.h> /*  TPR - <---- this is actually a *link* to the gdb gdb-7.6/bfd/config.h because it otherwise clashes with the Squeak one also in the assorted include paths. Must be a proper way to handle this case; it must happen elsewhere */
+#include <bfd.h>
+#include <dis-asm.h>
+
+#include <stdarg.h>
+
+//emulator
+#include <armdefs.h>
+#include <armemu.h>
+
+ARMul_State*	lastCPU = NULL;
+
+/* When compiling armulator, it generally sets NEED_UI_LOOP_HOOK, which 
+	makes the main emulation step require this symbol to be set. */
+extern int (*deprecated_ui_loop_hook) (int) = NULL;
+
+// These two variables exist, in case there are library-functions which write to a stream.
+// In that case, we would write functions which print to that stream instead of stderr or similar
+#define LOGSIZE 4096
+static char	gdb_log[LOGSIZE+1];
+static int	gdblog_index = 0;
+
+ulong	minReadAddress, minWriteAddress;
+
+// what is that for?
+	   void			(*prevInterruptCheckChain)() = 0;
+
+void
+print_state(ARMul_State* state)
+{
+	printf("NextInstr: %i\ttheMemory: 0x%p\tNumInstrs: 0x%p\tPC: 0x%p\tmode: %i\tEndCondition: %i\tEmulate: %i\n", 
+		state->NextInstr, state->MemDataPtr, 
+		state->NumInstrs, state->Reg[15], 
+		state->Mode, state->EndCondition, 
+		state->Emulate);
+}
+
+void*
+newCPU()
+{
+	if(lastCPU == NULL) ARMul_EmulateInit();
+	lastCPU = ARMul_NewState();
+	ARMul_SelectProcessor (lastCPU, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
+	return lastCPU;
+}
+
+int
+resetCPU(void* cpu)
+{
+	unsigned int i, j;
+	ARMul_State* state = (ARMul_State*) cpu;
+	// test whether the supplied instance is an ARMul type?
+	
+	gdblog_index = 0;
+	
+	// reset registers in all modes
+	for (i = 0; i < 16; i++)
+	{
+		state->Reg[i] = 0;
+		for (j = 0; j < 7; j++)
+			state->RegBank[j][i] = 0;
+	}
+	for (i = 0; i < 7; i++)
+		state->Spsr[i] = 0;
+	
+	ARMul_Reset(state);
+	return 0;
+}
+
+int
+runOnCPU(void *cpu, void *memory, 
+		ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr, ARMword (*run)(ARMul_State*))
+{
+	ARMul_State* state = (ARMul_State*) cpu;
+	lastCPU = state;
+	
+	// test whether the supplied instance is an ARMul type?
+	state->MemDataPtr = (unsigned char*) memory;
+	state->MemSize = byteSize;
+	minReadAddress = minAddr;
+	minWriteAddress = minWriteMaxExecAddr;
+	
+	gdblog_index = 0;
+	
+	state->EndCondition = NoError;
+	state->NextInstr = RESUME;
+	
+	state->Reg[15] = run(state);
+	
+	// collect the PSR from their dedicated flags to have easy access from the image.
+	ARMul_SetCPSR(state, ARMul_GetCPSR(state));
+	
+	if(state->EndCondition != NoError){
+		return state->EndCondition;
+	}
+	
+	return gdblog_index == 0 ? 0 : SomethingLoggedError;
+}
+
+int
+singleStepCPUInSizeMinAddressReadWrite(void *cpu, void *memory, 
+		ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr)
+{
+	return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoInstr);
+}
+
+int
+runCPUInSizeMinAddressReadWrite(void *cpu, void *memory, 
+		ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr)
+{
+	return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoProg);
+}
+
+/*
+ * Currently a dummy for ARM Processor Alien.
+ */
+void
+flushICacheFromTo(void *cpu, ulong saddr, ulong eaddr)
+{
+#if 0
+# error not yet implemented
+#endif
+}
+
+int
+gdb_log_printf(void* stream, const char * format, ...)
+{
+	va_list arg;
+	int n;
+	va_start(arg,format);
+	
+	if(stream == NULL){
+		n = vsnprintf((char*) (&gdb_log) + gdblog_index, LOGSIZE-gdblog_index, format, arg);
+		gdblog_index = gdblog_index + n;
+	} else {
+		vfprintf(stream, format, arg);
+	}
+	return 0;
+}
+
+int
+disassembleForAtInSize(void *cpu, ulong laddr,
+			void *memory, ulong byteSize)
+{
+	gdblog_index = 0;
+	// ignore the cpu
+	// start disassembling at laddr relative to memory
+	// stop disassembling at memory+byteSize
+	
+	disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info));
+	// void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func)
+	init_disassemble_info ( dis, NULL, gdb_log_printf);
+	
+	dis->arch = bfd_arch_arm;
+	dis->mach = bfd_mach_arm_unknown;
+	
+	// sets some fields in the structure dis to architecture specific values
+	disassemble_init_for_target( dis );
+	
+	dis->buffer_vma = 0;
+	dis->buffer = memory;
+	dis->buffer_length = byteSize;
+	
+	// first print the address
+	gdb_log_printf( NULL, "%08lx: ", laddr);
+	//other possible functions are listed in opcodes/dissassemble.c
+	unsigned int size = print_insn_little_arm((bfd_vma) laddr, dis);
+	
+	free(dis);
+	gdb_log[gdblog_index+1] = 0;
+	
+	return size;
+}
+
+void
+forceStopRunning()
+{
+	lastCPU->Emulate = STOP;
+}
+
+int
+errorAcorn(void) { return 0; }
+
+char *
+getlog(long *len)
+{
+	*len = gdblog_index;
+	return gdb_log;
+}
+
+// adding custom Software Interrupts to the ARMulator
+unsigned __real_ARMul_OSHandleSWI(ARMul_State*, ARMword);
+  
+unsigned
+__wrap_ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
+{
+	switch(number)
+	  {
+		case 0x200000:
+			// This is the SWI number which is returned by our memory interface 
+			// if there is an instruction fetch for an illegal address.
+			state->Emulate = STOP;
+			state->EndCondition = InstructionPrefetchError;
+			
+			// during execution, the pc points the next fetch address, which is 8 byte after the current instruction.
+			gdb_log_printf(NULL, "Illegal Instruction fetch address (%#p).", state->Reg[15]-8);
+			return TRUE;
+	  }
+	return __real_ARMul_OSHandleSWI(state, number);
+}


Property changes on: branches/Cog/platforms/unix/plugins/GdbARMPlugin/sqGdbARMPlugin.c
___________________________________________________________________
Added: svn:executable
   + *



More information about the Vm-dev mailing list