openocd/src/target/nds32.h

448 lines
12 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/***************************************************************************
* Copyright (C) 2013 Andes Technology *
* Hsiangkai Wang <hkwang@andestech.com> *
***************************************************************************/
#ifndef OPENOCD_TARGET_NDS32_H
#define OPENOCD_TARGET_NDS32_H
#include <jtag/jtag.h>
#include "target.h"
#include "target_type.h"
#include "register.h"
#include "breakpoints.h"
#include "nds32_reg.h"
#include "nds32_insn.h"
#include "nds32_edm.h"
#define NDS32_EDM_OPERATION_MAX_NUM 64
#define CHECK_RETVAL(action) \
do { \
int __retval = (action); \
if (__retval != ERROR_OK) { \
LOG_DEBUG("error while calling \"%s\"", \
# action); \
return __retval; \
} \
} while (0)
/**
* @file
* Holds the interface to Andes cores.
*/
extern const char *nds32_debug_type_name[11];
enum nds32_debug_reason {
NDS32_DEBUG_BREAK = 0,
NDS32_DEBUG_BREAK_16,
NDS32_DEBUG_INST_BREAK,
NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE,
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE,
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE,
NDS32_DEBUG_DEBUG_INTERRUPT,
NDS32_DEBUG_HARDWARE_SINGLE_STEP,
NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE,
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE,
NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP,
};
#define NDS32_STRUCT_STAT_SIZE 60
#define NDS32_STRUCT_TIMEVAL_SIZE 8
enum nds32_syscall_id {
NDS32_SYSCALL_UNDEFINED = 0,
NDS32_SYSCALL_EXIT = 1,
NDS32_SYSCALL_OPEN = 2,
NDS32_SYSCALL_CLOSE = 3,
NDS32_SYSCALL_READ = 4,
NDS32_SYSCALL_WRITE = 5,
NDS32_SYSCALL_LSEEK = 6,
NDS32_SYSCALL_UNLINK = 7,
NDS32_SYSCALL_RENAME = 3001,
NDS32_SYSCALL_FSTAT = 10,
NDS32_SYSCALL_STAT = 15,
NDS32_SYSCALL_GETTIMEOFDAY = 19,
NDS32_SYSCALL_ISATTY = 3002,
NDS32_SYSCALL_SYSTEM = 3003,
NDS32_SYSCALL_ERRNO = 6001,
};
#define NDS32_COMMON_MAGIC 0xADE5ADE5U
struct nds32_edm {
/** EDM_CFG.VER, indicate the EDM version */
int version;
/** The number of hardware breakpoints */
int breakpoint_num;
/** EDM_CFG.DALM, indicate if direct local memory access
* feature is supported or not */
bool direct_access_local_memory;
/** Support ACC_CTL register */
bool access_control;
/** */
bool support_max_stop;
};
struct nds32_cache {
/** enable cache or not */
bool enable;
/** cache sets per way */
int set;
/** cache ways */
int way;
/** cache line size */
int line_size;
/** cache locking support */
bool lock_support;
};
struct nds32_memory {
/** ICache */
struct nds32_cache icache;
/** DCache */
struct nds32_cache dcache;
/** On-chip instruction local memory base */
int ilm_base;
/** On-chip instruction local memory size */
int ilm_size;
/** ILM base register alignment version */
int ilm_align_ver;
/** DLM is enabled or not */
bool ilm_enable;
/** DLM start address */
int ilm_start;
/** DLM end address */
int ilm_end;
/** On-chip data local memory base */
int dlm_base;
/** On-chip data local memory size */
int dlm_size;
/** DLM base register alignment version */
int dlm_align_ver;
/** DLM is enabled or not */
bool dlm_enable;
/** DLM start address */
int dlm_start;
/** DLM end address */
int dlm_end;
/** Memory access method */
enum nds_memory_access access_channel;
/** Memory access mode */
enum nds_memory_select mode;
/** Address translation */
bool address_translation;
};
struct nds32_cpu_version {
bool performance_extension;
bool _16bit_extension;
bool performance_extension_2;
bool cop_fpu_extension;
bool string_extension;
int revision;
int cpu_id_family;
int cpu_id_version;
};
struct nds32_mmu_config {
int memory_protection;
int memory_protection_version;
bool fully_associative_tlb;
int tlb_size;
int tlb_ways;
int tlb_sets;
bool _8k_page_support;
int extra_page_size_support;
bool tlb_lock;
bool hardware_page_table_walker;
bool default_endian;
int partition_num;
bool invisible_tlb;
bool vlpt;
bool ntme;
bool drde;
int default_min_page_size;
bool multiple_page_size_in_use;
};
struct nds32_misc_config {
bool edm;
bool local_memory_dma;
bool performance_monitor;
bool high_speed_memory_port;
bool debug_tracer;
bool div_instruction;
bool mac_instruction;
int audio_isa;
bool l2_cache;
bool reduce_register;
bool addr_24;
bool interruption_level;
int baseline_instruction;
bool no_dx_register;
bool implement_dependant_register;
bool implement_dependant_sr_encoding;
bool ifc;
bool mcu;
bool ex9;
int shadow;
};
/**
* Represents a generic Andes core.
*/
struct nds32 {
unsigned int common_magic;
struct reg_cache *core_cache;
/** Handle for the debug module. */
struct nds32_edm edm;
/** Memory information */
struct nds32_memory memory;
/** cpu version */
struct nds32_cpu_version cpu_version;
/** MMU configuration */
struct nds32_mmu_config mmu_config;
/** Misc configuration */
struct nds32_misc_config misc_config;
/** Retrieve all core registers, for display. */
int (*full_context)(struct nds32 *nds32);
/** Register mappings */
int (*register_map)(struct nds32 *nds32, int reg_no);
/** Get debug exception virtual address */
int (*get_debug_reason)(struct nds32 *nds32, uint32_t *reason);
/** Restore target registers may be modified in debug state */
int (*leave_debug_state)(struct nds32 *nds32, bool enable_watchpoint);
/** Backup target registers may be modified in debug state */
int (*enter_debug_state)(struct nds32 *nds32, bool enable_watchpoint);
/** Get address hit watchpoint */
int (*get_watched_address)(struct nds32 *nds32, uint32_t *address, uint32_t reason);
/** maximum interrupt level */
uint32_t max_interrupt_level;
/** current interrupt level */
uint32_t current_interrupt_level;
uint32_t watched_address;
/** Flag reporting whether virtual hosting is active. */
bool virtual_hosting;
/** Flag reporting whether continue/step hits syscall or not */
bool hit_syscall;
/** Value to be returned by virtual hosting SYS_ERRNO request. */
int virtual_hosting_errno;
/** Flag reporting whether syscall is aborted */
bool virtual_hosting_ctrl_c;
/** Record syscall ID for other operations to do special processing for target */
int active_syscall_id;
struct breakpoint syscall_break;
/** Flag reporting whether global stop is active. */
bool global_stop;
/** Flag reporting whether to use soft-reset-halt or not as issuing reset-halt. */
bool soft_reset_halt;
/** reset-halt as target examine */
bool reset_halt_as_examine;
/** backup/restore target EDM_CTL value. As debugging target debug
* handler, it should be true. */
bool keep_target_edm_ctl;
/* Value of $EDM_CTL before target enters debug mode */
uint32_t backup_edm_ctl;
/** always use word-aligned address to access memory */
bool word_access_mem;
/** EDM passcode for debugging secure MCU */
char *edm_passcode;
/** current privilege_level if using secure MCU. value 0 is the highest level. */
int privilege_level;
/** Period to wait after SRST. */
uint32_t boot_time;
/** Flag to indicate HSS steps into ISR or not */
bool step_isr_enable;
/** Flag to indicate register table is ready or not */
bool init_arch_info_after_halted;
/** Flag to indicate audio-extension is enabled or not */
bool audio_enable;
/** Flag to indicate fpu-extension is enabled or not */
bool fpu_enable;
/* Andes Core has mixed endian model. Instruction is always big-endian.
* Data may be big or little endian. Device registers may have different
* endian from data and instruction. */
/** Endian of data memory */
enum target_endianness data_endian;
/** Endian of device registers */
enum target_endianness device_reg_endian;
/** Flag to indicate if auto convert software breakpoints to
* hardware breakpoints or not in ROM */
bool auto_convert_hw_bp;
/* Flag to indicate the target is attached by debugger or not */
bool attached;
/** Backpointer to the target. */
struct target *target;
void *arch_info;
};
struct nds32_reg {
int32_t num;
uint8_t value[8];
struct target *target;
struct nds32 *nds32;
bool enable;
};
struct nds32_edm_operation {
uint32_t reg_no;
uint32_t value;
};
extern int nds32_config(struct nds32 *nds32);
extern int nds32_init_arch_info(struct target *target, struct nds32 *nds32);
extern int nds32_full_context(struct nds32 *nds32);
extern int nds32_arch_state(struct target *target);
extern int nds32_add_software_breakpoint(struct target *target,
struct breakpoint *breakpoint);
extern int nds32_remove_software_breakpoint(struct target *target,
struct breakpoint *breakpoint);
extern int nds32_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size,
enum target_register_class reg_class);
extern int nds32_write_buffer(struct target *target, uint32_t address,
uint32_t size, const uint8_t *buffer);
extern int nds32_read_buffer(struct target *target, uint32_t address,
uint32_t size, uint8_t *buffer);
extern int nds32_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
extern int nds32_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
extern int nds32_init_register_table(struct nds32 *nds32);
extern int nds32_init_memory_info(struct nds32 *nds32);
extern int nds32_restore_context(struct target *target);
extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value);
extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value);
extern int nds32_edm_config(struct nds32 *nds32);
extern int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length);
extern int nds32_mmu(struct target *target, int *enabled);
extern int nds32_virtual_to_physical(struct target *target, target_addr_t address,
target_addr_t *physical);
extern int nds32_read_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
extern int nds32_write_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
extern uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address);
extern int nds32_examine_debug_reason(struct nds32 *nds32);
extern int nds32_step(struct target *target, int current,
target_addr_t address, int handle_breakpoints);
extern int nds32_target_state(struct nds32 *nds32, enum target_state *state);
extern int nds32_halt(struct target *target);
extern int nds32_poll(struct target *target);
extern int nds32_resume(struct target *target, int current,
target_addr_t address, int handle_breakpoints, int debug_execution);
extern int nds32_assert_reset(struct target *target);
extern int nds32_init(struct nds32 *nds32);
extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info);
extern int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address,
uint32_t size, const uint8_t *buffer);
extern int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c);
extern int nds32_reset_halt(struct nds32 *nds32);
extern int nds32_login(struct nds32 *nds32);
extern int nds32_profiling(struct target *target, uint32_t *samples,
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
/** Convert target handle to generic Andes target state handle. */
static inline struct nds32 *target_to_nds32(struct target *target)
{
assert(target);
return target->arch_info;
}
/** */
static inline struct aice_port_s *target_to_aice(struct target *target)
{
assert(target);
return target->tap->priv;
}
static inline bool is_nds32(struct nds32 *nds32)
{
assert(nds32);
return nds32->common_magic == NDS32_COMMON_MAGIC;
}
static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32)
{
assert(nds32);
return nds32->max_interrupt_level == nds32->current_interrupt_level;
}
#endif /* OPENOCD_TARGET_NDS32_H */