Skip to content

Commit 5f42c33

Browse files
committed
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20200702-1' into staging
This PR contains two patches to improve PLIC support in QEMU. It also contains one patch that fixes CLINT accesses for RISC-V. This fixes a regression for most RISC-V boards. The rest of the PR is adding support for the v0.7.1 RISC-V vector extensions. This is experimental support as the vector extensions are still in a draft state. This is a v2 pull request that has fixed the building on big endian machines failure. # gpg: Signature made Thu 02 Jul 2020 17:21:54 BST # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <[email protected]>" [full] # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair/tags/pull-riscv-to-apply-20200702-1: (64 commits) target/riscv: configure and turn on vector extension from command line target/riscv: vector compress instruction target/riscv: vector register gather instruction target/riscv: vector slide instructions target/riscv: floating-point scalar move instructions target/riscv: integer scalar move instruction target/riscv: integer extract instruction target/riscv: vector element index instruction target/riscv: vector iota instruction target/riscv: set-X-first mask bit target/riscv: vmfirst find-first-set mask bit target/riscv: vector mask population count vmpopc target/riscv: vector mask-register logical instructions target/riscv: vector widening floating-point reduction instructions target/riscv: vector single-width floating-point reduction instructions target/riscv: vector wideing integer reduction instructions target/riscv: vector single-width integer reduction instructions target/riscv: narrowing floating-point/integer type-convert instructions target/riscv: widening floating-point/integer type-convert instructions target/riscv: vector floating-point/integer type-convert instructions ... Signed-off-by: Peter Maydell <[email protected]>
2 parents 4abf70a + 6bf9161 commit 5f42c33

File tree

15 files changed

+9535
-51
lines changed

15 files changed

+9535
-51
lines changed

hw/riscv/sifive_clint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ static const MemoryRegionOps sifive_clint_ops = {
181181
.endianness = DEVICE_LITTLE_ENDIAN,
182182
.valid = {
183183
.min_access_size = 4,
184-
.max_access_size = 4
184+
.max_access_size = 8
185185
}
186186
};
187187

hw/riscv/sifive_plic.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ static void sifive_plic_update(SiFivePLICState *plic)
166166
static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
167167
{
168168
int i, j;
169+
uint32_t max_irq = 0;
170+
uint32_t max_prio = plic->target_priority[addrid];
171+
169172
for (i = 0; i < plic->bitfield_words; i++) {
170173
uint32_t pending_enabled_not_claimed =
171174
(plic->pending[i] & ~plic->claimed[i]) &
@@ -177,14 +180,18 @@ static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
177180
int irq = (i << 5) + j;
178181
uint32_t prio = plic->source_priority[irq];
179182
int enabled = pending_enabled_not_claimed & (1 << j);
180-
if (enabled && prio > plic->target_priority[addrid]) {
181-
sifive_plic_set_pending(plic, irq, false);
182-
sifive_plic_set_claimed(plic, irq, true);
183-
return irq;
183+
if (enabled && prio > max_prio) {
184+
max_irq = irq;
185+
max_prio = prio;
184186
}
185187
}
186188
}
187-
return 0;
189+
190+
if (max_irq) {
191+
sifive_plic_set_pending(plic, max_irq, false);
192+
sifive_plic_set_claimed(plic, max_irq, true);
193+
}
194+
return max_irq;
188195
}
189196

190197
static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
@@ -248,8 +255,8 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
248255
plic->addr_config[addrid].hartid,
249256
mode_to_char(plic->addr_config[addrid].mode),
250257
value);
251-
sifive_plic_print_state(plic);
252258
}
259+
sifive_plic_update(plic);
253260
return value;
254261
}
255262
}
@@ -280,6 +287,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
280287
qemu_log("plic: write priority: irq=%d priority=%d\n",
281288
irq, plic->source_priority[irq]);
282289
}
290+
sifive_plic_update(plic);
283291
return;
284292
} else if (addr >= plic->pending_base && /* 1 bit per source */
285293
addr < plic->pending_base + (plic->num_sources >> 3))

target/riscv/Makefile.objs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o gdbstub.o
1+
obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o vector_helper.o gdbstub.o
22
obj-$(CONFIG_SOFTMMU) += pmp.o
33

44
ifeq ($(CONFIG_SOFTMMU),y)

target/riscv/cpu.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ static void set_priv_version(CPURISCVState *env, int priv_ver)
106106
env->priv_ver = priv_ver;
107107
}
108108

