X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fd10v%2Finterp.c;h=5dfb100ab2613954284d6b0bdcd0f6177aea0c0d;hb=794e9ac96aca71d2cb7683383bb445c3125d9660;hp=f4c6fe1ba44ac38945488d06ea3ecf755b6d6f77;hpb=5c839c675af70a9760e714aaebfb3066ae6a3c37;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/d10v/interp.c b/sim/d10v/interp.c index f4c6fe1ba4..5dfb100ab2 100644 --- a/sim/d10v/interp.c +++ b/sim/d10v/interp.c @@ -1,5 +1,7 @@ #include #include "sysdep.h" +#include "bfd.h" +#include "callback.h" #include "remote-sim.h" #include "d10v_sim.h" @@ -10,6 +12,8 @@ enum _leftright { LEFT_FIRST, RIGHT_FIRST }; +static char *myname; +static SIM_OPEN_KIND sim_kind; int d10v_debug; host_callback *d10v_callback; unsigned long ins_type_counters[ (int)INS_MAX ]; @@ -17,6 +21,9 @@ unsigned long ins_type_counters[ (int)INS_MAX ]; uint16 OP[4]; static int init_text_p = 0; +/* non-zero if we opened prog_bfd */ +static int prog_bfd_was_opened_p; +bfd *prog_bfd; asection *text; bfd_vma text_start; bfd_vma text_end; @@ -28,23 +35,9 @@ static void do_long PARAMS ((uint32 ins)); static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright)); static void do_parallel PARAMS ((uint16 ins1, uint16 ins2)); static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value)); -extern void sim_size PARAMS ((int power)); static void init_system PARAMS ((void)); -extern int sim_write PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size)); -extern void sim_open PARAMS ((char *args)); -extern void sim_close PARAMS ((int quitting)); extern void sim_set_profile PARAMS ((int n)); extern void sim_set_profile_size PARAMS ((int n)); -extern void sim_resume PARAMS ((int step, int siggnal)); -extern void sim_info PARAMS ((int verbose)); -extern void sim_create_inferior PARAMS ((SIM_ADDR start_address, char **argv, char **env)); -extern void sim_kill PARAMS ((void)); -extern void sim_set_callbacks PARAMS ((host_callback *p)); -extern void sim_stop_reason PARAMS ((enum sim_stop *reason, int *sigrc)); -extern void sim_fetch_register PARAMS ((int rn, unsigned char *memory)); -extern void sim_store_register PARAMS ((int rn, unsigned char *memory)); -extern int sim_read PARAMS ((SIM_ADDR addr, unsigned char *buffer, int size)); -extern void sim_do_command PARAMS ((char *cmd)); #ifndef INLINE #if defined(__GNUC__) && defined(__OPTIMIZE__) @@ -60,6 +53,7 @@ struct hash_entry struct hash_entry *next; long opcode; long mask; + int size; struct simops *ops; }; @@ -88,7 +82,7 @@ lookup_hash (ins, size) else h = &hash_table[(ins & 0x7E00) >> 9]; - while ((ins & h->mask) != h->opcode) + while ((ins & h->mask) != h->opcode || h->size != size) { if (h->next == NULL) { @@ -122,12 +116,12 @@ decode_pc () if (!init_text_p) { init_text_p = 1; - for (s = exec_bfd->sections; s; s = s->next) - if (strcmp (bfd_get_section_name (exec_bfd, s), ".text") == 0) + for (s = prog_bfd->sections; s; s = s->next) + if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0) { text = s; - text_start = bfd_get_section_vma (exec_bfd, s); - text_end = text_start + bfd_section_size (exec_bfd, s); + text_start = bfd_get_section_vma (prog_bfd, s); + text_end = text_start + bfd_section_size (prog_bfd, s); break; } } @@ -368,29 +362,30 @@ xfer_mem (addr, buffer, size, write) /* to access data, we use the following mapping */ /* 0x01000000 - 0x0103ffff : instruction memory */ /* 0x02000000 - 0x0200ffff : data memory */ - /* 0x03000000 - 0x03ffffff : unified memory */ + /* 0x00000000 - 0x00ffffff : unified memory */ - if ( (addr & 0x03000000) == 0x03000000) + if ( (addr & 0x03000000) == 0) { /* UNIFIED MEMORY */ int segment; - addr &= ~0x03000000; segment = addr >> UMEM_SIZE; addr &= 0x1ffff; if (!State.umem[segment]) - State.umem[segment] = (uint8 *)calloc(1,1<printf_filtered) (d10v_callback,"Allocating %s bytes unified memory to region %d\n", + add_commas (buffer, sizeof (buffer), (1UL<printf_filtered) (d10v_callback, "Memory allocation failed.\n"); exit(1); } -#ifdef DEBUG - (*d10v_callback->printf_filtered) (d10v_callback,"Allocated %s bytes unified memory to region %d\n", - add_commas (buffer, sizeof (buffer), (1UL<printf_filtered) (d10v_callback, "ERROR: address 0x%x is not in valid range\n",addr); (*d10v_callback->printf_filtered) (d10v_callback, "Instruction addresses start at 0x01000000\n"); (*d10v_callback->printf_filtered) (d10v_callback, "Data addresses start at 0x02000000\n"); - (*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x03000000\n"); + (*d10v_callback->printf_filtered) (d10v_callback, "Unified addresses start at 0x00000000\n"); exit(1); } else @@ -438,7 +433,8 @@ xfer_mem (addr, buffer, size, write) int -sim_write (addr, buffer, size) +sim_write (sd, addr, buffer, size) + SIM_DESC sd; SIM_ADDR addr; unsigned char *buffer; int size; @@ -447,7 +443,8 @@ sim_write (addr, buffer, size) } int -sim_read (addr, buffer, size) +sim_read (sd, addr, buffer, size) + SIM_DESC sd; SIM_ADDR addr; unsigned char *buffer; int size; @@ -456,22 +453,30 @@ sim_read (addr, buffer, size) } -void -sim_open (args) - char *args; +SIM_DESC +sim_open (kind, callback, abfd, argv) + SIM_OPEN_KIND kind; + host_callback *callback; + struct _bfd *abfd; + char **argv; { struct simops *s; struct hash_entry *h; static int init_p = 0; + char **p; + + sim_kind = kind; + d10v_callback = callback; + myname = argv[0]; - if (args != NULL) + for (p = argv + 1; *p; ++p) { #ifdef DEBUG - if (strcmp (args, "-t") == 0) + if (strcmp (*p, "-t") == 0) d10v_debug = DEBUG; else #endif - (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",args); + (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p); } /* put all the opcodes in the hash table */ @@ -487,22 +492,31 @@ sim_open (args) if (h->ops) { - h->next = calloc(1,sizeof(struct hash_entry)); + h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry)); + if (!h->next) + perror ("malloc failure"); + h = h->next; } h->ops = s; h->mask = s->mask; h->opcode = s->opcode; + h->size = s->is_long; } } + + /* Fudge our descriptor. */ + return (SIM_DESC) 1; } void -sim_close (quitting) +sim_close (sd, quitting) + SIM_DESC sd; int quitting; { - /* nothing to do */ + if (prog_bfd != NULL && prog_bfd_was_opened_p) + bfd_close (prog_bfd); } void @@ -531,8 +545,12 @@ dmem_addr( addr ) if (addr > 0xbfff) { if ( (addr & 0xfff0) != 0xff00) - (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n", - (long)addr, (long)decode_pc ()); + { + (*d10v_callback->printf_filtered) (d10v_callback, "Data address 0x%lx is in I/O space, pc = 0x%lx.\n", + (long)addr, (long)decode_pc ()); + State.exception = SIGBUS; + } + return State.dmem + addr; } @@ -546,14 +564,14 @@ dmem_addr( addr ) /* unified memory */ /* this is ugly because we allocate unified memory in 128K segments and */ /* dmap addresses 16k segments */ - seg = (DMAP & 0x3ff) >> 2; + seg = (DMAP & 0x3ff) >> 3; if (State.umem[seg] == NULL) { (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n", seg, (long)decode_pc ()); - exit(1); + State.exception = SIGBUS; } - return State.umem[seg] + (DMAP & 3) * 0x4000; + return State.umem[seg] + (DMAP & 7) * 0x4000; } return State.dmem + addr; @@ -578,7 +596,7 @@ pc_addr() { (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unified memory region %d unmapped, pc = 0x%lx\n", imap & 0xff, (long)PC); - State.exception = SIGILL; + State.exception = SIGBUS; return 0; } @@ -586,20 +604,42 @@ pc_addr() } +static int stop_simulator; + +static void +sim_ctrl_c() +{ + stop_simulator = 1; +} + + +int +sim_stop (sd) + SIM_DESC sd; +{ + stop_simulator = 1; + return 1; +} + + +/* Run (or resume) the program. */ void -sim_resume (step, siggnal) +sim_resume (sd, step, siggnal) + SIM_DESC sd; int step, siggnal; { + void (*prev) (); uint32 inst; - reg_t oldpc = 0; /* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */ - State.exception = 0; + prev = signal(SIGINT, sim_ctrl_c); + stop_simulator = step; + do { inst = get_longword( pc_addr() ); - oldpc = PC; + State.pc_changed = 0; ins_type_counters[ (int)INS_CYCLES ]++; switch (inst & 0xC0000000) { @@ -628,30 +668,31 @@ sim_resume (step, siggnal) else PC = RPT_S; } - - /* FIXME */ - if (PC == oldpc) + else if (!State.pc_changed) PC++; - } - while ( !State.exception && !step); + while ( !State.exception && !stop_simulator); if (step && !State.exception) State.exception = SIGTRAP; + + signal(SIGINT, prev); } int -sim_trace () +sim_trace (sd) + SIM_DESC sd; { #ifdef DEBUG d10v_debug = DEBUG; #endif - sim_resume (0, 0); + sim_resume (sd, 0, 0); return 1; } void -sim_info (verbose) +sim_info (sd, verbose) + SIM_DESC sd; int verbose; { char buf1[40]; @@ -754,21 +795,27 @@ sim_info (verbose) size, add_commas (buf1, sizeof (buf1), total)); } -void -sim_create_inferior (start_address, argv, env) - SIM_ADDR start_address; +SIM_RC +sim_create_inferior (sd, abfd, argv, env) + SIM_DESC sd; + struct _bfd *abfd; char **argv; char **env; { -#ifdef DEBUG - if (d10v_debug) - (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%x\n", start_address); -#endif + bfd_vma start_address; /* reset all state information */ memset (&State.regs, 0, (int)&State.imem - (int)&State.regs[0]); /* set PC */ + if (abfd != NULL) + start_address = bfd_get_start_address (prog_bfd); + else + start_address = 0xffc0 << 2; +#ifdef DEBUG + if (d10v_debug) + (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address); +#endif PC = start_address >> 2; /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board */ @@ -777,25 +824,21 @@ sim_create_inferior (start_address, argv, env) SET_IMAP0(0x1000); SET_IMAP1(0x1000); SET_DMAP(0); -} - -void -sim_kill () -{ - /* nothing to do */ + return SIM_RC_OK; } + void -sim_set_callbacks(p) +sim_set_callbacks (p) host_callback *p; { -/* printf ("sim_set_callbacks\n"); */ d10v_callback = p; } void -sim_stop_reason (reason, sigrc) +sim_stop_reason (sd, reason, sigrc) + SIM_DESC sd; enum sim_stop *reason; int *sigrc; { @@ -821,7 +864,8 @@ sim_stop_reason (reason, sigrc) } void -sim_fetch_register (rn, memory) +sim_fetch_register (sd, rn, memory) + SIM_DESC sd; int rn; unsigned char *memory; { @@ -841,7 +885,8 @@ sim_fetch_register (rn, memory) } void -sim_store_register (rn, memory) +sim_store_register (sd, rn, memory) + SIM_DESC sd; int rn; unsigned char *memory; { @@ -862,17 +907,28 @@ sim_store_register (rn, memory) void -sim_do_command (cmd) +sim_do_command (sd, cmd) + SIM_DESC sd; char *cmd; { (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd); } -int -sim_load (prog, from_tty) +SIM_RC +sim_load (sd, prog, abfd, from_tty) + SIM_DESC sd; char *prog; + bfd *abfd; int from_tty; { - /* Return nonzero so GDB will handle it. */ - return 1; + extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ + + if (prog_bfd != NULL && prog_bfd_was_opened_p) + bfd_close (prog_bfd); + prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd, + sim_kind == SIM_OPEN_DEBUG); + if (prog_bfd == NULL) + return SIM_RC_FAIL; + prog_bfd_was_opened_p = abfd == NULL; + return SIM_RC_OK; }