aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-09-21 10:57:48 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-09-21 10:57:48 -0700
commit2c3e83f92d93fbab071b8a96b8ab769b01902475 (patch)
treed6462933ac8d7dff5598c3d688c5f8e9aae7e8ee /target
parent81ceb36b965c9d5ed5b1eb0ed80e23705802de15 (diff)
parented481d9837250aa682f5156528bc923e1b214f76 (diff)
Merge remote-tracking branch 'remotes/alistair23/tags/pull-riscv-to-apply-20210921' into staging
Second RISC-V PR for QEMU 6.2 - ePMP CSR address updates - Convert internal interrupts to use QEMU GPIO lines - SiFive PWM support - Support for RISC-V ACLINT - SiFive PDMA fixes - Update to u-boot instructions for sifive_u - mstatus.SD bug fix for hypervisor extensions - OpenTitan fix for USB dev address # gpg: Signature made Mon 20 Sep 2021 11:52:26 PM PDT # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [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: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair23/tags/pull-riscv-to-apply-20210921: (21 commits) hw/riscv: opentitan: Correct the USB Dev address target/riscv: csr: Rename HCOUNTEREN_CY and friends target/riscv: Backup/restore mstatus.SD bit when virtual register swapped docs/system/riscv: sifive_u: Update U-Boot instructions hw/dma: sifive_pdma: don't set Control.error if 0 bytes to transfer hw/dma: sifive_pdma: allow non-multiple transaction size transactions hw/dma: sifive_pdma: claim bit must be set before DMA transactions hw/dma: sifive_pdma: reset Next* registers when Control.claim is set hw/riscv: virt: Add optional ACLINT support to virt machine hw/riscv: virt: Re-factor FDT generation hw/intc: Upgrade the SiFive CLINT implementation to RISC-V ACLINT hw/intc: Rename sifive_clint sources to riscv_aclint sources sifive_u: Connect the SiFive PWM device hw/timer: Add SiFive PWM support hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines hw/intc: sifive_clint: Use RISC-V CPU GPIO lines target/riscv: Expose interrupt pending bits as GPIO lines target/riscv: Fix satp write ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/cpu.c31
-rw-r--r--target/riscv/cpu_bits.h12
-rw-r--r--target/riscv/cpu_helper.c3
-rw-r--r--target/riscv/csr.c26
4 files changed, 52 insertions, 20 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 13575c1408..7c626d89cd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -567,11 +567,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
mcc->parent_realize(dev, errp);
}
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_set_irq(void *opaque, int irq, int level)
+{
+ RISCVCPU *cpu = RISCV_CPU(opaque);
+
+ switch (irq) {
+ case IRQ_U_SOFT:
+ case IRQ_S_SOFT:
+ case IRQ_VS_SOFT:
+ case IRQ_M_SOFT:
+ case IRQ_U_TIMER:
+ case IRQ_S_TIMER:
+ case IRQ_VS_TIMER:
+ case IRQ_M_TIMER:
+ case IRQ_U_EXT:
+ case IRQ_S_EXT:
+ case IRQ_VS_EXT:
+ case IRQ_M_EXT:
+ riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+#endif /* CONFIG_USER_ONLY */
+
static void riscv_cpu_init(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+ qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
+#endif /* CONFIG_USER_ONLY */
}
static Property riscv_cpu_properties[] = {
@@ -599,6 +629,7 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ /* ePMP 0.9.3 */
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 7330ff5a19..999187a9ee 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -210,8 +210,8 @@
#define CSR_MTVAL2 0x34b
/* Enhanced Physical Memory Protection (ePMP) */
-#define CSR_MSECCFG 0x390
-#define CSR_MSECCFGH 0x391
+#define CSR_MSECCFG 0x747
+#define CSR_MSECCFGH 0x757
/* Physical Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
@@ -397,10 +397,10 @@
#define HSTATUS32_WPRI 0xFF8FF87E
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
-#define HCOUNTEREN_CY (1 << 0)
-#define HCOUNTEREN_TM (1 << 1)
-#define HCOUNTEREN_IR (1 << 2)
-#define HCOUNTEREN_HPM3 (1 << 3)
+#define COUNTEREN_CY (1 << 0)
+#define COUNTEREN_TM (1 << 1)
+#define COUNTEREN_IR (1 << 2)
+#define COUNTEREN_HPM3 (1 << 3)
/* Privilege modes */
#define PRV_U 0
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 701858d670..d41d5cd27c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -106,9 +106,10 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
{
+ uint64_t sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
- MSTATUS64_UXL;
+ MSTATUS64_UXL | sd;
bool current_virt = riscv_cpu_virt_enabled(env);
g_assert(riscv_has_ext(env, RVH));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 50a2c3a3b4..23fbbd3216 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -71,20 +71,20 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
if (riscv_cpu_virt_enabled(env)) {
switch (csrno) {
case CSR_CYCLE:
- if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
- get_field(env->mcounteren, HCOUNTEREN_CY)) {
+ if (!get_field(env->hcounteren, COUNTEREN_CY) &&
+ get_field(env->mcounteren, COUNTEREN_CY)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIME:
- if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
- get_field(env->mcounteren, HCOUNTEREN_TM)) {
+ if (!get_field(env->hcounteren, COUNTEREN_TM) &&
+ get_field(env->mcounteren, COUNTEREN_TM)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRET:
- if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
- get_field(env->mcounteren, HCOUNTEREN_IR)) {
+ if (!get_field(env->hcounteren, COUNTEREN_IR) &&
+ get_field(env->mcounteren, COUNTEREN_IR)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
@@ -98,20 +98,20 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
if (riscv_cpu_is_32bit(env)) {
switch (csrno) {
case CSR_CYCLEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
- get_field(env->mcounteren, HCOUNTEREN_CY)) {
+ if (!get_field(env->hcounteren, COUNTEREN_CY) &&
+ get_field(env->mcounteren, COUNTEREN_CY)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIMEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
- get_field(env->mcounteren, HCOUNTEREN_TM)) {
+ if (!get_field(env->hcounteren, COUNTEREN_TM) &&
+ get_field(env->mcounteren, COUNTEREN_TM)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRETH:
- if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
- get_field(env->mcounteren, HCOUNTEREN_IR)) {
+ if (!get_field(env->hcounteren, COUNTEREN_IR) &&
+ get_field(env->mcounteren, COUNTEREN_IR)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
@@ -986,7 +986,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
static RISCVException write_satp(CPURISCVState *env, int csrno,
target_ulong val)
{
- int vm, mask, asid;
+ target_ulong vm, mask, asid;
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
return RISCV_EXCP_NONE;