109+
static void set_vext_version(CPURISCVState *env, int vext_ver)
110+
{
111+
env->vext_ver = vext_ver;
112+
}
113+
109114
static void set_feature(CPURISCVState *env, int feature)
110115
{
111116
env->features |= (1ULL << feature);
@@ -334,6 +339,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
334339
CPURISCVState *env = &cpu->env;
335340
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
336341
int priv_version = PRIV_VERSION_1_11_0;
342+
int vext_version = VEXT_VERSION_0_07_1;
337343
target_ulong target_misa = 0;
338344
Error *local_err = NULL;
339345

@@ -357,6 +363,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
357363
}
358364

359365
set_priv_version(env, priv_version);
366+
set_vext_version(env, vext_version);
360367

361368
if (cpu->cfg.mmu) {
362369
set_feature(env, RISCV_FEATURE_MMU);
@@ -423,6 +430,45 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
423430
if (cpu->cfg.ext_h) {
424431
target_misa |= RVH;
425432
}
433+
if (cpu->cfg.ext_v) {
434+
target_misa |= RVV;
435+
if (!is_power_of_2(cpu->cfg.vlen)) {
436+
error_setg(errp,
437+
"Vector extension VLEN must be power of 2");
438+
return;
439+
}
440+
if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
441+
error_setg(errp,
442+
"Vector extension implementation only supports VLEN "
443+
"in the range [128, %d]", RV_VLEN_MAX);
444+
return;
445+
}
446+
if (!is_power_of_2(cpu->cfg.elen)) {
447+
error_setg(errp,
448+
"Vector extension ELEN must be power of 2");
449+
return;
450+
}
451+
if (cpu->cfg.elen > 64 || cpu->cfg.vlen < 8) {
452+
error_setg(errp,
453+
"Vector extension implementation only supports ELEN "
454+
"in the range [8, 64]");
455+
return;
456+
}
457+
if (cpu->cfg.vext_spec) {
458+
if (!g_strcmp0(cpu->cfg.vext_spec, "v0.7.1")) {
459+
vext_version = VEXT_VERSION_0_07_1;
460+
} else {
461+
error_setg(errp,
462+
"Unsupported vector spec version '%s'",
463+
cpu->cfg.vext_spec);
464+
return;
465+
}
466+
} else {
467+
qemu_log("vector verison is not specified, "
468+
"use the default value v0.7.1\n");
469+
}
470+
set_vext_version(env, vext_version);
471+
}
426472

