mirror of https://github.com/xemu-project/xemu.git
RISC-V Patches for 4.0-rc0, Part 2
This patch set contains three major sources of bug fixes: * Jim has added support for GDB XML files, as well as fixing access to CSRs via the GDB stub. * Alistair has rebased a large set of fixes from Michael that were still in his patch queue. These fix bugs all over our tree, including: * Logging of PMP errors. * User ABI cleanups and fixes, most notably on RVE guests. * Fixes for interrupt emulation fidelity. * Improvements to the emulation fidelity of the sifive_u machine. * Bin Meng has improved the emulation fidelity of the SiFive UART, which now supports both TX and RX interrupts (as well as setting the correct interrupt line). -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEAM520YNJYN/OiG3470yhUCzLq0EFAlyQ46MTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRDvTKFQLMurQT7CEACDhwOw5Xmp5OBUrZWBUG84nURt8yNG WJ4hPfyc765xVJ8FHPlRR5s1mAIF9232LfV/sBnAtlNnl1pRbyckPuOFxLUjPpjK DLY83z3zJgVhsTCa7oBGd2WSJG6YQ+uSS/g8MomtVUjU34qZliF0nX5HeLUmj/EY 2AAge+vYUj7+5aQh5pveRaC4F7aZ4hukowPsDTknUo8EpAR25DTtHIjfxxdo4ONQ 8gWxGsg/QpaJPyIw4fw5yBn1D49hq8+3VNaBNv+Lajq6BLl/esIIrCawvp90EGUx QeIm7Sws1vVaeOIYmrjLjChRveS4xxV7fjScZZ4IlhMqY0yQU7nNfcRkefsS0EoE 0TKEQxkNMLfJcB7SEL6FtbnPTfzz4nyouA9D4feZaLh6cgRXj77LyoO54kKRxugX m1+VOd0VT34VM1QaXIy6fYXod6GdXw5mAnSQsfIAKSk9/0fOzeafMBj5gAZuf7jI YWEKwXZOmENXehTXRvVDQh2A4j5tBXP9T2K3iSVktcxjc7/3a4vQAJZMudpYmLSx sKYTBSF2bQ379fZUoEU6B+7AwBSf7VT/WqOqf2GC/IJ/dmpxzZY7bq4G9lqodhGl zYgVOqAVJHjfEHSXaMICvAb+/mK6EGIw77xvHUZ3RPFWjaTrMHBifogzQMQ5+ZWD V3JBczHO9VrviA== =365E -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-4.0-rc0-2' into staging RISC-V Patches for 4.0-rc0, Part 2 This patch set contains three major sources of bug fixes: * Jim has added support for GDB XML files, as well as fixing access to CSRs via the GDB stub. * Alistair has rebased a large set of fixes from Michael that were still in his patch queue. These fix bugs all over our tree, including: * Logging of PMP errors. * User ABI cleanups and fixes, most notably on RVE guests. * Fixes for interrupt emulation fidelity. * Improvements to the emulation fidelity of the sifive_u machine. * Bin Meng has improved the emulation fidelity of the SiFive UART, which now supports both TX and RX interrupts (as well as setting the correct interrupt line). # gpg: Signature made Tue 19 Mar 2019 12:42:11 GMT # gpg: using RSA key 00CE76D1834960DFCE886DF8EF4CA1502CCBAB41 # gpg: issuer "palmer@dabbelt.com" # gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown] # gpg: aka "Palmer Dabbelt <palmer@sifive.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 00CE 76D1 8349 60DF CE88 6DF8 EF4C A150 2CCB AB41 * remotes/palmer/tags/riscv-for-master-4.0-rc0-2: riscv: sifive_u: Correct UART0's IRQ in the device tree riscv: sifive_uart: Generate TX interrupt target/riscv: Remove unused struct riscv: sifive_u: Allow up to 4 CPUs to be created RISC-V: Update load reservation comment in do_interrupt RISC-V: Convert trap debugging to trace events RISC-V: Add support for vectored interrupts RISC-V: Change local interrupts from edge to level RISC-V: linux-user support for RVE ABI elf: Add RISC-V PSABI ELF header defines RISC-V: Remove unnecessary disassembler constraints RISC-V: Allow interrupt controllers to claim interrupts RISC-V: Replace __builtin_popcount with ctpop8 in PLIC riscv: pmp: Log pmp access errors as guest errors RISC-V: Add hooks to use the gdb xml files. RISC-V: Add debug support for accessing CSRs. RISC-V: Fixes to CSR_* register macros. RISC-V: Add 64-bit gdb xml files. RISC-V: Add 32-bit gdb xml files. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
b98a66201d
|
@ -186,6 +186,7 @@ trace-events-subdirs += target/hppa
|
|||
trace-events-subdirs += target/i386
|
||||
trace-events-subdirs += target/mips
|
||||
trace-events-subdirs += target/ppc
|
||||
trace-events-subdirs += target/riscv
|
||||
trace-events-subdirs += target/s390x
|
||||
trace-events-subdirs += target/sparc
|
||||
trace-events-subdirs += ui
|
||||
|
|
|
@ -7514,12 +7514,14 @@ case "$target_name" in
|
|||
TARGET_BASE_ARCH=riscv
|
||||
TARGET_ABI_DIR=riscv
|
||||
mttcg=yes
|
||||
gdb_xml_files="riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-32bit-csr.xml"
|
||||
target_compiler=$cross_cc_riscv32
|
||||
;;
|
||||
riscv64)
|
||||
TARGET_BASE_ARCH=riscv
|
||||
TARGET_ABI_DIR=riscv
|
||||
mttcg=yes
|
||||
gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml"
|
||||
target_compiler=$cross_cc_riscv64
|
||||
;;
|
||||
sh4|sh4eb)
|
||||
|
|
138
disas/riscv.c
138
disas/riscv.c
|
@ -87,33 +87,10 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
rvc_end,
|
||||
rvc_simm_6,
|
||||
rvc_imm_6,
|
||||
rvc_imm_7,
|
||||
rvc_imm_8,
|
||||
rvc_imm_9,
|
||||
rvc_imm_10,
|
||||
rvc_imm_12,
|
||||
rvc_imm_18,
|
||||
rvc_imm_nz,
|
||||
rvc_imm_x2,
|
||||
rvc_imm_x4,
|
||||
rvc_imm_x8,
|
||||
rvc_imm_x16,
|
||||
rvc_rd_b3,
|
||||
rvc_rs1_b3,
|
||||
rvc_rs2_b3,
|
||||
rvc_rd_eq_rs1,
|
||||
rvc_rd_eq_ra,
|
||||
rvc_rd_eq_sp,
|
||||
rvc_rd_eq_x0,
|
||||
rvc_rs1_eq_sp,
|
||||
rvc_rs1_eq_x0,
|
||||
rvc_rs2_eq_x0,
|
||||
rvc_rd_ne_x0_x2,
|
||||
rvc_rd_ne_x0,
|
||||
rvc_rs1_ne_x0,
|
||||
rvc_rs2_ne_x0,
|
||||
rvc_rs2_eq_rs1,
|
||||
rvc_rs1_eq_ra,
|
||||
rvc_imm_eq_zero,
|
||||
|
@ -2522,111 +2499,16 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
|
|||
uint8_t rd = dec->rd, rs1 = dec->rs1, rs2 = dec->rs2;
|
||||
while (*c != rvc_end) {
|
||||
switch (*c) {
|
||||
case rvc_simm_6:
|
||||
if (!(imm >= -32 && imm < 32)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_6:
|
||||
if (!(imm <= 63)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_7:
|
||||
if (!(imm <= 127)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_8:
|
||||
if (!(imm <= 255)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_9:
|
||||
if (!(imm <= 511)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_10:
|
||||
if (!(imm <= 1023)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_12:
|
||||
if (!(imm <= 4095)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_18:
|
||||
if (!(imm <= 262143)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_nz:
|
||||
if (!(imm != 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_x2:
|
||||
if (!((imm & 0b1) == 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_x4:
|
||||
if (!((imm & 0b11) == 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_x8:
|
||||
if (!((imm & 0b111) == 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_imm_x16:
|
||||
if (!((imm & 0b1111) == 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_b3:
|
||||
if (!(rd >= 8 && rd <= 15)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs1_b3:
|
||||
if (!(rs1 >= 8 && rs1 <= 15)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs2_b3:
|
||||
if (!(rs2 >= 8 && rs2 <= 15)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_eq_rs1:
|
||||
if (!(rd == rs1)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_eq_ra:
|
||||
if (!(rd == 1)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_eq_sp:
|
||||
if (!(rd == 2)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_eq_x0:
|
||||
if (!(rd == 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs1_eq_sp:
|
||||
if (!(rs1 == 2)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs1_eq_x0:
|
||||
if (!(rs1 == 0)) {
|
||||
return false;
|
||||
|
@ -2637,26 +2519,6 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_ne_x0_x2:
|
||||
if (!(rd != 0 && rd != 2)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rd_ne_x0:
|
||||
if (!(rd != 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs1_ne_x0:
|
||||
if (!(rs1 != 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs2_ne_x0:
|
||||
if (!(rs2 != 0)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case rvc_rs2_eq_rs1:
|
||||
if (!(rs2 == rs1)) {
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!-- Register numbers are hard-coded in order to maintain backward
|
||||
compatibility with older versions of tools that didn't use xml
|
||||
register descriptions. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.cpu">
|
||||
<reg name="zero" bitsize="32" type="int" regnum="0"/>
|
||||
<reg name="ra" bitsize="32" type="code_ptr"/>
|
||||
<reg name="sp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="gp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="tp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="t0" bitsize="32" type="int"/>
|
||||
<reg name="t1" bitsize="32" type="int"/>
|
||||
<reg name="t2" bitsize="32" type="int"/>
|
||||
<reg name="fp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="s1" bitsize="32" type="int"/>
|
||||
<reg name="a0" bitsize="32" type="int"/>
|
||||
<reg name="a1" bitsize="32" type="int"/>
|
||||
<reg name="a2" bitsize="32" type="int"/>
|
||||
<reg name="a3" bitsize="32" type="int"/>
|
||||
<reg name="a4" bitsize="32" type="int"/>
|
||||
<reg name="a5" bitsize="32" type="int"/>
|
||||
<reg name="a6" bitsize="32" type="int"/>
|
||||
<reg name="a7" bitsize="32" type="int"/>
|
||||
<reg name="s2" bitsize="32" type="int"/>
|
||||
<reg name="s3" bitsize="32" type="int"/>
|
||||
<reg name="s4" bitsize="32" type="int"/>
|
||||
<reg name="s5" bitsize="32" type="int"/>
|
||||
<reg name="s6" bitsize="32" type="int"/>
|
||||
<reg name="s7" bitsize="32" type="int"/>
|
||||
<reg name="s8" bitsize="32" type="int"/>
|
||||
<reg name="s9" bitsize="32" type="int"/>
|
||||
<reg name="s10" bitsize="32" type="int"/>
|
||||
<reg name="s11" bitsize="32" type="int"/>
|
||||
<reg name="t3" bitsize="32" type="int"/>
|
||||
<reg name="t4" bitsize="32" type="int"/>
|
||||
<reg name="t5" bitsize="32" type="int"/>
|
||||
<reg name="t6" bitsize="32" type="int"/>
|
||||
<reg name="pc" bitsize="32" type="code_ptr"/>
|
||||
</feature>
|
|
@ -0,0 +1,250 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.csr">
|
||||
<reg name="ustatus" bitsize="32"/>
|
||||
<reg name="uie" bitsize="32"/>
|
||||
<reg name="utvec" bitsize="32"/>
|
||||
<reg name="uscratch" bitsize="32"/>
|
||||
<reg name="uepc" bitsize="32"/>
|
||||
<reg name="ucause" bitsize="32"/>
|
||||
<reg name="utval" bitsize="32"/>
|
||||
<reg name="uip" bitsize="32"/>
|
||||
<reg name="fflags" bitsize="32"/>
|
||||
<reg name="frm" bitsize="32"/>
|
||||
<reg name="fcsr" bitsize="32"/>
|
||||
<reg name="cycle" bitsize="32"/>
|
||||
<reg name="time" bitsize="32"/>
|
||||
<reg name="instret" bitsize="32"/>
|
||||
<reg name="hpmcounter3" bitsize="32"/>
|
||||
<reg name="hpmcounter4" bitsize="32"/>
|
||||
<reg name="hpmcounter5" bitsize="32"/>
|
||||
<reg name="hpmcounter6" bitsize="32"/>
|
||||
<reg name="hpmcounter7" bitsize="32"/>
|
||||
<reg name="hpmcounter8" bitsize="32"/>
|
||||
<reg name="hpmcounter9" bitsize="32"/>
|
||||
<reg name="hpmcounter10" bitsize="32"/>
|
||||
<reg name="hpmcounter11" bitsize="32"/>
|
||||
<reg name="hpmcounter12" bitsize="32"/>
|
||||
<reg name="hpmcounter13" bitsize="32"/>
|
||||
<reg name="hpmcounter14" bitsize="32"/>
|
||||
<reg name="hpmcounter15" bitsize="32"/>
|
||||
<reg name="hpmcounter16" bitsize="32"/>
|
||||
<reg name="hpmcounter17" bitsize="32"/>
|
||||
<reg name="hpmcounter18" bitsize="32"/>
|
||||
<reg name="hpmcounter19" bitsize="32"/>
|
||||
<reg name="hpmcounter20" bitsize="32"/>
|
||||
<reg name="hpmcounter21" bitsize="32"/>
|
||||
<reg name="hpmcounter22" bitsize="32"/>
|
||||
<reg name="hpmcounter23" bitsize="32"/>
|
||||
<reg name="hpmcounter24" bitsize="32"/>
|
||||
<reg name="hpmcounter25" bitsize="32"/>
|
||||
<reg name="hpmcounter26" bitsize="32"/>
|
||||
<reg name="hpmcounter27" bitsize="32"/>
|
||||
<reg name="hpmcounter28" bitsize="32"/>
|
||||
<reg name="hpmcounter29" bitsize="32"/>
|
||||
<reg name="hpmcounter30" bitsize="32"/>
|
||||
<reg name="hpmcounter31" bitsize="32"/>
|
||||
<reg name="cycleh" bitsize="32"/>
|
||||
<reg name="timeh" bitsize="32"/>
|
||||
<reg name="instreth" bitsize="32"/>
|
||||
<reg name="hpmcounter3h" bitsize="32"/>
|
||||
<reg name="hpmcounter4h" bitsize="32"/>
|
||||
<reg name="hpmcounter5h" bitsize="32"/>
|
||||
<reg name="hpmcounter6h" bitsize="32"/>
|
||||
<reg name="hpmcounter7h" bitsize="32"/>
|
||||
<reg name="hpmcounter8h" bitsize="32"/>
|
||||
<reg name="hpmcounter9h" bitsize="32"/>
|
||||
<reg name="hpmcounter10h" bitsize="32"/>
|
||||
<reg name="hpmcounter11h" bitsize="32"/>
|
||||
<reg name="hpmcounter12h" bitsize="32"/>
|
||||
<reg name="hpmcounter13h" bitsize="32"/>
|
||||
<reg name="hpmcounter14h" bitsize="32"/>
|
||||
<reg name="hpmcounter15h" bitsize="32"/>
|
||||
<reg name="hpmcounter16h" bitsize="32"/>
|
||||
<reg name="hpmcounter17h" bitsize="32"/>
|
||||
<reg name="hpmcounter18h" bitsize="32"/>
|
||||
<reg name="hpmcounter19h" bitsize="32"/>
|
||||
<reg name="hpmcounter20h" bitsize="32"/>
|
||||
<reg name="hpmcounter21h" bitsize="32"/>
|
||||
<reg name="hpmcounter22h" bitsize="32"/>
|
||||
<reg name="hpmcounter23h" bitsize="32"/>
|
||||
<reg name="hpmcounter24h" bitsize="32"/>
|
||||
<reg name="hpmcounter25h" bitsize="32"/>
|
||||
<reg name="hpmcounter26h" bitsize="32"/>
|
||||
<reg name="hpmcounter27h" bitsize="32"/>
|
||||
<reg name="hpmcounter28h" bitsize="32"/>
|
||||
<reg name="hpmcounter29h" bitsize="32"/>
|
||||
<reg name="hpmcounter30h" bitsize="32"/>
|
||||
<reg name="hpmcounter31h" bitsize="32"/>
|
||||
<reg name="sstatus" bitsize="32"/>
|
||||
<reg name="sedeleg" bitsize="32"/>
|
||||
<reg name="sideleg" bitsize="32"/>
|
||||
<reg name="sie" bitsize="32"/>
|
||||
<reg name="stvec" bitsize="32"/>
|
||||
<reg name="scounteren" bitsize="32"/>
|
||||
<reg name="sscratch" bitsize="32"/>
|
||||
<reg name="sepc" bitsize="32"/>
|
||||
<reg name="scause" bitsize="32"/>
|
||||
<reg name="stval" bitsize="32"/>
|
||||
<reg name="sip" bitsize="32"/>
|
||||
<reg name="satp" bitsize="32"/>
|
||||
<reg name="mvendorid" bitsize="32"/>
|
||||
<reg name="marchid" bitsize="32"/>
|
||||
<reg name="mimpid" bitsize="32"/>
|
||||
<reg name="mhartid" bitsize="32"/>
|
||||
<reg name="mstatus" bitsize="32"/>
|
||||
<reg name="misa" bitsize="32"/>
|
||||
<reg name="medeleg" bitsize="32"/>
|
||||
<reg name="mideleg" bitsize="32"/>
|
||||
<reg name="mie" bitsize="32"/>
|
||||
<reg name="mtvec" bitsize="32"/>
|
||||
<reg name="mcounteren" bitsize="32"/>
|
||||
<reg name="mscratch" bitsize="32"/>
|
||||
<reg name="mepc" bitsize="32"/>
|
||||
<reg name="mcause" bitsize="32"/>
|
||||
<reg name="mtval" bitsize="32"/>
|
||||
<reg name="mip" bitsize="32"/>
|
||||
<reg name="pmpcfg0" bitsize="32"/>
|
||||
<reg name="pmpcfg1" bitsize="32"/>
|
||||
<reg name="pmpcfg2" bitsize="32"/>
|
||||
<reg name="pmpcfg3" bitsize="32"/>
|
||||
<reg name="pmpaddr0" bitsize="32"/>
|
||||
<reg name="pmpaddr1" bitsize="32"/>
|
||||
<reg name="pmpaddr2" bitsize="32"/>
|
||||
<reg name="pmpaddr3" bitsize="32"/>
|
||||
<reg name="pmpaddr4" bitsize="32"/>
|
||||
<reg name="pmpaddr5" bitsize="32"/>
|
||||
<reg name="pmpaddr6" bitsize="32"/>
|
||||
<reg name="pmpaddr7" bitsize="32"/>
|
||||
<reg name="pmpaddr8" bitsize="32"/>
|
||||
<reg name="pmpaddr9" bitsize="32"/>
|
||||
<reg name="pmpaddr10" bitsize="32"/>
|
||||
<reg name="pmpaddr11" bitsize="32"/>
|
||||
<reg name="pmpaddr12" bitsize="32"/>
|
||||
<reg name="pmpaddr13" bitsize="32"/>
|
||||
<reg name="pmpaddr14" bitsize="32"/>
|
||||
<reg name="pmpaddr15" bitsize="32"/>
|
||||
<reg name="mcycle" bitsize="32"/>
|
||||
<reg name="minstret" bitsize="32"/>
|
||||
<reg name="mhpmcounter3" bitsize="32"/>
|
||||
<reg name="mhpmcounter4" bitsize="32"/>
|
||||
<reg name="mhpmcounter5" bitsize="32"/>
|
||||
<reg name="mhpmcounter6" bitsize="32"/>
|
||||
<reg name="mhpmcounter7" bitsize="32"/>
|
||||
<reg name="mhpmcounter8" bitsize="32"/>
|
||||
<reg name="mhpmcounter9" bitsize="32"/>
|
||||
<reg name="mhpmcounter10" bitsize="32"/>
|
||||
<reg name="mhpmcounter11" bitsize="32"/>
|
||||
<reg name="mhpmcounter12" bitsize="32"/>
|
||||
<reg name="mhpmcounter13" bitsize="32"/>
|
||||
<reg name="mhpmcounter14" bitsize="32"/>
|
||||
<reg name="mhpmcounter15" bitsize="32"/>
|
||||
<reg name="mhpmcounter16" bitsize="32"/>
|
||||
<reg name="mhpmcounter17" bitsize="32"/>
|
||||
<reg name="mhpmcounter18" bitsize="32"/>
|
||||
<reg name="mhpmcounter19" bitsize="32"/>
|
||||
<reg name="mhpmcounter20" bitsize="32"/>
|
||||
<reg name="mhpmcounter21" bitsize="32"/>
|
||||
<reg name="mhpmcounter22" bitsize="32"/>
|
||||
<reg name="mhpmcounter23" bitsize="32"/>
|
||||
<reg name="mhpmcounter24" bitsize="32"/>
|
||||
<reg name="mhpmcounter25" bitsize="32"/>
|
||||
<reg name="mhpmcounter26" bitsize="32"/>
|
||||
<reg name="mhpmcounter27" bitsize="32"/>
|
||||
<reg name="mhpmcounter28" bitsize="32"/>
|
||||
<reg name="mhpmcounter29" bitsize="32"/>
|
||||
<reg name="mhpmcounter30" bitsize="32"/>
|
||||
<reg name="mhpmcounter31" bitsize="32"/>
|
||||
<reg name="mcycleh" bitsize="32"/>
|
||||
<reg name="minstreth" bitsize="32"/>
|
||||
<reg name="mhpmcounter3h" bitsize="32"/>
|
||||
<reg name="mhpmcounter4h" bitsize="32"/>
|
||||
<reg name="mhpmcounter5h" bitsize="32"/>
|
||||
<reg name="mhpmcounter6h" bitsize="32"/>
|
||||
<reg name="mhpmcounter7h" bitsize="32"/>
|
||||
<reg name="mhpmcounter8h" bitsize="32"/>
|
||||
<reg name="mhpmcounter9h" bitsize="32"/>
|
||||
<reg name="mhpmcounter10h" bitsize="32"/>
|
||||
<reg name="mhpmcounter11h" bitsize="32"/>
|
||||
<reg name="mhpmcounter12h" bitsize="32"/>
|
||||
<reg name="mhpmcounter13h" bitsize="32"/>
|
||||
<reg name="mhpmcounter14h" bitsize="32"/>
|
||||
<reg name="mhpmcounter15h" bitsize="32"/>
|
||||
<reg name="mhpmcounter16h" bitsize="32"/>
|
||||
<reg name="mhpmcounter17h" bitsize="32"/>
|
||||
<reg name="mhpmcounter18h" bitsize="32"/>
|
||||
<reg name="mhpmcounter19h" bitsize="32"/>
|
||||
<reg name="mhpmcounter20h" bitsize="32"/>
|
||||
<reg name="mhpmcounter21h" bitsize="32"/>
|
||||
<reg name="mhpmcounter22h" bitsize="32"/>
|
||||
<reg name="mhpmcounter23h" bitsize="32"/>
|
||||
<reg name="mhpmcounter24h" bitsize="32"/>
|
||||
<reg name="mhpmcounter25h" bitsize="32"/>
|
||||
<reg name="mhpmcounter26h" bitsize="32"/>
|
||||
<reg name="mhpmcounter27h" bitsize="32"/>
|
||||
<reg name="mhpmcounter28h" bitsize="32"/>
|
||||
<reg name="mhpmcounter29h" bitsize="32"/>
|
||||
<reg name="mhpmcounter30h" bitsize="32"/>
|
||||
<reg name="mhpmcounter31h" bitsize="32"/>
|
||||
<reg name="mhpmevent3" bitsize="32"/>
|
||||
<reg name="mhpmevent4" bitsize="32"/>
|
||||
<reg name="mhpmevent5" bitsize="32"/>
|
||||
<reg name="mhpmevent6" bitsize="32"/>
|
||||
<reg name="mhpmevent7" bitsize="32"/>
|
||||
<reg name="mhpmevent8" bitsize="32"/>
|
||||
<reg name="mhpmevent9" bitsize="32"/>
|
||||
<reg name="mhpmevent10" bitsize="32"/>
|
||||
<reg name="mhpmevent11" bitsize="32"/>
|
||||
<reg name="mhpmevent12" bitsize="32"/>
|
||||
<reg name="mhpmevent13" bitsize="32"/>
|
||||
<reg name="mhpmevent14" bitsize="32"/>
|
||||
<reg name="mhpmevent15" bitsize="32"/>
|
||||
<reg name="mhpmevent16" bitsize="32"/>
|
||||
<reg name="mhpmevent17" bitsize="32"/>
|
||||
<reg name="mhpmevent18" bitsize="32"/>
|
||||
<reg name="mhpmevent19" bitsize="32"/>
|
||||
<reg name="mhpmevent20" bitsize="32"/>
|
||||
<reg name="mhpmevent21" bitsize="32"/>
|
||||
<reg name="mhpmevent22" bitsize="32"/>
|
||||
<reg name="mhpmevent23" bitsize="32"/>
|
||||
<reg name="mhpmevent24" bitsize="32"/>
|
||||
<reg name="mhpmevent25" bitsize="32"/>
|
||||
<reg name="mhpmevent26" bitsize="32"/>
|
||||
<reg name="mhpmevent27" bitsize="32"/>
|
||||
<reg name="mhpmevent28" bitsize="32"/>
|
||||
<reg name="mhpmevent29" bitsize="32"/>
|
||||
<reg name="mhpmevent30" bitsize="32"/>
|
||||
<reg name="mhpmevent31" bitsize="32"/>
|
||||
<reg name="tselect" bitsize="32"/>
|
||||
<reg name="tdata1" bitsize="32"/>
|
||||
<reg name="tdata2" bitsize="32"/>
|
||||
<reg name="tdata3" bitsize="32"/>
|
||||
<reg name="dcsr" bitsize="32"/>
|
||||
<reg name="dpc" bitsize="32"/>
|
||||
<reg name="dscratch" bitsize="32"/>
|
||||
<reg name="hstatus" bitsize="32"/>
|
||||
<reg name="hedeleg" bitsize="32"/>
|
||||
<reg name="hideleg" bitsize="32"/>
|
||||
<reg name="hie" bitsize="32"/>
|
||||
<reg name="htvec" bitsize="32"/>
|
||||
<reg name="hscratch" bitsize="32"/>
|
||||
<reg name="hepc" bitsize="32"/>
|
||||
<reg name="hcause" bitsize="32"/>
|
||||
<reg name="hbadaddr" bitsize="32"/>
|
||||
<reg name="hip" bitsize="32"/>
|
||||
<reg name="mbase" bitsize="32"/>
|
||||
<reg name="mbound" bitsize="32"/>
|
||||
<reg name="mibase" bitsize="32"/>
|
||||
<reg name="mibound" bitsize="32"/>
|
||||
<reg name="mdbase" bitsize="32"/>
|
||||
<reg name="mdbound" bitsize="32"/>
|
||||
<reg name="mucounteren" bitsize="32"/>
|
||||
<reg name="mscounteren" bitsize="32"/>
|
||||
<reg name="mhcounteren" bitsize="32"/>
|
||||
</feature>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!-- Register numbers are hard-coded in order to maintain backward
|
||||
compatibility with older versions of tools that didn't use xml
|
||||
register descriptions. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.fpu">
|
||||
<reg name="ft0" bitsize="32" type="ieee_single" regnum="33"/>
|
||||
<reg name="ft1" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft2" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft3" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft4" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft5" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft6" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft7" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs0" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs1" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa0" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa1" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa2" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa3" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa4" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa5" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa6" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fa7" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs2" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs3" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs4" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs5" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs6" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs7" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs8" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs9" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs10" bitsize="32" type="ieee_single"/>
|
||||
<reg name="fs11" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft8" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft9" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft10" bitsize="32" type="ieee_single"/>
|
||||
<reg name="ft11" bitsize="32" type="ieee_single"/>
|
||||
|
||||
<reg name="fflags" bitsize="32" type="int" regnum="66"/>
|
||||
<reg name="frm" bitsize="32" type="int" regnum="67"/>
|
||||
<reg name="fcsr" bitsize="32" type="int" regnum="68"/>
|
||||
</feature>
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!-- Register numbers are hard-coded in order to maintain backward
|
||||
compatibility with older versions of tools that didn't use xml
|
||||
register descriptions. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.cpu">
|
||||
<reg name="zero" bitsize="64" type="int" regnum="0"/>
|
||||
<reg name="ra" bitsize="64" type="code_ptr"/>
|
||||
<reg name="sp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="gp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="tp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="t0" bitsize="64" type="int"/>
|
||||
<reg name="t1" bitsize="64" type="int"/>
|
||||
<reg name="t2" bitsize="64" type="int"/>
|
||||
<reg name="fp" bitsize="64" type="data_ptr"/>
|
||||
<reg name="s1" bitsize="64" type="int"/>
|
||||
<reg name="a0" bitsize="64" type="int"/>
|
||||
<reg name="a1" bitsize="64" type="int"/>
|
||||
<reg name="a2" bitsize="64" type="int"/>
|
||||
<reg name="a3" bitsize="64" type="int"/>
|
||||
<reg name="a4" bitsize="64" type="int"/>
|
||||
<reg name="a5" bitsize="64" type="int"/>
|
||||
<reg name="a6" bitsize="64" type="int"/>
|
||||
<reg name="a7" bitsize="64" type="int"/>
|
||||
<reg name="s2" bitsize="64" type="int"/>
|
||||
<reg name="s3" bitsize="64" type="int"/>
|
||||
<reg name="s4" bitsize="64" type="int"/>
|
||||
<reg name="s5" bitsize="64" type="int"/>
|
||||
<reg name="s6" bitsize="64" type="int"/>
|
||||
<reg name="s7" bitsize="64" type="int"/>
|
||||
<reg name="s8" bitsize="64" type="int"/>
|
||||
<reg name="s9" bitsize="64" type="int"/>
|
||||
<reg name="s10" bitsize="64" type="int"/>
|
||||
<reg name="s11" bitsize="64" type="int"/>
|
||||
<reg name="t3" bitsize="64" type="int"/>
|
||||
<reg name="t4" bitsize="64" type="int"/>
|
||||
<reg name="t5" bitsize="64" type="int"/>
|
||||
<reg name="t6" bitsize="64" type="int"/>
|
||||
<reg name="pc" bitsize="64" type="code_ptr"/>
|
||||
</feature>
|
|
@ -0,0 +1,250 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.csr">
|
||||
<reg name="ustatus" bitsize="64"/>
|
||||
<reg name="uie" bitsize="64"/>
|
||||
<reg name="utvec" bitsize="64"/>
|
||||
<reg name="uscratch" bitsize="64"/>
|
||||
<reg name="uepc" bitsize="64"/>
|
||||
<reg name="ucause" bitsize="64"/>
|
||||
<reg name="utval" bitsize="64"/>
|
||||
<reg name="uip" bitsize="64"/>
|
||||
<reg name="fflags" bitsize="64"/>
|
||||
<reg name="frm" bitsize="64"/>
|
||||
<reg name="fcsr" bitsize="64"/>
|
||||
<reg name="cycle" bitsize="64"/>
|
||||
<reg name="time" bitsize="64"/>
|
||||
<reg name="instret" bitsize="64"/>
|
||||
<reg name="hpmcounter3" bitsize="64"/>
|
||||
<reg name="hpmcounter4" bitsize="64"/>
|
||||
<reg name="hpmcounter5" bitsize="64"/>
|
||||
<reg name="hpmcounter6" bitsize="64"/>
|
||||
<reg name="hpmcounter7" bitsize="64"/>
|
||||
<reg name="hpmcounter8" bitsize="64"/>
|
||||
<reg name="hpmcounter9" bitsize="64"/>
|
||||
<reg name="hpmcounter10" bitsize="64"/>
|
||||
<reg name="hpmcounter11" bitsize="64"/>
|
||||
<reg name="hpmcounter12" bitsize="64"/>
|
||||
<reg name="hpmcounter13" bitsize="64"/>
|
||||
<reg name="hpmcounter14" bitsize="64"/>
|
||||
<reg name="hpmcounter15" bitsize="64"/>
|
||||
<reg name="hpmcounter16" bitsize="64"/>
|
||||
<reg name="hpmcounter17" bitsize="64"/>
|
||||
<reg name="hpmcounter18" bitsize="64"/>
|
||||
<reg name="hpmcounter19" bitsize="64"/>
|
||||
<reg name="hpmcounter20" bitsize="64"/>
|
||||
<reg name="hpmcounter21" bitsize="64"/>
|
||||
<reg name="hpmcounter22" bitsize="64"/>
|
||||
<reg name="hpmcounter23" bitsize="64"/>
|
||||
<reg name="hpmcounter24" bitsize="64"/>
|
||||
<reg name="hpmcounter25" bitsize="64"/>
|
||||
<reg name="hpmcounter26" bitsize="64"/>
|
||||
<reg name="hpmcounter27" bitsize="64"/>
|
||||
<reg name="hpmcounter28" bitsize="64"/>
|
||||
<reg name="hpmcounter29" bitsize="64"/>
|
||||
<reg name="hpmcounter30" bitsize="64"/>
|
||||
<reg name="hpmcounter31" bitsize="64"/>
|
||||
<reg name="cycleh" bitsize="64"/>
|
||||
<reg name="timeh" bitsize="64"/>
|
||||
<reg name="instreth" bitsize="64"/>
|
||||
<reg name="hpmcounter3h" bitsize="64"/>
|
||||
<reg name="hpmcounter4h" bitsize="64"/>
|
||||
<reg name="hpmcounter5h" bitsize="64"/>
|
||||
<reg name="hpmcounter6h" bitsize="64"/>
|
||||
<reg name="hpmcounter7h" bitsize="64"/>
|
||||
<reg name="hpmcounter8h" bitsize="64"/>
|
||||
<reg name="hpmcounter9h" bitsize="64"/>
|
||||
<reg name="hpmcounter10h" bitsize="64"/>
|
||||
<reg name="hpmcounter11h" bitsize="64"/>
|
||||
<reg name="hpmcounter12h" bitsize="64"/>
|
||||
<reg name="hpmcounter13h" bitsize="64"/>
|
||||
<reg name="hpmcounter14h" bitsize="64"/>
|
||||
<reg name="hpmcounter15h" bitsize="64"/>
|
||||
<reg name="hpmcounter16h" bitsize="64"/>
|
||||
<reg name="hpmcounter17h" bitsize="64"/>
|
||||
<reg name="hpmcounter18h" bitsize="64"/>
|
||||
<reg name="hpmcounter19h" bitsize="64"/>
|
||||
<reg name="hpmcounter20h" bitsize="64"/>
|
||||
<reg name="hpmcounter21h" bitsize="64"/>
|
||||
<reg name="hpmcounter22h" bitsize="64"/>
|
||||
<reg name="hpmcounter23h" bitsize="64"/>
|
||||
<reg name="hpmcounter24h" bitsize="64"/>
|
||||
<reg name="hpmcounter25h" bitsize="64"/>
|
||||
<reg name="hpmcounter26h" bitsize="64"/>
|
||||
<reg name="hpmcounter27h" bitsize="64"/>
|
||||
<reg name="hpmcounter28h" bitsize="64"/>
|
||||
<reg name="hpmcounter29h" bitsize="64"/>
|
||||
<reg name="hpmcounter30h" bitsize="64"/>
|
||||
<reg name="hpmcounter31h" bitsize="64"/>
|
||||
<reg name="sstatus" bitsize="64"/>
|
||||
<reg name="sedeleg" bitsize="64"/>
|
||||
<reg name="sideleg" bitsize="64"/>
|
||||
<reg name="sie" bitsize="64"/>
|
||||
<reg name="stvec" bitsize="64"/>
|
||||
<reg name="scounteren" bitsize="64"/>
|
||||
<reg name="sscratch" bitsize="64"/>
|
||||
<reg name="sepc" bitsize="64"/>
|
||||
<reg name="scause" bitsize="64"/>
|
||||
<reg name="stval" bitsize="64"/>
|
||||
<reg name="sip" bitsize="64"/>
|
||||
<reg name="satp" bitsize="64"/>
|
||||
<reg name="mvendorid" bitsize="64"/>
|
||||
<reg name="marchid" bitsize="64"/>
|
||||
<reg name="mimpid" bitsize="64"/>
|
||||
<reg name="mhartid" bitsize="64"/>
|
||||
<reg name="mstatus" bitsize="64"/>
|
||||
<reg name="misa" bitsize="64"/>
|
||||
<reg name="medeleg" bitsize="64"/>
|
||||
<reg name="mideleg" bitsize="64"/>
|
||||
<reg name="mie" bitsize="64"/>
|
||||
<reg name="mtvec" bitsize="64"/>
|
||||
<reg name="mcounteren" bitsize="64"/>
|
||||
<reg name="mscratch" bitsize="64"/>
|
||||
<reg name="mepc" bitsize="64"/>
|
||||
<reg name="mcause" bitsize="64"/>
|
||||
<reg name="mtval" bitsize="64"/>
|
||||
<reg name="mip" bitsize="64"/>
|
||||
<reg name="pmpcfg0" bitsize="64"/>
|
||||
<reg name="pmpcfg1" bitsize="64"/>
|
||||
<reg name="pmpcfg2" bitsize="64"/>
|
||||
<reg name="pmpcfg3" bitsize="64"/>
|
||||
<reg name="pmpaddr0" bitsize="64"/>
|
||||
<reg name="pmpaddr1" bitsize="64"/>
|
||||
<reg name="pmpaddr2" bitsize="64"/>
|
||||
<reg name="pmpaddr3" bitsize="64"/>
|
||||
<reg name="pmpaddr4" bitsize="64"/>
|
||||
<reg name="pmpaddr5" bitsize="64"/>
|
||||
<reg name="pmpaddr6" bitsize="64"/>
|
||||
<reg name="pmpaddr7" bitsize="64"/>
|
||||
<reg name="pmpaddr8" bitsize="64"/>
|
||||
<reg name="pmpaddr9" bitsize="64"/>
|
||||
<reg name="pmpaddr10" bitsize="64"/>
|
||||
<reg name="pmpaddr11" bitsize="64"/>
|
||||
<reg name="pmpaddr12" bitsize="64"/>
|
||||
<reg name="pmpaddr13" bitsize="64"/>
|
||||
<reg name="pmpaddr14" bitsize="64"/>
|
||||
<reg name="pmpaddr15" bitsize="64"/>
|
||||
<reg name="mcycle" bitsize="64"/>
|
||||
<reg name="minstret" bitsize="64"/>
|
||||
<reg name="mhpmcounter3" bitsize="64"/>
|
||||
<reg name="mhpmcounter4" bitsize="64"/>
|
||||
<reg name="mhpmcounter5" bitsize="64"/>
|
||||
<reg name="mhpmcounter6" bitsize="64"/>
|
||||
<reg name="mhpmcounter7" bitsize="64"/>
|
||||
<reg name="mhpmcounter8" bitsize="64"/>
|
||||
<reg name="mhpmcounter9" bitsize="64"/>
|
||||
<reg name="mhpmcounter10" bitsize="64"/>
|
||||
<reg name="mhpmcounter11" bitsize="64"/>
|
||||
<reg name="mhpmcounter12" bitsize="64"/>
|
||||
<reg name="mhpmcounter13" bitsize="64"/>
|
||||
<reg name="mhpmcounter14" bitsize="64"/>
|
||||
<reg name="mhpmcounter15" bitsize="64"/>
|
||||
<reg name="mhpmcounter16" bitsize="64"/>
|
||||
<reg name="mhpmcounter17" bitsize="64"/>
|
||||
<reg name="mhpmcounter18" bitsize="64"/>
|
||||
<reg name="mhpmcounter19" bitsize="64"/>
|
||||
<reg name="mhpmcounter20" bitsize="64"/>
|
||||
<reg name="mhpmcounter21" bitsize="64"/>
|
||||
<reg name="mhpmcounter22" bitsize="64"/>
|
||||
<reg name="mhpmcounter23" bitsize="64"/>
|
||||
<reg name="mhpmcounter24" bitsize="64"/>
|
||||
<reg name="mhpmcounter25" bitsize="64"/>
|
||||
<reg name="mhpmcounter26" bitsize="64"/>
|
||||
<reg name="mhpmcounter27" bitsize="64"/>
|
||||
<reg name="mhpmcounter28" bitsize="64"/>
|
||||
<reg name="mhpmcounter29" bitsize="64"/>
|
||||
<reg name="mhpmcounter30" bitsize="64"/>
|
||||
<reg name="mhpmcounter31" bitsize="64"/>
|
||||
<reg name="mcycleh" bitsize="64"/>
|
||||
<reg name="minstreth" bitsize="64"/>
|
||||
<reg name="mhpmcounter3h" bitsize="64"/>
|
||||
<reg name="mhpmcounter4h" bitsize="64"/>
|
||||
<reg name="mhpmcounter5h" bitsize="64"/>
|
||||
<reg name="mhpmcounter6h" bitsize="64"/>
|
||||
<reg name="mhpmcounter7h" bitsize="64"/>
|
||||
<reg name="mhpmcounter8h" bitsize="64"/>
|
||||
<reg name="mhpmcounter9h" bitsize="64"/>
|
||||
<reg name="mhpmcounter10h" bitsize="64"/>
|
||||
<reg name="mhpmcounter11h" bitsize="64"/>
|
||||
<reg name="mhpmcounter12h" bitsize="64"/>
|
||||
<reg name="mhpmcounter13h" bitsize="64"/>
|
||||
<reg name="mhpmcounter14h" bitsize="64"/>
|
||||
<reg name="mhpmcounter15h" bitsize="64"/>
|
||||
<reg name="mhpmcounter16h" bitsize="64"/>
|
||||
<reg name="mhpmcounter17h" bitsize="64"/>
|
||||
<reg name="mhpmcounter18h" bitsize="64"/>
|
||||
<reg name="mhpmcounter19h" bitsize="64"/>
|
||||
<reg name="mhpmcounter20h" bitsize="64"/>
|
||||
<reg name="mhpmcounter21h" bitsize="64"/>
|
||||
<reg name="mhpmcounter22h" bitsize="64"/>
|
||||
<reg name="mhpmcounter23h" bitsize="64"/>
|
||||
<reg name="mhpmcounter24h" bitsize="64"/>
|
||||
<reg name="mhpmcounter25h" bitsize="64"/>
|
||||
<reg name="mhpmcounter26h" bitsize="64"/>
|
||||
<reg name="mhpmcounter27h" bitsize="64"/>
|
||||
<reg name="mhpmcounter28h" bitsize="64"/>
|
||||
<reg name="mhpmcounter29h" bitsize="64"/>
|
||||
<reg name="mhpmcounter30h" bitsize="64"/>
|
||||
<reg name="mhpmcounter31h" bitsize="64"/>
|
||||
<reg name="mhpmevent3" bitsize="64"/>
|
||||
<reg name="mhpmevent4" bitsize="64"/>
|
||||
<reg name="mhpmevent5" bitsize="64"/>
|
||||
<reg name="mhpmevent6" bitsize="64"/>
|
||||
<reg name="mhpmevent7" bitsize="64"/>
|
||||
<reg name="mhpmevent8" bitsize="64"/>
|
||||
<reg name="mhpmevent9" bitsize="64"/>
|
||||
<reg name="mhpmevent10" bitsize="64"/>
|
||||
<reg name="mhpmevent11" bitsize="64"/>
|
||||
<reg name="mhpmevent12" bitsize="64"/>
|
||||
<reg name="mhpmevent13" bitsize="64"/>
|
||||
<reg name="mhpmevent14" bitsize="64"/>
|
||||
<reg name="mhpmevent15" bitsize="64"/>
|
||||
<reg name="mhpmevent16" bitsize="64"/>
|
||||
<reg name="mhpmevent17" bitsize="64"/>
|
||||
<reg name="mhpmevent18" bitsize="64"/>
|
||||
<reg name="mhpmevent19" bitsize="64"/>
|
||||
<reg name="mhpmevent20" bitsize="64"/>
|
||||
<reg name="mhpmevent21" bitsize="64"/>
|
||||
<reg name="mhpmevent22" bitsize="64"/>
|
||||
<reg name="mhpmevent23" bitsize="64"/>
|
||||
<reg name="mhpmevent24" bitsize="64"/>
|
||||
<reg name="mhpmevent25" bitsize="64"/>
|
||||
<reg name="mhpmevent26" bitsize="64"/>
|
||||
<reg name="mhpmevent27" bitsize="64"/>
|
||||
<reg name="mhpmevent28" bitsize="64"/>
|
||||
<reg name="mhpmevent29" bitsize="64"/>
|
||||
<reg name="mhpmevent30" bitsize="64"/>
|
||||
<reg name="mhpmevent31" bitsize="64"/>
|
||||
<reg name="tselect" bitsize="64"/>
|
||||
<reg name="tdata1" bitsize="64"/>
|
||||
<reg name="tdata2" bitsize="64"/>
|
||||
<reg name="tdata3" bitsize="64"/>
|
||||
<reg name="dcsr" bitsize="64"/>
|
||||
<reg name="dpc" bitsize="64"/>
|
||||
<reg name="dscratch" bitsize="64"/>
|
||||
<reg name="hstatus" bitsize="64"/>
|
||||
<reg name="hedeleg" bitsize="64"/>
|
||||
<reg name="hideleg" bitsize="64"/>
|
||||
<reg name="hie" bitsize="64"/>
|
||||
<reg name="htvec" bitsize="64"/>
|
||||
<reg name="hscratch" bitsize="64"/>
|
||||
<reg name="hepc" bitsize="64"/>
|
||||
<reg name="hcause" bitsize="64"/>
|
||||
<reg name="hbadaddr" bitsize="64"/>
|
||||
<reg name="hip" bitsize="64"/>
|
||||
<reg name="mbase" bitsize="64"/>
|
||||
<reg name="mbound" bitsize="64"/>
|
||||
<reg name="mibase" bitsize="64"/>
|
||||
<reg name="mibound" bitsize="64"/>
|
||||
<reg name="mdbase" bitsize="64"/>
|
||||
<reg name="mdbound" bitsize="64"/>
|
||||
<reg name="mucounteren" bitsize="64"/>
|
||||
<reg name="mscounteren" bitsize="64"/>
|
||||
<reg name="mhcounteren" bitsize="64"/>
|
||||
</feature>
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!-- Register numbers are hard-coded in order to maintain backward
|
||||
compatibility with older versions of tools that didn't use xml
|
||||
register descriptions. -->
|
||||
|
||||
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||
<feature name="org.gnu.gdb.riscv.fpu">
|
||||
|
||||
<union id="riscv_double">
|
||||
<field name="float" type="ieee_single"/>
|
||||
<field name="double" type="ieee_double"/>
|
||||
</union>
|
||||
|
||||
<reg name="ft0" bitsize="64" type="riscv_double" regnum="33"/>
|
||||
<reg name="ft1" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft2" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft3" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft4" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft5" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft6" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft7" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs0" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs1" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa0" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa1" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa2" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa3" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa4" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa5" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa6" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fa7" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs2" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs3" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs4" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs5" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs6" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs7" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs8" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs9" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs10" bitsize="64" type="riscv_double"/>
|
||||
<reg name="fs11" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft8" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft9" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft10" bitsize="64" type="riscv_double"/>
|
||||
<reg name="ft11" bitsize="64" type="riscv_double"/>
|
||||
|
||||
<reg name="fflags" bitsize="32" type="int" regnum="66"/>
|
||||
<reg name="frm" bitsize="32" type="int" regnum="67"/>
|
||||
<reg name="fcsr" bitsize="32" type="int" regnum="68"/>
|
||||
</feature>
|
|
@ -23,6 +23,7 @@
|
|||
#include "qemu/error-report.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "target/riscv/cpu.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/riscv/sifive_plic.h"
|
||||
|
||||
#define RISCV_DEBUG_PLIC 0
|
||||
|
@ -383,7 +384,7 @@ static void parse_hart_config(SiFivePLICState *plic)
|
|||
p = plic->hart_config;
|
||||
while ((c = *p++)) {
|
||||
if (c == ',') {
|
||||
addrid += __builtin_popcount(modes);
|
||||
addrid += ctpop8(modes);
|
||||
modes = 0;
|
||||
hartid++;
|
||||
} else {
|
||||
|
@ -397,7 +398,7 @@ static void parse_hart_config(SiFivePLICState *plic)
|
|||
}
|
||||
}
|
||||
if (modes) {
|
||||
addrid += __builtin_popcount(modes);
|
||||
addrid += ctpop8(modes);
|
||||
}
|
||||
hartid++;
|
||||
|
||||
|
@ -431,6 +432,7 @@ static void sifive_plic_irq_request(void *opaque, int irq, int level)
|
|||
static void sifive_plic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SiFivePLICState *plic = SIFIVE_PLIC(dev);
|
||||
int i;
|
||||
|
||||
memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
|
||||
TYPE_SIFIVE_PLIC, plic->aperture_size);
|
||||
|
@ -443,6 +445,19 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
|
|||
plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
|
||||
qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
|
||||
|
||||
/* We can't allow the supervisor to control SEIP as this would allow the
|
||||
* supervisor to clear a pending external interrupt which will result in
|
||||
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
|
||||
* hardware controlled when a PLIC is attached.
|
||||
*/
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
|
||||
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
|
||||
error_report("SEIP already claimed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sifive_plic_class_init(ObjectClass *klass, void *data)
|
||||
|
|
|
@ -244,7 +244,7 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
|
|||
qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
|
||||
SIFIVE_U_CLOCK_FREQ / 2);
|
||||
qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
|
||||
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 1);
|
||||
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
|
||||
|
||||
qemu_fdt_add_subnode(fdt, "/chosen");
|
||||
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
|
||||
|
@ -398,7 +398,10 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
|
|||
{
|
||||
mc->desc = "RISC-V Board compatible with SiFive U SDK";
|
||||
mc->init = riscv_sifive_u_init;
|
||||
mc->max_cpus = 1;
|
||||
/* The real hardware has 5 CPUs, but one of them is a small embedded power
|
||||
* management CPU.
|
||||
*/
|
||||
mc->max_cpus = 4;
|
||||
}
|
||||
|
||||
DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
|
||||
|
|
|
@ -51,7 +51,8 @@ static uint64_t uart_ip(SiFiveUARTState *s)
|
|||
static void update_irq(SiFiveUARTState *s)
|
||||
{
|
||||
int cond = 0;
|
||||
if ((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len) {
|
||||
if ((s->ie & SIFIVE_UART_IE_TXWM) ||
|
||||
((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len)) {
|
||||
cond = 1;
|
||||
}
|
||||
if (cond) {
|
||||
|
@ -108,6 +109,7 @@ uart_write(void *opaque, hwaddr addr,
|
|||
switch (addr) {
|
||||
case SIFIVE_UART_TXFIFO:
|
||||
qemu_chr_fe_write(&s->chr, &ch, 1);
|
||||
update_irq(s);
|
||||
return;
|
||||
case SIFIVE_UART_IE:
|
||||
s->ie = val64;
|
||||
|
|
|
@ -1393,6 +1393,16 @@ typedef struct {
|
|||
#define R_RISCV_SET16 55
|
||||
#define R_RISCV_SET32 56
|
||||
|
||||
/* RISC-V ELF Flags. */
|
||||
#define EF_RISCV_RVC 0x0001
|
||||
#define EF_RISCV_FLOAT_ABI 0x0006
|
||||
#define EF_RISCV_FLOAT_ABI_SOFT 0x0000
|
||||
#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002
|
||||
#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
|
||||
#define EF_RISCV_FLOAT_ABI_QUAD 0x0006
|
||||
#define EF_RISCV_RVE 0x0008
|
||||
#define EF_RISCV_TSO 0x0010
|
||||
|
||||
typedef struct elf32_rel {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu.h"
|
||||
#include "cpu_loop-common.h"
|
||||
#include "elf.h"
|
||||
|
||||
void cpu_loop(CPURISCVState *env)
|
||||
{
|
||||
|
@ -53,7 +55,8 @@ void cpu_loop(CPURISCVState *env)
|
|||
ret = 0;
|
||||
} else {
|
||||
ret = do_syscall(env,
|
||||
env->gpr[xA7],
|
||||
env->gpr[(env->elf_flags & EF_RISCV_RVE)
|
||||
? xT0 : xA7],
|
||||
env->gpr[xA0],
|
||||
env->gpr[xA1],
|
||||
env->gpr[xA2],
|
||||
|
@ -113,6 +116,16 @@ void cpu_loop(CPURISCVState *env)
|
|||
|
||||
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
TaskState *ts = cpu->opaque;
|
||||
struct image_info *info = ts->info;
|
||||
|
||||
env->pc = regs->sepc;
|
||||
env->gpr[xSP] = regs->sp;
|
||||
env->elf_flags = info->elf_flags;
|
||||
|
||||
if ((env->misa & RVE) && !(env->elf_flags & EF_RISCV_RVE)) {
|
||||
error_report("Incompatible ELF: RVE cpu requires RVE ABI binary");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,12 +80,6 @@ const char * const riscv_intr_names[] = {
|
|||
"reserved"
|
||||
};
|
||||
|
||||
typedef struct RISCVCPUInfo {
|
||||
const int bit_widths;
|
||||
const char *name;
|
||||
void (*initfn)(Object *obj);
|
||||
} RISCVCPUInfo;
|
||||
|
||||
static void set_misa(CPURISCVState *env, target_ulong misa)
|
||||
{
|
||||
env->misa_mask = env->misa = misa;
|
||||
|
@ -311,6 +305,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
riscv_cpu_register_gdb_regs_for_features(cs);
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
cpu_reset(cs);
|
||||
|
||||
|
@ -351,7 +347,12 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
|
|||
cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
|
||||
cc->gdb_read_register = riscv_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = riscv_cpu_gdb_write_register;
|
||||
cc->gdb_num_core_regs = 65;
|
||||
cc->gdb_num_core_regs = 33;
|
||||
#if defined(TARGET_RISCV32)
|
||||
cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
|
||||
#elif defined(TARGET_RISCV64)
|
||||
cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
|
||||
#endif
|
||||
cc->gdb_stop_before_watchpoint = true;
|
||||
cc->disas_set_info = riscv_cpu_disas_set_info;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
|
|
|
@ -123,6 +123,10 @@ struct CPURISCVState {
|
|||
|
||||
uint32_t features;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
uint32_t elf_flags;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
target_ulong priv;
|
||||
target_ulong resetvec;
|
||||
|
@ -140,6 +144,7 @@ struct CPURISCVState {
|
|||
* mip is 32-bits to allow atomic_read on 32-bit hosts.
|
||||
*/
|
||||
uint32_t mip;
|
||||
uint32_t miclaim;
|
||||
|
||||
target_ulong mie;
|
||||
target_ulong mideleg;
|
||||
|
@ -172,6 +177,9 @@ struct CPURISCVState {
|
|||
|
||||
/* physical memory protection */
|
||||
pmp_table_t pmp_state;
|
||||
|
||||
/* True if in debugger mode. */
|
||||
bool debugger;
|
||||
#endif
|
||||
|
||||
float_status fp_status;
|
||||
|
@ -263,6 +271,7 @@ void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
|||
#define cpu_mmu_index riscv_cpu_mmu_index
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
|
||||
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
|
||||
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
|
||||
#endif
|
||||
|
@ -293,6 +302,8 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
|||
|
||||
int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
|
||||
target_ulong new_value, target_ulong write_mask);
|
||||
int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
|
||||
target_ulong new_value, target_ulong write_mask);
|
||||
|
||||
static inline void riscv_csr_write(CPURISCVState *env, int csrno,
|
||||
target_ulong val)
|
||||
|
@ -325,6 +336,8 @@ typedef struct {
|
|||
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
|
||||
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
|
||||
|
||||
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
#endif /* RISCV_CPU_H */
|
||||
|
|
|
@ -135,16 +135,22 @@
|
|||
/* Legacy Counter Setup (priv v1.9.1) */
|
||||
#define CSR_MUCOUNTEREN 0x320
|
||||
#define CSR_MSCOUNTEREN 0x321
|
||||
#define CSR_MHCOUNTEREN 0x322
|
||||
|
||||
/* Machine Trap Handling */
|
||||
#define CSR_MSCRATCH 0x340
|
||||
#define CSR_MEPC 0x341
|
||||
#define CSR_MCAUSE 0x342
|
||||
#define CSR_MBADADDR 0x343
|
||||
#define CSR_MTVAL 0x343
|
||||
#define CSR_MIP 0x344
|
||||
|
||||
/* Legacy Machine Trap Handling (priv v1.9.1) */
|
||||
#define CSR_MBADADDR 0x343
|
||||
|
||||
/* Supervisor Trap Setup */
|
||||
#define CSR_SSTATUS 0x100
|
||||
#define CSR_SEDELEG 0x102
|
||||
#define CSR_SIDELEG 0x103
|
||||
#define CSR_SIE 0x104
|
||||
#define CSR_STVEC 0x105
|
||||
#define CSR_SCOUNTEREN 0x106
|
||||
|
@ -153,9 +159,12 @@
|
|||
#define CSR_SSCRATCH 0x140
|
||||
#define CSR_SEPC 0x141
|
||||
#define CSR_SCAUSE 0x142
|
||||
#define CSR_SBADADDR 0x143
|
||||
#define CSR_STVAL 0x143
|
||||
#define CSR_SIP 0x144
|
||||
|
||||
/* Legacy Supervisor Trap Handling (priv v1.9.1) */
|
||||
#define CSR_SBADADDR 0x143
|
||||
|
||||
/* Supervisor Protection and Translation */
|
||||
#define CSR_SPTBR 0x180
|
||||
#define CSR_SATP 0x180
|
||||
|
@ -282,6 +291,28 @@
|
|||
#define CSR_MHPMCOUNTER30H 0xb9e
|
||||
#define CSR_MHPMCOUNTER31H 0xb9f
|
||||
|
||||
/* Legacy Hypervisor Trap Setup (priv v1.9.1) */
|
||||
#define CSR_HSTATUS 0x200
|
||||
#define CSR_HEDELEG 0x202
|
||||
#define CSR_HIDELEG 0x203
|
||||
#define CSR_HIE 0x204
|
||||
#define CSR_HTVEC 0x205
|
||||
|
||||
/* Legacy Hypervisor Trap Handling (priv v1.9.1) */
|
||||
#define CSR_HSCRATCH 0x240
|
||||
#define CSR_HEPC 0x241
|
||||
#define CSR_HCAUSE 0x242
|
||||
#define CSR_HBADADDR 0x243
|
||||
#define CSR_HIP 0x244
|
||||
|
||||
/* Legacy Machine Protection and Translation (priv v1.9.1) */
|
||||
#define CSR_MBASE 0x380
|
||||
#define CSR_MBOUND 0x381
|
||||
#define CSR_MIBASE 0x382
|
||||
#define CSR_MIBOUND 0x383
|
||||
#define CSR_MDBASE 0x384
|
||||
#define CSR_MDBOUND 0x385
|
||||
|
||||
/* mstatus CSR bits */
|
||||
#define MSTATUS_UIE 0x00000001
|
||||
#define MSTATUS_SIE 0x00000002
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "tcg-op.h"
|
||||
|
||||
#define RISCV_DEBUG_INTERRUPT 0
|
||||
#include "trace.h"
|
||||
|
||||
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
|
||||
{
|
||||
|
@ -72,6 +71,17 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
|||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
|
||||
{
|
||||
CPURISCVState *env = &cpu->env;
|
||||
if (env->miclaim & interrupts) {
|
||||
return -1;
|
||||
} else {
|
||||
env->miclaim |= interrupts;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* iothread_mutex must be held */
|
||||
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
|
||||
{
|
||||
|
@ -84,9 +94,9 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
|
|||
cmp = atomic_cmpxchg(&env->mip, old, new);
|
||||
} while (old != cmp);
|
||||
|
||||
if (new && !old) {
|
||||
if (new) {
|
||||
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
|
||||
} else if (!new && old) {
|
||||
} else {
|
||||
cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
|
||||
}
|
||||
|
||||
|
@ -443,121 +453,85 @@ void riscv_cpu_do_interrupt(CPUState *cs)
|
|||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
if (RISCV_DEBUG_INTERRUPT) {
|
||||
int log_cause = cs->exception_index & RISCV_EXCP_INT_MASK;
|
||||
if (cs->exception_index & RISCV_EXCP_INT_FLAG) {
|
||||
qemu_log_mask(LOG_TRACE, "core "
|
||||
TARGET_FMT_ld ": trap %s, epc 0x" TARGET_FMT_lx "\n",
|
||||
env->mhartid, riscv_intr_names[log_cause], env->pc);
|
||||
} else {
|
||||
qemu_log_mask(LOG_TRACE, "core "
|
||||
TARGET_FMT_ld ": intr %s, epc 0x" TARGET_FMT_lx "\n",
|
||||
env->mhartid, riscv_excp_names[log_cause], env->pc);
|
||||
/* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
|
||||
* so we mask off the MSB and separate into trap type and cause.
|
||||
*/
|
||||
bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG);
|
||||
target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
|
||||
target_ulong deleg = async ? env->mideleg : env->medeleg;
|
||||
target_ulong tval = 0;
|
||||
|
||||
static const int ecall_cause_map[] = {
|
||||
[PRV_U] = RISCV_EXCP_U_ECALL,
|
||||
[PRV_S] = RISCV_EXCP_S_ECALL,
|
||||
[PRV_H] = RISCV_EXCP_H_ECALL,
|
||||
[PRV_M] = RISCV_EXCP_M_ECALL
|
||||
};
|
||||
|
||||
if (!async) {
|
||||
/* set tval to badaddr for traps with address information */
|
||||
switch (cause) {
|
||||
case RISCV_EXCP_INST_ADDR_MIS:
|
||||
case RISCV_EXCP_INST_ACCESS_FAULT:
|
||||
case RISCV_EXCP_LOAD_ADDR_MIS:
|
||||
case RISCV_EXCP_STORE_AMO_ADDR_MIS:
|
||||
case RISCV_EXCP_LOAD_ACCESS_FAULT:
|
||||
case RISCV_EXCP_STORE_AMO_ACCESS_FAULT:
|
||||
case RISCV_EXCP_INST_PAGE_FAULT:
|
||||
case RISCV_EXCP_LOAD_PAGE_FAULT:
|
||||
case RISCV_EXCP_STORE_PAGE_FAULT:
|
||||
tval = env->badaddr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* ecall is dispatched as one cause so translate based on mode */
|
||||
if (cause == RISCV_EXCP_U_ECALL) {
|
||||
assert(env->priv <= 3);
|
||||
cause = ecall_cause_map[env->priv];
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong fixed_cause = 0;
|
||||
if (cs->exception_index & (RISCV_EXCP_INT_FLAG)) {
|
||||
/* hacky for now. the MSB (bit 63) indicates interrupt but cs->exception
|
||||
index is only 32 bits wide */
|
||||
fixed_cause = cs->exception_index & RISCV_EXCP_INT_MASK;
|
||||
fixed_cause |= ((target_ulong)1) << (TARGET_LONG_BITS - 1);
|
||||
} else {
|
||||
/* fixup User ECALL -> correct priv ECALL */
|
||||
if (cs->exception_index == RISCV_EXCP_U_ECALL) {
|
||||
switch (env->priv) {
|
||||
case PRV_U:
|
||||
fixed_cause = RISCV_EXCP_U_ECALL;
|
||||
break;
|
||||
case PRV_S:
|
||||
fixed_cause = RISCV_EXCP_S_ECALL;
|
||||
break;
|
||||
case PRV_H:
|
||||
fixed_cause = RISCV_EXCP_H_ECALL;
|
||||
break;
|
||||
case PRV_M:
|
||||
fixed_cause = RISCV_EXCP_M_ECALL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fixed_cause = cs->exception_index;
|
||||
}
|
||||
}
|
||||
trace_riscv_trap(env->mhartid, async, cause, env->pc, tval, cause < 16 ?
|
||||
(async ? riscv_intr_names : riscv_excp_names)[cause] : "(unknown)");
|
||||
|
||||
target_ulong backup_epc = env->pc;
|
||||
|
||||
target_ulong bit = fixed_cause;
|
||||
target_ulong deleg = env->medeleg;
|
||||
|
||||
int hasbadaddr =
|
||||
(fixed_cause == RISCV_EXCP_INST_ADDR_MIS) ||
|
||||
(fixed_cause == RISCV_EXCP_INST_ACCESS_FAULT) ||
|
||||
(fixed_cause == RISCV_EXCP_LOAD_ADDR_MIS) ||
|
||||
(fixed_cause == RISCV_EXCP_STORE_AMO_ADDR_MIS) ||
|
||||
(fixed_cause == RISCV_EXCP_LOAD_ACCESS_FAULT) ||
|
||||
(fixed_cause == RISCV_EXCP_STORE_AMO_ACCESS_FAULT) ||
|
||||
(fixed_cause == RISCV_EXCP_INST_PAGE_FAULT) ||
|
||||
(fixed_cause == RISCV_EXCP_LOAD_PAGE_FAULT) ||
|
||||
(fixed_cause == RISCV_EXCP_STORE_PAGE_FAULT);
|
||||
|
||||
if (bit & ((target_ulong)1 << (TARGET_LONG_BITS - 1))) {
|
||||
deleg = env->mideleg;
|
||||
bit &= ~((target_ulong)1 << (TARGET_LONG_BITS - 1));
|
||||
}
|
||||
|
||||
if (env->priv <= PRV_S && bit < 64 && ((deleg >> bit) & 1)) {
|
||||
if (env->priv <= PRV_S &&
|
||||
cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
|
||||
/* handle the trap in S-mode */
|
||||
/* No need to check STVEC for misaligned - lower 2 bits cannot be set */
|
||||
env->pc = env->stvec;
|
||||
env->scause = fixed_cause;
|
||||
env->sepc = backup_epc;
|
||||
|
||||
if (hasbadaddr) {
|
||||
if (RISCV_DEBUG_INTERRUPT) {
|
||||
qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld ": badaddr 0x"
|
||||
TARGET_FMT_lx "\n", env->mhartid, env->badaddr);
|
||||
}
|
||||
env->sbadaddr = env->badaddr;
|
||||
} else {
|
||||
/* otherwise we must clear sbadaddr/stval
|
||||
* todo: support populating stval on illegal instructions */
|
||||
env->sbadaddr = 0;
|
||||
}
|
||||
|
||||
target_ulong s = env->mstatus;
|
||||
s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
|
||||
get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << env->priv));
|
||||
s = set_field(s, MSTATUS_SPP, env->priv);
|
||||
s = set_field(s, MSTATUS_SIE, 0);
|
||||
env->mstatus = s;
|
||||
env->scause = cause | ~(((target_ulong)-1) >> async);
|
||||
env->sepc = env->pc;
|
||||
env->sbadaddr = tval;
|
||||
env->pc = (env->stvec >> 2 << 2) +
|
||||
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
|
||||
riscv_cpu_set_mode(env, PRV_S);
|
||||
} else {
|
||||
/* No need to check MTVEC for misaligned - lower 2 bits cannot be set */
|
||||
env->pc = env->mtvec;
|
||||
env->mepc = backup_epc;
|
||||
env->mcause = fixed_cause;
|
||||
|
||||
if (hasbadaddr) {
|
||||
if (RISCV_DEBUG_INTERRUPT) {
|
||||
qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld ": badaddr 0x"
|
||||
TARGET_FMT_lx "\n", env->mhartid, env->badaddr);
|
||||
}
|
||||
env->mbadaddr = env->badaddr;
|
||||
} else {
|
||||
/* otherwise we must clear mbadaddr/mtval
|
||||
* todo: support populating mtval on illegal instructions */
|
||||
env->mbadaddr = 0;
|
||||
}
|
||||
|
||||
/* handle the trap in M-mode */
|
||||
target_ulong s = env->mstatus;
|
||||
s = set_field(s, MSTATUS_MPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
|
||||
get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << env->priv));
|
||||
s = set_field(s, MSTATUS_MPP, env->priv);
|
||||
s = set_field(s, MSTATUS_MIE, 0);
|
||||
env->mstatus = s;
|
||||
env->mcause = cause | ~(((target_ulong)-1) >> async);
|
||||
env->mepc = env->pc;
|
||||
env->mbadaddr = tval;
|
||||
env->pc = (env->mtvec >> 2 << 2) +
|
||||
((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
|
||||
riscv_cpu_set_mode(env, PRV_M);
|
||||
}
|
||||
/* TODO yield load reservation */
|
||||
|
||||
/* NOTE: it is not necessary to yield load reservations here. It is only
|
||||
* necessary for an SC from "another hart" to cause a load reservation
|
||||
* to be yielded. Refer to the memory consistency model section of the
|
||||
* RISC-V ISA Specification.
|
||||
*/
|
||||
|
||||
#endif
|
||||
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
|
||||
}
|
||||
|
|
|
@ -10,4 +10,5 @@
|
|||
#define xA4 14
|
||||
#define xA5 15
|
||||
#define xA6 16
|
||||
#define xA7 17 /* syscall number goes here */
|
||||
#define xA7 17 /* syscall number for RVI ABI */
|
||||
#define xT0 5 /* syscall number for RVE ABI */
|
||||
|
|
|
@ -46,7 +46,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
|
|||
static int fs(CPURISCVState *env, int csrno)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -92,7 +92,7 @@ static int pmp(CPURISCVState *env, int csrno)
|
|||
static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -103,7 +103,7 @@ static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
env->mstatus |= MSTATUS_FS;
|
||||
|
@ -115,7 +115,7 @@ static int write_fflags(CPURISCVState *env, int csrno, target_ulong val)
|
|||
static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -126,7 +126,7 @@ static int read_frm(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
env->mstatus |= MSTATUS_FS;
|
||||
|
@ -138,7 +138,7 @@ static int write_frm(CPURISCVState *env, int csrno, target_ulong val)
|
|||
static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -150,7 +150,7 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (!(env->mstatus & MSTATUS_FS)) {
|
||||
if (!env->debugger && !(env->mstatus & MSTATUS_FS)) {
|
||||
return -1;
|
||||
}
|
||||
env->mstatus |= MSTATUS_FS;
|
||||
|
@ -435,10 +435,10 @@ static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
/* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
|
||||
if ((val & 3) == 0) {
|
||||
env->mtvec = val >> 2 << 2;
|
||||
if ((val & 3) < 2) {
|
||||
env->mtvec = val;
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: vectored traps not supported");
|
||||
qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -550,16 +550,10 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
|
|||
target_ulong new_value, target_ulong write_mask)
|
||||
{
|
||||
RISCVCPU *cpu = riscv_env_get_cpu(env);
|
||||
target_ulong mask = write_mask & delegable_ints;
|
||||
/* Allow software control of delegable interrupts not claimed by hardware */
|
||||
target_ulong mask = write_mask & delegable_ints & ~env->miclaim;
|
||||
uint32_t old_mip;
|
||||
|
||||
/* We can't allow the supervisor to control SEIP as this would allow the
|
||||
* supervisor to clear a pending external interrupt which will result in
|
||||
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
|
||||
* hardware controlled when a PLIC is attached. This should be an option
|
||||
* for CPUs with software-delegated Supervisor External Interrupts. */
|
||||
mask &= ~MIP_SEIP;
|
||||
|
||||
if (mask) {
|
||||
qemu_mutex_lock_iothread();
|
||||
old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
|
||||
|
@ -613,10 +607,10 @@ static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_stvec(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
/* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
|
||||
if ((val & 3) == 0) {
|
||||
env->stvec = val >> 2 << 2;
|
||||
if ((val & 3) < 2) {
|
||||
env->stvec = val;
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP, "CSR_STVEC: vectored traps not supported");
|
||||
qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -827,6 +821,24 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugger support. If not in user mode, set env->debugger before the
|
||||
* riscv_csrrw call and clear it after the call.
|
||||
*/
|
||||
int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
|
||||
target_ulong new_value, target_ulong write_mask)
|
||||
{
|
||||
int ret;
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
env->debugger = true;
|
||||
#endif
|
||||
ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
env->debugger = false;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Control and Status Register function table */
|
||||
static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
||||
/* User Floating-Point CSRs */
|
||||
|
|
|
@ -21,6 +21,255 @@
|
|||
#include "exec/gdbstub.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* The GDB CSR xml files list them in documentation order, not numerical order,
|
||||
* and are missing entries for unnamed CSRs. So we need to map the gdb numbers
|
||||
* to the hardware numbers.
|
||||
*/
|
||||
|
||||
static int csr_register_map[] = {
|
||||
CSR_USTATUS,
|
||||
CSR_UIE,
|
||||
CSR_UTVEC,
|
||||
CSR_USCRATCH,
|
||||
CSR_UEPC,
|
||||
CSR_UCAUSE,
|
||||
CSR_UTVAL,
|
||||
CSR_UIP,
|
||||
CSR_FFLAGS,
|
||||
CSR_FRM,
|
||||
CSR_FCSR,
|
||||
CSR_CYCLE,
|
||||
CSR_TIME,
|
||||
CSR_INSTRET,
|
||||
CSR_HPMCOUNTER3,
|
||||
CSR_HPMCOUNTER4,
|
||||
CSR_HPMCOUNTER5,
|
||||
CSR_HPMCOUNTER6,
|
||||
CSR_HPMCOUNTER7,
|
||||
CSR_HPMCOUNTER8,
|
||||
CSR_HPMCOUNTER9,
|
||||
CSR_HPMCOUNTER10,
|
||||
CSR_HPMCOUNTER11,
|
||||
CSR_HPMCOUNTER12,
|
||||
CSR_HPMCOUNTER13,
|
||||
CSR_HPMCOUNTER14,
|
||||
CSR_HPMCOUNTER15,
|
||||
CSR_HPMCOUNTER16,
|
||||
CSR_HPMCOUNTER17,
|
||||
CSR_HPMCOUNTER18,
|
||||
CSR_HPMCOUNTER19,
|
||||
CSR_HPMCOUNTER20,
|
||||
CSR_HPMCOUNTER21,
|
||||
CSR_HPMCOUNTER22,
|
||||
CSR_HPMCOUNTER23,
|
||||
CSR_HPMCOUNTER24,
|
||||
CSR_HPMCOUNTER25,
|
||||
CSR_HPMCOUNTER26,
|
||||
CSR_HPMCOUNTER27,
|
||||
CSR_HPMCOUNTER28,
|
||||
CSR_HPMCOUNTER29,
|
||||
CSR_HPMCOUNTER30,
|
||||
CSR_HPMCOUNTER31,
|
||||
CSR_CYCLEH,
|
||||
CSR_TIMEH,
|
||||
CSR_INSTRETH,
|
||||
CSR_HPMCOUNTER3H,
|
||||
CSR_HPMCOUNTER4H,
|
||||
CSR_HPMCOUNTER5H,
|
||||
CSR_HPMCOUNTER6H,
|
||||
CSR_HPMCOUNTER7H,
|
||||
CSR_HPMCOUNTER8H,
|
||||
CSR_HPMCOUNTER9H,
|
||||
CSR_HPMCOUNTER10H,
|
||||
CSR_HPMCOUNTER11H,
|
||||
CSR_HPMCOUNTER12H,
|
||||
CSR_HPMCOUNTER13H,
|
||||
CSR_HPMCOUNTER14H,
|
||||
CSR_HPMCOUNTER15H,
|
||||
CSR_HPMCOUNTER16H,
|
||||
CSR_HPMCOUNTER17H,
|
||||
CSR_HPMCOUNTER18H,
|
||||
CSR_HPMCOUNTER19H,
|
||||
CSR_HPMCOUNTER20H,
|
||||
CSR_HPMCOUNTER21H,
|
||||
CSR_HPMCOUNTER22H,
|
||||
CSR_HPMCOUNTER23H,
|
||||
CSR_HPMCOUNTER24H,
|
||||
CSR_HPMCOUNTER25H,
|
||||
CSR_HPMCOUNTER26H,
|
||||
CSR_HPMCOUNTER27H,
|
||||
CSR_HPMCOUNTER28H,
|
||||
CSR_HPMCOUNTER29H,
|
||||
CSR_HPMCOUNTER30H,
|
||||
CSR_HPMCOUNTER31H,
|
||||
CSR_SSTATUS,
|
||||
CSR_SEDELEG,
|
||||
CSR_SIDELEG,
|
||||
CSR_SIE,
|
||||
CSR_STVEC,
|
||||
CSR_SCOUNTEREN,
|
||||
CSR_SSCRATCH,
|
||||
CSR_SEPC,
|
||||
CSR_SCAUSE,
|
||||
CSR_STVAL,
|
||||
CSR_SIP,
|
||||
CSR_SATP,
|
||||
CSR_MVENDORID,
|
||||
CSR_MARCHID,
|
||||
CSR_MIMPID,
|
||||
CSR_MHARTID,
|
||||
CSR_MSTATUS,
|
||||
CSR_MISA,
|
||||
CSR_MEDELEG,
|
||||
CSR_MIDELEG,
|
||||
CSR_MIE,
|
||||
CSR_MTVEC,
|
||||
CSR_MCOUNTEREN,
|
||||
CSR_MSCRATCH,
|
||||
CSR_MEPC,
|
||||
CSR_MCAUSE,
|
||||
CSR_MTVAL,
|
||||
CSR_MIP,
|
||||
CSR_PMPCFG0,
|
||||
CSR_PMPCFG1,
|
||||
CSR_PMPCFG2,
|
||||
CSR_PMPCFG3,
|
||||
CSR_PMPADDR0,
|
||||
CSR_PMPADDR1,
|
||||
CSR_PMPADDR2,
|
||||
CSR_PMPADDR3,
|
||||
CSR_PMPADDR4,
|
||||
CSR_PMPADDR5,
|
||||
CSR_PMPADDR6,
|
||||
CSR_PMPADDR7,
|
||||
CSR_PMPADDR8,
|
||||
CSR_PMPADDR9,
|
||||
CSR_PMPADDR10,
|
||||
CSR_PMPADDR11,
|
||||
CSR_PMPADDR12,
|
||||
CSR_PMPADDR13,
|
||||
CSR_PMPADDR14,
|
||||
CSR_PMPADDR15,
|
||||
CSR_MCYCLE,
|
||||
CSR_MINSTRET,
|
||||
CSR_MHPMCOUNTER3,
|
||||
CSR_MHPMCOUNTER4,
|
||||
CSR_MHPMCOUNTER5,
|
||||
CSR_MHPMCOUNTER6,
|
||||
CSR_MHPMCOUNTER7,
|
||||
CSR_MHPMCOUNTER8,
|
||||
CSR_MHPMCOUNTER9,
|
||||
CSR_MHPMCOUNTER10,
|
||||
CSR_MHPMCOUNTER11,
|
||||
CSR_MHPMCOUNTER12,
|
||||
CSR_MHPMCOUNTER13,
|
||||
CSR_MHPMCOUNTER14,
|
||||
CSR_MHPMCOUNTER15,
|
||||
CSR_MHPMCOUNTER16,
|
||||
CSR_MHPMCOUNTER17,
|
||||
CSR_MHPMCOUNTER18,
|
||||
CSR_MHPMCOUNTER19,
|
||||
CSR_MHPMCOUNTER20,
|
||||
CSR_MHPMCOUNTER21,
|
||||
CSR_MHPMCOUNTER22,
|
||||
CSR_MHPMCOUNTER23,
|
||||
CSR_MHPMCOUNTER24,
|
||||
CSR_MHPMCOUNTER25,
|
||||
CSR_MHPMCOUNTER26,
|
||||
CSR_MHPMCOUNTER27,
|
||||
CSR_MHPMCOUNTER28,
|
||||
CSR_MHPMCOUNTER29,
|
||||
CSR_MHPMCOUNTER30,
|
||||
CSR_MHPMCOUNTER31,
|
||||
CSR_MCYCLEH,
|
||||
CSR_MINSTRETH,
|
||||
CSR_MHPMCOUNTER3H,
|
||||
CSR_MHPMCOUNTER4H,
|
||||
CSR_MHPMCOUNTER5H,
|
||||
CSR_MHPMCOUNTER6H,
|
||||
CSR_MHPMCOUNTER7H,
|
||||
CSR_MHPMCOUNTER8H,
|
||||
CSR_MHPMCOUNTER9H,
|
||||
CSR_MHPMCOUNTER10H,
|
||||
CSR_MHPMCOUNTER11H,
|
||||
CSR_MHPMCOUNTER12H,
|
||||
CSR_MHPMCOUNTER13H,
|
||||
CSR_MHPMCOUNTER14H,
|
||||
CSR_MHPMCOUNTER15H,
|
||||
CSR_MHPMCOUNTER16H,
|
||||
CSR_MHPMCOUNTER17H,
|
||||
CSR_MHPMCOUNTER18H,
|
||||
CSR_MHPMCOUNTER19H,
|
||||
CSR_MHPMCOUNTER20H,
|
||||
CSR_MHPMCOUNTER21H,
|
||||
CSR_MHPMCOUNTER22H,
|
||||
CSR_MHPMCOUNTER23H,
|
||||
CSR_MHPMCOUNTER24H,
|
||||
CSR_MHPMCOUNTER25H,
|
||||
CSR_MHPMCOUNTER26H,
|
||||
CSR_MHPMCOUNTER27H,
|
||||
CSR_MHPMCOUNTER28H,
|
||||
CSR_MHPMCOUNTER29H,
|
||||
CSR_MHPMCOUNTER30H,
|
||||
CSR_MHPMCOUNTER31H,
|
||||
CSR_MHPMEVENT3,
|
||||
CSR_MHPMEVENT4,
|
||||
CSR_MHPMEVENT5,
|
||||
CSR_MHPMEVENT6,
|
||||
CSR_MHPMEVENT7,
|
||||
CSR_MHPMEVENT8,
|
||||
CSR_MHPMEVENT9,
|
||||
CSR_MHPMEVENT10,
|
||||
CSR_MHPMEVENT11,
|
||||
CSR_MHPMEVENT12,
|
||||
CSR_MHPMEVENT13,
|
||||
CSR_MHPMEVENT14,
|
||||
CSR_MHPMEVENT15,
|
||||
CSR_MHPMEVENT16,
|
||||
CSR_MHPMEVENT17,
|
||||
CSR_MHPMEVENT18,
|
||||
CSR_MHPMEVENT19,
|
||||
CSR_MHPMEVENT20,
|
||||
CSR_MHPMEVENT21,
|
||||
CSR_MHPMEVENT22,
|
||||
CSR_MHPMEVENT23,
|
||||
CSR_MHPMEVENT24,
|
||||
CSR_MHPMEVENT25,
|
||||
CSR_MHPMEVENT26,
|
||||
CSR_MHPMEVENT27,
|
||||
CSR_MHPMEVENT28,
|
||||
CSR_MHPMEVENT29,
|
||||
CSR_MHPMEVENT30,
|
||||
CSR_MHPMEVENT31,
|
||||
CSR_TSELECT,
|
||||
CSR_TDATA1,
|
||||
CSR_TDATA2,
|
||||
CSR_TDATA3,
|
||||
CSR_DCSR,
|
||||
CSR_DPC,
|
||||
CSR_DSCRATCH,
|
||||
CSR_HSTATUS,
|
||||
CSR_HEDELEG,
|
||||
CSR_HIDELEG,
|
||||
CSR_HIE,
|
||||
CSR_HTVEC,
|
||||
CSR_HSCRATCH,
|
||||
CSR_HEPC,
|
||||
CSR_HCAUSE,
|
||||
CSR_HBADADDR,
|
||||
CSR_HIP,
|
||||
CSR_MBASE,
|
||||
CSR_MBOUND,
|
||||
CSR_MIBASE,
|
||||
CSR_MIBOUND,
|
||||
CSR_MDBASE,
|
||||
CSR_MDBOUND,
|
||||
CSR_MUCOUNTEREN,
|
||||
CSR_MSCOUNTEREN,
|
||||
CSR_MHCOUNTEREN,
|
||||
};
|
||||
|
||||
int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
|
@ -30,13 +279,6 @@ int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
return gdb_get_regl(mem_buf, env->gpr[n]);
|
||||
} else if (n == 32) {
|
||||
return gdb_get_regl(mem_buf, env->pc);
|
||||
} else if (n < 65) {
|
||||
return gdb_get_reg64(mem_buf, env->fpr[n - 33]);
|
||||
} else if (n < 4096 + 65) {
|
||||
target_ulong val = 0;
|
||||
if (riscv_csrrw(env, n - 65, &val, 0, 0) == 0) {
|
||||
return gdb_get_regl(mem_buf, val);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -55,14 +297,100 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||
} else if (n == 32) {
|
||||
env->pc = ldtul_p(mem_buf);
|
||||
return sizeof(target_ulong);
|
||||
} else if (n < 65) {
|
||||
env->fpr[n - 33] = ldq_p(mem_buf); /* always 64-bit */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
return gdb_get_reg64(mem_buf, env->fpr[n]);
|
||||
/* there is hole between ft11 and fflags in fpu.xml */
|
||||
} else if (n < 36 && n > 32) {
|
||||
target_ulong val = 0;
|
||||
int result;
|
||||
/*
|
||||
* CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
|
||||
* register 33, so we recalculate the map index.
|
||||
* This also works for CSR_FRM and CSR_FCSR.
|
||||
*/
|
||||
result = riscv_csrrw_debug(env, n - 33 + 8, &val, 0, 0);
|
||||
if (result == 0) {
|
||||
return gdb_get_regl(mem_buf, val);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
|
||||
return sizeof(uint64_t);
|
||||
} else if (n < 4096 + 65) {
|
||||
/* there is hole between ft11 and fflags in fpu.xml */
|
||||
} else if (n < 36 && n > 32) {
|
||||
target_ulong val = ldtul_p(mem_buf);
|
||||
if (riscv_csrrw(env, n - 65, NULL, val, -1) == 0) {
|
||||
int result;
|
||||
/*
|
||||
* CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP
|
||||
* register 33, so we recalculate the map index.
|
||||
* This also works for CSR_FRM and CSR_FCSR.
|
||||
*/
|
||||
result = riscv_csrrw_debug(env, n - 33 + 8, NULL, val, -1);
|
||||
if (result == 0) {
|
||||
return sizeof(target_ulong);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < ARRAY_SIZE(csr_register_map)) {
|
||||
target_ulong val = 0;
|
||||
int result;
|
||||
|
||||
result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
|
||||
if (result == 0) {
|
||||
return gdb_get_regl(mem_buf, val);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < ARRAY_SIZE(csr_register_map)) {
|
||||
target_ulong val = ldtul_p(mem_buf);
|
||||
int result;
|
||||
|
||||
result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
|
||||
if (result == 0) {
|
||||
return sizeof(target_ulong);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
#if defined(TARGET_RISCV32)
|
||||
if (env->misa & RVF) {
|
||||
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
|
||||
36, "riscv-32bit-fpu.xml", 0);
|
||||
}
|
||||
|
||||
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
|
||||
4096, "riscv-32bit-csr.xml", 0);
|
||||
#elif defined(TARGET_RISCV64)
|
||||
if (env->misa & RVF) {
|
||||
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
|
||||
36, "riscv-64bit-fpu.xml", 0);
|
||||
}
|
||||
|
||||
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
|
||||
4096, "riscv-64bit-csr.xml", 0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -113,10 +113,11 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
|
|||
env->pmp_state.pmp[pmp_index].cfg_reg = val;
|
||||
pmp_update_rule(env, pmp_index);
|
||||
} else {
|
||||
PMP_DEBUG("ignoring write - locked");
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
|
||||
}
|
||||
} else {
|
||||
PMP_DEBUG("ignoring write - out of bounds");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ignoring pmpcfg write - out of bounds\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +250,8 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
|
|||
|
||||
/* partially inside */
|
||||
if ((s + e) == 1) {
|
||||
PMP_DEBUG("pmp violation - access is partially inside");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"pmp violation - access is partially inside\n");
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -306,7 +308,8 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
|
|||
env->mhartid, reg_index, val);
|
||||
|
||||
if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
|
||||
PMP_DEBUG("ignoring write - incorrect address");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ignoring pmpcfg write - incorrect address\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -353,10 +356,12 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
|
|||
env->pmp_state.pmp[addr_index].addr_reg = val;
|
||||
pmp_update_rule(env, addr_index);
|
||||
} else {
|
||||
PMP_DEBUG("ignoring write - locked");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ignoring pmpaddr write - locked\n");
|
||||
}
|
||||
} else {
|
||||
PMP_DEBUG("ignoring write - out of bounds");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ignoring pmpaddr write - out of bounds\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,7 +377,8 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
|
|||
if (addr_index < MAX_RISCV_PMPS) {
|
||||
return env->pmp_state.pmp[addr_index].addr_reg;
|
||||
} else {
|
||||
PMP_DEBUG("ignoring read - out of bounds");
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"ignoring pmpaddr read - out of bounds\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# target/riscv/cpu_helper.c
|
||||
riscv_trap(uint64_t hartid, bool async, uint64_t cause, uint64_t epc, uint64_t tval, const char *desc) "hart:%"PRId64", async:%d, cause:%"PRId64", epc:0x%"PRIx64", tval:0x%"PRIx64", desc=%s"
|
Loading…
Reference in New Issue