Upstream a whole host of RISC-V changes.
[openocd.git] / src / target / riscv / riscv.h
index d943134e23e46b72f461a46ae8743ba0ec8352aa..d0f4f6ec048bbd5e2b2130680954bbaadd60ad95 100644 (file)
@@ -10,6 +10,7 @@ struct riscv_program;
 #include "gdb_regs.h"
 #include "jtag/jtag.h"
 #include "target/register.h"
+#include <helper/command.h>
 
 /* The register cache is statically allocated. */
 #define RISCV_MAX_HARTS 1024
@@ -26,6 +27,8 @@ struct riscv_program;
 
 # define PG_MAX_LEVEL 4
 
+#define RISCV_NUM_MEM_ACCESS_METHODS  3
+
 extern struct target_type riscv011_target;
 extern struct target_type riscv013_target;
 
@@ -36,6 +39,13 @@ typedef uint64_t riscv_reg_t;
 typedef uint32_t riscv_insn_t;
 typedef uint64_t riscv_addr_t;
 
+enum riscv_mem_access_method {
+       RISCV_MEM_ACCESS_UNSPECIFIED,
+       RISCV_MEM_ACCESS_PROGBUF,
+       RISCV_MEM_ACCESS_SYSBUS,
+       RISCV_MEM_ACCESS_ABSTRACT
+};
+
 enum riscv_halt_reason {
        RISCV_HALT_INTERRUPT,
        RISCV_HALT_BREAKPOINT,
@@ -51,15 +61,35 @@ typedef struct {
        unsigned custom_number;
 } riscv_reg_info_t;
 
+#define RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE      0x80
+#define RISCV_SAMPLE_BUF_TIMESTAMP_AFTER       0x81
+struct riscv_sample_buf {
+       uint8_t *buf;
+       unsigned int used;
+       unsigned int size;
+};
+
+typedef struct {
+       bool enabled;
+       struct {
+               bool enabled;
+               target_addr_t address;
+               uint32_t size_bytes;
+       } bucket[16];
+} riscv_sample_config_t;
+
+typedef struct {
+       struct list_head list;
+       uint16_t low, high;
+       char *name;
+} range_list_t;
+
 typedef struct {
        unsigned dtm_version;
 
        struct command_context *cmd_ctx;
        void *version_specific;
 
-       /* The hart that the RTOS thinks is currently being debugged. */
-       int rtos_hartid;
-
        /* The hart that is currently being debugged.  Note that this is
         * different than the hartid that the RTOS is expected to use.  This
         * one will change all the time, it's more of a global argument to
@@ -76,13 +106,13 @@ typedef struct {
        char *reg_names;
 
        /* It's possible that each core has a different supported ISA set. */
-       int xlen[RISCV_MAX_HARTS];
-       riscv_reg_t misa[RISCV_MAX_HARTS];
+       int xlen;
+       riscv_reg_t misa;
        /* Cached value of vlenb. 0 if vlenb is not readable for some reason. */
-       unsigned vlenb[RISCV_MAX_HARTS];
+       unsigned int vlenb;
 
        /* The number of triggers per hart. */
-       unsigned trigger_count[RISCV_MAX_HARTS];
+       unsigned int trigger_count;
 
        /* For each physical trigger, contains -1 if the hwbp is available, or the
         * unique_id of the breakpoint/watchpoint that is using it.
@@ -91,7 +121,7 @@ typedef struct {
        int trigger_unique_id[RISCV_MAX_HWBPS];
 
        /* The number of entries in the debug buffer. */
-       int debug_buffer_size[RISCV_MAX_HARTS];
+       int debug_buffer_size;
 
        /* This avoids invalidating the register cache too often. */
        bool registers_initialized;
@@ -112,10 +142,8 @@ typedef struct {
 
        /* Helper functions that target the various RISC-V debug spec
         * implementations. */
-       int (*get_register)(struct target *target,
-               riscv_reg_t *value, int hid, int rid);
-       int (*set_register)(struct target *target, int hartid, int regid,
-                       uint64_t value);
+       int (*get_register)(struct target *target, riscv_reg_t *value, int regid);
+       int (*set_register)(struct target *target, int regid, uint64_t value);
        int (*get_register_buf)(struct target *target, uint8_t *buf, int regno);
        int (*set_register_buf)(struct target *target, int regno,
                        const uint8_t *buf);
@@ -143,8 +171,8 @@ typedef struct {
        void (*fill_dmi_read_u64)(struct target *target, char *buf, int a);
        void (*fill_dmi_nop_u64)(struct target *target, char *buf);
 
-       int (*authdata_read)(struct target *target, uint32_t *value);
-       int (*authdata_write)(struct target *target, uint32_t value);
+       int (*authdata_read)(struct target *target, uint32_t *value, unsigned int index);
+       int (*authdata_write)(struct target *target, uint32_t value, unsigned int index);
 
        int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
        int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
@@ -152,7 +180,10 @@ typedef struct {
        int (*test_sba_config_reg)(struct target *target, target_addr_t legal_address,
                        uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test);
 
-       int (*test_compliance)(struct target *target);
+       int (*sample_memory)(struct target *target,
+                                                struct riscv_sample_buf *buf,
+                                                riscv_sample_config_t *config,
+                                                int64_t until_ms);
 
        int (*read_memory)(struct target *target, target_addr_t address,
                        uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);
@@ -161,6 +192,8 @@ typedef struct {
        int (*hart_count)(struct target *target);
        unsigned (*data_bits)(struct target *target);
 
+       COMMAND_HELPER((*print_info), struct target *target);
+
        /* Storage for vector register types. */
        struct reg_data_type_vector vector_uint8;
        struct reg_data_type_vector vector_uint16;
@@ -179,8 +212,31 @@ typedef struct {
        /* Set when trigger registers are changed by the user. This indicates we eed
         * to beware that we may hit a trigger that we didn't realize had been set. */
        bool manual_hwbp_set;
+
+       /* Memory access methods to use, ordered by priority, highest to lowest. */
+       int mem_access_methods[RISCV_NUM_MEM_ACCESS_METHODS];
+
+       /* Different memory regions may need different methods but single configuration is applied
+        * for all. Following flags are used to warn only once about failing memory access method. */
+       bool mem_access_progbuf_warn;
+       bool mem_access_sysbus_warn;
+       bool mem_access_abstract_warn;
+
+       /* In addition to the ones in the standard spec, we'll also expose additional
+        * CSRs in this list. */
+       struct list_head expose_csr;
+       /* Same, but for custom registers.
+        * Custom registers are for non-standard extensions and use abstract register numbers
+        * from range 0xc000 ... 0xffff. */
+       struct list_head expose_custom;
+
+       riscv_sample_config_t sample_config;
+       struct riscv_sample_buf sample_buf;
 } riscv_info_t;
 
+COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
+                          unsigned int value);
+
 typedef struct {
        uint8_t tunneled_dr_width;
        struct scan_field tunneled_dr[4];
@@ -205,8 +261,6 @@ extern int riscv_command_timeout_sec;
 /* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
 extern int riscv_reset_timeout_sec;
 
-extern bool riscv_prefer_sba;
-
 extern bool riscv_enable_virtual;
 extern bool riscv_ebreakm;
 extern bool riscv_ebreaks;
@@ -216,7 +270,10 @@ extern bool riscv_ebreaku;
  * that provides that. */
 static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));
 static inline riscv_info_t *riscv_info(const struct target *target)
-{ return target->arch_info; }
+{
+       assert(target->arch_info);
+       return target->arch_info;
+}
 #define RISCV_INFO(R) riscv_info_t *R = riscv_info(target);
 
 extern uint8_t ir_dtmcontrol[4];
@@ -269,44 +326,30 @@ void riscv_info_init(struct target *target, riscv_info_t *r);
  * then the only hart. */
 int riscv_step_rtos_hart(struct target *target);
 
-bool riscv_supports_extension(struct target *target, int hartid, char letter);
+bool riscv_supports_extension(struct target *target, char letter);
 
 /* Returns XLEN for the given (or current) hart. */
 unsigned riscv_xlen(const struct target *target);
-int riscv_xlen_of_hart(const struct target *target, int hartid);
-
-bool riscv_rtos_enabled(const struct target *target);
+int riscv_xlen_of_hart(const struct target *target);
 
 /* Sets the current hart, which is the hart that will actually be used when
  * issuing debug commands. */
 int riscv_set_current_hartid(struct target *target, int hartid);
+int riscv_select_current_hart(struct target *target);
 int riscv_current_hartid(const struct target *target);
 
 /*** Support functions for the RISC-V 'RTOS', which provides multihart support
  * without requiring multiple targets.  */
 
-/* When using the RTOS to debug, this selects the hart that is currently being
- * debugged.  This doesn't propagate to the hardware. */
-void riscv_set_all_rtos_harts(struct target *target);
-void riscv_set_rtos_hartid(struct target *target, int hartid);
-
 /* Lists the number of harts in the system, which are assumed to be
  * consecutive and start with mhartid=0. */
 int riscv_count_harts(struct target *target);
 
-/* Returns TRUE if the target has the given register on the given hart.  */
-bool riscv_has_register(struct target *target, int hartid, int regid);
-
 /** Set register, updating the cache. */
 int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
-/** Set register, updating the cache. */
-int riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
 /** Get register, from the cache if it's in there. */
 int riscv_get_register(struct target *target, riscv_reg_t *value,
                enum gdb_regno r);
-/** Get register, from the cache if it's in there. */
-int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value,
-               int hartid, enum gdb_regno regid);
 
 /* Checks the state of the current hart -- "is_halted" checks the actual
  * on-device register. */
@@ -329,9 +372,6 @@ int riscv_dmi_write_u64_bits(struct target *target);
 /* Invalidates the register cache. */
 void riscv_invalidate_register_cache(struct target *target);
 
-/* Returns TRUE when a hart is enabled in this target. */
-bool riscv_hart_enabled(struct target *target, int hartid);
-
 int riscv_enumerate_triggers(struct target *target);
 
 int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
@@ -356,4 +396,7 @@ semihosting_result_t riscv_semihosting(struct target *target, int *retval);
 void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,
                riscv_bscan_tunneled_scan_context_t *ctxt);
 
+int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
+int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
+
 #endif

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)