Compare commits

...

8 Commits

Author SHA1 Message Date
fk-sc 94c2e356b0
Merge cc7e5e3aad into 67082829da 2025-03-07 17:59:46 +03:00
Evgeniy Naydanov 67082829da
Merge pull request #1225 from JanMatCodasip/jm-codasip/fix-datatypes-around-program
Fix data types around opcodes.h and program.{c,h}
2025-03-07 12:57:57 +03:00
Evgeniy Naydanov e88edb71a5
Merge pull request #1171 from lz-bro/handle-all-trigger-halt
target/riscv: Fix SMP group is in inconsistent state
2025-03-07 11:26:16 +03:00
liangzhen d5969d5f43 target/riscv: Fix SMP group is in inconsistent state
If the harts are just in the process of halting due to
being members of the halt group, we should wait until
they finish halting, so that the true halt reason can
be discovered  (e.g. semihosting request, and then
handled correctly).
2025-03-04 16:29:04 +08:00
Jan Matyas 64f30dc279 Clean up return type of riscv_progbuf_size() + related
SSIA

Change-Id: I3e0b2fad84411c530f56cdbe33f3d8b4dbf81cf6
Signed-off-by: Jan Matyas <jan.matyas@codasip.com>
2025-02-28 12:10:41 +01:00
Jan Matyas b272470dff riscv-011: Fix datatypes to correspond to opcodes.h
Callers of functions from opcodes.h need to be updated accordingly, too.

Change-Id: Ic42156b2843be682bc1cf9c720b73687008a2aa6
Signed-off-by: Jan Matyas <jan.matyas@codasip.com>
2025-02-26 15:27:14 +01:00
Jan Matyas c133dbef03 opcodes.h: Do not use casts in MIN_* and MAX_* macros
This is to make it consistent with stdint.h.

Change-Id: Ibba824dad431b3a1675700ad4cc15f3e39a187f7
Signed-off-by: Jan Matyas <jan.matyas@codasip.com>
2025-02-26 15:27:14 +01:00
Jan Matyas 068f566fb8 Fix datatypes around opcodes.h and program.{c,h}
- Fix and clean-up datatypes in opcodes.h and program.{c,h}.
  Some of the changes were pointed by -Wconversion, others
  come from manual code inspection.

- Remove commented code from opcodes.h (unused for very long time).

- Add assertions to opcodes.h to check that instruction
  immediates (and other fields) don't exceed their range.

Change-Id: I7fc7c30ac2fdb00a93158d63d1379e7f16b1d168
Signed-off-by: Jan Matyas <jan.matyas@codasip.com>
2025-02-26 15:27:14 +01:00
7 changed files with 331 additions and 161 deletions

View File

