Line 55... |
Line 55... |
#include "except.h"
|
#include "except.h"
|
#include "opcode/or32.h"
|
#include "opcode/or32.h"
|
#include "spr-defs.h"
|
#include "spr-defs.h"
|
#include "execute.h"
|
#include "execute.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "debug.h"
|
|
#include "toplevel-support.h"
|
#include "toplevel-support.h"
|
|
#include "rsp-server.h"
|
|
|
|
|
DECLARE_DEBUG_CHANNEL (jtag);
|
|
|
|
/*! The fields for the RISCOP register in the development interface scan chain
|
/*! The fields for the RISCOP register in the development interface scan chain
|
(JTAG_CHAIN_DEVELOPMENT). */
|
(JTAG_CHAIN_DEVELOPMENT). */
|
#define RISCOP_STALL 0x00000001 /*!< Stall processor */
|
#define RISCOP_STALL 0x00000001 /*!< Stall processor */
|
#define RISCOP_RESET 0x00000002 /*!< Reset processor (clears stall) */
|
#define RISCOP_RESET 0x00000002 /*!< Reset processor (clears stall) */
|
|
|
Line 665... |
Line 663... |
debug_get_register (oraddr_t address,
|
debug_get_register (oraddr_t address,
|
uorreg_t *data)
|
uorreg_t *data)
|
{
|
{
|
int err = ERR_NONE;
|
int err = ERR_NONE;
|
|
|
TRACE_ (jtag) ("Debug get register %x\n", address);
|
|
|
|
switch (current_scan_chain)
|
switch (current_scan_chain)
|
{
|
{
|
case JTAG_CHAIN_DEBUG_UNIT:
|
case JTAG_CHAIN_DEBUG_UNIT:
|
*data = mfspr (address);
|
*data = mfspr (address);
|
TRACE_ (jtag) ("READ spr: %s\n", dump_spr (address, *data));
|
|
/* printf ("=== R SPR 0x%04x = 0x%08x\n", address, *data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
case JTAG_CHAIN_TRACE:
|
case JTAG_CHAIN_TRACE:
|
err = JTAG_PROXY_INVALID_CHAIN; /* Not yet implemented */
|
err = JTAG_PROXY_INVALID_CHAIN; /* Not yet implemented */
|
break;
|
break;
|
|
|
case JTAG_CHAIN_DEVELOPMENT:
|
case JTAG_CHAIN_DEVELOPMENT:
|
err = get_devint_reg (address, (unsigned long *)data);
|
err = get_devint_reg (address, (unsigned long *)data);
|
/* printf ("=== R DEV 0x%1x = 0x%08x\n", address, *data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
case JTAG_CHAIN_WISHBONE:
|
case JTAG_CHAIN_WISHBONE:
|
err = debug_get_mem (address, data);
|
err = debug_get_mem (address, data);
|
/* printf ("=== R WB 0x%08x = 0x%08x\n", address, *data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
default:
|
default:
|
err = JTAG_PROXY_INVALID_CHAIN;
|
err = JTAG_PROXY_INVALID_CHAIN;
|
}
|
}
|
|
|
TRACE_ (jtag) ("!get reg %" PRIxREG "\n", *data);
|
|
|
|
return err;
|
return err;
|
|
|
} /* debug_get_register () */
|
} /* debug_get_register () */
|
|
|
|
|
Line 719... |
Line 706... |
debug_set_register (oraddr_t address,
|
debug_set_register (oraddr_t address,
|
uorreg_t data)
|
uorreg_t data)
|
{
|
{
|
int err = ERR_NONE;
|
int err = ERR_NONE;
|
|
|
TRACE_ (jtag) ("Debug set register %" PRIxADDR " <- %" PRIxREG "\n",
|
|
address, data);
|
|
|
|
switch (current_scan_chain)
|
switch (current_scan_chain)
|
{
|
{
|
case JTAG_CHAIN_DEBUG_UNIT:
|
case JTAG_CHAIN_DEBUG_UNIT:
|
TRACE_ (jtag) ("WRITE spr: %s\n", dump_spr (address, data));
|
|
mtspr (address, data);
|
mtspr (address, data);
|
/* printf ("=== W SPR 0x%04x = 0x%08x\n", address, data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
case JTAG_CHAIN_TRACE:
|
case JTAG_CHAIN_TRACE:
|
err = JTAG_PROXY_ACCESS_EXCEPTION; /* Not yet implemented */
|
err = JTAG_PROXY_ACCESS_EXCEPTION; /* Not yet implemented */
|
break;
|
break;
|
|
|
case JTAG_CHAIN_DEVELOPMENT:
|
case JTAG_CHAIN_DEVELOPMENT:
|
err = set_devint_reg (address, data);
|
err = set_devint_reg (address, data);
|
/* printf ("=== W DEV 0x%1x = 0x%08x\n", address, data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
case JTAG_CHAIN_WISHBONE:
|
case JTAG_CHAIN_WISHBONE:
|
err = debug_set_mem (address, data);
|
err = debug_set_mem (address, data);
|
/* printf ("=== W WB 0x%08x = 0x%08x\n", address, data); */
|
|
/* fflush (stdout); */
|
|
break;
|
break;
|
|
|
default:
|
default:
|
err = JTAG_PROXY_INVALID_CHAIN;
|
err = JTAG_PROXY_INVALID_CHAIN;
|
}
|
}
|
|
|
TRACE_ (jtag) ("!set reg\n");
|
|
|
|
return err;
|
return err;
|
|
|
} /* debug_set_register () */
|
} /* debug_set_register () */
|
|
|
|
|
Line 770... |
Line 745... |
@return An error code (including ERR_NONE) if there is no error */
|
@return An error code (including ERR_NONE) if there is no error */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
int
|
int
|
debug_set_chain (enum debug_scan_chain_ids chain)
|
debug_set_chain (enum debug_scan_chain_ids chain)
|
{
|
{
|
TRACE_ (jtag) ("Debug set chain %x\n", chain);
|
|
switch (chain)
|
switch (chain)
|
{
|
{
|
case JTAG_CHAIN_DEBUG_UNIT:
|
case JTAG_CHAIN_DEBUG_UNIT:
|
case JTAG_CHAIN_DEVELOPMENT:
|
case JTAG_CHAIN_DEVELOPMENT:
|
case JTAG_CHAIN_WISHBONE:
|
case JTAG_CHAIN_WISHBONE:
|
Line 816... |
Line 790... |
else
|
else
|
{
|
{
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
}
|
}
|
|
|
TRACE_ (jtag) ("get_devint_reg %08x = %08lx\n", address, *data);
|
|
|
|
return err;
|
return err;
|
|
|
} /* get_devint_reg () */
|
} /* get_devint_reg () */
|
|
|
|
|
Line 864... |
Line 836... |
else
|
else
|
{
|
{
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
}
|
}
|
|
|
TRACE_ (jtag) ("set_devint_reg %08x = %08lx\n", address, data);
|
|
|
|
return err;
|
return err;
|
|
|
} /* set_devint_reg() */
|
} /* set_devint_reg() */
|
|
|
|
|
Line 894... |
Line 864... |
else
|
else
|
{
|
{
|
*data = eval_direct32 (address, 0, 0);
|
*data = eval_direct32 (address, 0, 0);
|
}
|
}
|
|
|
TRACE_ (jtag) ("MEMREAD (%" PRIxADDR ") = %" PRIxADDR "\n", address,
|
|
*data);
|
|
return err;
|
return err;
|
|
|
} /* debug_get_mem () */
|
} /* debug_get_mem () */
|
|
|
|
|
Line 915... |
Line 883... |
debug_set_mem (oraddr_t address,
|
debug_set_mem (oraddr_t address,
|
uint32_t data)
|
uint32_t data)
|
{
|
{
|
int err = ERR_NONE;
|
int err = ERR_NONE;
|
|
|
TRACE_ (jtag) ("MEMWRITE (%" PRIxADDR ") = %" PRIx32 "\n", address, data);
|
|
|
|
if (!verify_memoryarea (address))
|
if (!verify_memoryarea (address))
|
{
|
{
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
err = JTAG_PROXY_INVALID_ADDRESS;
|
}
|
}
|
else
|
else
|
Line 968... |
Line 934... |
}
|
}
|
|
|
cpu_state.sprs[SPR_DRR] |= result;
|
cpu_state.sprs[SPR_DRR] |= result;
|
set_stall_state (result != 0);
|
set_stall_state (result != 0);
|
|
|
|
/* Notify RSP if enabled. TODO: Should we actually notify ALL exceptions,
|
|
not just those maked in the DSR? */
|
|
|
|
if (config.debug.rsp_enabled && (0 != result))
|
|
{
|
|
rsp_exception (except);
|
|
}
|
|
|
return (result != 0);
|
return (result != 0);
|
|
|
} /* debug_ignore_exception () */
|
} /* debug_ignore_exception () */
|
|
|
|
|
Line 981... |
Line 955... |
Set the corresponding field in the UPR
|
Set the corresponding field in the UPR
|
|
|
@param[in] val The value to use
|
@param[in] val The value to use
|
@param[in] dat The config data structure (not used here) */
|
@param[in] dat The config data structure (not used here) */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
void
|
static void
|
debug_enabled (union param_val val, void *dat)
|
debug_enabled (union param_val val, void *dat)
|
{
|
{
|
if (val.int_val)
|
if (val.int_val)
|
{
|
{
|
cpu_state.sprs[SPR_UPR] |= SPR_UPR_DUP;
|
cpu_state.sprs[SPR_UPR] |= SPR_UPR_DUP;
|
Line 999... |
Line 973... |
|
|
} /* debug_enabled() */
|
} /* debug_enabled() */
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
/*!Enable or disable the GDB interface to the debug unit
|
/*!Enable or disable the legacy GDB interface to the debug unit
|
|
|
Set the corresponding field in the UPR
|
This is for use with the OpenRISC Remote JTAG protocol (now deprecated). It
|
|
may only be specified if the RSP interface is not specified. If both are
|
|
specified, the RSP will be used.
|
|
|
@param[in] val The value to use
|
@param[in] val The value to use
|
@param[in] dat The config data structure (not used here) */
|
@param[in] dat The config data structure (not used here) */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
void
|
static void
|
debug_gdb_enabled (union param_val val, void *dat)
|
debug_gdb_enabled (union param_val val, void *dat)
|
{
|
{
|
config.debug.gdb_enabled = val.int_val;
|
config.debug.gdb_enabled = val.int_val;
|
|
|
|
if (config.debug.gdb_enabled && config.debug.rsp_enabled)
|
|
{
|
|
fprintf (stderr, "WARNING. Cannot specify both legacy and RSP GDB "
|
|
"interfaces: legacy interface ignored\n");
|
|
config.debug.gdb_enabled = 0;
|
|
}
|
} /* debug_gdb_enabled () */
|
} /* debug_gdb_enabled () */
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
/*!Set the GDB server port
|
/*!Enable or disable Remote Serial Protocol GDB interface to the debug unit
|
|
|
|
This is the preferred interface. It may only be specified if the RSP
|
|
interface is not specified. If both are specified, the RSP will be used.
|
|
|
|
@param[in] val The value to use
|
|
@param[in] dat The config data structure (not used here) */
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
debug_rsp_enabled (union param_val val, void *dat)
|
|
{
|
|
config.debug.rsp_enabled = val.int_val;
|
|
|
|
if (config.debug.gdb_enabled && config.debug.rsp_enabled)
|
|
{
|
|
fprintf (stderr, "WARNING. Cannot specify both legacy and RSP GDB "
|
|
"interfaces: legacy interface ignored\n");
|
|
config.debug.gdb_enabled = 0;
|
|
}
|
|
} /* debug_rsp_enabled () */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*!Set the legacy GDB server port
|
|
|
|
This is for use with the OpenRISC Remote JTAG protocol (now deprecated).
|
Ensure the value chosen is valid. Note that 0 is permitted, meaning the
|
Ensure the value chosen is valid. Note that 0 is permitted, meaning the
|
connection should be to the "or1ksim" service, rather than a port.
|
connection should be to the "or1ksim" service, rather than a port.
|
|
|
|
Both this and the RSP port may be specified, but only one may be enabled
|
|
(see debug_gdb_enabled() and debug_rsp_enabled()).
|
|
|
@param[in] val The value to use
|
@param[in] val The value to use
|
@param[in] dat The config data structure (not used here) */
|
@param[in] dat The config data structure (not used here) */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
void
|
static void
|
debug_server_port (union param_val val, void *dat)
|
debug_server_port (union param_val val, void *dat)
|
{
|
{
|
if ((val.int_val < 0) || (val.int_val > 65535))
|
if ((val.int_val < 0) || (val.int_val > 65535))
|
{
|
{
|
fprintf (stderr, "Warning: invalid GDB port specified: ignored\n");
|
fprintf (stderr, "Warning: invalid legacy GDB port specified: ignored\n");
|
}
|
}
|
else
|
else
|
{
|
{
|
config.debug.server_port = val.int_val;
|
config.debug.server_port = val.int_val;
|
}
|
}
|
} /* debug_server_port() */
|
} /* debug_server_port() */
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
|
/*!Set the Remote Serial Protocol GDB server port
|
|
|
|
This is for use with the RSP, which is now the preferred interface. Ensure
|
|
the value chosen is valid. Note that 0 is permitted, meaning the connection
|
|
should be to the "or1ksim-rsp" service, rather than a port.
|
|
|
|
Both this and the legacy port may be specified, but only one may be enabled
|
|
(see debug_gdb_enabled() and debug_rsp_enabled()).
|
|
|
|
@param[in] val The value to use
|
|
@param[in] dat The config data structure (not used here) */
|
|
/*---------------------------------------------------------------------------*/
|
|
static void
|
|
debug_rsp_port (union param_val val, void *dat)
|
|
{
|
|
if ((val.int_val < 0) || (val.int_val > 65535))
|
|
{
|
|
fprintf (stderr, "Warning: invalid RSP GDB port specified: ignored\n");
|
|
}
|
|
else
|
|
{
|
|
config.debug.rsp_port = val.int_val;
|
|
}
|
|
} /* debug_rsp_port() */
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
/*!Set the VAPI ID for the debug unit
|
/*!Set the VAPI ID for the debug unit
|
|
|
@param[in] val The value to use
|
@param[in] val The value to use
|
@param[in] dat The config data structure (not used here) */
|
@param[in] dat The config data structure (not used here) */
|
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
void
|
static void
|
debug_vapi_id (union param_val val, void *dat)
|
debug_vapi_id (union param_val val, void *dat)
|
{
|
{
|
config.debug.vapi_id = val.int_val;
|
config.debug.vapi_id = val.int_val;
|
|
|
} /* debug_vapi_id () */
|
} /* debug_vapi_id () */
|
Line 1061... |
Line 1097... |
{
|
{
|
struct config_section *sec = reg_config_sec ("debug", NULL, NULL);
|
struct config_section *sec = reg_config_sec ("debug", NULL, NULL);
|
|
|
reg_config_param (sec, "enabled", paramt_int, debug_enabled);
|
reg_config_param (sec, "enabled", paramt_int, debug_enabled);
|
reg_config_param (sec, "gdb_enabled", paramt_int, debug_gdb_enabled);
|
reg_config_param (sec, "gdb_enabled", paramt_int, debug_gdb_enabled);
|
|
reg_config_param (sec, "rsp_enabled", paramt_int, debug_rsp_enabled);
|
reg_config_param (sec, "server_port", paramt_int, debug_server_port);
|
reg_config_param (sec, "server_port", paramt_int, debug_server_port);
|
|
reg_config_param (sec, "rsp_port", paramt_int, debug_rsp_port);
|
reg_config_param (sec, "vapi_id", paramt_int, debug_vapi_id);
|
reg_config_param (sec, "vapi_id", paramt_int, debug_vapi_id);
|
|
|
} /* reg_debug_sec () */
|
} /* reg_debug_sec () */
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|