1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit 4d285821c5055ed68a6f6b7693fd11a06a1aa426:
2
2
3
The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1:
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200618' into staging (2020-06-19 11:44:03 +0100)
4
5
Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200619-3
10
8
11
for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3:
9
for you to fetch changes up to 3eaea6eb4e534f7b87c6eca808149bb671976800:
12
10
13
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000)
11
hw/riscv: sifive_u: Add a dummy DDR memory controller device (2020-06-19 08:25:27 -0700)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Seventh RISC-V PR for QEMU 6.2
14
This is a range of patches for RISC-V.
17
15
18
- Deprecate IF_NONE for SiFive OTP
16
Some key points are:
19
- Don't reset SiFive OTP content
17
- Generalise the CPU init functions
18
- Support the SiFive revB machine
19
- Improvements to the Hypervisor implementation and error checking
20
- Connect some OpenTitan devices
21
- Changes to the sifive_u machine to support U-boot
22
23
v2:
24
- Fix missing realise assert
20
25
21
----------------------------------------------------------------
26
----------------------------------------------------------------
22
Philippe Mathieu-Daudé (1):
27
Alistair Francis (11):
23
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset
28
sifive_e: Support the revB machine
29
target/riscv: Set access as data_load when validating stage-2 PTEs
30
target/riscv: Report errors validating 2nd-stage PTEs
31
target/riscv: Move the hfence instructions to the rvh decode
32
target/riscv: Implement checks for hfence
33
riscv/opentitan: Fix the ROM size
34
hw/char: Initial commit of Ibex UART
35
hw/intc: Initial commit of lowRISC Ibex PLIC
36
riscv/opentitan: Connect the PLIC device
37
riscv/opentitan: Connect the UART device
38
target/riscv: Use a smaller guess size for no-MMU PMP
24
39
25
Thomas Huth (1):
40
Bin Meng (20):
26
hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE
41
riscv: Generalize CPU init routine for the base CPU
42
riscv: Generalize CPU init routine for the gcsu CPU
43
riscv: Generalize CPU init routine for the imacu CPU
44
riscv: Keep the CPU init routine names consistent
45
hw/riscv: sifive_e: Remove the riscv_ prefix of the machine* and soc* functions
46
hw/riscv: opentitan: Remove the riscv_ prefix of the machine* and soc* functions
47
hw/riscv: sifive_u: Simplify the GEM IRQ connect code a little bit
48
hw/riscv: sifive_u: Generate device tree node for OTP
49
hw/riscv: sifive_gpio: Clean up the codes
50
hw/riscv: sifive_gpio: Add a new 'ngpio' property
51
hw/riscv: sifive_u: Hook a GPIO controller
52
hw/riscv: sifive_gpio: Do not blindly trigger output IRQs
53
hw/riscv: sifive_u: Add reset functionality
54
hw/riscv: sifive_u: Rename serial property get/set functions to a generic name
55
hw/riscv: sifive_u: Add a new property msel for MSEL pin state
56
target/riscv: Rename IBEX CPU init routine
57
hw/riscv: sifive: Change SiFive E/U CPU reset vector to 0x1004
58
hw/riscv: sifive_u: Support different boot source per MSEL pin state
59
hw/riscv: sifive_u: Sort the SoC memmap table entries
60
hw/riscv: sifive_u: Add a dummy DDR memory controller device
27
61
28
docs/about/deprecated.rst | 6 ++++++
62
Ian Jiang (1):
29
hw/misc/sifive_u_otp.c | 22 +++++++++++++---------
63
riscv: Add helper to make NaN-boxing for FP register
30
2 files changed, 19 insertions(+), 9 deletions(-)
31
64
65
include/hw/char/ibex_uart.h | 110 ++++++
66
include/hw/intc/ibex_plic.h | 63 ++++
67
include/hw/riscv/opentitan.h | 16 +
68
include/hw/riscv/sifive_e.h | 1 +
69
include/hw/riscv/sifive_gpio.h | 8 +-
70
include/hw/riscv/sifive_u.h | 27 ++
71
target/riscv/helper.h | 5 +
72
target/riscv/insn32.decode | 8 +-
73
hw/char/ibex_uart.c | 492 +++++++++++++++++++++++++
74
hw/intc/ibex_plic.c | 261 +++++++++++++
75
hw/riscv/opentitan.c | 71 +++-
76
hw/riscv/sifive_e.c | 60 ++-
77
hw/riscv/sifive_gpio.c | 45 ++-
78
hw/riscv/sifive_u.c | 157 ++++++--
79
target/riscv/cpu.c | 69 ++--
80
target/riscv/cpu_helper.c | 9 +-
81
target/riscv/insn_trans/trans_privileged.inc.c | 38 --
82
target/riscv/insn_trans/trans_rvf.inc.c | 17 +-
83
target/riscv/insn_trans/trans_rvh.inc.c | 37 ++
84
target/riscv/op_helper.c | 13 +
85
target/riscv/pmp.c | 14 +-
86
target/riscv/translate.c | 1 +
87
MAINTAINERS | 4 +
88
hw/char/Makefile.objs | 1 +
89
hw/intc/Makefile.objs | 1 +
90
hw/riscv/Kconfig | 4 +
91
26 files changed, 1350 insertions(+), 182 deletions(-)
92
create mode 100644 include/hw/char/ibex_uart.h
93
create mode 100644 include/hw/intc/ibex_plic.h
94
create mode 100644 hw/char/ibex_uart.c
95
create mode 100644 hw/intc/ibex_plic.c
96
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
97
diff view generated by jsdifflib
New patch
1
From: Ian Jiang <ianjiang.ict@gmail.com>
1
2
3
The function that makes NaN-boxing when a 32-bit value is assigned
4
to a 64-bit FP register is split out to a helper gen_nanbox_fpr().
5
Then it is applied in translating of the FLW instruction.
6
7
Signed-off-by: Ian Jiang <ianjiang.ict@gmail.com>
8
Message-Id: <20200128003707.17028-1-ianjiang.ict@gmail.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvf.inc.c | 17 +++++++++++++++--
14
1 file changed, 15 insertions(+), 2 deletions(-)
15
16
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvf.inc.c
19
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
20
@@ -XXX,XX +XXX,XX @@
21
return false; \
22
} while (0)
23
24
+/*
25
+ * RISC-V requires NaN-boxing of narrower width floating
26
+ * point values. This applies when a 32-bit value is
27
+ * assigned to a 64-bit FP register. Thus this does not
28
+ * apply when the RVD extension is not present.
29
+ */
30
+static void gen_nanbox_fpr(DisasContext *ctx, int regno)
31
+{
32
+ if (has_ext(ctx, RVD)) {
33
+ tcg_gen_ori_i64(cpu_fpr[regno], cpu_fpr[regno],
34
+ MAKE_64BIT_MASK(32, 32));
35
+ }
36
+}
37
+
38
static bool trans_flw(DisasContext *ctx, arg_flw *a)
39
{
40
TCGv t0 = tcg_temp_new();
41
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
42
tcg_gen_addi_tl(t0, t0, a->imm);
43
44
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
45
- /* RISC-V requires NaN-boxing of narrower width floating point values */
46
- tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL);
47
+ gen_nanbox_fpr(ctx, a->rd);
48
49
tcg_temp_free(t0);
50
mark_fs_dirty(ctx);
51
--
52
2.27.0
53
54
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
---
3
include/hw/riscv/sifive_e.h | 1 +
4
hw/riscv/sifive_e.c | 34 ++++++++++++++++++++++++++++++----
5
2 files changed, 31 insertions(+), 4 deletions(-)
1
6
7
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
8
index XXXXXXX..XXXXXXX 100644
9
--- a/include/hw/riscv/sifive_e.h
10
+++ b/include/hw/riscv/sifive_e.h
11
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveEState {
12
13
/*< public >*/
14
SiFiveESoCState soc;
15
+ bool revb;
16
} SiFiveEState;
17
18
#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
19
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/sifive_e.c
22
+++ b/hw/riscv/sifive_e.c
23
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
24
memmap[SIFIVE_E_DTIM].base, main_mem);
25
26
/* Mask ROM reset vector */
27
- uint32_t reset_vec[2] = {
28
- 0x204002b7, /* 0x1000: lui t0,0x20400 */
29
- 0x00028067, /* 0x1004: jr t0 */
30
- };
31
+ uint32_t reset_vec[2];
32
+
33
+ if (s->revb) {
34
+ reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
35
+ } else {
36
+ reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
37
+ }
38
+ reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
43
}
44
}
45
46
+static bool sifive_e_machine_get_revb(Object *obj, Error **errp)
47
+{
48
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
49
+
50
+ return s->revb;
51
+}
52
+
53
+static void sifive_e_machine_set_revb(Object *obj, bool value, Error **errp)
54
+{
55
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
56
+
57
+ s->revb = value;
58
+}
59
+
60
static void sifive_e_machine_instance_init(Object *obj)
61
{
62
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
63
+
64
+ s->revb = false;
65
+ object_property_add_bool(obj, "revb", sifive_e_machine_get_revb,
66
+ sifive_e_machine_set_revb);
67
+ object_property_set_description(obj, "revb",
68
+ "Set on to tell QEMU that it should model "
69
+ "the revB HiFive1 board");
70
}
71
72
static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
73
--
74
2.27.0
75
76
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
There is no need to have two functions that have exactly the same
4
codes for 32-bit and 64-bit base CPUs.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591837729-27486-1-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591837729-27486-1-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.c | 18 +++++-------------
13
1 file changed, 5 insertions(+), 13 deletions(-)
14
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
20
set_resetvec(env, DEFAULT_RSTVEC);
21
}
22
23
-#if defined(TARGET_RISCV32)
24
-
25
-static void riscv_base32_cpu_init(Object *obj)
26
+static void riscv_base_cpu_init(Object *obj)
27
{
28
CPURISCVState *env = &RISCV_CPU(obj)->env;
29
/* We set this in the realise function */
30
@@ -XXX,XX +XXX,XX @@ static void riscv_base32_cpu_init(Object *obj)
31
set_resetvec(env, DEFAULT_RSTVEC);
32
}
33
34
+#if defined(TARGET_RISCV32)
35
+
36
static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
37
{
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
40
41
#elif defined(TARGET_RISCV64)
42
43
-static void riscv_base64_cpu_init(Object *obj)
44
-{
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
46
- /* We set this in the realise function */
47
- set_misa(env, 0);
48
- set_resetvec(env, DEFAULT_RSTVEC);
49
-}
50
-
51
static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
},
56
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
57
#if defined(TARGET_RISCV32)
58
- DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
60
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
61
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
63
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
64
#elif defined(TARGET_RISCV64)
65
- DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
66
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
67
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
68
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
69
#endif
70
--
71
2.27.0
72
73
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
There is no need to have two functions that have almost the same
4
codes for 32-bit and 64-bit gcsu CPUs.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <1591837729-27486-2-git-send-email-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 20 ++++++--------------
12
1 file changed, 6 insertions(+), 14 deletions(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
19
set_resetvec(env, DEFAULT_RSTVEC);
20
}
21
22
-#if defined(TARGET_RISCV32)
23
-
24
-static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
25
+static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
26
{
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
28
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
30
set_priv_version(env, PRIV_VERSION_1_10_0);
31
set_resetvec(env, DEFAULT_RSTVEC);
32
}
33
34
+#if defined(TARGET_RISCV32)
35
+
36
static void rv32imcu_nommu_cpu_init(Object *obj)
37
{
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
40
41
#elif defined(TARGET_RISCV64)
42
43
-static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
44
-{
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
46
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
47
- set_priv_version(env, PRIV_VERSION_1_10_0);
48
- set_resetvec(env, DEFAULT_RSTVEC);
49
-}
50
-
51
static void rv64imacu_nommu_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
56
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
57
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
58
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
60
#elif defined(TARGET_RISCV64)
61
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
63
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
64
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
65
#endif
66
};
67
68
--
69
2.27.0
70
71
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
There is no need to have two functions that have almost the same
4
codes for 32-bit and 64-bit imacu CPUs.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <1591837729-27486-3-git-send-email-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 31 ++++++++++---------------------
12
1 file changed, 10 insertions(+), 21 deletions(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
19
set_resetvec(env, DEFAULT_RSTVEC);
20
}
21
22
-#if defined(TARGET_RISCV32)
23
-
24
-static void rv32imcu_nommu_cpu_init(Object *obj)
25
+static void rvxx_imacu_nommu_cpu_init(Object *obj)
26
{
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
28
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
30
set_priv_version(env, PRIV_VERSION_1_10_0);
31
- set_resetvec(env, 0x8090);
32
+ set_resetvec(env, DEFAULT_RSTVEC);
33
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
34
}
35
36
-static void rv32imacu_nommu_cpu_init(Object *obj)
37
+#if defined(TARGET_RISCV32)
38
+
39
+static void rv32imcu_nommu_cpu_init(Object *obj)
40
{
41
CPURISCVState *env = &RISCV_CPU(obj)->env;
42
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
43
+ set_misa(env, RV32 | RVI | RVM | RVC | RVU);
44
set_priv_version(env, PRIV_VERSION_1_10_0);
45
- set_resetvec(env, DEFAULT_RSTVEC);
46
+ set_resetvec(env, 0x8090);
47
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
51
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
52
}
53
54
-#elif defined(TARGET_RISCV64)
55
-
56
-static void rv64imacu_nommu_cpu_init(Object *obj)
57
-{
58
- CPURISCVState *env = &RISCV_CPU(obj)->env;
59
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
60
- set_priv_version(env, PRIV_VERSION_1_10_0);
61
- set_resetvec(env, DEFAULT_RSTVEC);
62
- qdev_prop_set_bit(DEVICE(obj), "mmu", false);
63
-}
64
-
65
#endif
66
67
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
68
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
69
#if defined(TARGET_RISCV32)
70
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
71
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
72
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
73
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
74
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
75
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
76
#elif defined(TARGET_RISCV64)
77
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
78
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
79
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
80
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
81
#endif
82
};
83
--
84
2.27.0
85
86
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Adding a _ to keep some consistency among the CPU init routines.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <1591837729-27486-4-git-send-email-bmeng.cn@gmail.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/cpu.c | 8 ++++----
11
1 file changed, 4 insertions(+), 4 deletions(-)
12
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
18
19
#if defined(TARGET_RISCV32)
20
21
-static void rv32imcu_nommu_cpu_init(Object *obj)
22
+static void rv32_imcu_nommu_cpu_init(Object *obj)
23
{
24
CPURISCVState *env = &RISCV_CPU(obj)->env;
25
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
26
@@ -XXX,XX +XXX,XX @@ static void rv32imcu_nommu_cpu_init(Object *obj)
27
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
28
}
29
30
-static void rv32imafcu_nommu_cpu_init(Object *obj)
31
+static void rv32_imafcu_nommu_cpu_init(Object *obj)
32
{
33
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
35
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
36
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
37
#if defined(TARGET_RISCV32)
38
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
39
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
40
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
41
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
42
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
43
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
44
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
45
#elif defined(TARGET_RISCV64)
46
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
47
--
48
2.27.0
49
50
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/riscv/cpu_helper.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
1
6
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
11
@@ -XXX,XX +XXX,XX @@ restart:
12
hwaddr vbase;
13
14
/* Do the second stage translation on the base PTE address. */
15
- get_physical_address(env, &vbase, &vbase_prot, base, access_type,
16
+ get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
17
mmu_idx, false, true);
18
19
pte_addr = vbase + idx * ptesize;
20
--
21
2.27.0
22
23
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
4
target/riscv/cpu_helper.c | 9 +++++++--
5
1 file changed, 7 insertions(+), 2 deletions(-)
1
6
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
11
@@ -XXX,XX +XXX,XX @@ restart:
12
hwaddr vbase;
13
14
/* Do the second stage translation on the base PTE address. */
15
- get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
16
- mmu_idx, false, true);
17
+ int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
18
+ base, MMU_DATA_LOAD,
19
+ mmu_idx, false, true);
20
+
21
+ if (vbase_ret != TRANSLATE_SUCCESS) {
22
+ return vbase_ret;
23
+ }
24
25
pte_addr = vbase + idx * ptesize;
26
} else {
27
--
28
2.27.0
29
30
diff view generated by jsdifflib
New patch
1
Also correct the name of the VVMA instruction.
1
2
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
---
6
target/riscv/insn32.decode | 8 ++-
7
.../riscv/insn_trans/trans_privileged.inc.c | 38 -------------
8
target/riscv/insn_trans/trans_rvh.inc.c | 57 +++++++++++++++++++
9
target/riscv/translate.c | 1 +
10
4 files changed, 63 insertions(+), 41 deletions(-)
11
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
12
13
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn32.decode
16
+++ b/target/riscv/insn32.decode
17
@@ -XXX,XX +XXX,XX @@
18
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
19
20
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
21
-@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1
22
+@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1
23
24
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
25
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
26
@@ -XXX,XX +XXX,XX @@ uret 0000000 00010 00000 000 00000 1110011
27
sret 0001000 00010 00000 000 00000 1110011
28
mret 0011000 00010 00000 000 00000 1110011
29
wfi 0001000 00101 00000 000 00000 1110011
30
-hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
31
-hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma
32
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
33
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
34
35
@@ -XXX,XX +XXX,XX @@ fcvt_w_d 1100001 00000 ..... ... ..... 1010011 @r2_rm
36
fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm
37
fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
38
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
39
+
40
+# *** RV32H Base Instruction Set ***
41
+hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
42
+hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
43
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/insn_trans/trans_privileged.inc.c
46
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
47
@@ -XXX,XX +XXX,XX @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
48
{
49
return false;
50
}
51
-
52
-static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
53
-{
54
-#ifndef CONFIG_USER_ONLY
55
- if (has_ext(ctx, RVH)) {
56
- /* Hpervisor extensions exist */
57
- /*
58
- * if (env->priv == PRV_M ||
59
- * (env->priv == PRV_S &&
60
- * !riscv_cpu_virt_enabled(env) &&
61
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
62
- */
63
- gen_helper_tlb_flush(cpu_env);
64
- return true;
65
- /* } */
66
- }
67
-#endif
68
- return false;
69
-}
70
-
71
-static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
72
-{
73
-#ifndef CONFIG_USER_ONLY
74
- if (has_ext(ctx, RVH)) {
75
- /* Hpervisor extensions exist */
76
- /*
77
- * if (env->priv == PRV_M ||
78
- * (env->priv == PRV_S &&
79
- * !riscv_cpu_virt_enabled(env) &&
80
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
81
- */
82
- gen_helper_tlb_flush(cpu_env);
83
- return true;
84
- /* } */
85
- }
86
-#endif
87
- return false;
88
-}
89
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
90
new file mode 100644
91
index XXXXXXX..XXXXXXX
92
--- /dev/null
93
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
94
@@ -XXX,XX +XXX,XX @@
95
+/*
96
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
97
+ *
98
+ * Copyright (c) 2020 Western Digital
99
+ *
100
+ * This program is free software; you can redistribute it and/or modify it
101
+ * under the terms and conditions of the GNU General Public License,
102
+ * version 2 or later, as published by the Free Software Foundation.
103
+ *
104
+ * This program is distributed in the hope it will be useful, but WITHOUT
105
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
106
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
107
+ * more details.
108
+ *
109
+ * You should have received a copy of the GNU General Public License along with
110
+ * this program. If not, see <http://www.gnu.org/licenses/>.
111
+ */
112
+
113
+static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
114
+{
115
+#ifndef CONFIG_USER_ONLY
116
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
117
+ has_ext(ctx, RVH)) {
118
+ /* Hpervisor extensions exist */
119
+ /*
120
+ * if (env->priv == PRV_M ||
121
+ * (env->priv == PRV_S &&
122
+ * !riscv_cpu_virt_enabled(env) &&
123
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
124
+ */
125
+ gen_helper_tlb_flush(cpu_env);
126
+ return true;
127
+ /* } */
128
+ }
129
+#endif
130
+ return false;
131
+}
132
+
133
+static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
134
+{
135
+#ifndef CONFIG_USER_ONLY
136
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
137
+ has_ext(ctx, RVH)) {
138
+ /* Hpervisor extensions exist */
139
+ /*
140
+ * if (env->priv == PRV_M ||
141
+ * (env->priv == PRV_S &&
142
+ * !riscv_cpu_virt_enabled(env) &&
143
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
144
+ */
145
+ gen_helper_tlb_flush(cpu_env);
146
+ return true;
147
+ /* } */
148
+ }
149
+#endif
150
+ return false;
151
+}
152
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/riscv/translate.c
155
+++ b/target/riscv/translate.c
156
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
157
#include "insn_trans/trans_rva.inc.c"
158
#include "insn_trans/trans_rvf.inc.c"
159
#include "insn_trans/trans_rvd.inc.c"
160
+#include "insn_trans/trans_rvh.inc.c"
161
#include "insn_trans/trans_privileged.inc.c"
162
163
/* Include the auto-generated decoder for 16 bit insn */
164
--
165
2.27.0
166
167
diff view generated by jsdifflib
New patch
1
Call the helper_hyp_tlb_flush() function on hfence instructions which
2
will generate an illegal insruction execption if we don't have
3
permission to flush the Hypervisor level TLBs.
1
4
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
target/riscv/helper.h | 5 ++++
9
target/riscv/insn_trans/trans_rvh.inc.c | 32 +++++--------------------
10
target/riscv/op_helper.c | 13 ++++++++++
11
3 files changed, 24 insertions(+), 26 deletions(-)
12
13
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/helper.h
16
+++ b/target/riscv/helper.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(mret, tl, env, tl)
18
DEF_HELPER_1(wfi, void, env)
19
DEF_HELPER_1(tlb_flush, void, env)
20
#endif
21
+
22
+/* Hypervisor functions */
23
+#ifndef CONFIG_USER_ONLY
24
+DEF_HELPER_1(hyp_tlb_flush, void, env)
25
+#endif
26
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/insn_trans/trans_rvh.inc.c
29
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
30
@@ -XXX,XX +XXX,XX @@
31
32
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
33
{
34
+ REQUIRE_EXT(ctx, RVH);
35
#ifndef CONFIG_USER_ONLY
36
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
37
- has_ext(ctx, RVH)) {
38
- /* Hpervisor extensions exist */
39
- /*
40
- * if (env->priv == PRV_M ||
41
- * (env->priv == PRV_S &&
42
- * !riscv_cpu_virt_enabled(env) &&
43
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
44
- */
45
- gen_helper_tlb_flush(cpu_env);
46
- return true;
47
- /* } */
48
- }
49
+ gen_helper_hyp_tlb_flush(cpu_env);
50
+ return true;
51
#endif
52
return false;
53
}
54
55
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
56
{
57
+ REQUIRE_EXT(ctx, RVH);
58
#ifndef CONFIG_USER_ONLY
59
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
60
- has_ext(ctx, RVH)) {
61
- /* Hpervisor extensions exist */
62
- /*
63
- * if (env->priv == PRV_M ||
64
- * (env->priv == PRV_S &&
65
- * !riscv_cpu_virt_enabled(env) &&
66
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
67
- */
68
- gen_helper_tlb_flush(cpu_env);
69
- return true;
70
- /* } */
71
- }
72
+ gen_helper_hyp_tlb_flush(cpu_env);
73
+ return true;
74
#endif
75
return false;
76
}
77
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/op_helper.c
80
+++ b/target/riscv/op_helper.c
81
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
82
}
83
}
84
85
+void helper_hyp_tlb_flush(CPURISCVState *env)
86
+{
87
+ CPUState *cs = env_cpu(env);
88
+
89
+ if (env->priv == PRV_M ||
90
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
91
+ tlb_flush(cs);
92
+ return;
93
+ }
94
+
95
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
96
+}
97
+
98
#endif /* !CONFIG_USER_ONLY */
99
--
100
2.27.0
101
102
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reported-by: Damien Hedde <damien.hedde@greensocs.com>
3
---
4
hw/riscv/opentitan.c | 3 ++-
5
1 file changed, 2 insertions(+), 1 deletion(-)
1
6
7
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/hw/riscv/opentitan.c
10
+++ b/hw/riscv/opentitan.c
11
@@ -XXX,XX +XXX,XX @@
12
#include "hw/misc/unimp.h"
13
#include "hw/riscv/boot.h"
14
#include "exec/address-spaces.h"
15
+#include "qemu/units.h"
16
17
static const struct MemmapEntry {
18
hwaddr base;
19
hwaddr size;
20
} ibex_memmap[] = {
21
- [IBEX_ROM] = { 0x00008000, 0xc000 },
22
+ [IBEX_ROM] = { 0x00008000, 16 * KiB },
23
[IBEX_RAM] = { 0x10000000, 0x10000 },
24
[IBEX_FLASH] = { 0x20000000, 0x80000 },
25
[IBEX_UART] = { 0x40000000, 0x10000 },
26
--
27
2.27.0
28
29
diff view generated by jsdifflib
New patch
1
This is the initial commit of the Ibex UART device. Serial TX is
2
working, while RX has been implemeneted but untested.
1
3
4
This is based on the documentation from:
5
https://docs.opentitan.org/hw/ip/uart/doc/
6
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: LIU Zhiwei<zhiwei_liu@c-sky.com>
9
---
10
include/hw/char/ibex_uart.h | 110 ++++++++
11
hw/char/ibex_uart.c | 492 ++++++++++++++++++++++++++++++++++++
12
MAINTAINERS | 2 +
13
hw/char/Makefile.objs | 1 +
14
hw/riscv/Kconfig | 4 +
15
5 files changed, 609 insertions(+)
16
create mode 100644 include/hw/char/ibex_uart.h
17
create mode 100644 hw/char/ibex_uart.c
18
19
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/hw/char/ibex_uart.h
24
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+ * QEMU lowRISC Ibex UART device
27
+ *
28
+ * Copyright (c) 2020 Western Digital
29
+ *
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * in the Software without restriction, including without limitation the rights
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * copies of the Software, and to permit persons to whom the Software is
35
+ * furnished to do so, subject to the following conditions:
36
+ *
37
+ * The above copyright notice and this permission notice shall be included in
38
+ * all copies or substantial portions of the Software.
39
+ *
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * THE SOFTWARE.
47
+ */
48
+
49
+#ifndef HW_IBEX_UART_H
50
+#define HW_IBEX_UART_H
51
+
52
+#include "hw/sysbus.h"
53
+#include "chardev/char-fe.h"
54
+#include "qemu/timer.h"
55
+
56
+#define IBEX_UART_INTR_STATE 0x00
57
+ #define INTR_STATE_TX_WATERMARK (1 << 0)
58
+ #define INTR_STATE_RX_WATERMARK (1 << 1)
59
+ #define INTR_STATE_TX_EMPTY (1 << 2)
60
+ #define INTR_STATE_RX_OVERFLOW (1 << 3)
61
+#define IBEX_UART_INTR_ENABLE 0x04
62
+#define IBEX_UART_INTR_TEST 0x08
63
+
64
+#define IBEX_UART_CTRL 0x0c
65
+ #define UART_CTRL_TX_ENABLE (1 << 0)
66
+ #define UART_CTRL_RX_ENABLE (1 << 1)
67
+ #define UART_CTRL_NF (1 << 2)
68
+ #define UART_CTRL_SLPBK (1 << 4)
69
+ #define UART_CTRL_LLPBK (1 << 5)
70
+ #define UART_CTRL_PARITY_EN (1 << 6)
71
+ #define UART_CTRL_PARITY_ODD (1 << 7)
72
+ #define UART_CTRL_RXBLVL (3 << 8)
73
+ #define UART_CTRL_NCO (0xFFFF << 16)
74
+
75
+#define IBEX_UART_STATUS 0x10
76
+ #define UART_STATUS_TXFULL (1 << 0)
77
+ #define UART_STATUS_RXFULL (1 << 1)
78
+ #define UART_STATUS_TXEMPTY (1 << 2)
79
+ #define UART_STATUS_RXIDLE (1 << 4)
80
+ #define UART_STATUS_RXEMPTY (1 << 5)
81
+
82
+#define IBEX_UART_RDATA 0x14
83
+#define IBEX_UART_WDATA 0x18
84
+
85
+#define IBEX_UART_FIFO_CTRL 0x1c
86
+ #define FIFO_CTRL_RXRST (1 << 0)
87
+ #define FIFO_CTRL_TXRST (1 << 1)
88
+ #define FIFO_CTRL_RXILVL (7 << 2)
89
+ #define FIFO_CTRL_RXILVL_SHIFT (2)
90
+ #define FIFO_CTRL_TXILVL (3 << 5)
91
+ #define FIFO_CTRL_TXILVL_SHIFT (5)
92
+
93
+#define IBEX_UART_FIFO_STATUS 0x20
94
+#define IBEX_UART_OVRD 0x24
95
+#define IBEX_UART_VAL 0x28
96
+#define IBEX_UART_TIMEOUT_CTRL 0x2c
97
+
98
+#define IBEX_UART_TX_FIFO_SIZE 16
99
+
100
+#define TYPE_IBEX_UART "ibex-uart"
101
+#define IBEX_UART(obj) \
102
+ OBJECT_CHECK(IbexUartState, (obj), TYPE_IBEX_UART)
103
+
104
+typedef struct {
105
+ /* <private> */
106
+ SysBusDevice parent_obj;
107
+
108
+ /* <public> */
109
+ MemoryRegion mmio;
110
+
111
+ uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
112
+ uint32_t tx_level;
113
+
114
+ QEMUTimer *fifo_trigger_handle;
115
+ uint64_t char_tx_time;
116
+
117
+ uint32_t uart_intr_state;
118
+ uint32_t uart_intr_enable;
119
+ uint32_t uart_ctrl;
120
+ uint32_t uart_status;
121
+ uint32_t uart_rdata;
122
+ uint32_t uart_fifo_ctrl;
123
+ uint32_t uart_fifo_status;
124
+ uint32_t uart_ovrd;
125
+ uint32_t uart_val;
126
+ uint32_t uart_timeout_ctrl;
127
+
128
+ CharBackend chr;
129
+ qemu_irq tx_watermark;
130
+ qemu_irq rx_watermark;
131
+ qemu_irq tx_empty;
132
+ qemu_irq rx_overflow;
133
+} IbexUartState;
134
+#endif /* HW_IBEX_UART_H */
135
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
136
new file mode 100644
137
index XXXXXXX..XXXXXXX
138
--- /dev/null
139
+++ b/hw/char/ibex_uart.c
140
@@ -XXX,XX +XXX,XX @@
141
+/*
142
+ * QEMU lowRISC Ibex UART device
143
+ *
144
+ * Copyright (c) 2020 Western Digital
145
+ *
146
+ * For details check the documentation here:
147
+ * https://docs.opentitan.org/hw/ip/uart/doc/
148
+ *
149
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
150
+ * of this software and associated documentation files (the "Software"), to deal
151
+ * in the Software without restriction, including without limitation the rights
152
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
153
+ * copies of the Software, and to permit persons to whom the Software is
154
+ * furnished to do so, subject to the following conditions:
155
+ *
156
+ * The above copyright notice and this permission notice shall be included in
157
+ * all copies or substantial portions of the Software.
158
+ *
159
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
160
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
162
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
163
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
164
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
165
+ * THE SOFTWARE.
166
+ */
167
+
168
+#include "qemu/osdep.h"
169
+#include "hw/char/ibex_uart.h"
170
+#include "hw/irq.h"
171
+#include "hw/qdev-properties.h"
172
+#include "migration/vmstate.h"
173
+#include "qemu/log.h"
174
+#include "qemu/module.h"
175
+
176
+static void ibex_uart_update_irqs(IbexUartState *s)
177
+{
178
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) {
179
+ qemu_set_irq(s->tx_watermark, 1);
180
+ } else {
181
+ qemu_set_irq(s->tx_watermark, 0);
182
+ }
183
+
184
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) {
185
+ qemu_set_irq(s->rx_watermark, 1);
186
+ } else {
187
+ qemu_set_irq(s->rx_watermark, 0);
188
+ }
189
+
190
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
191
+ qemu_set_irq(s->tx_empty, 1);
192
+ } else {
193
+ qemu_set_irq(s->tx_empty, 0);
194
+ }
195
+
196
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) {
197
+ qemu_set_irq(s->rx_overflow, 1);
198
+ } else {
199
+ qemu_set_irq(s->rx_overflow, 0);
200
+ }
201
+}
202
+
203
+static int ibex_uart_can_receive(void *opaque)
204
+{
205
+ IbexUartState *s = opaque;
206
+
207
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
208
+ return 1;
209
+ }
210
+
211
+ return 0;
212
+}
213
+
214
+static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
215
+{
216
+ IbexUartState *s = opaque;
217
+ uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL)
218
+ >> FIFO_CTRL_RXILVL_SHIFT;
219
+
220
+ s->uart_rdata = *buf;
221
+
222
+ s->uart_status &= ~UART_STATUS_RXIDLE;
223
+ s->uart_status &= ~UART_STATUS_RXEMPTY;
224
+
225
+ if (size > rx_fifo_level) {
226
+ s->uart_intr_state |= INTR_STATE_RX_WATERMARK;
227
+ }
228
+
229
+ ibex_uart_update_irqs(s);
230
+}
231
+
232
+static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
233
+ void *opaque)
234
+{
235
+ IbexUartState *s = opaque;
236
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
237
+ >> FIFO_CTRL_TXILVL_SHIFT;
238
+ int ret;
239
+
240
+ /* instant drain the fifo when there's no back-end */
241
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
242
+ s->tx_level = 0;
243
+ return FALSE;
244
+ }
245
+
246
+ if (!s->tx_level) {
247
+ s->uart_status &= ~UART_STATUS_TXFULL;
248
+ s->uart_status |= UART_STATUS_TXEMPTY;
249
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
250
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
251
+ ibex_uart_update_irqs(s);
252
+ return FALSE;
253
+ }
254
+
255
+ ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
256
+
257
+ if (ret >= 0) {
258
+ s->tx_level -= ret;
259
+ memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
260
+ }
261
+
262
+ if (s->tx_level) {
263
+ guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
264
+ ibex_uart_xmit, s);
265
+ if (!r) {
266
+ s->tx_level = 0;
267
+ return FALSE;
268
+ }
269
+ }
270
+
271
+ /* Clear the TX Full bit */
272
+ if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
273
+ s->uart_status &= ~UART_STATUS_TXFULL;
274
+ }
275
+
276
+ /* Disable the TX_WATERMARK IRQ */
277
+ if (s->tx_level < tx_fifo_level) {
278
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
279
+ }
280
+
281
+ /* Set TX empty */
282
+ if (s->tx_level == 0) {
283
+ s->uart_status |= UART_STATUS_TXEMPTY;
284
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
285
+ }
286
+
287
+ ibex_uart_update_irqs(s);
288
+ return FALSE;
289
+}
290
+
291
+static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
292
+ int size)
293
+{
294
+ uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
295
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
296
+ >> FIFO_CTRL_TXILVL_SHIFT;
297
+
298
+ if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
299
+ size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
300
+ qemu_log_mask(LOG_GUEST_ERROR, "ibex_uart: TX FIFO overflow");
301
+ }
302
+
303
+ memcpy(s->tx_fifo + s->tx_level, buf, size);
304
+ s->tx_level += size;
305
+
306
+ if (s->tx_level > 0) {
307
+ s->uart_status &= ~UART_STATUS_TXEMPTY;
308
+ }
309
+
310
+ if (s->tx_level >= tx_fifo_level) {
311
+ s->uart_intr_state |= INTR_STATE_TX_WATERMARK;
312
+ ibex_uart_update_irqs(s);
313
+ }
314
+
315
+ if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
316
+ s->uart_status |= UART_STATUS_TXFULL;
317
+ }
318
+
319
+ timer_mod(s->fifo_trigger_handle, current_time +
320
+ (s->char_tx_time * 4));
321
+}
322
+
323
+static void ibex_uart_reset(DeviceState *dev)
324
+{
325
+ IbexUartState *s = IBEX_UART(dev);
326
+
327
+ s->uart_intr_state = 0x00000000;
328
+ s->uart_intr_state = 0x00000000;
329
+ s->uart_intr_enable = 0x00000000;
330
+ s->uart_ctrl = 0x00000000;
331
+ s->uart_status = 0x0000003c;
332
+ s->uart_rdata = 0x00000000;
333
+ s->uart_fifo_ctrl = 0x00000000;
334
+ s->uart_fifo_status = 0x00000000;
335
+ s->uart_ovrd = 0x00000000;
336
+ s->uart_val = 0x00000000;
337
+ s->uart_timeout_ctrl = 0x00000000;
338
+
339
+ s->tx_level = 0;
340
+
341
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
342
+
343
+ ibex_uart_update_irqs(s);
344
+}
345
+
346
+static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
347
+ unsigned int size)
348
+{
349
+ IbexUartState *s = opaque;
350
+ uint64_t retvalue = 0;
351
+
352
+ switch (addr) {
353
+ case IBEX_UART_INTR_STATE:
354
+ retvalue = s->uart_intr_state;
355
+ break;
356
+ case IBEX_UART_INTR_ENABLE:
357
+ retvalue = s->uart_intr_enable;
358
+ break;
359
+ case IBEX_UART_INTR_TEST:
360
+ qemu_log_mask(LOG_GUEST_ERROR,
361
+ "%s: wdata is write only\n", __func__);
362
+ break;
363
+
364
+ case IBEX_UART_CTRL:
365
+ retvalue = s->uart_ctrl;
366
+ break;
367
+ case IBEX_UART_STATUS:
368
+ retvalue = s->uart_status;
369
+ break;
370
+
371
+ case IBEX_UART_RDATA:
372
+ retvalue = s->uart_rdata;
373
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
374
+ qemu_chr_fe_accept_input(&s->chr);
375
+
376
+ s->uart_status |= UART_STATUS_RXIDLE;
377
+ s->uart_status |= UART_STATUS_RXEMPTY;
378
+ }
379
+ break;
380
+ case IBEX_UART_WDATA:
381
+ qemu_log_mask(LOG_GUEST_ERROR,
382
+ "%s: wdata is write only\n", __func__);
383
+ break;
384
+
385
+ case IBEX_UART_FIFO_CTRL:
386
+ retvalue = s->uart_fifo_ctrl;
387
+ break;
388
+ case IBEX_UART_FIFO_STATUS:
389
+ retvalue = s->uart_fifo_status;
390
+
391
+ retvalue |= s->tx_level & 0x1F;
392
+
393
+ qemu_log_mask(LOG_UNIMP,
394
+ "%s: RX fifos are not supported\n", __func__);
395
+ break;
396
+
397
+ case IBEX_UART_OVRD:
398
+ retvalue = s->uart_ovrd;
399
+ qemu_log_mask(LOG_UNIMP,
400
+ "%s: ovrd is not supported\n", __func__);
401
+ break;
402
+ case IBEX_UART_VAL:
403
+ retvalue = s->uart_val;
404
+ qemu_log_mask(LOG_UNIMP,
405
+ "%s: val is not supported\n", __func__);
406
+ break;
407
+ case IBEX_UART_TIMEOUT_CTRL:
408
+ retvalue = s->uart_timeout_ctrl;
409
+ qemu_log_mask(LOG_UNIMP,
410
+ "%s: timeout_ctrl is not supported\n", __func__);
411
+ break;
412
+ default:
413
+ qemu_log_mask(LOG_GUEST_ERROR,
414
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
415
+ return 0;
416
+ }
417
+
418
+ return retvalue;
419
+}
420
+
421
+static void ibex_uart_write(void *opaque, hwaddr addr,
422
+ uint64_t val64, unsigned int size)
423
+{
424
+ IbexUartState *s = opaque;
425
+ uint32_t value = val64;
426
+
427
+ switch (addr) {
428
+ case IBEX_UART_INTR_STATE:
429
+ /* Write 1 clear */
430
+ s->uart_intr_state &= ~value;
431
+ ibex_uart_update_irqs(s);
432
+ break;
433
+ case IBEX_UART_INTR_ENABLE:
434
+ s->uart_intr_enable = value;
435
+ ibex_uart_update_irqs(s);
436
+ break;
437
+ case IBEX_UART_INTR_TEST:
438
+ s->uart_intr_state |= value;
439
+ ibex_uart_update_irqs(s);
440
+ break;
441
+
442
+ case IBEX_UART_CTRL:
443
+ s->uart_ctrl = value;
444
+
445
+ if (value & UART_CTRL_NF) {
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: UART_CTRL_NF is not supported\n", __func__);
448
+ }
449
+ if (value & UART_CTRL_SLPBK) {
450
+ qemu_log_mask(LOG_UNIMP,
451
+ "%s: UART_CTRL_SLPBK is not supported\n", __func__);
452
+ }
453
+ if (value & UART_CTRL_LLPBK) {
454
+ qemu_log_mask(LOG_UNIMP,
455
+ "%s: UART_CTRL_LLPBK is not supported\n", __func__);
456
+ }
457
+ if (value & UART_CTRL_PARITY_EN) {
458
+ qemu_log_mask(LOG_UNIMP,
459
+ "%s: UART_CTRL_PARITY_EN is not supported\n",
460
+ __func__);
461
+ }
462
+ if (value & UART_CTRL_PARITY_ODD) {
463
+ qemu_log_mask(LOG_UNIMP,
464
+ "%s: UART_CTRL_PARITY_ODD is not supported\n",
465
+ __func__);
466
+ }
467
+ if (value & UART_CTRL_RXBLVL) {
468
+ qemu_log_mask(LOG_UNIMP,
469
+ "%s: UART_CTRL_RXBLVL is not supported\n", __func__);
470
+ }
471
+ if (value & UART_CTRL_NCO) {
472
+ uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
473
+ baud *= 1000;
474
+ baud /= 2 ^ 20;
475
+
476
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
477
+ }
478
+ break;
479
+ case IBEX_UART_STATUS:
480
+ qemu_log_mask(LOG_GUEST_ERROR,
481
+ "%s: status is read only\n", __func__);
482
+ break;
483
+
484
+ case IBEX_UART_RDATA:
485
+ qemu_log_mask(LOG_GUEST_ERROR,
486
+ "%s: rdata is read only\n", __func__);
487
+ break;
488
+ case IBEX_UART_WDATA:
489
+ uart_write_tx_fifo(s, (uint8_t *) &value, 1);
490
+ break;
491
+
492
+ case IBEX_UART_FIFO_CTRL:
493
+ s->uart_fifo_ctrl = value;
494
+
495
+ if (value & FIFO_CTRL_RXRST) {
496
+ qemu_log_mask(LOG_UNIMP,
497
+ "%s: RX fifos are not supported\n", __func__);
498
+ }
499
+ if (value & FIFO_CTRL_TXRST) {
500
+ s->tx_level = 0;
501
+ }
502
+ break;
503
+ case IBEX_UART_FIFO_STATUS:
504
+ qemu_log_mask(LOG_GUEST_ERROR,
505
+ "%s: fifo_status is read only\n", __func__);
506
+ break;
507
+
508
+ case IBEX_UART_OVRD:
509
+ s->uart_ovrd = value;
510
+ qemu_log_mask(LOG_UNIMP,
511
+ "%s: ovrd is not supported\n", __func__);
512
+ break;
513
+ case IBEX_UART_VAL:
514
+ qemu_log_mask(LOG_GUEST_ERROR,
515
+ "%s: val is read only\n", __func__);
516
+ break;
517
+ case IBEX_UART_TIMEOUT_CTRL:
518
+ s->uart_timeout_ctrl = value;
519
+ qemu_log_mask(LOG_UNIMP,
520
+ "%s: timeout_ctrl is not supported\n", __func__);
521
+ break;
522
+ default:
523
+ qemu_log_mask(LOG_GUEST_ERROR,
524
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
525
+ }
526
+}
527
+
528
+static void fifo_trigger_update(void *opaque)
529
+{
530
+ IbexUartState *s = opaque;
531
+
532
+ if (s->uart_ctrl & UART_CTRL_TX_ENABLE) {
533
+ ibex_uart_xmit(NULL, G_IO_OUT, s);
534
+ }
535
+}
536
+
537
+static const MemoryRegionOps ibex_uart_ops = {
538
+ .read = ibex_uart_read,
539
+ .write = ibex_uart_write,
540
+ .endianness = DEVICE_NATIVE_ENDIAN,
541
+ .impl.min_access_size = 4,
542
+ .impl.max_access_size = 4,
543
+};
544
+
545
+static int ibex_uart_post_load(void *opaque, int version_id)
546
+{
547
+ IbexUartState *s = opaque;
548
+
549
+ ibex_uart_update_irqs(s);
550
+ return 0;
551
+}
552
+
553
+static const VMStateDescription vmstate_ibex_uart = {
554
+ .name = TYPE_IBEX_UART,
555
+ .version_id = 1,
556
+ .minimum_version_id = 1,
557
+ .post_load = ibex_uart_post_load,
558
+ .fields = (VMStateField[]) {
559
+ VMSTATE_UINT8_ARRAY(tx_fifo, IbexUartState,
560
+ IBEX_UART_TX_FIFO_SIZE),
561
+ VMSTATE_UINT32(tx_level, IbexUartState),
562
+ VMSTATE_UINT64(char_tx_time, IbexUartState),
563
+ VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexUartState),
564
+ VMSTATE_UINT32(uart_intr_state, IbexUartState),
565
+ VMSTATE_UINT32(uart_intr_enable, IbexUartState),
566
+ VMSTATE_UINT32(uart_ctrl, IbexUartState),
567
+ VMSTATE_UINT32(uart_status, IbexUartState),
568
+ VMSTATE_UINT32(uart_rdata, IbexUartState),
569
+ VMSTATE_UINT32(uart_fifo_ctrl, IbexUartState),
570
+ VMSTATE_UINT32(uart_fifo_status, IbexUartState),
571
+ VMSTATE_UINT32(uart_ovrd, IbexUartState),
572
+ VMSTATE_UINT32(uart_val, IbexUartState),
573
+ VMSTATE_UINT32(uart_timeout_ctrl, IbexUartState),
574
+ VMSTATE_END_OF_LIST()
575
+ }
576
+};
577
+
578
+static Property ibex_uart_properties[] = {
579
+ DEFINE_PROP_CHR("chardev", IbexUartState, chr),
580
+ DEFINE_PROP_END_OF_LIST(),
581
+};
582
+
583
+static void ibex_uart_init(Object *obj)
584
+{
585
+ IbexUartState *s = IBEX_UART(obj);
586
+
587
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
588
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
589
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
590
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_overflow);
591
+
592
+ memory_region_init_io(&s->mmio, obj, &ibex_uart_ops, s,
593
+ TYPE_IBEX_UART, 0x400);
594
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
595
+}
596
+
597
+static void ibex_uart_realize(DeviceState *dev, Error **errp)
598
+{
599
+ IbexUartState *s = IBEX_UART(dev);
600
+
601
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
602
+ fifo_trigger_update, s);
603
+
604
+ qemu_chr_fe_set_handlers(&s->chr, ibex_uart_can_receive,
605
+ ibex_uart_receive, NULL, NULL,
606
+ s, NULL, true);
607
+}
608
+
609
+static void ibex_uart_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+
613
+ dc->reset = ibex_uart_reset;
614
+ dc->realize = ibex_uart_realize;
615
+ dc->vmsd = &vmstate_ibex_uart;
616
+ device_class_set_props(dc, ibex_uart_properties);
617
+}
618
+
619
+static const TypeInfo ibex_uart_info = {
620
+ .name = TYPE_IBEX_UART,
621
+ .parent = TYPE_SYS_BUS_DEVICE,
622
+ .instance_size = sizeof(IbexUartState),
623
+ .instance_init = ibex_uart_init,
624
+ .class_init = ibex_uart_class_init,
625
+};
626
+
627
+static void ibex_uart_register_types(void)
628
+{
629
+ type_register_static(&ibex_uart_info);
630
+}
631
+
632
+type_init(ibex_uart_register_types)
633
diff --git a/MAINTAINERS b/MAINTAINERS
634
index XXXXXXX..XXXXXXX 100644
635
--- a/MAINTAINERS
636
+++ b/MAINTAINERS
637
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <Alistair.Francis@wdc.com>
638
L: qemu-riscv@nongnu.org
639
S: Supported
640
F: hw/riscv/opentitan.c
641
+F: hw/char/ibex_uart.c
642
F: include/hw/riscv/opentitan.h
643
+F: include/hw/char/ibex_uart.h
644
645
SH4 Machines
646
------------
647
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
648
index XXXXXXX..XXXXXXX 100644
649
--- a/hw/char/Makefile.objs
650
+++ b/hw/char/Makefile.objs
651
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
652
common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
653
common-obj-$(CONFIG_XEN) += xen_console.o
654
common-obj-$(CONFIG_CADENCE) += cadence_uart.o
655
+common-obj-$(CONFIG_IBEX) += ibex_uart.o
656
657
common-obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
658
common-obj-$(CONFIG_COLDFIRE) += mcf_uart.o
659
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
660
index XXXXXXX..XXXXXXX 100644
661
--- a/hw/riscv/Kconfig
662
+++ b/hw/riscv/Kconfig
663
@@ -XXX,XX +XXX,XX @@ config HTIF
664
config HART
665
bool
666
667
+config IBEX
668
+ bool
669
+
670
config SIFIVE
671
bool
672
select MSI_NONBROKEN
673
@@ -XXX,XX +XXX,XX @@ config SPIKE
674
675
config OPENTITAN
676
bool
677
+ select IBEX
678
select HART
679
select UNIMP
680
681
--
682
2.27.0
683
684
diff view generated by jsdifflib
New patch
1
1
The Ibex core contains a PLIC that although similar to the RISC-V spec
2
is not RISC-V spec compliant.
3
4
This patch implements a Ibex PLIC in a somewhat generic way.
5
6
As the current RISC-V PLIC needs tidying up, my hope is that as the Ibex
7
PLIC move towards spec compliance this PLIC implementation can be
8
updated until it can replace the current PLIC.
9
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
13
include/hw/intc/ibex_plic.h | 63 +++++++++
14
hw/intc/ibex_plic.c | 261 ++++++++++++++++++++++++++++++++++++
15
MAINTAINERS | 2 +
16
hw/intc/Makefile.objs | 1 +
17
4 files changed, 327 insertions(+)
18
create mode 100644 include/hw/intc/ibex_plic.h
19
create mode 100644 hw/intc/ibex_plic.c
20
21
diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
22
new file mode 100644
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/include/hw/intc/ibex_plic.h
26
@@ -XXX,XX +XXX,XX @@
27
+/*
28
+ * QEMU RISC-V lowRISC Ibex PLIC
29
+ *
30
+ * Copyright (c) 2020 Western Digital
31
+ *
32
+ * This program is free software; you can redistribute it and/or modify it
33
+ * under the terms and conditions of the GNU General Public License,
34
+ * version 2 or later, as published by the Free Software Foundation.
35
+ *
36
+ * This program is distributed in the hope it will be useful, but WITHOUT
37
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
39
+ * more details.
40
+ *
41
+ * You should have received a copy of the GNU General Public License along with
42
+ * this program. If not, see <http://www.gnu.org/licenses/>.
43
+ */
44
+
45
+#ifndef HW_IBEX_PLIC_H
46
+#define HW_IBEX_PLIC_H
47
+
48
+#include "hw/sysbus.h"
49
+
50
+#define TYPE_IBEX_PLIC "ibex-plic"
51
+#define IBEX_PLIC(obj) \
52
+ OBJECT_CHECK(IbexPlicState, (obj), TYPE_IBEX_PLIC)
53
+
54
+typedef struct IbexPlicState {
55
+ /*< private >*/
56
+ SysBusDevice parent_obj;
57
+
58
+ /*< public >*/
59
+ MemoryRegion mmio;
60
+
61
+ uint32_t *pending;
62
+ uint32_t *source;
63
+ uint32_t *priority;
64
+ uint32_t *enable;
65
+ uint32_t threshold;
66
+ uint32_t claim;
67
+
68
+ /* config */
69
+ uint32_t num_cpus;
70
+ uint32_t num_sources;
71
+
72
+ uint32_t pending_base;
73
+ uint32_t pending_num;
74
+
75
+ uint32_t source_base;
76
+ uint32_t source_num;
77
+
78
+ uint32_t priority_base;
79
+ uint32_t priority_num;
80
+
81
+ uint32_t enable_base;
82
+ uint32_t enable_num;
83
+
84
+ uint32_t threshold_base;
85
+
86
+ uint32_t claim_base;
87
+} IbexPlicState;
88
+
89
+#endif /* HW_IBEX_PLIC_H */
90
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/hw/intc/ibex_plic.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * QEMU RISC-V lowRISC Ibex PLIC
98
+ *
99
+ * Copyright (c) 2020 Western Digital
100
+ *
101
+ * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
102
+ *
103
+ * This program is free software; you can redistribute it and/or modify it
104
+ * under the terms and conditions of the GNU General Public License,
105
+ * version 2 or later, as published by the Free Software Foundation.
106
+ *
107
+ * This program is distributed in the hope it will be useful, but WITHOUT
108
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
109
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
110
+ * more details.
111
+ *
112
+ * You should have received a copy of the GNU General Public License along with
113
+ * this program. If not, see <http://www.gnu.org/licenses/>.
114
+ */
115
+
116
+#include "qemu/osdep.h"
117
+#include "qemu/log.h"
118
+#include "hw/qdev-properties.h"
119
+#include "hw/core/cpu.h"
120
+#include "hw/boards.h"
121
+#include "hw/pci/msi.h"
122
+#include "target/riscv/cpu_bits.h"
123
+#include "target/riscv/cpu.h"
124
+#include "hw/intc/ibex_plic.h"
125
+
126
+static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
127
+{
128
+ uint32_t end = base + (num * 0x04);
129
+
130
+ if (addr >= base && addr < end) {
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+}
136
+
137
+static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
138
+{
139
+ int pending_num = irq / 32;
140
+
141
+ s->pending[pending_num] |= level << (irq % 32);
142
+}
143
+
144
+static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
145
+{
146
+ int i;
147
+
148
+ for (i = 0; i < s->pending_num; i++) {
149
+ uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
150
+
151
+ if (!(s->pending[i] & s->enable[i])) {
152
+ /* No pending and enabled IRQ */
153
+ continue;
154
+ }
155
+
156
+ if (s->priority[irq_num] > s->threshold) {
157
+ if (!s->claim) {
158
+ s->claim = irq_num;
159
+ }
160
+ return true;
161
+ }
162
+ }
163
+
164
+ return false;
165
+}
166
+
167
+static void ibex_plic_update(IbexPlicState *s)
168
+{
169
+ CPUState *cpu;
170
+ int level, i;
171
+
172
+ for (i = 0; i < s->num_cpus; i++) {
173
+ cpu = qemu_get_cpu(i);
174
+
175
+ if (!cpu) {
176
+ continue;
177
+ }
178
+
179
+ level = ibex_plic_irqs_pending(s, 0);
180
+
181
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
182
+ }
183
+}
184
+
185
+static void ibex_plic_reset(DeviceState *dev)
186
+{
187
+ IbexPlicState *s = IBEX_PLIC(dev);
188
+
189
+ s->threshold = 0x00000000;
190
+ s->claim = 0x00000000;
191
+}
192
+
193
+static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
194
+ unsigned int size)
195
+{
196
+ IbexPlicState *s = opaque;
197
+ int offset;
198
+ uint32_t ret = 0;
199
+
200
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
201
+ offset = (addr - s->pending_base) / 4;
202
+ ret = s->pending[offset];
203
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "%s: Interrupt source mode not supported\n", __func__);
206
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
207
+ offset = (addr - s->priority_base) / 4;
208
+ ret = s->priority[offset];
209
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
210
+ offset = (addr - s->enable_base) / 4;
211
+ ret = s->enable[offset];
212
+ } else if (addr_between(addr, s->threshold_base, 1)) {
213
+ ret = s->threshold;
214
+ } else if (addr_between(addr, s->claim_base, 1)) {
215
+ int pending_num = s->claim / 32;
216
+ s->pending[pending_num] &= ~(1 << (s->claim % 32));
217
+
218
+ ret = s->claim;
219
+ }
220
+
221
+ return ret;
222
+}
223
+
224
+static void ibex_plic_write(void *opaque, hwaddr addr,
225
+ uint64_t value, unsigned int size)
226
+{
227
+ IbexPlicState *s = opaque;
228
+
229
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
230
+ qemu_log_mask(LOG_GUEST_ERROR,
231
+ "%s: Pending registers are read only\n", __func__);
232
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
233
+ qemu_log_mask(LOG_UNIMP,
234
+ "%s: Interrupt source mode not supported\n", __func__);
235
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
236
+ uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
237
+ s->priority[irq] = value & 7;
238
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
239
+ uint32_t enable_reg = (addr - s->enable_base) / 4;
240
+
241
+ s->enable[enable_reg] = value;
242
+ } else if (addr_between(addr, s->threshold_base, 1)) {
243
+ s->threshold = value & 3;
244
+ } else if (addr_between(addr, s->claim_base, 1)) {
245
+ if (s->claim == value) {
246
+ /* Interrupt was completed */
247
+ s->claim = 0;
248
+ }
249
+ }
250
+
251
+ ibex_plic_update(s);
252
+}
253
+
254
+static const MemoryRegionOps ibex_plic_ops = {
255
+ .read = ibex_plic_read,
256
+ .write = ibex_plic_write,
257
+ .endianness = DEVICE_NATIVE_ENDIAN,
258
+ .valid = {
259
+ .min_access_size = 4,
260
+ .max_access_size = 4
261
+ }
262
+};
263
+
264
+static void ibex_plic_irq_request(void *opaque, int irq, int level)
265
+{
266
+ IbexPlicState *s = opaque;
267
+
268
+ ibex_plic_irqs_set_pending(s, irq, level > 0);
269
+ ibex_plic_update(s);
270
+}
271
+
272
+static Property ibex_plic_properties[] = {
273
+ DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
274
+ DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 80),
275
+
276
+ DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
277
+ DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 3),
278
+
279
+ DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x0c),
280
+ DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 3),
281
+
282
+ DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x18),
283
+ DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 80),
284
+
285
+ DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x200),
286
+ DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 3),
287
+
288
+ DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x20c),
289
+
290
+ DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x210),
291
+ DEFINE_PROP_END_OF_LIST(),
292
+};
293
+
294
+static void ibex_plic_init(Object *obj)
295
+{
296
+ IbexPlicState *s = IBEX_PLIC(obj);
297
+
298
+ memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
299
+ TYPE_IBEX_PLIC, 0x400);
300
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
301
+}
302
+
303
+static void ibex_plic_realize(DeviceState *dev, Error **errp)
304
+{
305
+ IbexPlicState *s = IBEX_PLIC(dev);
306
+ int i;
307
+
308
+ s->pending = g_new0(uint32_t, s->pending_num);
309
+ s->source = g_new0(uint32_t, s->source_num);
310
+ s->priority = g_new0(uint32_t, s->priority_num);
311
+ s->enable = g_new0(uint32_t, s->enable_num);
312
+
313
+ qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
314
+
315
+ /*
316
+ * We can't allow the supervisor to control SEIP as this would allow the
317
+ * supervisor to clear a pending external interrupt which will result in
318
+ * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
319
+ * hardware controlled when a PLIC is attached.
320
+ */
321
+ MachineState *ms = MACHINE(qdev_get_machine());
322
+ unsigned int smp_cpus = ms->smp.cpus;
323
+ for (i = 0; i < smp_cpus; i++) {
324
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
325
+ if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
326
+ error_report("SEIP already claimed");
327
+ exit(1);
328
+ }
329
+ }
330
+
331
+ msi_nonbroken = true;
332
+}
333
+
334
+static void ibex_plic_class_init(ObjectClass *klass, void *data)
335
+{
336
+ DeviceClass *dc = DEVICE_CLASS(klass);
337
+
338
+ dc->reset = ibex_plic_reset;
339
+ device_class_set_props(dc, ibex_plic_properties);
340
+ dc->realize = ibex_plic_realize;
341
+}
342
+
343
+static const TypeInfo ibex_plic_info = {
344
+ .name = TYPE_IBEX_PLIC,
345
+ .parent = TYPE_SYS_BUS_DEVICE,
346
+ .instance_size = sizeof(IbexPlicState),
347
+ .instance_init = ibex_plic_init,
348
+ .class_init = ibex_plic_class_init,
349
+};
350
+
351
+static void ibex_plic_register_types(void)
352
+{
353
+ type_register_static(&ibex_plic_info);
354
+}
355
+
356
+type_init(ibex_plic_register_types)
357
diff --git a/MAINTAINERS b/MAINTAINERS
358
index XXXXXXX..XXXXXXX 100644
359
--- a/MAINTAINERS
360
+++ b/MAINTAINERS
361
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
362
S: Supported
363
F: hw/riscv/opentitan.c
364
F: hw/char/ibex_uart.c
365
+F: hw/intc/ibex_plic.c
366
F: include/hw/riscv/opentitan.h
367
F: include/hw/char/ibex_uart.h
368
+F: include/hw/intc/ibex_plic.h
369
370
SH4 Machines
371
------------
372
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
373
index XXXXXXX..XXXXXXX 100644
374
--- a/hw/intc/Makefile.objs
375
+++ b/hw/intc/Makefile.objs
376
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
377
obj-$(CONFIG_MIPS_CPS) += mips_gic.o
378
obj-$(CONFIG_NIOS2) += nios2_iic.o
379
obj-$(CONFIG_OMPIC) += ompic.o
380
+obj-$(CONFIG_IBEX) += ibex_plic.o
381
--
382
2.27.0
383
384
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
5
include/hw/riscv/opentitan.h | 3 +++
6
hw/riscv/opentitan.c | 14 ++++++++++++--
7
2 files changed, 15 insertions(+), 2 deletions(-)
1
8
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
12
+++ b/include/hw/riscv/opentitan.h
13
@@ -XXX,XX +XXX,XX @@
14
#define HW_OPENTITAN_H
15
16
#include "hw/riscv/riscv_hart.h"
17
+#include "hw/intc/ibex_plic.h"
18
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
20
#define RISCV_IBEX_SOC(obj) \
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
22
23
/*< public >*/
24
RISCVHartArrayState cpus;
25
+ IbexPlicState plic;
26
+
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
} LowRISCIbexSoCState;
30
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/opentitan.c
33
+++ b/hw/riscv/opentitan.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "hw/riscv/boot.h"
36
#include "exec/address-spaces.h"
37
#include "qemu/units.h"
38
+#include "sysemu/sysemu.h"
39
40
static const struct MemmapEntry {
41
hwaddr base;
42
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
43
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
44
45
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
46
+
47
+ object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
48
}
49
50
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
51
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
52
MachineState *ms = MACHINE(qdev_get_machine());
53
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
54
MemoryRegion *sys_mem = get_system_memory();
55
+ Error *err = NULL;
56
57
object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
58
&error_abort);
59
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
60
memory_region_add_subregion(sys_mem, memmap[IBEX_FLASH].base,
61
&s->flash_mem);
62
63
+ /* PLIC */
64
+ sysbus_realize(SYS_BUS_DEVICE(&s->plic), &err);
65
+ if (err != NULL) {
66
+ error_propagate(errp, err);
67
+ return;
68
+ }
69
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
70
+
71
create_unimplemented_device("riscv.lowrisc.ibex.uart",
72
memmap[IBEX_UART].base, memmap[IBEX_UART].size);
73
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
74
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
75
memmap[IBEX_AES].base, memmap[IBEX_AES].size);
76
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
77
memmap[IBEX_HMAC].base, memmap[IBEX_HMAC].size);
78
- create_unimplemented_device("riscv.lowrisc.ibex.plic",
79
- memmap[IBEX_PLIC].base, memmap[IBEX_PLIC].size);
80
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
81
memmap[IBEX_PINMUX].base, memmap[IBEX_PINMUX].size);
82
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
83
--
84
2.27.0
85
86
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
5
include/hw/riscv/opentitan.h | 13 +++++++++++++
6
hw/riscv/opentitan.c | 25 +++++++++++++++++++++++--
7
2 files changed, 36 insertions(+), 2 deletions(-)
1
8
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
12
+++ b/include/hw/riscv/opentitan.h
13
@@ -XXX,XX +XXX,XX @@
14
15
#include "hw/riscv/riscv_hart.h"
16
#include "hw/intc/ibex_plic.h"
17
+#include "hw/char/ibex_uart.h"
18
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
20
#define RISCV_IBEX_SOC(obj) \
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
22
/*< public >*/
23
RISCVHartArrayState cpus;
24
IbexPlicState plic;
25
+ IbexUartState uart;
26
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
@@ -XXX,XX +XXX,XX @@ enum {
30
IBEX_PADCTRL,
31
};
32
33
+enum {
34
+ IBEX_UART_RX_PARITY_ERR_IRQ = 0x28,
35
+ IBEX_UART_RX_TIMEOUT_IRQ = 0x27,
36
+ IBEX_UART_RX_BREAK_ERR_IRQ = 0x26,
37
+ IBEX_UART_RX_FRAME_ERR_IRQ = 0x25,
38
+ IBEX_UART_RX_OVERFLOW_IRQ = 0x24,
39
+ IBEX_UART_TX_EMPTY_IRQ = 0x23,
40
+ IBEX_UART_RX_WATERMARK_IRQ = 0x22,
41
+ IBEX_UART_TX_WATERMARK_IRQ = 0x21,
42
+};
43
+
44
#endif
45
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/riscv/opentitan.c
48
+++ b/hw/riscv/opentitan.c
49
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
50
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
51
52
object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
53
+
54
+ object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
55
}
56
57
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
59
}
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
61
62
- create_unimplemented_device("riscv.lowrisc.ibex.uart",
63
- memmap[IBEX_UART].base, memmap[IBEX_UART].size);
64
+ /* UART */
65
+ qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
66
+ sysbus_realize(SYS_BUS_DEVICE(&s->uart), &err);
67
+ if (err != NULL) {
68
+ error_propagate(errp, err);
69
+ return;
70
+ }
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart), 0, memmap[IBEX_UART].base);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
73
+ 0, qdev_get_gpio_in(DEVICE(&s->plic),
74
+ IBEX_UART_TX_WATERMARK_IRQ));
75
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
76
+ 1, qdev_get_gpio_in(DEVICE(&s->plic),
77
+ IBEX_UART_RX_WATERMARK_IRQ));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
79
+ 2, qdev_get_gpio_in(DEVICE(&s->plic),
80
+ IBEX_UART_TX_EMPTY_IRQ));
81
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
82
+ 3, qdev_get_gpio_in(DEVICE(&s->plic),
83
+ IBEX_UART_RX_OVERFLOW_IRQ));
84
+
85
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
86
memmap[IBEX_GPIO].base, memmap[IBEX_GPIO].size);
87
create_unimplemented_device("riscv.lowrisc.ibex.spi",
88
--
89
2.27.0
90
91
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
---
4
target/riscv/pmp.c | 14 +++++++++-----
5
1 file changed, 9 insertions(+), 5 deletions(-)
1
6
7
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/pmp.c
10
+++ b/target/riscv/pmp.c
11
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
12
return true;
13
}
14
15
- /*
16
- * if size is unknown (0), assume that all bytes
17
- * from addr to the end of the page will be accessed.
18
- */
19
if (size == 0) {
20
- pmp_size = -(addr | TARGET_PAGE_MASK);
21
+ if (riscv_feature(env, RISCV_FEATURE_MMU)) {
22
+ /*
23
+ * If size is unknown (0), assume that all bytes
24
+ * from addr to the end of the page will be accessed.
25
+ */
26
+ pmp_size = -(addr | TARGET_PAGE_MASK);
27
+ } else {
28
+ pmp_size = sizeof(target_ulong);
29
+ }
30
} else {
31
pmp_size = size;
32
}
33
--
34
2.27.0
35
36
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
This was done in the virt & sifive_u codes, but sifive_e codes were
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-2-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591625864-31494-2-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/sifive_e.c | 24 ++++++++++++------------
13
1 file changed, 12 insertions(+), 12 deletions(-)
14
15
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_e.c
18
+++ b/hw/riscv/sifive_e.c
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
20
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
21
};
22
23
-static void riscv_sifive_e_init(MachineState *machine)
24
+static void sifive_e_machine_init(MachineState *machine)
25
{
26
const struct MemmapEntry *memmap = sifive_e_memmap;
27
28
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
29
MachineClass *mc = MACHINE_CLASS(oc);
30
31
mc->desc = "RISC-V Board compatible with SiFive E SDK";
32
- mc->init = riscv_sifive_e_init;
33
+ mc->init = sifive_e_machine_init;
34
mc->max_cpus = 1;
35
mc->default_cpu_type = SIFIVE_E_CPU;
36
}
37
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init_register_types(void)
38
39
type_init(sifive_e_machine_init_register_types)
40
41
-static void riscv_sifive_e_soc_init(Object *obj)
42
+static void sifive_e_soc_init(Object *obj)
43
{
44
MachineState *ms = MACHINE(qdev_get_machine());
45
SiFiveESoCState *s = RISCV_E_SOC(obj);
46
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_init(Object *obj)
47
TYPE_SIFIVE_GPIO);
48
}
49
50
-static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
51
+static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
52
{
53
MachineState *ms = MACHINE(qdev_get_machine());
54
const struct MemmapEntry *memmap = sifive_e_memmap;
55
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
56
&s->xip_mem);
57
}
58
59
-static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
60
+static void sifive_e_soc_class_init(ObjectClass *oc, void *data)
61
{
62
DeviceClass *dc = DEVICE_CLASS(oc);
63
64
- dc->realize = riscv_sifive_e_soc_realize;
65
+ dc->realize = sifive_e_soc_realize;
66
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
67
dc->user_creatable = false;
68
}
69
70
-static const TypeInfo riscv_sifive_e_soc_type_info = {
71
+static const TypeInfo sifive_e_soc_type_info = {
72
.name = TYPE_RISCV_E_SOC,
73
.parent = TYPE_DEVICE,
74
.instance_size = sizeof(SiFiveESoCState),
75
- .instance_init = riscv_sifive_e_soc_init,
76
- .class_init = riscv_sifive_e_soc_class_init,
77
+ .instance_init = sifive_e_soc_init,
78
+ .class_init = sifive_e_soc_class_init,
79
};
80
81
-static void riscv_sifive_e_soc_register_types(void)
82
+static void sifive_e_soc_register_types(void)
83
{
84
- type_register_static(&riscv_sifive_e_soc_type_info);
85
+ type_register_static(&sifive_e_soc_type_info);
86
}
87
88
-type_init(riscv_sifive_e_soc_register_types)
89
+type_init(sifive_e_soc_register_types)
90
--
91
2.27.0
92
93
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
This was done in the virt & sifive_u codes, but opentitan codes were
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-3-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591625864-31494-3-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/opentitan.c | 29 ++++++++++++++---------------
13
1 file changed, 14 insertions(+), 15 deletions(-)
14
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/opentitan.c
18
+++ b/hw/riscv/opentitan.c
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
20
[IBEX_PADCTRL] = { 0x40160000, 0x10000 }
21
};
22
23
-static void riscv_opentitan_init(MachineState *machine)
24
+static void opentitan_board_init(MachineState *machine)
25
{
26
const struct MemmapEntry *memmap = ibex_memmap;
27
OpenTitanState *s = g_new0(OpenTitanState, 1);
28
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
29
memory_region_add_subregion(sys_mem,
30
memmap[IBEX_RAM].base, main_mem);
31
32
-
33
if (machine->firmware) {
34
riscv_load_firmware(machine->firmware, memmap[IBEX_RAM].base, NULL);
35
}
36
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
37
}
38
}
39
40
-static void riscv_opentitan_machine_init(MachineClass *mc)
41
+static void opentitan_machine_init(MachineClass *mc)
42
{
43
mc->desc = "RISC-V Board compatible with OpenTitan";
44
- mc->init = riscv_opentitan_init;
45
+ mc->init = opentitan_board_init;
46
mc->max_cpus = 1;
47
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
48
}
49
50
-DEFINE_MACHINE("opentitan", riscv_opentitan_machine_init)
51
+DEFINE_MACHINE("opentitan", opentitan_machine_init)
52
53
-static void riscv_lowrisc_ibex_soc_init(Object *obj)
54
+static void lowrisc_ibex_soc_init(Object *obj)
55
{
56
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
57
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
59
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
60
}
61
62
-static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
63
+static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
64
{
65
const struct MemmapEntry *memmap = ibex_memmap;
66
MachineState *ms = MACHINE(qdev_get_machine());
67
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
68
memmap[IBEX_PADCTRL].base, memmap[IBEX_PADCTRL].size);
69
}
70
71
-static void riscv_lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
72
+static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
73
{
74
DeviceClass *dc = DEVICE_CLASS(oc);
75
76
- dc->realize = riscv_lowrisc_ibex_soc_realize;
77
+ dc->realize = lowrisc_ibex_soc_realize;
78
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
79
dc->user_creatable = false;
80
}
81
82
-static const TypeInfo riscv_lowrisc_ibex_soc_type_info = {
83
+static const TypeInfo lowrisc_ibex_soc_type_info = {
84
.name = TYPE_RISCV_IBEX_SOC,
85
.parent = TYPE_DEVICE,
86
.instance_size = sizeof(LowRISCIbexSoCState),
87
- .instance_init = riscv_lowrisc_ibex_soc_init,
88
- .class_init = riscv_lowrisc_ibex_soc_class_init,
89
+ .instance_init = lowrisc_ibex_soc_init,
90
+ .class_init = lowrisc_ibex_soc_class_init,
91
};
92
93
-static void riscv_lowrisc_ibex_soc_register_types(void)
94
+static void lowrisc_ibex_soc_register_types(void)
95
{
96
- type_register_static(&riscv_lowrisc_ibex_soc_type_info);
97
+ type_register_static(&lowrisc_ibex_soc_type_info);
98
}
99
100
-type_init(riscv_lowrisc_ibex_soc_register_types)
101
+type_init(lowrisc_ibex_soc_register_types)
102
--
103
2.27.0
104
105
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
There is no need to retrieve all PLIC IRQ information in order to
4
just connect the GEM IRQ. Use qdev_get_gpio_in() directly like
5
what is done for other peripherals.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-4-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1591625864-31494-4-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/sifive_u.c | 7 +------
14
1 file changed, 1 insertion(+), 6 deletions(-)
15
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
19
+++ b/hw/riscv/sifive_u.c
20
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
21
MemoryRegion *system_memory = get_system_memory();
22
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
23
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
24
- qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
25
char *plic_hart_config;
26
size_t plic_hart_config_len;
27
int i;
28
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
29
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
30
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
31
32
- for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
33
- plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
34
- }
35
-
36
if (nd->used) {
37
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
38
qdev_set_nic_properties(DEVICE(&s->gem), nd);
39
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
40
}
41
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
42
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
43
- plic_gpios[SIFIVE_U_GEM_IRQ]);
44
+ qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
45
46
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
47
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
48
--
49
2.27.0
50
51
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Upstream U-Boot v2020.07 codes switch to access SiFive FU540 OTP
4
based on device tree information. Let's generate the device tree
5
node for OTP.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-5-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1591625864-31494-5-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/sifive_u.c | 11 +++++++++++
14
1 file changed, 11 insertions(+)
15
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
19
+++ b/hw/riscv/sifive_u.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
21
g_free(cells);
22
g_free(nodename);
23
24
+ nodename = g_strdup_printf("/soc/otp@%lx",
25
+ (long)memmap[SIFIVE_U_OTP].base);
26
+ qemu_fdt_add_subnode(fdt, nodename);
27
+ qemu_fdt_setprop_cell(fdt, nodename, "fuse-count", SIFIVE_U_OTP_REG_SIZE);
28
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
29
+ 0x0, memmap[SIFIVE_U_OTP].base,
30
+ 0x0, memmap[SIFIVE_U_OTP].size);
31
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
32
+ "sifive,fu540-c000-otp");
33
+ g_free(nodename);
34
+
35
prci_phandle = phandle++;
36
nodename = g_strdup_printf("/soc/clock-controller@%lx",
37
(long)memmap[SIFIVE_U_PRCI].base);
38
--
39
2.27.0
40
41
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Do various minor clean-ups to the exisiting codes for:
4
5
- coding convention conformance
6
- remove unnecessary blank lines
7
- spell SiFive correctly
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1591625864-31494-6-git-send-email-bmeng.cn@gmail.com
12
Message-Id: <1591625864-31494-6-git-send-email-bmeng.cn@gmail.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
include/hw/riscv/sifive_gpio.h | 7 ++++---
16
hw/riscv/sifive_gpio.c | 13 +++++--------
17
2 files changed, 9 insertions(+), 11 deletions(-)
18
19
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_gpio.h
22
+++ b/include/hw/riscv/sifive_gpio.h
23
@@ -XXX,XX +XXX,XX @@
24
/*
25
- * sifive System-on-Chip general purpose input/output register definition
26
+ * SiFive System-on-Chip general purpose input/output register definition
27
*
28
* Copyright 2019 AdaCore
29
*
30
@@ -XXX,XX +XXX,XX @@
31
* This code is licensed under the GPL version 2 or later. See
32
* the COPYING file in the top-level directory.
33
*/
34
+
35
#ifndef SIFIVE_GPIO_H
36
#define SIFIVE_GPIO_H
37
38
#include "hw/sysbus.h"
39
+
40
#define TYPE_SIFIVE_GPIO "sifive_soc.gpio"
41
#define SIFIVE_GPIO(obj) OBJECT_CHECK(SIFIVEGPIOState, (obj), TYPE_SIFIVE_GPIO)
42
43
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
44
uint32_t out_xor;
45
uint32_t in;
46
uint32_t in_mask;
47
-
48
} SIFIVEGPIOState;
49
50
-#endif
51
+#endif /* SIFIVE_GPIO_H */
52
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/riscv/sifive_gpio.c
55
+++ b/hw/riscv/sifive_gpio.c
56
@@ -XXX,XX +XXX,XX @@
57
/*
58
- * sifive System-on-Chip general purpose input/output register definition
59
+ * SiFive System-on-Chip general purpose input/output register definition
60
*
61
* Copyright 2019 AdaCore
62
*
63
@@ -XXX,XX +XXX,XX @@
64
65
static void update_output_irq(SIFIVEGPIOState *s)
66
{
67
-
68
uint32_t pending;
69
uint32_t pin;
70
71
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_gpio_read(void *opaque, hwaddr offset, unsigned int size)
72
}
73
74
static void sifive_gpio_write(void *opaque, hwaddr offset,
75
- uint64_t value, unsigned int size)
76
+ uint64_t value, unsigned int size)
77
{
78
SIFIVEGPIOState *s = SIFIVE_GPIO(opaque);
79
80
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_reset(DeviceState *dev)
81
s->out_xor = 0;
82
s->in = 0;
83
s->in_mask = 0;
84
-
85
}
86
87
static const VMStateDescription vmstate_sifive_gpio = {
88
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
89
VMSTATE_UINT32(iof_en, SIFIVEGPIOState),
90
VMSTATE_UINT32(iof_sel, SIFIVEGPIOState),
91
VMSTATE_UINT32(out_xor, SIFIVEGPIOState),
92
- VMSTATE_UINT32(in, SIFIVEGPIOState),
93
- VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
94
+ VMSTATE_UINT32(in, SIFIVEGPIOState),
95
+ VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
96
VMSTATE_END_OF_LIST()
97
}
98
};
99
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_init(Object *obj)
100
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
101
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
102
103
-
104
for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
105
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_class_init(ObjectClass *klass, void *data)
108
109
dc->vmsd = &vmstate_sifive_gpio;
110
dc->reset = sifive_gpio_reset;
111
- dc->desc = "sifive GPIO";
112
+ dc->desc = "SiFive GPIO";
113
}
114
115
static const TypeInfo sifive_gpio_info = {
116
--
117
2.27.0
118
119
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Once a "One Time Programmable" is programmed, it shouldn't be reset.
3
Add a new property to represent the number of GPIO pins supported
4
by the GPIO controller.
4
5
5
Do not re-initialize the OTP content in the DeviceReset handler,
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
initialize it once in the DeviceRealize one.
7
8
Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP")
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20211119104757.331579-1-f4bug@amsat.org>
8
Message-id: 1591625864-31494-7-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591625864-31494-7-git-send-email-bmeng.cn@gmail.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
hw/misc/sifive_u_otp.c | 13 +++++--------
12
include/hw/riscv/sifive_gpio.h | 3 +++
15
1 file changed, 5 insertions(+), 8 deletions(-)
13
hw/riscv/sifive_gpio.c | 30 +++++++++++++++++++-----------
14
2 files changed, 22 insertions(+), 11 deletions(-)
16
15
17
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
16
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/sifive_u_otp.c
18
--- a/include/hw/riscv/sifive_gpio.h
20
+++ b/hw/misc/sifive_u_otp.c
19
+++ b/include/hw/riscv/sifive_gpio.h
21
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
22
21
uint32_t out_xor;
23
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
22
uint32_t in;
24
error_setg(errp, "failed to read the initial flash content");
23
uint32_t in_mask;
25
+ return;
24
+
26
}
25
+ /* config */
27
}
26
+ uint32_t ngpio;
27
} SIFIVEGPIOState;
28
29
#endif /* SIFIVE_GPIO_H */
30
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/sifive_gpio.c
33
+++ b/hw/riscv/sifive_gpio.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "qemu/osdep.h"
36
#include "qemu/log.h"
37
#include "hw/irq.h"
38
+#include "hw/qdev-properties.h"
39
#include "hw/riscv/sifive_gpio.h"
40
#include "migration/vmstate.h"
41
#include "trace.h"
42
@@ -XXX,XX +XXX,XX @@ static void update_output_irq(SIFIVEGPIOState *s)
43
pending |= s->rise_ip & s->rise_ie;
44
pending |= s->fall_ip & s->fall_ie;
45
46
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
47
+ for (int i = 0; i < s->ngpio; i++) {
48
pin = 1 << i;
49
qemu_set_irq(s->irq[i], (pending & pin) != 0);
50
trace_sifive_gpio_update_output_irq(i, (pending & pin) != 0);
51
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
52
bool prev_ival, in, in_mask, port, out_xor, pull, output_en, input_en,
53
rise_ip, fall_ip, low_ip, high_ip, oval, actual_value, ival;
54
55
- for (i = 0; i < SIFIVE_GPIO_PINS; i++) {
56
+ for (i = 0; i < s->ngpio; i++) {
57
58
prev_ival = extract32(s->value, i, 1);
59
in = extract32(s->in, i, 1);
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
28
}
61
}
29
-}
62
};
30
-
63
31
-static void sifive_u_otp_reset(DeviceState *dev)
64
-static void sifive_gpio_init(Object *obj)
32
-{
65
+static Property sifive_gpio_properties[] = {
33
- SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
66
+ DEFINE_PROP_UINT32("ngpio", SIFIVEGPIOState, ngpio, SIFIVE_GPIO_PINS),
34
67
+ DEFINE_PROP_END_OF_LIST(),
35
/* Initialize all fuses' initial value to 0xFFs */
68
+};
36
memset(s->fuse, 0xff, sizeof(s->fuse));
69
+
37
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev)
70
+static void sifive_gpio_realize(DeviceState *dev, Error **errp)
38
serial_data = s->serial;
71
{
39
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
72
- SIFIVEGPIOState *s = SIFIVE_GPIO(obj);
40
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
73
+ SIFIVEGPIOState *s = SIFIVE_GPIO(dev);
41
- error_report("write error index<%d>", index);
74
42
+ error_setg(errp, "failed to write index<%d>", index);
75
- memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
43
+ return;
76
+ memory_region_init_io(&s->mmio, OBJECT(dev), &gpio_ops, s,
44
}
77
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
45
78
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
46
serial_data = ~(s->serial);
79
47
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
80
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
48
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
81
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
49
- error_report("write error index<%d>", index + 1);
82
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
50
+ error_setg(errp, "failed to write index<%d>", index + 1);
83
+
51
+ return;
84
+ for (int i = 0; i < s->ngpio; i++) {
52
}
85
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
53
}
86
}
54
87
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
88
- qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, SIFIVE_GPIO_PINS);
56
89
- qdev_init_gpio_out(DEVICE(s), s->output, SIFIVE_GPIO_PINS);
57
device_class_set_props(dc, sifive_u_otp_properties);
90
+ qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, s->ngpio);
58
dc->realize = sifive_u_otp_realize;
91
+ qdev_init_gpio_out(DEVICE(s), s->output, s->ngpio);
59
- dc->reset = sifive_u_otp_reset;
60
}
92
}
61
93
62
static const TypeInfo sifive_u_otp_info = {
94
static void sifive_gpio_class_init(ObjectClass *klass, void *data)
95
{
96
DeviceClass *dc = DEVICE_CLASS(klass);
97
98
+ device_class_set_props(dc, sifive_gpio_properties);
99
dc->vmsd = &vmstate_sifive_gpio;
100
+ dc->realize = sifive_gpio_realize;
101
dc->reset = sifive_gpio_reset;
102
dc->desc = "SiFive GPIO";
103
}
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sifive_gpio_info = {
105
.name = TYPE_SIFIVE_GPIO,
106
.parent = TYPE_SYS_BUS_DEVICE,
107
.instance_size = sizeof(SIFIVEGPIOState),
108
- .instance_init = sifive_gpio_init,
109
.class_init = sifive_gpio_class_init
110
};
111
63
--
112
--
64
2.31.1
113
2.27.0
65
114
66
115
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
SiFive FU540 SoC integrates a GPIO controller with 16 GPIO lines.
4
This hooks the exsiting SiFive GPIO model to the SoC, and adds its
5
device tree data as well.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-8-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1591625864-31494-8-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
include/hw/riscv/sifive_u.h | 19 ++++++++++++++++
14
hw/riscv/sifive_u.c | 43 +++++++++++++++++++++++++++++++++++--
15
2 files changed, 60 insertions(+), 2 deletions(-)
16
17
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/sifive_u.h
20
+++ b/include/hw/riscv/sifive_u.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/net/cadence_gem.h"
23
#include "hw/riscv/riscv_hart.h"
24
#include "hw/riscv/sifive_cpu.h"
25
+#include "hw/riscv/sifive_gpio.h"
26
#include "hw/riscv/sifive_u_prci.h"
27
#include "hw/riscv/sifive_u_otp.h"
28
29
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUSoCState {
30
RISCVHartArrayState u_cpus;
31
DeviceState *plic;
32
SiFiveUPRCIState prci;
33
+ SIFIVEGPIOState gpio;
34
SiFiveUOTPState otp;
35
CadenceGEMState gem;
36
37
@@ -XXX,XX +XXX,XX @@ enum {
38
SIFIVE_U_PRCI,
39
SIFIVE_U_UART0,
40
SIFIVE_U_UART1,
41
+ SIFIVE_U_GPIO,
42
SIFIVE_U_OTP,
43
SIFIVE_U_FLASH0,
44
SIFIVE_U_DRAM,
45
@@ -XXX,XX +XXX,XX @@ enum {
46
enum {
47
SIFIVE_U_UART0_IRQ = 4,
48
SIFIVE_U_UART1_IRQ = 5,
49
+ SIFIVE_U_GPIO_IRQ0 = 7,
50
+ SIFIVE_U_GPIO_IRQ1 = 8,
51
+ SIFIVE_U_GPIO_IRQ2 = 9,
52
+ SIFIVE_U_GPIO_IRQ3 = 10,
53
+ SIFIVE_U_GPIO_IRQ4 = 11,
54
+ SIFIVE_U_GPIO_IRQ5 = 12,
55
+ SIFIVE_U_GPIO_IRQ6 = 13,
56
+ SIFIVE_U_GPIO_IRQ7 = 14,
57
+ SIFIVE_U_GPIO_IRQ8 = 15,
58
+ SIFIVE_U_GPIO_IRQ9 = 16,
59
+ SIFIVE_U_GPIO_IRQ10 = 17,
60
+ SIFIVE_U_GPIO_IRQ11 = 18,
61
+ SIFIVE_U_GPIO_IRQ12 = 19,
62
+ SIFIVE_U_GPIO_IRQ13 = 20,
63
+ SIFIVE_U_GPIO_IRQ14 = 21,
64
+ SIFIVE_U_GPIO_IRQ15 = 22,
65
SIFIVE_U_GEM_IRQ = 0x35
66
};
67
68
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/sifive_u.c
71
+++ b/hw/riscv/sifive_u.c
72
@@ -XXX,XX +XXX,XX @@
73
* 1) CLINT (Core Level Interruptor)
74
* 2) PLIC (Platform Level Interrupt Controller)
75
* 3) PRCI (Power, Reset, Clock, Interrupt)
76
- * 4) OTP (One-Time Programmable) memory with stored serial number
77
- * 5) GEM (Gigabit Ethernet Controller) and management block
78
+ * 4) GPIO (General Purpose Input/Output Controller)
79
+ * 5) OTP (One-Time Programmable) memory with stored serial number
80
+ * 6) GEM (Gigabit Ethernet Controller) and management block
81
*
82
* This board currently generates devicetree dynamically that indicates at least
83
* two harts and up to five harts.
84
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
85
[SIFIVE_U_PRCI] = { 0x10000000, 0x1000 },
86
[SIFIVE_U_UART0] = { 0x10010000, 0x1000 },
87
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
88
+ [SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
89
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
90
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
91
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
92
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
93
g_free(cells);
94
g_free(nodename);
95
96
+ nodename = g_strdup_printf("/soc/gpio@%lx",
97
+ (long)memmap[SIFIVE_U_GPIO].base);
98
+ qemu_fdt_add_subnode(fdt, nodename);
99
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks",
100
+ prci_phandle, PRCI_CLK_TLCLK);
101
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
102
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
103
+ qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2);
104
+ qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0);
105
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
106
+ 0x0, memmap[SIFIVE_U_GPIO].base,
107
+ 0x0, memmap[SIFIVE_U_GPIO].size);
108
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GPIO_IRQ0,
109
+ SIFIVE_U_GPIO_IRQ1, SIFIVE_U_GPIO_IRQ2, SIFIVE_U_GPIO_IRQ3,
110
+ SIFIVE_U_GPIO_IRQ4, SIFIVE_U_GPIO_IRQ5, SIFIVE_U_GPIO_IRQ6,
111
+ SIFIVE_U_GPIO_IRQ7, SIFIVE_U_GPIO_IRQ8, SIFIVE_U_GPIO_IRQ9,
112
+ SIFIVE_U_GPIO_IRQ10, SIFIVE_U_GPIO_IRQ11, SIFIVE_U_GPIO_IRQ12,
113
+ SIFIVE_U_GPIO_IRQ13, SIFIVE_U_GPIO_IRQ14, SIFIVE_U_GPIO_IRQ15);
114
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
115
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
116
+ g_free(nodename);
117
+
118
phy_phandle = phandle++;
119
nodename = g_strdup_printf("/soc/ethernet@%lx",
120
(long)memmap[SIFIVE_U_GEM].base);
121
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_instance_init(Object *obj)
122
object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
123
object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
124
object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
125
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
126
}
127
128
static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
129
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
130
sysbus_realize(SYS_BUS_DEVICE(&s->prci), &err);
131
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
132
133
+ qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
134
+ sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err);
135
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_GPIO].base);
136
+
137
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
138
+ qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
139
+
140
+ /* Connect GPIO interrupts to the PLIC */
141
+ for (i = 0; i < 16; i++) {
142
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
143
+ qdev_get_gpio_in(DEVICE(s->plic),
144
+ SIFIVE_U_GPIO_IRQ0 + i));
145
+ }
146
+
147
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
148
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
149
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
150
--
151
2.27.0
152
153
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
At present the GPIO output IRQs are triggered each time any GPIO
4
register is written. However this is not correct. We should only
5
trigger the output IRQ when the pin is configured as output enable.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-9-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1591625864-31494-9-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/sifive_gpio.c | 4 +++-
14
1 file changed, 3 insertions(+), 1 deletion(-)
15
16
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_gpio.c
19
+++ b/hw/riscv/sifive_gpio.c
20
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
21
actual_value = pull;
22
}
23
24
- qemu_set_irq(s->output[i], actual_value);
25
+ if (output_en) {
26
+ qemu_set_irq(s->output[i], actual_value);
27
+ }
28
29
/* Input value */
30
ival = input_en && actual_value;
31
--
32
2.27.0
33
34
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
The HiFive Unleashed board wires GPIO pin#10 to the input of the
4
system reset signal. Let's set up the GPIO pin#10 and insert a
5
"gpio-restart" device tree node so that reboot is now functional
6
with QEMU 'sifive_u' machine.
7
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1591625864-31494-10-git-send-email-bmeng.cn@gmail.com
11
Message-Id: <1591625864-31494-10-git-send-email-bmeng.cn@gmail.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/riscv/sifive_u.c | 24 +++++++++++++++++++++++-
15
1 file changed, 23 insertions(+), 1 deletion(-)
16
17
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_u.c
20
+++ b/hw/riscv/sifive_u.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/error.h"
23
#include "qapi/visitor.h"
24
#include "hw/boards.h"
25
+#include "hw/irq.h"
26
#include "hw/loader.h"
27
#include "hw/sysbus.h"
28
#include "hw/char/serial.h"
29
@@ -XXX,XX +XXX,XX @@
30
#include "net/eth.h"
31
#include "sysemu/arch_init.h"
32
#include "sysemu/device_tree.h"
33
+#include "sysemu/runstate.h"
34
#include "sysemu/sysemu.h"
35
#include "exec/address-spaces.h"
36
37
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
38
uint32_t *cells;
39
char *nodename;
40
char ethclk_names[] = "pclk\0hclk";
41
- uint32_t plic_phandle, prci_phandle, phandle = 1;
42
+ uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
43
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
44
45
fdt = s->fdt = create_device_tree(&s->fdt_size);
46
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
47
g_free(cells);
48
g_free(nodename);
49
50
+ gpio_phandle = phandle++;
51
nodename = g_strdup_printf("/soc/gpio@%lx",
52
(long)memmap[SIFIVE_U_GPIO].base);
53
qemu_fdt_add_subnode(fdt, nodename);
54
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
55
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
56
prci_phandle, PRCI_CLK_TLCLK);
57
qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
58
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
59
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
60
g_free(nodename);
61
62
+ nodename = g_strdup_printf("/gpio-restart");
63
+ qemu_fdt_add_subnode(fdt, nodename);
64
+ qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
65
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
66
+ g_free(nodename);
67
+
68
phy_phandle = phandle++;
69
nodename = g_strdup_printf("/soc/ethernet@%lx",
70
(long)memmap[SIFIVE_U_GEM].base);
71
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
72
g_free(nodename);
73
}
74
75
+static void sifive_u_machine_reset(void *opaque, int n, int level)
76
+{
77
+ /* gpio pin active low triggers reset */
78
+ if (!level) {
79
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
80
+ }
81
+}
82
+
83
static void sifive_u_machine_init(MachineState *machine)
84
{
85
const struct MemmapEntry *memmap = sifive_u_memmap;
86
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
87
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
88
flash0);
89
90
+ /* register gpio-restart */
91
+ qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
92
+ qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
93
+
94
/* create device tree */
95
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
96
97
--
98
2.27.0
99
100
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
In prepration to add more properties to this machine, rename the
4
existing serial property get/set functions to a generic name.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-11-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591625864-31494-11-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/sifive_u.c | 14 ++++++++------
13
1 file changed, 8 insertions(+), 6 deletions(-)
14
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_u.c
18
+++ b/hw/riscv/sifive_u.c
19
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error *
20
s->start_in_flash = value;
21
}
22
23
-static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name,
24
- void *opaque, Error **errp)
25
+static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v,
26
+ const char *name, void *opaque,
27
+ Error **errp)
28
{
29
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
30
}
31
32
-static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name,
33
- void *opaque, Error **errp)
34
+static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v,
35
+ const char *name, void *opaque,
36
+ Error **errp)
37
{
38
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
39
}
40
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
41
42
s->serial = OTP_SERIAL;
43
object_property_add(obj, "serial", "uint32",
44
- sifive_u_machine_get_serial,
45
- sifive_u_machine_set_serial, NULL, &s->serial);
46
+ sifive_u_machine_get_uint32_prop,
47
+ sifive_u_machine_set_uint32_prop, NULL, &s->serial);
48
object_property_set_description(obj, "serial", "Board serial number");
49
}
50
51
--
52
2.27.0
53
54
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
On SiFive FU540 SoC, the value stored at physical address 0x1000
4
stores the MSEL pin state that is used to control the next boot
5
location that ROM codes jump to.
6
7
Add a new property msel to sifive_u machine for this.
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1591625864-31494-12-git-send-email-bmeng.cn@gmail.com
12
Message-Id: <1591625864-31494-12-git-send-email-bmeng.cn@gmail.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
include/hw/riscv/sifive_u.h | 1 +
16
hw/riscv/sifive_u.c | 7 +++++++
17
2 files changed, 8 insertions(+)
18
19
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_u.h
22
+++ b/include/hw/riscv/sifive_u.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUState {
24
int fdt_size;
25
26
bool start_in_flash;
27
+ uint32_t msel;
28
uint32_t serial;
29
} SiFiveUState;
30
31
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/sifive_u.c
34
+++ b/hw/riscv/sifive_u.c
35
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
36
"Set on to tell QEMU's ROM to jump to "
37
"flash. Otherwise QEMU will jump to DRAM");
38
39
+ s->msel = 0;
40
+ object_property_add(obj, "msel", "uint32",
41
+ sifive_u_machine_get_uint32_prop,
42
+ sifive_u_machine_set_uint32_prop, NULL, &s->msel);
43
+ object_property_set_description(obj, "msel",
44
+ "Mode Select (MSEL[3:0]) pin state");
45
+
46
s->serial = OTP_SERIAL;
47
object_property_add(obj, "serial", "uint32",
48
sifive_u_machine_get_uint32_prop,
49
--
50
2.27.0
51
52
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Current IBEX CPU init routine name seems to be too generic.
4
Since it uses a different reset vector from the generic one,
5
it merits a dedicated name.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1592268641-7478-2-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1592268641-7478-2-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
21
22
#if defined(TARGET_RISCV32)
23
24
-static void rv32_imcu_nommu_cpu_init(Object *obj)
25
+static void rv32_ibex_cpu_init(Object *obj)
26
{
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
28
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
29
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
30
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
31
#if defined(TARGET_RISCV32)
32
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
33
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
34
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
35
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
36
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
37
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
38
--
39
2.27.0
40
41
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Per the SiFive manual, all E/U series CPU cores' reset vector is
4
at 0x1004. Update our codes to match the hardware.
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1592268641-7478-3-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1592268641-7478-3-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/sifive_e.c | 10 ++++++----
13
hw/riscv/sifive_u.c | 6 +++---
14
target/riscv/cpu.c | 16 ++++++++--------
15
3 files changed, 17 insertions(+), 15 deletions(-)
16
17
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_e.c
20
+++ b/hw/riscv/sifive_e.c
21
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
22
memmap[SIFIVE_E_DTIM].base, main_mem);
23
24
/* Mask ROM reset vector */
25
- uint32_t reset_vec[2];
26
+ uint32_t reset_vec[4];
27
28
if (s->revb) {
29
- reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
30
+ reset_vec[1] = 0x200102b7; /* 0x1004: lui t0,0x20010 */
31
} else {
32
- reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
33
+ reset_vec[1] = 0x204002b7; /* 0x1004: lui t0,0x20400 */
34
}
35
- reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
36
+ reset_vec[2] = 0x00028067; /* 0x1008: jr t0 */
37
+
38
+ reset_vec[0] = reset_vec[3] = 0;
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/riscv/sifive_u.c
45
+++ b/hw/riscv/sifive_u.c
46
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
47
48
/* reset vector */
49
uint32_t reset_vec[8] = {
50
+ 0x00000000,
51
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
52
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
53
+ 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
54
0xf1402573, /* csrr a0, mhartid */
55
#if defined(TARGET_RISCV32)
56
0x0182a283, /* lw t0, 24(t0) */
57
#elif defined(TARGET_RISCV64)
58
- 0x0182b283, /* ld t0, 24(t0) */
59
+ 0x0182e283, /* lwu t0, 24(t0) */
60
#endif
61
0x00028067, /* jr t0 */
62
0x00000000,
63
start_addr, /* start: .dword */
64
- 0x00000000,
65
/* dtb: */
66
};
67
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
73
set_resetvec(env, DEFAULT_RSTVEC);
74
}
75
76
-static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
77
+static void rvxx_sifive_u_cpu_init(Object *obj)
78
{
79
CPURISCVState *env = &RISCV_CPU(obj)->env;
80
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
81
set_priv_version(env, PRIV_VERSION_1_10_0);
82
- set_resetvec(env, DEFAULT_RSTVEC);
83
+ set_resetvec(env, 0x1004);
84
}
85
86
-static void rvxx_imacu_nommu_cpu_init(Object *obj)
87
+static void rvxx_sifive_e_cpu_init(Object *obj)
88
{
89
CPURISCVState *env = &RISCV_CPU(obj)->env;
90
set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
91
set_priv_version(env, PRIV_VERSION_1_10_0);
92
- set_resetvec(env, DEFAULT_RSTVEC);
93
+ set_resetvec(env, 0x1004);
94
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
98
#if defined(TARGET_RISCV32)
99
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
100
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
101
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
102
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
103
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
104
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
105
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
106
#elif defined(TARGET_RISCV64)
107
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
108
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
109
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
110
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
111
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
112
#endif
113
};
114
115
--
116
2.27.0
117
118
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
SiFive FU540 SoC supports booting from several sources, which are
4
controlled using the Mode Select (MSEL[3:0]) pins on the chip.
5
Typically, the boot process runs through several stages before it
6
begins execution of user-provided programs.
7
8
The SoC supports booting from memory-mapped QSPI flash, which is
9
how start_in_flash property is used for at present. This matches
10
MSEL = 1 configuration (QSPI0).
11
12
Typical booting flows involve the Zeroth Stage Boot Loader (ZSBL).
13
It's not necessary for QEMU to implement the full ZSBL ROM codes,
14
because we know ZSBL downloads the next stage program into the L2
15
LIM at address 0x8000000 and executes from there. We can bypass
16
the whole ZSBL execution and use "-bios" to load the next stage
17
program directly if MSEL indicates a ZSBL booting flow.
18
19
Signed-off-by: Bin Meng <bin.meng@windriver.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-id: 1592268641-7478-4-git-send-email-bmeng.cn@gmail.com
22
Message-Id: <1592268641-7478-4-git-send-email-bmeng.cn@gmail.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
25
include/hw/riscv/sifive_u.h | 6 ++++++
26
hw/riscv/sifive_u.c | 39 +++++++++++++++++++++++++++++--------
27
2 files changed, 37 insertions(+), 8 deletions(-)
28
29
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/sifive_u.h
32
+++ b/include/hw/riscv/sifive_u.h
33
@@ -XXX,XX +XXX,XX @@ enum {
34
SIFIVE_U_RTCCLK_FREQ = 1000000
35
};
36
37
+enum {
38
+ MSEL_MEMMAP_QSPI0_FLASH = 1,
39
+ MSEL_L2LIM_QSPI0_FLASH = 6,
40
+ MSEL_L2LIM_QSPI2_SD = 11
41
+};
42
+
43
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
44
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
45
46
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/riscv/sifive_u.c
49
+++ b/hw/riscv/sifive_u.c
50
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
51
/* create device tree */
52
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
53
54
- riscv_find_and_load_firmware(machine, BIOS_FILENAME,
55
- memmap[SIFIVE_U_DRAM].base, NULL);
56
+ if (s->start_in_flash) {
57
+ /*
58
+ * If start_in_flash property is given, assign s->msel to a value
59
+ * that representing booting from QSPI0 memory-mapped flash.
60
+ *
61
+ * This also means that when both start_in_flash and msel properties
62
+ * are given, start_in_flash takes the precedence over msel.
63
+ *
64
+ * Note this is to keep backward compatibility not to break existing
65
+ * users that use start_in_flash property.
66
+ */
67
+ s->msel = MSEL_MEMMAP_QSPI0_FLASH;
68
+ }
69
+
70
+ switch (s->msel) {
71
+ case MSEL_MEMMAP_QSPI0_FLASH:
72
+ start_addr = memmap[SIFIVE_U_FLASH0].base;
73
+ break;
74
+ case MSEL_L2LIM_QSPI0_FLASH:
75
+ case MSEL_L2LIM_QSPI2_SD:
76
+ start_addr = memmap[SIFIVE_U_L2LIM].base;
77
+ break;
78
+ default:
79
+ start_addr = memmap[SIFIVE_U_DRAM].base;
80
+ break;
81
+ }
82
+
83
+ riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
84
85
if (machine->kernel_filename) {
86
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
87
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
88
}
89
}
90
91
- if (s->start_in_flash) {
92
- start_addr = memmap[SIFIVE_U_FLASH0].base;
93
- }
94
-
95
/* reset vector */
96
uint32_t reset_vec[8] = {
97
- 0x00000000,
98
+ s->msel, /* MSEL pin state */
99
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
100
0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
101
0xf1402573, /* csrr a0, mhartid */
102
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
103
sifive_u_machine_set_start_in_flash);
104
object_property_set_description(obj, "start-in-flash",
105
"Set on to tell QEMU's ROM to jump to "
106
- "flash. Otherwise QEMU will jump to DRAM");
107
+ "flash. Otherwise QEMU will jump to DRAM "
108
+ "or L2LIM depending on the msel value");
109
110
s->msel = 0;
111
object_property_add(obj, "msel", "uint32",
112
--
113
2.27.0
114
115
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bin.meng@windriver.com>
1
2
3
Move the flash and DRAM to the end of the SoC memmap table.
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 1592268641-7478-5-git-send-email-bmeng.cn@gmail.com
8
Message-Id: <1592268641-7478-5-git-send-email-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/sifive_u.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/sifive_u.c
17
+++ b/hw/riscv/sifive_u.c
18
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
19
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
20
[SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
21
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
22
- [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
23
- [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
24
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
25
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
26
+ [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
27
+ [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
28
};
29
30
#define OTP_SERIAL 1
31
--
32
2.27.0
33
34
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Configuring a drive with "if=none" is meant for creation of a backend
3
It is enough to simply map the SiFive FU540 DDR memory controller
4
only, it should not get automatically assigned to a device frontend.
4
into the MMIO space using create_unimplemented_device(), to make
5
Use "if=pflash" for the One-Time-Programmable device instead (like
5
the upstream U-Boot v2020.07 DDR memory initialization codes happy.
6
it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c).
7
6
8
Since the old way of configuring the device has already been published
7
Note we do not generate device tree fragment for the DDR memory
9
with the previous QEMU versions, we cannot remove this immediately, but
8
controller. Since the controller data in device tree consumes a
10
have to deprecate it and support it for at least two more releases.
9
very large space (see fu540-hifive-unleashed-a00-ddr.dtsi in the
10
U-Boot source), and it is only needed by U-Boot SPL but not any
11
operating system, we choose not to generate the fragment here.
12
This also means when testing with U-Boot SPL, the device tree has
13
to come from U-Boot SPL itself, but not the one generated by QEMU
14
on the fly. The memory has to be set to 8GiB to match the real
15
HiFive Unleashed board when invoking QEMU (-m 8G).
11
16
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
17
With this commit, QEMU can boot U-Boot SPL built for SiFive FU540
13
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
all the way up to loading U-Boot proper from MMC:
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
19
20
$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -m 8G -bios u-boot-spl.bin
21
22
U-Boot SPL 2020.07-rc3-00208-g88bd5b1 (Jun 08 2020 - 20:16:10 +0800)
23
Trying to boot from MMC1
24
Unhandled exception: Load access fault
25
EPC: 0000000008009be6 TVAL: 0000000010050014
26
27
The above exception is expected because QSPI is unsupported yet.
28
29
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20211119102549.217755-1-thuth@redhat.com
31
Message-id: 1592268641-7478-6-git-send-email-bmeng.cn@gmail.com
32
Message-Id: <1592268641-7478-6-git-send-email-bmeng.cn@gmail.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
34
---
19
docs/about/deprecated.rst | 6 ++++++
35
include/hw/riscv/sifive_u.h | 1 +
20
hw/misc/sifive_u_otp.c | 9 ++++++++-
36
hw/riscv/sifive_u.c | 4 ++++
21
2 files changed, 14 insertions(+), 1 deletion(-)
37
2 files changed, 5 insertions(+)
22
38
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
39
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
24
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
25
--- a/docs/about/deprecated.rst
41
--- a/include/hw/riscv/sifive_u.h
26
+++ b/docs/about/deprecated.rst
42
+++ b/include/hw/riscv/sifive_u.h
27
@@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
43
@@ -XXX,XX +XXX,XX @@ enum {
28
However, short-form booleans are deprecated and full explicit ``arg_name=on``
44
SIFIVE_U_UART1,
29
form is preferred.
45
SIFIVE_U_GPIO,
30
46
SIFIVE_U_OTP,
31
+``-drive if=none`` for the sifive_u OTP device (since 6.2)
47
+ SIFIVE_U_DMC,
32
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
48
SIFIVE_U_FLASH0,
49
SIFIVE_U_DRAM,
50
SIFIVE_U_GEM,
51
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/sifive_u.c
54
+++ b/hw/riscv/sifive_u.c
55
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
56
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
57
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
58
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
59
+ [SIFIVE_U_DMC] = { 0x100b0000, 0x10000 },
60
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
61
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
62
};
63
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
64
65
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
66
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
33
+
67
+
34
+Using ``-drive if=none`` to configure the OTP device of the sifive_u
68
+ create_unimplemented_device("riscv.sifive.u.dmc",
35
+RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
69
+ memmap[SIFIVE_U_DMC].base, memmap[SIFIVE_U_DMC].size);
36
+
70
}
37
71
38
QEMU Machine Protocol (QMP) commands
72
static Property sifive_u_soc_props[] = {
39
------------------------------------
40
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/sifive_u_otp.c
43
+++ b/hw/misc/sifive_u_otp.c
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
45
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
46
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
47
48
- dinfo = drive_get_next(IF_NONE);
49
+ dinfo = drive_get_next(IF_PFLASH);
50
+ if (!dinfo) {
51
+ dinfo = drive_get_next(IF_NONE);
52
+ if (dinfo) {
53
+ warn_report("using \"-drive if=none\" for the OTP is deprecated, "
54
+ "use \"-drive if=pflash\" instead.");
55
+ }
56
+ }
57
if (dinfo) {
58
int ret;
59
uint64_t perm;
60
--
73
--
61
2.31.1
74
2.27.0
62
75
63
76
diff view generated by jsdifflib