427473
set_misa(env, RVXLEN | target_misa);
428474
}
@@ -462,10 +508,14 @@ static Property riscv_cpu_properties[] = {
462508
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
463509
/* This is experimental so mark with 'x-' */
464510
DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
511+
DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
465512
DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
466513
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
467514
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
468515
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
516+
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
517+
DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
518+
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
469519
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
470520
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
471521
DEFINE_PROP_END_OF_LIST(),

target/riscv/cpu.h

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define RISCV_CPU_H
2222

2323
#include "hw/core/cpu.h"
24+
#include "hw/registerfields.h"
2425
#include "exec/cpu-defs.h"
2526
#include "fpu/softfloat-types.h"
2627

@@ -59,6 +60,7 @@
5960
#define RVA RV('A')
6061
#define RVF RV('F')
6162
#define RVD RV('D')
63+
#define RVV RV('V')
6264
#define RVC RV('C')
6365
#define RVS RV('S')
6466
#define RVU RV('U')
@@ -77,6 +79,8 @@ enum {
7779
#define PRIV_VERSION_1_10_0 0x00011000
7880
#define PRIV_VERSION_1_11_0 0x00011100
7981

82+
#define VEXT_VERSION_0_07_1 0x00000701
83+
8084
#define TRANSLATE_PMP_FAIL 2
8185
#define TRANSLATE_FAIL 1
8286
#define TRANSLATE_SUCCESS 0
@@ -88,9 +92,26 @@ typedef struct CPURISCVState CPURISCVState;
8892

8993
#include "pmp.h"
9094

95+
#define RV_VLEN_MAX 256
96+
97+
FIELD(VTYPE, VLMUL, 0, 2)
98+
FIELD(VTYPE, VSEW, 2, 3)
99+
FIELD(VTYPE, VEDIV, 5, 2)
100+
FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
101+
FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1)
102+
91103
struct CPURISCVState {
92104
target_ulong gpr[32];
93105
uint64_t fpr[32]; /* assume both F and D extensions */
106+
107+
/* vector coprocessor state. */
108+
uint64_t vreg[32 * RV_VLEN_MAX / 64] QEMU_ALIGNED(16);
109+
target_ulong vxrm;
110+
target_ulong vxsat;
111+
target_ulong vl;
112+
target_ulong vstart;
113+
target_ulong vtype;
114+
94115
target_ulong pc;
95116
target_ulong load_res;
96117
target_ulong load_val;
@@ -101,6 +122,7 @@ struct CPURISCVState {
101122
target_ulong guest_phys_fault_addr;
102123

103124
target_ulong priv_ver;
125+
target_ulong vext_ver;
104126
target_ulong misa;
105127
target_ulong misa_mask;
106128

@@ -257,12 +279,16 @@ typedef struct RISCVCPU {
257279
bool ext_s;
258280
bool ext_u;
259281
bool ext_h;
282+
bool ext_v;
260283
bool ext_counters;
261284
bool ext_ifencei;
262285
bool ext_icsr;
263286

264287
char *priv_spec;
265288
char *user_spec;
289+
char *vext_spec;
290+
uint16_t vlen;
291+
uint16_t elen;
266292
bool mmu;
267293
bool pmp;
268294
} cfg;
@@ -335,19 +361,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
335361
#define TB_FLAGS_MMU_MASK 3
336362
#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
337363

364+
typedef CPURISCVState CPUArchState;
365+
typedef RISCVCPU ArchCPU;
366+
#include "exec/cpu-all.h"
367+
368+
FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
369+
FIELD(TB_FLAGS, LMUL, 3, 2)
370+
FIELD(TB_FLAGS, SEW, 5, 3)
371+
FIELD(TB_FLAGS, VILL, 8, 1)
372+
373+
/*
374+
* A simplification for VLMAX
375+
* = (1 << LMUL) * VLEN / (8 * (1 << SEW))
376+
* = (VLEN << LMUL) / (8 << SEW)
377+
* = (VLEN << LMUL) >> (SEW + 3)
378+
* = VLEN >> (SEW + 3 - LMUL)
379+
*/
380+
static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
381+
{
382+
uint8_t sew, lmul;
383+
384+
sew = FIELD_EX64(vtype, VTYPE, VSEW);
385+
lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
386+
return cpu->cfg.vlen >> (sew + 3 - lmul);
387+
}
388+
338389
static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
339-
target_ulong *cs_base, uint32_t *flags)
390+
target_ulong *cs_base, uint32_t *pflags)
340391
{
392+
uint32_t flags = 0;
393+
341394
*pc = env->pc;
342395
*cs_base = 0;
396+
397+
if (riscv_has_ext(env, RVV)) {
398+
uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
399+
bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
400+
flags = FIELD_DP32(flags, TB_FLAGS, VILL,
401+
FIELD_EX64(env->vtype, VTYPE, VILL));
402+
flags = FIELD_DP32(flags, TB_FLAGS, SEW,
403+
FIELD_EX64(env->vtype, VTYPE, VSEW));
404+
flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
405+
FIELD_EX64(env->vtype, VTYPE, VLMUL));
406+
flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
407+
} else {
408+
flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
409+
}
410+
343411
#ifdef CONFIG_USER_ONLY
344-
*flags = TB_FLAGS_MSTATUS_FS;
412+
flags |= TB_FLAGS_MSTATUS_FS;
345413
#else
346-
*flags = cpu_mmu_index(env, 0);
414+
flags |= cpu_mmu_index(env, 0);
347415
if (riscv_cpu_fp_enabled(env)) {
348-
*flags |= env->mstatus & MSTATUS_FS;
416+
flags |= env->mstatus & MSTATUS_FS;
349417
}
350418
#endif
419+
*pflags = flags;
351420
}
352421

353422
int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
@@ -388,9 +457,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
388457

389458
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
390459

391-
typedef CPURISCVState CPUArchState;
392-
typedef RISCVCPU ArchCPU;
393-
394-
#include "exec/cpu-all.h"
395-
396460
#endif /* RISCV_CPU_H */

target/riscv/cpu_bits.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
3030
#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
3131

32+
/* Vector Fixed-Point round model */
33+
#define FSR_VXRM_SHIFT 9
34+
#define FSR_VXRM (0x3 << FSR_VXRM_SHIFT)
35+
36+
/* Vector Fixed-Point saturation flag */
37+
#define FSR_VXSAT_SHIFT 8
38+
#define FSR_VXSAT (0x1 << FSR_VXSAT_SHIFT)
39+
3240
/* Control and Status Registers */
3341

3442
/* User Trap Setup */
@@ -48,6 +56,13 @@
4856
#define CSR_FRM 0x002
4957
#define CSR_FCSR 0x003
5058

59+
/* User Vector CSRs */
60+
#define CSR_VSTART 0x008
61+
#define CSR_VXSAT 0x009
62+
#define CSR_VXRM 0x00a
63+
#define CSR_VL 0xc20
64+
#define CSR_VTYPE 0xc21
65+
5166
/* User Timers and Counters */
5267
#define CSR_CYCLE 0xc00
5368
#define CSR_TIME 0xc01

0 commit comments

Comments
 (0)