@ -4,15 +4,36 @@
#define OPENOCD_TARGET_RISCV_OPCODES_H
#include "encoding.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#define ZERO 0
#define T0 5
#define S0 8
#define S1 9
#define MAX_GPR_NUM 31
#define MAX_FPR_NUM 31
#define MAX_VREG_NUM 31
#define MAX_CSR_NUM 4095
#define MIN_INT12 (-0x800)
#define MAX_INT12 0x7ff
#define MIN_INT13 (-0x1000)
#define MAX_INT13 0xfff
#define MIN_INT21 (-0x100000)
#define MAX_INT21 0xfffff
#define MAX_UINT5 0x1f
#define MAX_UINT11 0x7ff
#define MAX_UINT12 0xfff
static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo)
{
return (value >> lo) & ((1 << (hi+1-lo)) - 1);
return (value >> lo) & (((uint32_t)1 << (hi + 1 - lo)) - 1);
}
static uint32_t bit(uint32_t value, unsigned int b)
@ -68,153 +89,246 @@ static uint32_t imm_j(uint32_t imm)
return (bits(imm, 19, 12) << 12) | (bit(imm, 11) << 20) | (bits(imm, 10, 1) << 21) | (bit(imm, 20) << 31);
}
static uint32_t jal(unsigned int rd, uint32_t imm) __attribute__ ((unused));
static uint32_t jal(unsigned int rd, uint32_t imm)
static uint32_t jal(unsigned int rd, int32_t imm) __attribute__ ((unused));
static uint32_t jal(unsigned int rd, int32_t imm)
{
return imm_j(imm) | inst_rd(rd) | MATCH_JAL;
assert(rd <= MAX_GPR_NUM);
assert((imm >= MIN_INT21) && (imm <= MAX_INT21));
assert((imm & 1) == 0);
return imm_j((uint32_t)imm) | inst_rd(rd) | MATCH_JAL;
}
static uint32_t csrsi(unsigned int csr, uint16_t imm) __attribute__ ((unused));
static uint32_t csrsi(unsigned int csr, uint16_t imm)
static uint32_t csrsi(unsigned int csr, uint8_t imm) __attribute__ ((unused));
static uint32_t csrsi(unsigned int csr, uint8_t imm)
{
assert(csr <= MAX_CSR_NUM);
assert(imm <= MAX_UINT5);
return imm_i(csr) | inst_rs1(imm) | MATCH_CSRRSI;
}
static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t sw(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t sw(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SW;
assert(src <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SW;
}
static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t sd(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t sd(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SD;
assert(src <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SD;
}
static uint32_t sh(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t sh(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t sh(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t sh(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SH;
assert(src <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SH;
}
static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t sb(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t sb(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SB;
assert(src <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SB;
}
static uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset)
static uint32_t ld(unsigned int rd, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t ld(unsigned int rd, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LD;
assert(rd <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LD;
}
static uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset)
static uint32_t lw(unsigned int rd, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t lw(unsigned int rd, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LW;
assert(rd <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LW;
}
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset)
static uint32_t lh(unsigned int rd, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t lh(unsigned int rd, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LH;
assert(rd <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LH;
}
static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset)
static uint32_t lb(unsigned int rd, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t lb(unsigned int rd, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LB;
assert(rd <= MAX_GPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LB;
}
static uint32_t csrw(unsigned int source, unsigned int csr) __attribute__ ((unused));
static uint32_t csrw(unsigned int source, unsigned int csr)
{
assert(source <= MAX_GPR_NUM);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rs1(source) | MATCH_CSRRW;
}
static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));
static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm)
static uint32_t addi(unsigned int dest, unsigned int src, int16_t imm) __attribute__ ((unused));
static uint32_t addi(unsigned int dest, unsigned int src, int16_t imm)
{
return imm_i(imm) | inst_rs1(src) | inst_rd(dest) | MATCH_ADDI;
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_GPR_NUM);
assert((imm >= MIN_INT12) && (imm <= MAX_INT12));
return imm_i((uint16_t)imm) | inst_rs1(src) | inst_rd(dest) | MATCH_ADDI;
}
static uint32_t csrr(unsigned int rd, unsigned int csr) __attribute__ ((unused));
static uint32_t csrr(unsigned int rd, unsigned int csr)
{
assert(rd <= MAX_GPR_NUM);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rd(rd) | MATCH_CSRRS;
}
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr)
{
assert(rd <= MAX_GPR_NUM);
assert(rs <= MAX_GPR_NUM);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rs1(rs) | inst_rd(rd) | MATCH_CSRRS;
}
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr)
{
assert(rd <= MAX_GPR_NUM);
assert(rs <= MAX_GPR_NUM);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rs1(rs) | inst_rd(rd) | MATCH_CSRRW;
}
static uint32_t csrrci(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrci(unsigned int rd, unsigned int zimm, unsigned int csr)
static uint32_t csrrci(unsigned int rd, uint8_t zimm, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrci(unsigned int rd, uint8_t zimm, unsigned int csr)
{
assert(rd <= MAX_GPR_NUM);
assert(zimm <= MAX_UINT5);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rs1(zimm) | inst_rd(rd) | MATCH_CSRRCI;
}
static uint32_t csrrsi(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrsi(unsigned int rd, unsigned int zimm, unsigned int csr)
static uint32_t csrrsi(unsigned int rd, uint8_t zimm, unsigned int csr) __attribute__ ((unused));
static uint32_t csrrsi(unsigned int rd, uint8_t zimm, unsigned int csr)
{
assert(rd <= MAX_GPR_NUM);
assert(zimm <= MAX_UINT5);
assert(csr <= MAX_CSR_NUM);
return imm_i(csr) | inst_rs1(zimm) | inst_rd(rd) | MATCH_CSRRSI;
}
static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t fsw(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t fsw(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSW;
assert(src <= MAX_FPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSW;
}
static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset)
static uint32_t fsd(unsigned int src, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t fsd(unsigned int src, unsigned int base, int16_t offset)
{
return imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSD;
assert(src <= MAX_FPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_s((uint16_t)offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSD;
}
static uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset)
static uint32_t flw(unsigned int dest, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t flw(unsigned int dest, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLW;
assert(dest <= MAX_FPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLW;
}
static uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset)
static uint32_t fld(unsigned int dest, unsigned int base, int16_t offset) __attribute__ ((unused));
static uint32_t fld(unsigned int dest, unsigned int base, int16_t offset)
{
return imm_i(offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLD;
assert(dest <= MAX_FPR_NUM);
assert(base <= MAX_GPR_NUM);
assert((offset >= MIN_INT12) && (offset <= MAX_INT12));
return imm_i((uint16_t)offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLD;
}
static uint32_t fmv_x_w(unsigned int dest, unsigned int src) __attribute__ ((unused));
static uint32_t fmv_x_w(unsigned int dest, unsigned int src)
{
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_FPR_NUM);
return inst_rs1(src) | inst_rd(dest) | MATCH_FMV_X_W;
}
static uint32_t fmv_x_d(unsigned int dest, unsigned int src) __attribute__ ((unused));
static uint32_t fmv_x_d(unsigned int dest, unsigned int src)
{
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_FPR_NUM);
return inst_rs1(src) | inst_rd(dest) | MATCH_FMV_X_D;
}
static uint32_t fmv_w_x(unsigned int dest, unsigned int src) __attribute__ ((unused));
static uint32_t fmv_w_x(unsigned int dest, unsigned int src)
{
assert(dest <= MAX_FPR_NUM);
assert(src <= MAX_GPR_NUM);
return inst_rs1(src) | inst_rd(dest) | MATCH_FMV_W_X;
}
static uint32_t fmv_d_x(unsigned int dest, unsigned int src) __attribute__ ((unused));
static uint32_t fmv_d_x(unsigned int dest, unsigned int src)
{
assert(dest <= MAX_FPR_NUM);
assert(src <= MAX_GPR_NUM);
return inst_rs1(src) | inst_rd(dest) | MATCH_FMV_D_X;
}
@ -241,59 +355,29 @@ static uint32_t fence_i(void)
static uint32_t lui(unsigned int dest, uint32_t imm) __attribute__ ((unused));
static uint32_t lui(unsigned int dest, uint32_t imm)
{
assert(dest <= MAX_GPR_NUM);
assert(bits(imm, 11, 0) == 0);
return imm_u(imm) | inst_rd(dest) | MATCH_LUI;
}
/*
static uint32_t csrci(unsigned int csr, uint16_t imm) __attribute__ ((unused));
static uint32_t csrci(unsigned int csr, uint16_t imm)
static uint32_t xori(unsigned int dest, unsigned int src, int16_t imm) __attribute__ ((unused));
static uint32_t xori(unsigned int dest, unsigned int src, int16_t imm)
{
return (csr << 20) |
(bits(imm, 4, 0) << 15) |
MATCH_CSRRCI;
}
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_GPR_NUM);
assert((imm >= MIN_INT12) && (imm <= MAX_INT12));
static uint32_t li(unsigned int dest, uint16_t imm) __attribute__ ((unused));
static uint32_t li(unsigned int dest, uint16_t imm)
{
return addi(dest, 0, imm);
}
static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));
static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset)
{
return (bits(offset, 11, 5) << 25) |
(bits(src, 4, 0) << 20) |
(base << 15) |
(bits(offset, 4, 0) << 7) |
MATCH_FSD;
}
static uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));
static uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm)
{
return (bits(imm, 11, 0) << 20) |
(src << 15) |
(dest << 7) |
MATCH_ORI;
}
static uint32_t nop(void) __attribute__ ((unused));
static uint32_t nop(void)
{
return addi(0, 0, 0);
}
*/
static uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));
static uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm)
{
return imm_i(imm) | inst_rs1(src) | inst_rd(dest) | MATCH_XORI;
return imm_i((uint16_t)imm) | inst_rs1(src) | inst_rd(dest) | MATCH_XORI;
}
static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt) __attribute__ ((unused));
static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt)
{
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_GPR_NUM);
assert(shamt <= MAX_UINT5);
return inst_rs2(shamt) | inst_rs1(src) | inst_rd(dest) | MATCH_SRLI;
}
@ -307,39 +391,59 @@ static uint32_t fence_rw_rw(void)
static uint32_t auipc(unsigned int dest) __attribute__((unused));
static uint32_t auipc(unsigned int dest)
{
assert(dest <= MAX_GPR_NUM);
return MATCH_AUIPC | inst_rd(dest);
}
static uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t imm) __attribute__((unused));
static uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t imm)
static uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t vtypei) __attribute__((unused));
static uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t vtypei)
{
return (bits(imm, 10, 0) << 20) | inst_rs1(src) | inst_rd(dest) | MATCH_VSETVLI;
assert(dest <= MAX_GPR_NUM);
assert(src <= MAX_GPR_NUM);
assert(vtypei <= MAX_UINT11);
return (bits(vtypei, 10, 0) << 20) | inst_rs1(src) | inst_rd(dest) | MATCH_VSETVLI;
}
static uint32_t vsetvl(unsigned int rd, unsigned int rs1, unsigned int rs2) __attribute__((unused));
static uint32_t vsetvl(unsigned int rd, unsigned int rs1, unsigned int rs2)
{
assert(rd <= MAX_GPR_NUM);
assert(rs1 <= MAX_GPR_NUM);
assert(rs2 <= MAX_GPR_NUM);
return inst_rd(rd) | inst_rs1(rs1) | inst_rs2(rs2) | MATCH_VSETVL;
}
static uint32_t vmv_x_s(unsigned int rd, unsigned int vs2) __attribute__((unused));
static uint32_t vmv_x_s(unsigned int rd, unsigned int vs2)
{
assert(rd <= MAX_GPR_NUM);
assert(vs2 <= MAX_VREG_NUM);
return inst_rs2(vs2) | inst_rd(rd) | MATCH_VMV_X_S;
}
static uint32_t vmv_s_x(unsigned int vd, unsigned int vs2) __attribute__((unused));
static uint32_t vmv_s_x(unsigned int vd, unsigned int rs1)
static uint32_t vmv_s_x(unsigned int vd, unsigned int rs2) __attribute__((unused));
static uint32_t vmv_s_x(unsigned int vd, unsigned int rs2)
{
return inst_rs1(rs1) | inst_rd(vd) | MATCH_VMV_S_X;
assert(vd <= MAX_VREG_NUM);
assert(rs2 <= MAX_GPR_NUM);
return inst_rs1(rs2) | inst_rd(vd) | MATCH_VMV_S_X;
}
static uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,
unsigned int rs1, unsigned int vm) __attribute__((unused));
unsigned int rs1, bool vm) __attribute__((unused));
static uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,
unsigned int rs1, unsigned int vm)
unsigned int rs1, bool vm)
{
return ((vm & 1) << 25) | inst_rs2(vs2) | inst_rs1(rs1) | inst_rd(vd) | MATCH_VSLIDE1DOWN_VX;
assert(vd <= MAX_VREG_NUM);
assert(vs2 <= MAX_VREG_NUM);
assert(rs1 <= MAX_GPR_NUM);
return (vm ? (1u << 25) : 0u) | inst_rs2(vs2) | inst_rs1(rs1) | inst_rd(vd) | MATCH_VSLIDE1DOWN_VX;
}
#endif /* OPENOCD_TARGET_RISCV_OPCODES_H */

View File

@ -20,8 +20,8 @@ int riscv_program_init(struct riscv_program *p, struct target *target)
p->target = target;
p->instruction_count = 0;
for (size_t i = 0; i < RISCV_MAX_PROGBUF_SIZE; ++i)
p->progbuf[i] = -1;
for (unsigned int i = 0; i < RISCV013_MAX_PROGBUF_SIZE; ++i)
p->progbuf[i] = (uint32_t)(-1);
p->execution_result = RISCV_PROGBUF_EXEC_RESULT_NOT_EXECUTED;
return ERROR_OK;
@ -47,9 +47,9 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
if (riscv_program_ebreak(p) != ERROR_OK) {
LOG_TARGET_ERROR(t, "Unable to insert ebreak into program buffer");
for (size_t i = 0; i < riscv_progbuf_size(p->target); ++i)
LOG_TARGET_ERROR(t, "ram[%02x]: DASM(0x%08" PRIx32 ") [0x%08" PRIx32 "]",
(int)i, p->progbuf[i], p->progbuf[i]);
for (unsigned int i = 0; i < riscv_progbuf_size(p->target); ++i)
LOG_TARGET_ERROR(t, "progbuf[%02x]: DASM(0x%08" PRIx32 ") [0x%08" PRIx32 "]",
i, p->progbuf[i], p->progbuf[i]);
return ERROR_FAIL;
}
@ -70,27 +70,27 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
return ERROR_OK;
}
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, sd(d, b, offset));
}
int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, sw(d, b, offset));
}
int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, sh(d, b, offset));
}
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, sb(d, b, offset));
}
int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset,
int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset,
unsigned int size)
{
switch (size) {
@ -107,27 +107,27 @@ int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regn
return ERROR_FAIL;
}
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, ld(d, b, offset));
}
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, lw(d, b, offset));
}
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, lh(d, b, offset));
}
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset)
{
return riscv_program_insert(p, lb(d, b, offset));
}
int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset,
int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t offset,
unsigned int size)
{
switch (size) {
@ -144,13 +144,13 @@ int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno
return ERROR_FAIL;
}
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
{
assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
return riscv_program_insert(p, csrrsi(d, z, csr - GDB_REGNO_CSR0));
}
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr)
{
assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
return riscv_program_insert(p, csrrci(d, z, csr - GDB_REGNO_CSR0));
@ -164,7 +164,7 @@ int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
{
assert(csr >= GDB_REGNO_CSR0);
assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
return riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));
}
@ -198,8 +198,8 @@ int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
{
if (p->instruction_count >= riscv_progbuf_size(p->target)) {
LOG_TARGET_ERROR(p->target, "Unable to insert program into progbuf, "
"capacity would be exceeded (progbufsize=%d).",
(int)riscv_progbuf_size(p->target));
"capacity would be exceeded (progbufsize=%u).",
riscv_progbuf_size(p->target));
return ERROR_FAIL;
}

