mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-riscv-to-apply-20220703-1' of github.com:alistair23/qemu into staging
Fifth RISC-V PR for QEMU 7.1 * Fix register zero guarding for auipc and lui * Ensure bins (mtval) is set correctly * Minimize the calls to decode_save_opc * Guard against PMP ranges with a negative size * Implement mcountinhibit CSR * Add support for hpmcounters/hpmevents * Improve PMU implenentation * Support mcycle/minstret write operation * Fixup MSECCFG minimum priv check * Ibex (OpenTitan) fixup priv version * Fix bug resulting in always using latest priv spec * Reduce FDT address alignment constraints * Set minumum priv spec version for mcountinhibit * AIA update to v0.3 of the spec # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCAAdFiEE9sSsRtSTSGjTuM6PIeENKd+XcFQFAmLA3r8ACgkQIeENKd+X # cFQdFQf6A63mocJxSc0vqMTBNULwgcUKbRbnkazbFS4vtbo/YXioCGaHA8c8trKj # HbZfJv64phOThj7Y8ifLozENjnHX7dHbspPOcWIK9yalvKLA4EB4+OI7LisoL1vg # H4E+9nXSzskaCmJgwSM6WlS0Vf89VxL0CoBb3XqJocSaajstg1XpqrR9anTZlUhl # N712cLze+bOxBHTdjtC5Kxuxj+zmNvcMmuhldIJRdPCW8P5v2yccNVc6+hrE3WUX # 9jHGMthS4qC5oVhok14/tPoyL0QTZpU2DXrJPFGUigOvUHoMBfQ3Qhulx3/rGLZv # 4SdTD9ASrNWJfa+eyHAPNw//5NxTYA== # =N7VN # -----END PGP SIGNATURE----- # gpg: Signature made Sun 03 Jul 2022 05:41:43 AM +0530 # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [undefined] # 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: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * tag 'pull-riscv-to-apply-20220703-1' of github.com:alistair23/qemu: target/riscv: Update default priority table for local interrupts target/riscv: Remove CSRs that set/clear an IMSIC interrupt file bits target/riscv: Set minumum priv spec version for mcountinhibit hw/riscv: boot: Reduce FDT address alignment constraints target/riscv: Don't force update priv spec version to latest target/riscv: Ibex: Support priv version 1.11 target/riscv: Fixup MSECCFG minimum priv check target/riscv: Support mcycle/minstret write operation target/riscv: Add support for hpmcounters/hpmevents target/riscv: Implement mcountinhibit CSR target/riscv: pmu: Make number of counters configurable target/riscv: pmu: Rename the counters extension to pmu target/riscv: Implement PMU CSR predicate function for S-mode target/riscv: Fix PMU CSR predicate function target/riscv/pmp: guard against PMP ranges with a negative size target/riscv: Minimize the calls to decode_save_opc target/riscv: Remove generate_exception_mtval target/riscv: Set env->bins in gen_exception_illegal target/riscv: Remove condition guarding register zero for auipc and lui Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
+2
-2
@@ -227,11 +227,11 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
|
||||
/*
|
||||
* We should put fdt as far as possible to avoid kernel/initrd overwriting
|
||||
* its content. But it should be addressable by 32 bit system as well.
|
||||
* Thus, put it at an 16MB aligned address that less than fdt size from the
|
||||
* Thus, put it at an 2MB aligned address that less than fdt size from the
|
||||
* end of dram or 3GB whichever is lesser.
|
||||
*/
|
||||
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
|
||||
fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB);
|
||||
fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
|
||||
|
||||
ret = fdt_pack(fdt);
|
||||
/* Should only fail if we've built a corrupted tree */
|
||||
|
||||
+10
-7
@@ -173,6 +173,8 @@ static void rv64_base_cpu_init(Object *obj)
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV64, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
}
|
||||
|
||||
static void rv64_sifive_u_cpu_init(Object *obj)
|
||||
@@ -204,6 +206,8 @@ static void rv128_base_cpu_init(Object *obj)
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV128, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
}
|
||||
#else
|
||||
static void rv32_base_cpu_init(Object *obj)
|
||||
@@ -212,6 +216,8 @@ static void rv32_base_cpu_init(Object *obj)
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, MXL_RV32, 0);
|
||||
register_cpu_props(DEVICE(obj));
|
||||
/* Set latest version of privileged specification */
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
}
|
||||
|
||||
static void rv32_sifive_u_cpu_init(Object *obj)
|
||||
@@ -237,7 +243,7 @@ static void rv32_ibex_cpu_init(Object *obj)
|
||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
set_priv_version(env, PRIV_VERSION_1_11_0);
|
||||
cpu->cfg.mmu = false;
|
||||
cpu->cfg.epmp = true;
|
||||
}
|
||||
@@ -524,7 +530,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
CPURISCVState *env = &cpu->env;
|
||||
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
||||
CPUClass *cc = CPU_CLASS(mcc);
|
||||
int priv_version = 0;
|
||||
int priv_version = -1;
|
||||
Error *local_err = NULL;
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
@@ -548,10 +554,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
if (priv_version) {
|
||||
if (priv_version >= PRIV_VERSION_1_10_0) {
|
||||
set_priv_version(env, priv_version);
|
||||
} else if (!env->priv_ver) {
|
||||
set_priv_version(env, PRIV_VERSION_1_12_0);
|
||||
}
|
||||
|
||||
if (cpu->cfg.mmu) {
|
||||
@@ -851,7 +855,6 @@ static void riscv_cpu_init(Object *obj)
|
||||
{
|
||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||
|
||||
cpu->cfg.ext_counters = true;
|
||||
cpu->cfg.ext_ifencei = true;
|
||||
cpu->cfg.ext_icsr = true;
|
||||
cpu->cfg.mmu = true;
|
||||
@@ -879,7 +882,7 @@ static Property riscv_cpu_extensions[] = {
|
||||
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
|
||||
DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
|
||||
DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
|
||||
DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
|
||||
DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
|
||||
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
|
||||
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
|
||||
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
|
||||
|
||||
+23
-1
@@ -117,6 +117,8 @@ typedef struct CPUArchState CPURISCVState;
|
||||
#endif
|
||||
|
||||
#define RV_VLEN_MAX 1024
|
||||
#define RV_MAX_MHPMEVENTS 32
|
||||
#define RV_MAX_MHPMCOUNTERS 32
|
||||
|
||||
FIELD(VTYPE, VLMUL, 0, 3)
|
||||
FIELD(VTYPE, VSEW, 3, 3)
|
||||
@@ -125,6 +127,18 @@ FIELD(VTYPE, VMA, 7, 1)
|
||||
FIELD(VTYPE, VEDIV, 8, 2)
|
||||
FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
|
||||
|
||||
typedef struct PMUCTRState {
|
||||
/* Current value of a counter */
|
||||
target_ulong mhpmcounter_val;
|
||||
/* Current value of a counter in RV32*/
|
||||
target_ulong mhpmcounterh_val;
|
||||
/* Snapshot values of counter */
|
||||
target_ulong mhpmcounter_prev;
|
||||
/* Snapshort value of a counter in RV32 */
|
||||
target_ulong mhpmcounterh_prev;
|
||||
bool started;
|
||||
} PMUCTRState;
|
||||
|
||||
struct CPUArchState {
|
||||
target_ulong gpr[32];
|
||||
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
|
||||
@@ -275,6 +289,14 @@ struct CPUArchState {
|
||||
target_ulong scounteren;
|
||||
target_ulong mcounteren;
|
||||
|
||||
target_ulong mcountinhibit;
|
||||
|
||||
/* PMU counter state */
|
||||
PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
|
||||
|
||||
/* PMU event selector configured values. First three are unused*/
|
||||
target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
|
||||
|
||||
target_ulong sscratch;
|
||||
target_ulong mscratch;
|
||||
|
||||
@@ -397,7 +419,6 @@ struct RISCVCPUConfig {
|
||||
bool ext_zksed;
|
||||
bool ext_zksh;
|
||||
bool ext_zkt;
|
||||
bool ext_counters;
|
||||
bool ext_ifencei;
|
||||
bool ext_icsr;
|
||||
bool ext_svinval;
|
||||
@@ -421,6 +442,7 @@ struct RISCVCPUConfig {
|
||||
/* Vendor-specific custom extensions */
|
||||
bool ext_XVentanaCondOps;
|
||||
|
||||
uint8_t pmu_num;
|
||||
char *priv_spec;
|
||||
char *user_spec;
|
||||
char *bext_spec;
|
||||
|
||||
+8
-22
@@ -174,14 +174,8 @@
|
||||
#define CSR_MIREG 0x351
|
||||
|
||||
/* Machine-Level Interrupts (AIA) */
|
||||
#define CSR_MTOPI 0xfb0
|
||||
|
||||
/* Machine-Level IMSIC Interface (AIA) */
|
||||
#define CSR_MSETEIPNUM 0x358
|
||||
#define CSR_MCLREIPNUM 0x359
|
||||
#define CSR_MSETEIENUM 0x35a
|
||||
#define CSR_MCLREIENUM 0x35b
|
||||
#define CSR_MTOPEI 0x35c
|
||||
#define CSR_MTOPI 0xfb0
|
||||
|
||||
/* Virtual Interrupts for Supervisor Level (AIA) */
|
||||
#define CSR_MVIEN 0x308
|
||||
@@ -221,14 +215,8 @@
|
||||
#define CSR_SIREG 0x151
|
||||
|
||||
/* Supervisor-Level Interrupts (AIA) */
|
||||
#define CSR_STOPI 0xdb0
|
||||
|
||||
/* Supervisor-Level IMSIC Interface (AIA) */
|
||||
#define CSR_SSETEIPNUM 0x158
|
||||
#define CSR_SCLREIPNUM 0x159
|
||||
#define CSR_SSETEIENUM 0x15a
|
||||
#define CSR_SCLREIENUM 0x15b
|
||||
#define CSR_STOPEI 0x15c
|
||||
#define CSR_STOPI 0xdb0
|
||||
|
||||
/* Supervisor-Level High-Half CSRs (AIA) */
|
||||
#define CSR_SIEH 0x114
|
||||
@@ -279,14 +267,8 @@
|
||||
#define CSR_VSIREG 0x251
|
||||
|
||||
/* VS-Level Interrupts (H-extension with AIA) */
|
||||
#define CSR_VSTOPI 0xeb0
|
||||
|
||||
/* VS-Level IMSIC Interface (H-extension with AIA) */
|
||||
#define CSR_VSSETEIPNUM 0x258
|
||||
#define CSR_VSCLREIPNUM 0x259
|
||||
#define CSR_VSSETEIENUM 0x25a
|
||||
#define CSR_VSCLREIENUM 0x25b
|
||||
#define CSR_VSTOPEI 0x25c
|
||||
#define CSR_VSTOPI 0xeb0
|
||||
|
||||
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
|
||||
#define CSR_HIDELEGH 0x613
|
||||
@@ -367,6 +349,10 @@
|
||||
#define CSR_MHPMCOUNTER29 0xb1d
|
||||
#define CSR_MHPMCOUNTER30 0xb1e
|
||||
#define CSR_MHPMCOUNTER31 0xb1f
|
||||
|
||||
/* Machine counter-inhibit register */
|
||||
#define CSR_MCOUNTINHIBIT 0x320
|
||||
|
||||
#define CSR_MHPMEVENT3 0x323
|
||||
#define CSR_MHPMEVENT4 0x324
|
||||
#define CSR_MHPMEVENT5 0x325
|
||||
@@ -788,7 +774,7 @@ typedef enum RISCVException {
|
||||
#define IPRIO_IRQ_BITS 8
|
||||
#define IPRIO_MMAXIPRIO 255
|
||||
#define IPRIO_DEFAULT_UPPER 4
|
||||
#define IPRIO_DEFAULT_MIDDLE (IPRIO_DEFAULT_UPPER + 24)
|
||||
#define IPRIO_DEFAULT_MIDDLE (IPRIO_DEFAULT_UPPER + 12)
|
||||
#define IPRIO_DEFAULT_M IPRIO_DEFAULT_MIDDLE
|
||||
#define IPRIO_DEFAULT_S (IPRIO_DEFAULT_M + 3)
|
||||
#define IPRIO_DEFAULT_SGEXT (IPRIO_DEFAULT_S + 3)
|
||||
|
||||
+61
-65
@@ -168,17 +168,17 @@ void riscv_cpu_update_mask(CPURISCVState *env)
|
||||
* 14 "
|
||||
* 15 "
|
||||
* 16 "
|
||||
* 18 Debug/trace interrupt
|
||||
* 20 (Reserved interrupt)
|
||||
* 17 "
|
||||
* 18 "
|
||||
* 19 "
|
||||
* 20 "
|
||||
* 21 "
|
||||
* 22 "
|
||||
* 24 "
|
||||
* 26 "
|
||||
* 28 "
|
||||
* 30 (Reserved for standard reporting of bus or system errors)
|
||||
* 23 "
|
||||
*/
|
||||
|
||||
static const int hviprio_index2irq[] = {
|
||||
0, 1, 4, 5, 8, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30 };
|
||||
0, 1, 4, 5, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
|
||||
static const int hviprio_index2rdzero[] = {
|
||||
1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
@@ -207,50 +207,60 @@ int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero)
|
||||
* Default |
|
||||
* Priority | Major Interrupt Numbers
|
||||
* ----------------------------------------------------------------
|
||||
* Highest | 63 (3f), 62 (3e), 31 (1f), 30 (1e), 61 (3d), 60 (3c),
|
||||
* | 59 (3b), 58 (3a), 29 (1d), 28 (1c), 57 (39), 56 (38),
|
||||
* | 55 (37), 54 (36), 27 (1b), 26 (1a), 53 (35), 52 (34),
|
||||
* | 51 (33), 50 (32), 25 (19), 24 (18), 49 (31), 48 (30)
|
||||
* Highest | 47, 23, 46, 45, 22, 44,
|
||||
* | 43, 21, 42, 41, 20, 40
|
||||
* |
|
||||
* | 11 (0b), 3 (03), 7 (07)
|
||||
* | 9 (09), 1 (01), 5 (05)
|
||||
* | 12 (0c)
|
||||
* | 10 (0a), 2 (02), 6 (06)
|
||||
* |
|
||||
* | 47 (2f), 46 (2e), 23 (17), 22 (16), 45 (2d), 44 (2c),
|
||||
* | 43 (2b), 42 (2a), 21 (15), 20 (14), 41 (29), 40 (28),
|
||||
* | 39 (27), 38 (26), 19 (13), 18 (12), 37 (25), 36 (24),
|
||||
* Lowest | 35 (23), 34 (22), 17 (11), 16 (10), 33 (21), 32 (20)
|
||||
* | 39, 19, 38, 37, 18, 36,
|
||||
* Lowest | 35, 17, 34, 33, 16, 32
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static const uint8_t default_iprio[64] = {
|
||||
[63] = IPRIO_DEFAULT_UPPER,
|
||||
[62] = IPRIO_DEFAULT_UPPER + 1,
|
||||
[31] = IPRIO_DEFAULT_UPPER + 2,
|
||||
[30] = IPRIO_DEFAULT_UPPER + 3,
|
||||
[61] = IPRIO_DEFAULT_UPPER + 4,
|
||||
[60] = IPRIO_DEFAULT_UPPER + 5,
|
||||
/* Custom interrupts 48 to 63 */
|
||||
[63] = IPRIO_MMAXIPRIO,
|
||||
[62] = IPRIO_MMAXIPRIO,
|
||||
[61] = IPRIO_MMAXIPRIO,
|
||||
[60] = IPRIO_MMAXIPRIO,
|
||||
[59] = IPRIO_MMAXIPRIO,
|
||||
[58] = IPRIO_MMAXIPRIO,
|
||||
[57] = IPRIO_MMAXIPRIO,
|
||||
[56] = IPRIO_MMAXIPRIO,
|
||||
[55] = IPRIO_MMAXIPRIO,
|
||||
[54] = IPRIO_MMAXIPRIO,
|
||||
[53] = IPRIO_MMAXIPRIO,
|
||||
[52] = IPRIO_MMAXIPRIO,
|
||||
[51] = IPRIO_MMAXIPRIO,
|
||||
[50] = IPRIO_MMAXIPRIO,
|
||||
[49] = IPRIO_MMAXIPRIO,
|
||||
[48] = IPRIO_MMAXIPRIO,
|
||||
|
||||
[59] = IPRIO_DEFAULT_UPPER + 6,
|
||||
[58] = IPRIO_DEFAULT_UPPER + 7,
|
||||
[29] = IPRIO_DEFAULT_UPPER + 8,
|
||||
[28] = IPRIO_DEFAULT_UPPER + 9,
|
||||
[57] = IPRIO_DEFAULT_UPPER + 10,
|
||||
[56] = IPRIO_DEFAULT_UPPER + 11,
|
||||
/* Custom interrupts 24 to 31 */
|
||||
[31] = IPRIO_MMAXIPRIO,
|
||||
[30] = IPRIO_MMAXIPRIO,
|
||||
[29] = IPRIO_MMAXIPRIO,
|
||||
[28] = IPRIO_MMAXIPRIO,
|
||||
[27] = IPRIO_MMAXIPRIO,
|
||||
[26] = IPRIO_MMAXIPRIO,
|
||||
[25] = IPRIO_MMAXIPRIO,
|
||||
[24] = IPRIO_MMAXIPRIO,
|
||||
|
||||
[55] = IPRIO_DEFAULT_UPPER + 12,
|
||||
[54] = IPRIO_DEFAULT_UPPER + 13,
|
||||
[27] = IPRIO_DEFAULT_UPPER + 14,
|
||||
[26] = IPRIO_DEFAULT_UPPER + 15,
|
||||
[53] = IPRIO_DEFAULT_UPPER + 16,
|
||||
[52] = IPRIO_DEFAULT_UPPER + 17,
|
||||
[47] = IPRIO_DEFAULT_UPPER,
|
||||
[23] = IPRIO_DEFAULT_UPPER + 1,
|
||||
[46] = IPRIO_DEFAULT_UPPER + 2,
|
||||
[45] = IPRIO_DEFAULT_UPPER + 3,
|
||||
[22] = IPRIO_DEFAULT_UPPER + 4,
|
||||
[44] = IPRIO_DEFAULT_UPPER + 5,
|
||||
|
||||
[51] = IPRIO_DEFAULT_UPPER + 18,
|
||||
[50] = IPRIO_DEFAULT_UPPER + 19,
|
||||
[25] = IPRIO_DEFAULT_UPPER + 20,
|
||||
[24] = IPRIO_DEFAULT_UPPER + 21,
|
||||
[49] = IPRIO_DEFAULT_UPPER + 22,
|
||||
[48] = IPRIO_DEFAULT_UPPER + 23,
|
||||
[43] = IPRIO_DEFAULT_UPPER + 6,
|
||||
[21] = IPRIO_DEFAULT_UPPER + 7,
|
||||
[42] = IPRIO_DEFAULT_UPPER + 8,
|
||||
[41] = IPRIO_DEFAULT_UPPER + 9,
|
||||
[20] = IPRIO_DEFAULT_UPPER + 10,
|
||||
[40] = IPRIO_DEFAULT_UPPER + 11,
|
||||
|
||||
[11] = IPRIO_DEFAULT_M,
|
||||
[3] = IPRIO_DEFAULT_M + 1,
|
||||
@@ -266,33 +276,19 @@ static const uint8_t default_iprio[64] = {
|
||||
[2] = IPRIO_DEFAULT_VS + 1,
|
||||
[6] = IPRIO_DEFAULT_VS + 2,
|
||||
|
||||
[47] = IPRIO_DEFAULT_LOWER,
|
||||
[46] = IPRIO_DEFAULT_LOWER + 1,
|
||||
[23] = IPRIO_DEFAULT_LOWER + 2,
|
||||
[22] = IPRIO_DEFAULT_LOWER + 3,
|
||||
[45] = IPRIO_DEFAULT_LOWER + 4,
|
||||
[44] = IPRIO_DEFAULT_LOWER + 5,
|
||||
[39] = IPRIO_DEFAULT_LOWER,
|
||||
[19] = IPRIO_DEFAULT_LOWER + 1,
|
||||
[38] = IPRIO_DEFAULT_LOWER + 2,
|
||||
[37] = IPRIO_DEFAULT_LOWER + 3,
|
||||
[18] = IPRIO_DEFAULT_LOWER + 4,
|
||||
[36] = IPRIO_DEFAULT_LOWER + 5,
|
||||
|
||||
[43] = IPRIO_DEFAULT_LOWER + 6,
|
||||
[42] = IPRIO_DEFAULT_LOWER + 7,
|
||||
[21] = IPRIO_DEFAULT_LOWER + 8,
|
||||
[20] = IPRIO_DEFAULT_LOWER + 9,
|
||||
[41] = IPRIO_DEFAULT_LOWER + 10,
|
||||
[40] = IPRIO_DEFAULT_LOWER + 11,
|
||||
|
||||
[39] = IPRIO_DEFAULT_LOWER + 12,
|
||||
[38] = IPRIO_DEFAULT_LOWER + 13,
|
||||
[19] = IPRIO_DEFAULT_LOWER + 14,
|
||||
[18] = IPRIO_DEFAULT_LOWER + 15,
|
||||
[37] = IPRIO_DEFAULT_LOWER + 16,
|
||||
[36] = IPRIO_DEFAULT_LOWER + 17,
|
||||
|
||||
[35] = IPRIO_DEFAULT_LOWER + 18,
|
||||
[34] = IPRIO_DEFAULT_LOWER + 19,
|
||||
[17] = IPRIO_DEFAULT_LOWER + 20,
|
||||
[16] = IPRIO_DEFAULT_LOWER + 21,
|
||||
[33] = IPRIO_DEFAULT_LOWER + 22,
|
||||
[32] = IPRIO_DEFAULT_LOWER + 23,
|
||||
[35] = IPRIO_DEFAULT_LOWER + 6,
|
||||
[17] = IPRIO_DEFAULT_LOWER + 7,
|
||||
[34] = IPRIO_DEFAULT_LOWER + 8,
|
||||
[33] = IPRIO_DEFAULT_LOWER + 9,
|
||||
[16] = IPRIO_DEFAULT_LOWER + 10,
|
||||
[32] = IPRIO_DEFAULT_LOWER + 11,
|
||||
};
|
||||
|
||||
uint8_t riscv_cpu_default_priority(int irq)
|
||||
|
||||
+525
-328
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (has_ext(ctx, RVS)) {
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_sret(cpu_pc, cpu_env);
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
@@ -90,6 +91,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
|
||||
static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_mret(cpu_pc, cpu_env);
|
||||
tcg_gen_exit_tb(NULL, 0); /* no chaining */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
@@ -102,6 +104,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
||||
static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
gen_helper_wfi(cpu_env);
|
||||
return true;
|
||||
@@ -113,6 +116,7 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
|
||||
static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_tlb_flush(cpu_env);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
@@ -169,6 +169,7 @@ static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||
{
|
||||
REQUIRE_EXT(ctx, RVH);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_hyp_gvma_tlb_flush(cpu_env);
|
||||
return true;
|
||||
#endif
|
||||
@@ -179,6 +180,7 @@ static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||
{
|
||||
REQUIRE_EXT(ctx, RVH);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_hyp_tlb_flush(cpu_env);
|
||||
return true;
|
||||
#endif
|
||||
|
||||
@@ -32,17 +32,13 @@ static bool trans_c64_illegal(DisasContext *ctx, arg_empty *a)
|
||||
|
||||
static bool trans_lui(DisasContext *ctx, arg_lui *a)
|
||||
{
|
||||
if (a->rd != 0) {
|
||||
gen_set_gpri(ctx, a->rd, a->imm);
|
||||
}
|
||||
gen_set_gpri(ctx, a->rd, a->imm);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
|
||||
{
|
||||
if (a->rd != 0) {
|
||||
gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
|
||||
}
|
||||
gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -822,6 +818,8 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
||||
|
||||
static bool do_csr_post(DisasContext *ctx)
|
||||
{
|
||||
/* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
|
||||
decode_save_opc(ctx);
|
||||
/* We may have changed important cpu state -- exit to main loop. */
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
|
||||
@@ -279,7 +279,28 @@ static const VMStateDescription vmstate_envcfg = {
|
||||
VMSTATE_UINT64(env.menvcfg, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.senvcfg, RISCVCPU),
|
||||
VMSTATE_UINT64(env.henvcfg, RISCVCPU),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static bool pmu_needed(void *opaque)
|
||||
{
|
||||
RISCVCPU *cpu = opaque;
|
||||
|
||||
return cpu->cfg.pmu_num;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_pmu_ctr_state = {
|
||||
.name = "cpu/pmu",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = pmu_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINTTL(mhpmcounter_val, PMUCTRState),
|
||||
VMSTATE_UINTTL(mhpmcounterh_val, PMUCTRState),
|
||||
VMSTATE_UINTTL(mhpmcounter_prev, PMUCTRState),
|
||||
VMSTATE_UINTTL(mhpmcounterh_prev, PMUCTRState),
|
||||
VMSTATE_BOOL(started, PMUCTRState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
@@ -330,6 +351,10 @@ const VMStateDescription vmstate_riscv_cpu = {
|
||||
VMSTATE_UINTTL(env.siselect, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.scounteren, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
|
||||
VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0,
|
||||
vmstate_pmu_ctr_state, PMUCTRState),
|
||||
VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS),
|
||||
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
|
||||
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
|
||||
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
|
||||
|
||||
@@ -30,7 +30,8 @@ riscv_softmmu_ss.add(files(
|
||||
'pmp.c',
|
||||
'debug.c',
|
||||
'monitor.c',
|
||||
'machine.c'
|
||||
'machine.c',
|
||||
'pmu.c'
|
||||
))
|
||||
|
||||
target_arch += {'riscv': riscv_ss}
|
||||
|
||||
@@ -167,6 +167,9 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
|
||||
case PMP_AMATCH_TOR:
|
||||
sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
|
||||
ea = (this_addr << 2) - 1u;
|
||||
if (sa > ea) {
|
||||
sa = ea = 0u;
|
||||
}
|
||||
break;
|
||||
|
||||
case PMP_AMATCH_NA4:
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* RISC-V PMU file.
|
||||
*
|
||||
* Copyright (c) 2021 Western Digital Corporation or its affiliates.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "pmu.h"
|
||||
|
||||
bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
|
||||
uint32_t target_ctr)
|
||||
{
|
||||
return (target_ctr == 0) ? true : false;
|
||||
}
|
||||
|
||||
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr)
|
||||
{
|
||||
return (target_ctr == 2) ? true : false;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* RISC-V PMU header file.
|
||||
*
|
||||
* Copyright (c) 2021 Western Digital Corporation or its affiliates.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
|
||||
uint32_t target_ctr);
|
||||
bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
|
||||
uint32_t target_ctr);
|
||||
+13
-18
@@ -206,6 +206,13 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
|
||||
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
|
||||
}
|
||||
|
||||
static void decode_save_opc(DisasContext *ctx)
|
||||
{
|
||||
assert(ctx->insn_start != NULL);
|
||||
tcg_set_insn_start_param(ctx->insn_start, 1, ctx->opcode);
|
||||
ctx->insn_start = NULL;
|
||||
}
|
||||
|
||||
static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
|
||||
{
|
||||
if (get_xl(ctx) == MXL_RV32) {
|
||||
@@ -230,22 +237,17 @@ static void generate_exception(DisasContext *ctx, int excp)
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void generate_exception_mtval(DisasContext *ctx, int excp)
|
||||
{
|
||||
gen_set_pc_imm(ctx, ctx->base.pc_next);
|
||||
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_exception_illegal(DisasContext *ctx)
|
||||
{
|
||||
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
|
||||
offsetof(CPURISCVState, bins));
|
||||
generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
|
||||
}
|
||||
|
||||
static void gen_exception_inst_addr_mis(DisasContext *ctx)
|
||||
{
|
||||
generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
|
||||
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
|
||||
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
|
||||
}
|
||||
|
||||
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
@@ -640,6 +642,8 @@ static void gen_set_rm(DisasContext *ctx, int rm)
|
||||
return;
|
||||
}
|
||||
|
||||
/* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
|
||||
decode_save_opc(ctx);
|
||||
gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
|
||||
}
|
||||
|
||||
@@ -1018,13 +1022,6 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
|
||||
/* Include decoders for factored-out extensions */
|
||||
#include "decode-XVentanaCondOps.c.inc"
|
||||
|
||||
static inline void decode_save_opc(DisasContext *ctx, target_ulong opc)
|
||||
{
|
||||
assert(ctx->insn_start != NULL);
|
||||
tcg_set_insn_start_param(ctx->insn_start, 1, opc);
|
||||
ctx->insn_start = NULL;
|
||||
}
|
||||
|
||||
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
|
||||
{
|
||||
/*
|
||||
@@ -1041,7 +1038,6 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
|
||||
|
||||
/* Check for compressed insn */
|
||||
if (extract16(opcode, 0, 2) != 3) {
|
||||
decode_save_opc(ctx, opcode);
|
||||
if (!has_ext(ctx, RVC)) {
|
||||
gen_exception_illegal(ctx);
|
||||
} else {
|
||||
@@ -1056,7 +1052,6 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
|
||||
opcode32 = deposit32(opcode32, 16, 16,
|
||||
translator_lduw(env, &ctx->base,
|
||||
ctx->base.pc_next + 2));
|
||||
decode_save_opc(ctx, opcode32);
|
||||
ctx->opcode = opcode32;
|
||||
ctx->pc_succ_insn = ctx->base.pc_next + 4;
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# RISC-V system tests
|
||||
#
|
||||
|
||||
TEST_SRC = $(SRC_PATH)/tests/tcg/riscv64
|
||||
VPATH += $(TEST_SRC)
|
||||
|
||||
LINK_SCRIPT = $(TEST_SRC)/semihost.ld
|
||||
LDFLAGS = -T $(LINK_SCRIPT)
|
||||
CFLAGS += -g -Og
|
||||
|
||||
%.o: %.S
|
||||
$(CC) $(CFLAGS) $< -c -o $@
|
||||
%: %.o $(LINK_SCRIPT)
|
||||
$(LD) $(LDFLAGS) $< -o $@
|
||||
|
||||
QEMU_OPTS += -M virt -display none -semihosting -device loader,file=
|
||||
|
||||
EXTRA_RUNS += run-issue1060
|
||||
run-issue1060: issue1060
|
||||
$(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
|
||||
@@ -0,0 +1,53 @@
|
||||
.option norvc
|
||||
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
lla t0, trap
|
||||
csrw mtvec, t0
|
||||
|
||||
# These are all illegal instructions
|
||||
csrw time, x0
|
||||
.insn i CUSTOM_0, 0, x0, x0, 0x321
|
||||
csrw time, x0
|
||||
.insn i CUSTOM_0, 0, x0, x0, 0x123
|
||||
csrw cycle, x0
|
||||
|
||||
# Success!
|
||||
li a0, 0
|
||||
j _exit
|
||||
|
||||
trap:
|
||||
# When an instruction traps, compare it to the insn in memory.
|
||||
csrr t0, mepc
|
||||
csrr t1, mtval
|
||||
lwu t2, 0(t0)
|
||||
bne t1, t2, fail
|
||||
|
||||
# Skip the insn and continue.
|
||||
addi t0, t0, 4
|
||||
csrw mepc, t0
|
||||
mret
|
||||
|
||||
fail:
|
||||
li a0, 1
|
||||
|
||||
# Exit code in a0
|
||||
_exit:
|
||||
lla a1, semiargs
|
||||
li t0, 0x20026 # ADP_Stopped_ApplicationExit
|
||||
sd t0, 0(a1)
|
||||
sd a0, 8(a1)
|
||||
li a0, 0x20 # TARGET_SYS_EXIT_EXTENDED
|
||||
|
||||
# Semihosting call sequence
|
||||
.balign 16
|
||||
slli zero, zero, 0x1f
|
||||
ebreak
|
||||
srai zero, zero, 0x7
|
||||
j .
|
||||
|
||||
.data
|
||||
.balign 16
|
||||
semiargs:
|
||||
.space 16
|
||||
@@ -0,0 +1,21 @@
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* virt machine, RAM starts at 2gb */
|
||||
. = 0x80000000;
|
||||
.text : {
|
||||
*(.text)
|
||||
}
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
}
|
||||
/* align r/w section to next 2mb */
|
||||
. = ALIGN(1 << 21);
|
||||
.data : {
|
||||
*(.data)
|
||||
}
|
||||
.bss : {
|
||||
*(.bss)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user