Fix the detection of illegal memory accesses in the MSP430 simulator.
authorNick Clifton <nickc@redhat.com>
Tue, 24 Feb 2015 10:27:07 +0000 (10:27 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 24 Feb 2015 10:27:07 +0000 (10:27 +0000)
* msp430-sim.c (sim_open): Allocate memory regions matching those
declared in the libgloss/msp430 linker scripts.
Allow sim_load_file to fail.
(get_op): Test the correct address bit when checking for out of
range addresses.
Include the address in the error message when an illegal access to
the hardware multiplier is detected.
(put_op): Test the correct address bit when checking for out of
range addresses.

sim/msp430/ChangeLog
sim/msp430/msp430-sim.c

index 88cf019827094e67e02fa914a44931654bf60a92..9ec71ecb52c476177f9ce5e28d6f7273dccd2766 100644 (file)
@@ -1,3 +1,15 @@
+2015-02-24  Nick Clifton  <nickc@redhat.com>
+
+       * msp430-sim.c (sim_open): Allocate memory regions matching those
+       declared in the libgloss/msp430 linker scripts.
+       Allow sim_load_file to fail.
+       (get_op): Test the correct address bit when checking for out of
+       range addresses.
+       Include the address in the error message when an illegal access to
+       the hardware multiplier is detected.
+       (put_op): Test the correct address bit when checking for out of
+       range addresses.
+
 2014-08-19  Alan Modra  <amodra@gmail.com>
 
        * configure: Regenerate.
index abf40605f8d05393ca0424ec4f4405bea0a4a1a3..ee86339c72f9fbf3431cd7290838f1ffa073814f 100644 (file)
@@ -174,15 +174,18 @@ sim_open (SIM_OPEN_KIND kind,
   CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
   CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
 
-  /* Allocate memory if none specified by user.  */
-  if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x130, 1) == 0)
-    sim_do_commandf (sd, "memory-region 0,0x20");
+  /* Allocate memory if none specified by user.
+     Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts.  */
+  if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
+    sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite.  */
   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x200, 1) == 0)
-    sim_do_commandf (sd, "memory-region 0x200,0xffe00");
+    sim_do_commandf (sd, "memory-region 0x200,0xfd00");  /* RAM and/or ROM */
   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
-    sim_do_commandf (sd, "memory-region 0xfffe,2");
+    sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS.  */
   if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
-    sim_do_commandf (sd, "memory-region 0x10000,0x100000");
+    sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM.  */
+  if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0)
+    sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM.  */
 
   /* Check for/establish the a reference program image.  */
   if (sim_analyze_program (sd,
@@ -200,11 +203,7 @@ sim_open (SIM_OPEN_KIND kind,
                            0 /* verbose */,
                            1 /* use LMA instead of VMA */,
                            loader_write_mem);
-  if (prog_bfd == NULL)
-    {
-      sim_state_free (sd);
-      return 0;
-    }
+  /* Allow prog_bfd to be NULL - this is needed by the GDB testsuite.  */
 
   /* Establish any remaining configuration options.  */
   if (sim_config (sd) != SIM_RC_OK)
@@ -225,10 +224,13 @@ sim_open (SIM_OPEN_KIND kind,
 
   msp430_trace_init (STATE_PROG_BFD (sd));
 
-  MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
-  MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
-  if (MSP430_CPU (sd)->state.cio_buffer == -1)
-    MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
+  if (prog_bfd != NULL)
+    {
+      MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
+      MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
+      if (MSP430_CPU (sd)->state.cio_buffer == -1)
+       MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
+    }
 
   return sd;
 }
@@ -360,16 +362,25 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
       addr = op->addend;
       if (op->reg != MSR_None)
        {
-         int reg;
-         /* Index values are signed, but the sum is limited to 16
-            bits if the register < 64k, for MSP430 compatibility in
-            MSP430X chips.  */
-         if (addr & 0x8000)
-           addr |= -1 << 16;
-         reg = REG_GET (op->reg);
+         int reg = REG_GET (op->reg);
+         int sign = opc->ofs_430x ? 20 : 16;
+
+         /* Index values are signed.  */
+         if (addr & (1 << (sign - 1)))
+           addr |= -1 << sign;
+
          addr += reg;
+
+         /* For MSP430 instructions the sum is limited to 16 bits if the
+            address in the index register is less than 64k even if we are
+            running on an MSP430X CPU.  This is for MSP430 compatibility.  */
          if (reg < 0x10000 && ! opc->ofs_430x)
-           addr &= 0xffff;
+           {
+             if (addr >= 0x10000)
+               fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
+
+             addr &= 0xffff;
+           }
        }
       addr &= 0xfffff;
       switch (opc->size)
@@ -407,7 +418,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
                case UNSIGN_32:
                  rv = zero_ext (HWMULT (sd, hwmult_result), 16);
                  break;
-               case SIGN_MAC_32: 
+               case SIGN_MAC_32:
                case SIGN_32:
                  rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
                  break;
@@ -468,7 +479,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
              break;
 
            default:
-             fprintf (stderr, "unimplemented HW MULT read!\n");
+             fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
              break;
            }
        }
@@ -477,6 +488,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
        trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
                       "GET: [%#x].%d -> %#x", addr, opc->size, rv);
       break;
+
     default:
       fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
       abort ();
@@ -544,16 +556,25 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
       addr = op->addend;
       if (op->reg != MSR_None)
        {
-         int reg;
-         /* Index values are signed, but the sum is limited to 16
-            bits if the register < 64k, for MSP430 compatibility in
-            MSP430X chips.  */
-         if (addr & 0x8000)
-           addr |= -1 << 16;
-         reg = REG_GET (op->reg);
+         int reg = REG_GET (op->reg);
+         int sign = opc->ofs_430x ? 20 : 16;
+
+         /* Index values are signed.  */
+         if (addr & (1 << (sign - 1)))
+           addr |= -1 << sign;
+
          addr += reg;
-         if (reg < 0x10000)
-           addr &= 0xffff;
+
+         /* For MSP430 instructions the sum is limited to 16 bits if the
+            address in the index register is less than 64k even if we are
+            running on an MSP430X CPU.  This is for MSP430 compatibility.  */
+         if (reg < 0x10000 && ! opc->ofs_430x)
+           {
+             if (addr >= 0x10000)
+               fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
+               
+             addr &= 0xffff;
+           }
        }
       addr &= 0xfffff;
 
This page took 0.028435 seconds and 4 git commands to generate.