View File

@ -5,9 +5,7 @@
#include "riscv.h"
#define RISCV_MAX_PROGBUF_SIZE 32
#define RISCV_REGISTER_COUNT 32
#define RISCV_DSCRATCH_COUNT 2
#define RISCV013_MAX_PROGBUF_SIZE 16
typedef enum {
RISCV_PROGBUF_EXEC_RESULT_NOT_EXECUTED,
@ -23,10 +21,10 @@ typedef enum {
struct riscv_program {
struct target *target;
uint32_t progbuf[RISCV_MAX_PROGBUF_SIZE];
uint32_t progbuf[RISCV013_MAX_PROGBUF_SIZE];
/* Number of 32-bit instructions in the program. */
size_t instruction_count;
unsigned int instruction_count;
/* execution result of the program */
/* TODO: remove this field. We should make it a parameter to riscv_program_exec */
@ -52,22 +50,22 @@ int riscv_program_insert(struct riscv_program *p, riscv_insn_t i);
/* Helpers to assemble various instructions. Return 0 on success. These might
* assemble into a multi-instruction sequence that overwrites some other
* register, but those will be properly saved and restored. */
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int o,
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int16_t o);
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int16_t o);
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int16_t o);
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int16_t o);
int riscv_program_load(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t o,
unsigned int s);
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
int riscv_program_swr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
int riscv_program_shr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int o,
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int16_t o);
int riscv_program_swr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int16_t o);
int riscv_program_shr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int16_t o);
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int16_t o);
int riscv_program_store(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int16_t o,
unsigned int s);
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr);
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr);
int riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr);
int riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, uint8_t z, enum gdb_regno csr);
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr);
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr);

