aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote-z8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/remote-z8k.c')
-rw-r--r--gdb/remote-z8k.c445
1 files changed, 445 insertions, 0 deletions
diff --git a/gdb/remote-z8k.c b/gdb/remote-z8k.c
new file mode 100644
index 0000000..48d6a71
--- /dev/null
+++ b/gdb/remote-z8k.c
@@ -0,0 +1,445 @@
+/* Remote debugging interface for Zilog Z8000 simulator
+ Copyright 1992 Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by Steve Chamberlain
+ (sac@cygnus.com).
+
+This file is part of GDB.
+
+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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "wait.h"
+#include "value.h"
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+#include "terminal.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "../z8ksim/sim.h"
+
+/* External data declarations */
+extern int stop_soon_quietly; /* for wait_for_inferior */
+
+/* Forward data declarations */
+extern struct target_ops sim_ops; /* Forward declaration */
+
+/* Forward function declarations */
+static void sim_fetch_registers ();
+static void sim_close ();
+
+void sim_store_register();
+
+void sim_set_oc();
+
+
+int
+sim_write_inferior_memory (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ unsigned char *myaddr;
+ int len;
+{
+return sim_write(memaddr, myaddr, len);
+}
+
+static int
+store_register(regno)
+int regno;
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < 16; regno++)
+ store_register(regno);
+ }
+ else
+ {
+ sim_store_register(regno,read_register(regno));
+ }
+ return 0;
+}
+
+
+
+void
+sim_kill(arg,from_tty)
+char *arg;
+int from_tty;
+{
+
+}
+
+
+
+/*
+ * Download a file specified in 'args', to the sim.
+ */
+static void
+sim_load(args,fromtty)
+char *args;
+int fromtty;
+{
+ bfd *abfd;
+ asection *s;
+
+ inferior_pid = 0;
+ abfd = bfd_openr(args,"coff-z8k");
+
+ if (!abfd)
+ {
+ printf_filtered("Unable to open file %s\n", args);
+ return;
+ }
+
+ if (bfd_check_format(abfd, bfd_object) ==0)
+ {
+ printf_filtered("File is not an object file\n");
+ return ;
+ }
+
+ s = abfd->sections;
+ while (s != (asection *)NULL)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ int i;
+ int delta = 4096;
+ char *buffer = xmalloc(delta);
+ printf_filtered("%s\t: 0x%4x .. 0x%4x ",
+ s->name, s->vma, s->vma + s->_raw_size);
+ for (i = 0; i < s->_raw_size; i+= delta)
+ {
+ int sub_delta = delta;
+ if (sub_delta > s->_raw_size - i)
+ sub_delta = s->_raw_size - i ;
+
+ bfd_get_section_contents(abfd, s, buffer, i, sub_delta);
+ sim_write_inferior_memory(s->vma + i, buffer, sub_delta);
+ printf_filtered("*");
+ fflush(stdout);
+ }
+ printf_filtered( "\n");
+ free(buffer);
+ }
+ s = s->next;
+ }
+
+ sim_set_pc(abfd->start_address);
+}
+
+/* This is called not only when we first attach, but also when the
+ user types "run" after having attached. */
+void
+sim_create_inferior (execfile, args, env)
+ char *execfile;
+ char *args;
+ char **env;
+{
+ int entry_pt;
+ char buffer[100];
+
+ if (args && *args)
+ error ("Can't pass arguments to remote sim process.");
+
+ if (execfile == 0 || exec_bfd == 0)
+ error ("No exec file specified");
+
+ entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+
+
+ sim_kill(NULL,NULL);
+ sim_clear_breakpoints();
+ init_wait_for_inferior ();
+
+
+
+ insert_breakpoints (); /* Needed to get correct instruction in cache */
+ proceed(entry_pt, -1, 0);
+}
+
+
+
+static void
+sim_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ if(name == 0)
+ {
+ name = "";
+ }
+
+ /* Clear any break points */
+ sim_clear_breakpoints();
+
+ push_target (&sim_ops);
+ target_fetch_registers(-1);
+
+ printf_filtered("Connected to the Z8000 Simulator.\n");
+}
+
+/* Close out all files and local state before this target loses control. */
+
+static void
+sim_close (quitting)
+ int quitting;
+{
+
+
+ /* Clear any break points */
+ sim_clear_breakpoints();
+
+ /* Put this port back into REMOTE mode */
+ sleep(1); /* Let any output make it all the way back */
+}
+
+/* Terminate the open connection to the remote debugger.
+ Use this when you want to detach and do something else
+ with your gdb. */
+int
+sim_detach (args,from_tty)
+ char *args;
+ int from_tty;
+{
+ sim_clear_breakpoints();
+
+ pop_target(); /* calls sim_close to do the real work */
+ if (from_tty)
+ printf_filtered ("Ending remote %s debugging\n", target_shortname);
+ return 0;
+}
+
+/* Tell the remote machine to resume. */
+
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would. */
+
+int
+sim_wait (status)
+ WAITTYPE *status;
+{
+
+*status = sim_stop_signal();
+return 0;
+}
+
+/* Return the name of register number REGNO
+ in the form input and output by sim.
+
+ Returns a pointer to a static buffer containing the answer. */
+static char *
+get_reg_name (regno)
+ int regno;
+{
+ static char *rn[NUM_REGS]= REGISTER_NAMES;
+ return rn[regno];
+}
+
+
+
+
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+void
+sim_prepare_to_store ()
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static CORE_ADDR
+translate_addr(addr)
+CORE_ADDR addr;
+{
+
+ return(addr);
+
+}
+
+/* Read a word from remote address ADDR and return it.
+ * This goes through the data cache.
+ */
+int
+sim_fetch_word (addr)
+ CORE_ADDR addr;
+{
+/* return dcache_fetch (addr);*/
+}
+
+
+static void
+fetch_register(regno)
+int regno;
+{
+ if (regno == -1)
+ {
+ for (regno = 0; regno < 16; regno++)
+ fetch_register(regno);
+ }
+ else {
+ char buf[MAX_REGISTER_RAW_SIZE];
+ sim_fetch_register(regno, buf);
+ supply_register(regno, buf);
+ }
+}
+
+/* Write a word WORD into remote address ADDR.
+ This goes through the data cache. */
+
+void
+sim_store_word (addr, word)
+ CORE_ADDR addr;
+ int word;
+{
+/* dcache_poke (addr, word);*/
+}
+
+int
+sim_xfer_inferior_memory(memaddr, myaddr, len, write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int write;
+ struct target_ops *target; /* ignored */
+{
+ if (write)
+ {
+ sim_write(memaddr, myaddr, len);
+
+ }
+ else
+ {
+ sim_read(memaddr, myaddr, len);
+ }
+ return len;
+}
+
+void
+sim_files_info ()
+{
+char *file = "nothing";
+if (exec_bfd)
+ file = bfd_get_filename(exec_bfd);
+
+if (exec_bfd)
+#ifdef __GO32__
+ printf_filtered("\tAttached to DOS asynctsr and running program %s\n",file);
+#else
+ printf_filtered("\tAttached to %s at %d baud and running program %s\n",file);
+#endif
+ printf_filtered("\ton an H8/300 processor.\n");
+}
+
+/* This routine is run as a hook, just before the main command loop is
+ entered. If gdb is configured for the H8, but has not had its
+ target specified yet, this will loop prompting the user to do so.
+*/
+
+void
+sim_before_main_loop ()
+{
+ char ttyname[100];
+ char *p, *p2;
+ extern FILE *instream;
+ extern jmp_buf to_top_level;
+
+ push_target (&sim_ops);
+}
+
+
+#define MAX_BREAKS 16
+static int num_brkpts=0;
+static int
+sim_insert_breakpoint(addr, save)
+CORE_ADDR addr;
+char *save; /* Throw away, let sim save instructions */
+{
+ abort();
+}
+static int
+sim_remove_breakpoint(addr, save)
+CORE_ADDR addr;
+char *save; /* Throw away, let sim save instructions */
+{
+ abort();
+}
+
+/* Clear the sims notion of what the break points are */
+static int
+sim_mourn()
+{
+ sim_clear_breakpoints();
+ generic_mourn_inferior ();
+ return 0;
+}
+
+static int rem_resume(a,b)
+{
+ sim_resume(a,b);
+ return 0;
+}
+
+/* Define the target subroutine names */
+
+struct target_ops sim_ops =
+{
+ "sim", "Remote SIM monitor",
+ "Use the Z8000 simulator",
+ sim_open, sim_close,
+ 0, sim_detach, rem_resume, sim_wait, /* attach */
+ fetch_register, store_register,
+ sim_prepare_to_store,
+ sim_xfer_inferior_memory,
+ sim_files_info,
+ 0, 0, /* Breakpoints */
+ 0, 0, 0, 0, 0, /* Terminal handling */
+ sim_kill, /* FIXME, kill */
+ sim_load,
+ 0, /* lookup_symbol */
+ sim_create_inferior, /* create_inferior */
+ sim_mourn, /* mourn_inferior FIXME */
+ 0, /* can_run */
+ 0, /* notice_signals */
+ process_stratum, 0, /* next */
+ 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
+ 0,0, /* Section pointers */
+ OPS_MAGIC, /* Always the last thing */
+};
+
+
+
+
+
+
+/***********************************************************************/
+
+void
+_initialize_remote_sim ()
+{
+ extern int sim_z8001_mode;
+ sim_z8001_mode = z8001_mode;
+ add_target (&sim_ops);
+}
+
+