Line 48... |
Line 48... |
#include "spr-defs.h"
|
#include "spr-defs.h"
|
#include "execute.h"
|
#include "execute.h"
|
#include "debug-unit.h"
|
#include "debug-unit.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "toplevel-support.h"
|
#include "toplevel-support.h"
|
|
#include "dcache-model.h"
|
|
#include "icache-model.h"
|
|
|
|
|
/* Define to log each packet */
|
/* Define to log each packet */
|
/* #define RSP_TRACE 1 */
|
/* #define RSP_TRACE 1 */
|
|
|
Line 1614... |
Line 1616... |
else
|
else
|
{
|
{
|
unsigned char nyb1 = hex (symdat[off * 2]);
|
unsigned char nyb1 = hex (symdat[off * 2]);
|
unsigned char nyb2 = hex (symdat[off * 2 + 1]);
|
unsigned char nyb2 = hex (symdat[off * 2 + 1]);
|
|
|
// circumvent the read-only check usually done for mem accesses
|
/* circumvent the read-only check usually done for mem accesses
|
// data is in host order, because that's what set_direct32 needs
|
data is in host order, because that's what set_direct32 needs
|
|
|
|
We make sure both data and instruction cache are invalidated
|
|
first, so that the write goes through the cache. */
|
|
dc_inv (addr + off);
|
|
ic_inv (addr + off);
|
set_program8 (addr + off, (nyb1 << 4) | nyb2);
|
set_program8 (addr + off, (nyb1 << 4) | nyb2);
|
}
|
}
|
}
|
}
|
|
|
put_str_packet ("OK");
|
put_str_packet ("OK");
|
Line 2198... |
Line 2205... |
put_str_packet ("E01");
|
put_str_packet ("E01");
|
return;
|
return;
|
}
|
}
|
else
|
else
|
{
|
{
|
// Circumvent the read-only check usually done for mem accesses
|
/* Circumvent the read-only check usually done for mem accesses
|
|
|
|
We make sure both data and instruction cache are invalidated
|
|
first, so that the write goes through the cache. */
|
|
dc_inv (addr + off);
|
|
ic_inv (addr + off);
|
set_program8 (addr + off, bindat[off]);
|
set_program8 (addr + off, bindat[off]);
|
}
|
}
|
}
|
}
|
|
|
put_str_packet ("OK");
|
put_str_packet ("OK");
|
Line 2223... |
Line 2235... |
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
static void
|
static void
|
rsp_remove_matchpoint (struct rsp_buf *buf)
|
rsp_remove_matchpoint (struct rsp_buf *buf)
|
{
|
{
|
enum mp_type type; /* What sort of matchpoint */
|
enum mp_type type; /* What sort of matchpoint */
|
|
int type_for_scanf; /* To avoid old GCC limitations */
|
unsigned long int addr; /* Address specified */
|
unsigned long int addr; /* Address specified */
|
int len; /* Matchpoint length (not used) */
|
int len; /* Matchpoint length (not used) */
|
struct mp_entry *mpe; /* Info about the replaced instr */
|
struct mp_entry *mpe; /* Info about the replaced instr */
|
|
|
/* Break out the instruction */
|
/* Break out the instruction. We have to use an intermediary for the type,
|
if (3 != sscanf (buf->data, "z%1d,%lx,%1d", (int *)&type, &addr, &len))
|
since older GCCs do not like taking the address of an enum
|
|
(dereferencing type-punned pointer). */
|
|
if (3 != sscanf (buf->data, "z%1d,%lx,%1d", &type_for_scanf, &addr, &len))
|
{
|
{
|
fprintf (stderr, "Warning: RSP matchpoint deletion request not "
|
fprintf (stderr, "Warning: RSP matchpoint deletion request not "
|
"recognized: ignored\n");
|
"recognized: ignored\n");
|
put_str_packet ("E01");
|
put_str_packet ("E01");
|
return;
|
return;
|
}
|
}
|
|
|
|
type = type_for_scanf;
|
|
|
/* Sanity check that the length is 4 */
|
/* Sanity check that the length is 4 */
|
if (4 != len)
|
if (4 != len)
|
{
|
{
|
fprintf (stderr, "Warning: RSP matchpoint deletion length %d not "
|
fprintf (stderr, "Warning: RSP matchpoint deletion length %d not "
|
"valid: 4 assumed\n", len);
|
"valid: 4 assumed\n", len);
|
Line 2252... |
Line 2269... |
case BP_MEMORY:
|
case BP_MEMORY:
|
/* Memory breakpoint - replace the original instruction. */
|
/* Memory breakpoint - replace the original instruction. */
|
mpe = mp_hash_delete (type, addr);
|
mpe = mp_hash_delete (type, addr);
|
|
|
/* If the BP hasn't yet been deleted, put the original instruction
|
/* If the BP hasn't yet been deleted, put the original instruction
|
back. Don't forget to free the hash table entry afterwards. */
|
back. Don't forget to free the hash table entry afterwards.
|
|
|
|
We make sure both the instruction cache is invalidated first, so that
|
|
the write goes through the cache. */
|
if (NULL != mpe)
|
if (NULL != mpe)
|
{
|
{
|
|
ic_inv (addr);
|
set_program32 (addr, mpe->instr);
|
set_program32 (addr, mpe->instr);
|
free (mpe);
|
free (mpe);
|
}
|
}
|
|
|
put_str_packet ("OK");
|
put_str_packet ("OK");
|
Line 2304... |
Line 2325... |
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
static void
|
static void
|
rsp_insert_matchpoint (struct rsp_buf *buf)
|
rsp_insert_matchpoint (struct rsp_buf *buf)
|
{
|
{
|
enum mp_type type; /* What sort of matchpoint */
|
enum mp_type type; /* What sort of matchpoint */
|
|
int type_for_scanf; /* To avoid old GCC limitations */
|
unsigned long int addr; /* Address specified */
|
unsigned long int addr; /* Address specified */
|
int len; /* Matchpoint length (not used) */
|
int len; /* Matchpoint length (not used) */
|
|
|
/* Break out the instruction */
|
/* Break out the instruction. We have to use an intermediary for the type,
|
if (3 != sscanf (buf->data, "Z%1d,%lx,%1d", (int *)&type, &addr, &len))
|
since older GCCs do not like taking the address of an enum
|
|
(dereferencing type-punned pointer). */
|
|
if (3 != sscanf (buf->data, "Z%1d,%lx,%1d", &type_for_scanf, &addr, &len))
|
{
|
{
|
fprintf (stderr, "Warning: RSP matchpoint insertion request not "
|
fprintf (stderr, "Warning: RSP matchpoint insertion request not "
|
"recognized: ignored\n");
|
"recognized: ignored\n");
|
put_str_packet ("E01");
|
put_str_packet ("E01");
|
return;
|
return;
|
}
|
}
|
|
|
|
type = type_for_scanf;
|
|
|
/* Sanity check that the length is 4 */
|
/* Sanity check that the length is 4 */
|
if (4 != len)
|
if (4 != len)
|
{
|
{
|
fprintf (stderr, "Warning: RSP matchpoint insertion length %d not "
|
fprintf (stderr, "Warning: RSP matchpoint insertion length %d not "
|
"valid: 4 assumed\n", len);
|
"valid: 4 assumed\n", len);
|
Line 2328... |
Line 2354... |
|
|
/* Sort out the type of matchpoint */
|
/* Sort out the type of matchpoint */
|
switch (type)
|
switch (type)
|
{
|
{
|
case BP_MEMORY:
|
case BP_MEMORY:
|
/* Memory breakpoint - substitute a TRAP instruction */
|
/* Memory breakpoint - substitute a TRAP instruction
|
|
|
|
We make sure th instruction cache is invalidated first, so that the
|
|
read and write always work correctly. */
|
mp_hash_add (type, addr, eval_direct32 (addr, 0, 0));
|
mp_hash_add (type, addr, eval_direct32 (addr, 0, 0));
|
|
ic_inv (addr);
|
set_program32 (addr, OR1K_TRAP_INSTR);
|
set_program32 (addr, OR1K_TRAP_INSTR);
|
put_str_packet ("OK");
|
put_str_packet ("OK");
|
|
|
return;
|
return;
|
|
|