View File

@ -251,7 +251,7 @@ static unsigned int slot_offset(const struct target *target, slot_t slot)
}
static uint32_t load(const struct target *target, unsigned int rd,
unsigned int base, uint16_t offset)
unsigned int base, int16_t offset)
{
switch (riscv_xlen(target)) {
case 32:
@ -264,7 +264,7 @@ static uint32_t load(const struct target *target, unsigned int rd,
}
static uint32_t store(const struct target *target, unsigned int src,
unsigned int base, uint16_t offset)
unsigned int base, int16_t offset)
{
switch (riscv_xlen(target)) {
case 32:
@ -280,14 +280,16 @@ static uint32_t load_slot(const struct target *target, unsigned int dest,
slot_t slot)
{
unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
return load(target, dest, ZERO, offset);
assert(offset <= MAX_INT12);
return load(target, dest, ZERO, (int16_t)offset);
}
static uint32_t store_slot(const struct target *target, unsigned int src,
slot_t slot)
{
unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
return store(target, src, ZERO, offset);
assert(offset <= MAX_INT12);
return store(target, src, ZERO, (int16_t)offset);
}
static uint16_t dram_address(unsigned int index)
@ -599,9 +601,9 @@ static void scans_add_write32(scans_t *scans, uint16_t address, uint32_t data,
static void scans_add_write_jump(scans_t *scans, uint16_t address,
bool set_interrupt)
{
scans_add_write32(scans, address,
jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*address))),
set_interrupt);
unsigned int jump_offset = DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4 * address);
assert(jump_offset <= MAX_INT21);
scans_add_write32(scans, address, jal(0, (int32_t)jump_offset), set_interrupt);
}
/** Add a 32-bit dbus write for an instruction that loads from the indicated
@ -780,22 +782,25 @@ static void cache_set(struct target *target, slot_t slot, uint64_t data)
static void cache_set_jump(struct target *target, unsigned int index)
{
cache_set32(target, index,
jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index))));
unsigned int jump_offset = DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4 * index);
assert(jump_offset <= MAX_INT21);
cache_set32(target, index, jal(0, (int32_t)jump_offset));
}
static void cache_set_load(struct target *target, unsigned int index,
unsigned int reg, slot_t slot)
{
uint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
cache_set32(target, index, load(target, reg, ZERO, offset));
unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
assert(offset <= MAX_INT12);
cache_set32(target, index, load(target, reg, ZERO, (int16_t)offset));
}
static void cache_set_store(struct target *target, unsigned int index,
unsigned int reg, slot_t slot)
{
uint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
cache_set32(target, index, store(target, reg, ZERO, offset));
unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);
assert(offset <= MAX_INT12);
cache_set32(target, index, store(target, reg, ZERO, (int16_t)offset));
}
static void dump_debug_ram(struct target *target)
@ -1004,9 +1009,9 @@ static uint64_t cache_get(struct target *target, slot_t slot)
static void dram_write_jump(struct target *target, unsigned int index,
bool set_interrupt)
{
dram_write32(target, index,
jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index))),
set_interrupt);
unsigned int jump_offset = DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4 * index);
assert(jump_offset <= MAX_INT21);
dram_write32(target, index, jal(0, (int32_t)jump_offset), set_interrupt);
}
static int wait_for_state(struct target *target, enum target_state state)

View File

@ -4963,7 +4963,7 @@ static int write_memory_progbuf_fill_progbuf(struct target *target, uint32_t siz
if (riscv_program_store(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0, size) != ERROR_OK)
return ERROR_FAIL;
if (riscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, size) != ERROR_OK)
if (riscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, (int16_t)size) != ERROR_OK)
return ERROR_FAIL;
if (riscv_program_ebreak(&program) != ERROR_OK)
@ -5339,9 +5339,12 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
static int riscv013_write_progbuf(struct target *target, unsigned int index, riscv_insn_t data)
{
assert(index < RISCV013_MAX_PROGBUF_SIZE);
dm013_info_t *dm = get_dm(target);
if (!dm)
return ERROR_FAIL;
if (dm->progbuf_cache[index] != data) {
if (dm_write(target, DM_PROGBUF0 + index, data) != ERROR_OK)
return ERROR_FAIL;

View File

@ -37,6 +37,8 @@
#define RISCV_TRIGGER_HIT_NOT_FOUND ((int64_t)-1)
#define RISCV_HALT_GROUP_REPOLL_LIMIT 5
static uint8_t ir_dtmcontrol[4] = {DTMCONTROL};
struct scan_field select_dtmcontrol = {
.in_value = NULL,
@ -4025,6 +4027,8 @@ int riscv_openocd_poll(struct target *target)
{
LOG_TARGET_DEBUG(target, "Polling all harts.");
struct riscv_info *i = riscv_info(target);
struct list_head *targets;
OOCD_LIST_HEAD(single_target_list);
@ -4046,6 +4050,7 @@ int riscv_openocd_poll(struct target *target)
unsigned int should_resume = 0;
unsigned int halted = 0;
unsigned int running = 0;
unsigned int cause_groups = 0;
struct target_list *entry;
foreach_smp_target(entry, targets) {
struct target *t = entry->target;
@ -4093,6 +4098,59 @@ int riscv_openocd_poll(struct target *target)
LOG_TARGET_DEBUG(target, "resume all");
riscv_resume(target, true, 0, 0, 0, false);
} else if (halted && running) {
LOG_TARGET_DEBUG(target, "SMP group is in inconsistent state: %u halted, %u running",
halted, running);
/* The SMP group is in an inconsistent state - some harts in the group have halted
* whereas others are running. The reasons for that (and corresponding
* OpenOCD actions) could be:
* 1) The targets are in the process of halting due to halt groups
* but not all of them halted --> poll again so that the halt reason of every
* hart can be accurately determined (e.g. semihosting).
* 2) The targets do not support halt groups --> OpenOCD must halt
* the remaining harts by a standard halt request.
* 3) The hart states got out of sync for some other unknown reason (problem?). -->
* Same as previous - try to halt the harts by a standard halt request
* to get them back in sync. */
/* Detect if the harts are just in the process of halting due to a halt group */
foreach_smp_target(entry, targets)
{
struct target *t = entry->target;
if (t->state == TARGET_HALTED) {
riscv_reg_t dcsr;
if (riscv_reg_get(t, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)
return ERROR_FAIL;
if (get_field(dcsr, CSR_DCSR_CAUSE) == CSR_DCSR_CAUSE_GROUP)
cause_groups++;
else
/* This hart has halted due to something else than a halt group.
* Don't continue checking the rest - exit early. */
break;
}
}
/* Condition: halted == cause_groups
*
* This condition indicates a paradox where:
* - All currently halted harts show CSR_DCSR_CAUSE_GROUP
* - However, no individual hart can be identified as the actual initiator of the halt condition
*
* Poll again so that the true halt reason can be discovered (e.g. CSR_DCSR_CAUSE_EBREAK) */
if (halted == cause_groups) {
LOG_TARGET_DEBUG(target, "The harts appear to just be in the process of halting due to a halt group.");
if (i->halt_group_repoll_count < RISCV_HALT_GROUP_REPOLL_LIMIT) {
/* Wait a little, then re-poll. */
i->halt_group_repoll_count++;
alive_sleep(10);
LOG_TARGET_DEBUG(target, "Re-polling the state of the SMP group.");
return riscv_openocd_poll(target);
}
/* We have already re-polled multiple times but the halt group is still inconsistent. */
LOG_TARGET_DEBUG(target, "Re-polled the SMP group %d times it is still not in a consistent state.",
RISCV_HALT_GROUP_REPOLL_LIMIT);
}
/* Halting the whole SMP group to bring it in sync. */
LOG_TARGET_DEBUG(target, "halt all; halted=%d",
halted);
riscv_halt(target);
@ -4110,6 +4168,8 @@ int riscv_openocd_poll(struct target *target)
}
}
i->halt_group_repoll_count = 0;
/* Call tick() for every hart. What happens in tick() is opaque to this
* layer. The reason it's outside the previous loop is that at this point
* the state of every hart has settled, so any side effects happening in
@ -6048,17 +6108,16 @@ static enum riscv_halt_reason riscv_halt_reason(struct target *target)
return r->halt_reason(target);
}
size_t riscv_progbuf_size(struct target *target)
unsigned int riscv_progbuf_size(struct target *target)
{
RISCV_INFO(r);
return r->get_progbufsize(target);
}
int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn)
int riscv_write_progbuf(struct target *target, unsigned int index, riscv_insn_t insn)
{
RISCV_INFO(r);
r->write_progbuf(target, index, insn);
return ERROR_OK;
return r->write_progbuf(target, index, insn);
}
riscv_insn_t riscv_read_progbuf(struct target *target, int index)

View File

@ -239,6 +239,7 @@ struct riscv_info {
/* Used by riscv_openocd_poll(). */
bool halted_needs_event_callback;
enum target_event halted_callback_event;
unsigned int halt_group_repoll_count;
enum riscv_isrmasking_mode isrmask_mode;
@ -473,10 +474,10 @@ int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state);
/* These helper functions let the generic program interface get target-specific
* information. */
size_t riscv_progbuf_size(struct target *target);
unsigned int riscv_progbuf_size(struct target *target);
riscv_insn_t riscv_read_progbuf(struct target *target, int index);
int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn);
int riscv_write_progbuf(struct target *target, unsigned int index, riscv_insn_t insn);
int riscv_execute_progbuf(struct target *target, uint32_t *cmderr);
void riscv_fill_dm_nop(const struct target *target, uint8_t *buf);