openocd/src/target/arc.h
Antonio Borneo c3d3487d61 openocd: src: fix incorrect SPDX tags
The SPDX tag is aimed at machine handling and it's thus expected
to be placed in the first line in specific format.

Move the SPDX tag to the first line and fix it where needed.

The SPDX tag on files *.c is incorrect, as it should use the C99
single line comment using '//'. But current checkpatch doesn't
allow C99 comments, so keep using standard C comments, by now.

Change-Id: Ie9a05f530009d482a4116eebd147fd7e1ee3d41e
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7066
Tested-by: jenkins
2022-07-23 13:16:09 +00:00

361 lines
9.2 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/***************************************************************************
* Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. *
* Frank Dols <frank.dols@synopsys.com> *
* Mischa Jonker <mischa.jonker@synopsys.com> *
* Anton Kolesov <anton.kolesov@synopsys.com> *
* Evgeniy Didin <didin@synopsys.com> *
***************************************************************************/
#ifndef OPENOCD_TARGET_ARC_H
#define OPENOCD_TARGET_ARC_H
#include <helper/time_support.h>
#include <jtag/jtag.h>
#include "algorithm.h"
#include "breakpoints.h"
#include "jtag/interface.h"
#include "register.h"
#include "target.h"
#include "target_request.h"
#include "target_type.h"
#include "helper/bits.h"
#include "arc_jtag.h"
#include "arc_cmd.h"
#include "arc_mem.h"
#define ARC_COMMON_MAGIC 0xB32EB324 /* just a unique number */
#define AUX_DEBUG_REG 0x5
#define AUX_PC_REG 0x6
#define AUX_STATUS32_REG 0xA
#define SET_CORE_FORCE_HALT BIT(1)
#define SET_CORE_HALT_BIT BIT(0) /* STATUS32[0] = H field */
#define SET_CORE_ENABLE_INTERRUPTS BIT(31)
/* STATUS32[5] or AE bit indicates if the processor is in exception state */
#define SET_CORE_AE_BIT BIT(5)
/* Single instruction step bit in Debug register */
#define SET_CORE_SINGLE_INSTR_STEP BIT(11)
#define AUX_STATUS32_REG_HALT_BIT BIT(0)
#define AUX_STATUS32_REG_IE_BIT BIT(31) /* STATUS32[31] = IE field */
/* ARC register numbers */
enum {
ARC_R0,
ARC_R1,
ARC_R2,
ARC_R3,
ARC_R4,
ARC_R5,
ARC_R6,
ARC_R7,
ARC_R8,
ARC_R9,
ARC_R10,
ARC_R11,
ARC_R12,
ARC_R13,
ARC_R14,
ARC_R15,
ARC_R16,
ARC_R17,
ARC_R18,
ARC_R19,
ARC_R20,
ARC_R21,
ARC_R22,
ARC_R23,
ARC_R24,
ARC_R25,
ARC_GP = 26,
ARC_FP = 27,
ARC_SP = 28,
ARC_ILINK = 29,
ARC_R30,
ARC_BLINK = 31,
ARC_LP_COUNT = 60,
/* Reserved registers */
ARC_R61 = 61,
ARC_R62 = 62,
ARC_PCL = 63,
ARC_PC = 64,
ARC_LP_START = 65,
ARC_LP_END = 66,
ARC_STATUS32 = 67,
};
#define CORE_REG_MAX_NUMBER (63)
/* Limit reg_type/reg_type_field name to 20 symbols */
#define REG_TYPE_MAX_NAME_LENGTH 20
/* ARC 32bits opcodes */
#define ARC_SDBBP_32 0x256F003FU /* BRK */
/* ARC 16bits opcodes */
#define ARC_SDBBP_16 0x7FFF /* BRK_S */
/* Cache registers */
#define AUX_IC_IVIC_REG 0X10
#define IC_IVIC_INVALIDATE 0XFFFFFFFF
#define AUX_DC_IVDC_REG 0X47
#define DC_IVDC_INVALIDATE BIT(0)
#define AUX_DC_CTRL_REG 0X48
#define DC_CTRL_IM BIT(6)
/* L2 cache registers */
#define SLC_AUX_CACHE_CTRL 0x903
#define L2_CTRL_IM BIT(6)
#define L2_CTRL_BS BIT(8) /* Busy flag */
#define SLC_AUX_CACHE_FLUSH 0x904
#define L2_FLUSH_FL BIT(0)
#define SLC_AUX_CACHE_INV 0x905
#define L2_INV_IV BIT(0)
/* Action Point */
#define AP_AC_AT_INST_ADDR 0x0
#define AP_AC_AT_MEMORY_ADDR 0x2
#define AP_AC_AT_AUXREG_ADDR 0x4
#define AP_AC_TT_DISABLE 0x00
#define AP_AC_TT_WRITE 0x10
#define AP_AC_TT_READ 0x20
#define AP_AC_TT_READWRITE 0x30
struct arc_reg_bitfield {
struct reg_data_type_bitfield bitfield;
char name[REG_TYPE_MAX_NAME_LENGTH];
};
/* Register data type */
struct arc_reg_data_type {
struct list_head list;
struct reg_data_type data_type;
struct reg_data_type_flags data_type_flags;
struct reg_data_type_struct data_type_struct;
char data_type_id[REG_TYPE_MAX_NAME_LENGTH];
struct arc_reg_bitfield *bitfields;
union {
struct reg_data_type_struct_field *reg_type_struct_field;
struct reg_data_type_flags_field *reg_type_flags_field;
};
};
/* Standard GDB register types */
static const struct reg_data_type standard_gdb_types[] = {
{ .type = REG_TYPE_INT, .id = "int" },
{ .type = REG_TYPE_INT8, .id = "int8" },
{ .type = REG_TYPE_INT16, .id = "int16" },
{ .type = REG_TYPE_INT32, .id = "int32" },
{ .type = REG_TYPE_INT64, .id = "int64" },
{ .type = REG_TYPE_INT128, .id = "int128" },
{ .type = REG_TYPE_UINT8, .id = "uint8" },
{ .type = REG_TYPE_UINT16, .id = "uint16" },
{ .type = REG_TYPE_UINT32, .id = "uint32" },
{ .type = REG_TYPE_UINT64, .id = "uint64" },
{ .type = REG_TYPE_UINT128, .id = "uint128" },
{ .type = REG_TYPE_CODE_PTR, .id = "code_ptr" },
{ .type = REG_TYPE_DATA_PTR, .id = "data_ptr" },
{ .type = REG_TYPE_FLOAT, .id = "float" },
{ .type = REG_TYPE_IEEE_SINGLE, .id = "ieee_single" },
{ .type = REG_TYPE_IEEE_DOUBLE, .id = "ieee_double" },
};
enum arc_actionpointype {
ARC_AP_BREAKPOINT,
ARC_AP_WATCHPOINT,
};
/* Actionpoint related fields */
struct arc_actionpoint {
int used;
uint32_t bp_value;
uint32_t reg_address;
enum arc_actionpointype type;
};
struct arc_common {
uint32_t common_magic;
struct arc_jtag jtag_info;
struct reg_cache *core_and_aux_cache;
struct reg_cache *bcr_cache;
/* Cache control */
bool has_dcache;
bool has_icache;
bool has_l2cache;
/* If true, then D$ has been already flushed since core has been
* halted. */
bool dcache_flushed;
/* If true, then L2 has been already flushed since core has been
* halted. */
bool l2cache_flushed;
/* If true, then caches have been already flushed since core has been
* halted. */
bool icache_invalidated;
bool dcache_invalidated;
bool l2cache_invalidated;
/* Indicate if cache was built (for deinit function) */
bool core_aux_cache_built;
bool bcr_cache_built;
/* Closely Coupled memory(CCM) regions for performance-critical
* code (optional). */
uint32_t iccm0_start;
uint32_t iccm0_end;
uint32_t iccm1_start;
uint32_t iccm1_end;
uint32_t dccm_start;
uint32_t dccm_end;
int irq_state;
/* Register descriptions */
struct list_head reg_data_types;
struct list_head core_reg_descriptions;
struct list_head aux_reg_descriptions;
struct list_head bcr_reg_descriptions;
unsigned long num_regs;
unsigned long num_core_regs;
unsigned long num_aux_regs;
unsigned long num_bcr_regs;
unsigned long last_general_reg;
/* PC register location in register cache. */
unsigned long pc_index_in_cache;
/* DEBUG register location in register cache. */
unsigned long debug_index_in_cache;
/* Actionpoints */
unsigned int actionpoints_num;
unsigned int actionpoints_num_avail;
struct arc_actionpoint *actionpoints_list;
};
/* Borrowed from nds32.h */
#define CHECK_RETVAL(action) \
do { \
int __retval = (action); \
if (__retval != ERROR_OK) { \
LOG_DEBUG("error while calling \"%s\"", \
# action); \
return __retval; \
} \
} while (0)
#define JIM_CHECK_RETVAL(action) \
do { \
int __retval = (action); \
if (__retval != JIM_OK) { \
LOG_DEBUG("error while calling \"%s\"", \
# action); \
return __retval; \
} \
} while (0)
static inline struct arc_common *target_to_arc(struct target *target)
{
return target->arch_info;
}
/* ----- Inlined functions ------------------------------------------------- */
/**
* Convert data in host endianness to the middle endian. This is required to
* write 4-byte instructions.
*/
static inline void arc_h_u32_to_me(uint8_t *buf, int val)
{
buf[1] = (uint8_t) (val >> 24);
buf[0] = (uint8_t) (val >> 16);
buf[3] = (uint8_t) (val >> 8);
buf[2] = (uint8_t) (val >> 0);
}
/**
* Convert data in middle endian to host endian. This is required to read 32-bit
* instruction from little endian ARCs.
*/
static inline uint32_t arc_me_to_h_u32(const uint8_t *buf)
{
return (uint32_t)(buf[2] | buf[3] << 8 | buf[0] << 16 | buf[1] << 24);
}
/* ARC Register description */
struct arc_reg_desc {
struct target *target;
/* Register name */
char *name;
/* Actual place of storing reg_value */
uint8_t reg_value[4];
/* Actual place of storing register feature */
struct reg_feature feature;
/* GDB XML feature */
char *gdb_xml_feature;
/* Is this a register in g/G-packet? */
bool is_general;
/* Architectural number: core reg num or AUX reg num */
uint32_t arch_num;
/* Core or AUX register? */
bool is_core;
/* Build configuration register? */
bool is_bcr;
/* Data type */
struct reg_data_type *data_type;
struct list_head list;
};
/* Error codes */
#define ERROR_ARC_REGISTER_NOT_FOUND (-700)
#define ERROR_ARC_REGISTER_FIELD_NOT_FOUND (-701)
#define ERROR_ARC_REGISTER_IS_NOT_STRUCT (-702)
#define ERROR_ARC_FIELD_IS_NOT_BITFIELD (-703)
#define ERROR_ARC_REGTYPE_NOT_FOUND (-704)
void free_reg_desc(struct arc_reg_desc *r);
void arc_reg_data_type_add(struct target *target,
struct arc_reg_data_type *data_type);
int arc_reg_add(struct target *target, struct arc_reg_desc *arc_reg,
const char * const type_name, const size_t type_name_len);
struct reg *arc_reg_get_by_name(struct reg_cache *first,
const char *name, bool search_all);
int arc_reg_get_field(struct target *target, const char *reg_name,
const char *field_name, uint32_t *value_ptr);
int arc_cache_flush(struct target *target);
int arc_cache_invalidate(struct target *target);
int arc_add_auxreg_actionpoint(struct target *target,
uint32_t auxreg_addr, uint32_t transaction);
int arc_remove_auxreg_actionpoint(struct target *target, uint32_t auxreg_addr);
int arc_set_actionpoints_num(struct target *target, uint32_t ap_num);
#endif /* OPENOCD_TARGET_ARC_H */