1
The following changes since commit c95bd5ff1660883d15ad6e0005e4c8571604f51a:
1
The following changes since commit 83851c7c60c90e9fb6a23ff48076387a77bc33cd:
2
2
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-fixes-20210322' into staging (2021-03-22 14:26:13 +0000)
3
Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2020-10-27-v3-tag' into staging (2020-11-03 12:47:58 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210322-2
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20201103
8
8
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
9
for you to fetch changes up to 422819776101520cb56658ee5facf926526cf870:
10
10
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
11
target/riscv/csr.c : add space before the open parenthesis '(' (2020-11-03 07:17:23 -0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 6.0
14
This series adds support for migration to RISC-V QEMU and expands the
15
15
Microchip PFSoC to allow unmodified HSS and Linux boots.
16
This PR includes:
17
- Fix for vector CSR access
18
- Improvements to the Ibex UART device
19
- PMP improvements and bug fixes
20
- Hypervisor extension bug fixes
21
- ramfb support for the virt machine
22
- Fast read support for SST flash
23
- Improvements to the microchip_pfsoc machine
24
16
25
----------------------------------------------------------------
17
----------------------------------------------------------------
26
Alexander Wagner (1):
18
Anup Patel (2):
27
hw/char: disable ibex uart receive if the buffer is full
19
hw/riscv: sifive_u: Allow passing custom DTB
20
hw/riscv: virt: Allow passing custom DTB
28
21
29
Asherah Connor (2):
22
Bin Meng (10):
30
hw/riscv: Add fw_cfg support to virt
23
hw/riscv: microchip_pfsoc: Document where to look at the SoC memory maps
31
hw/riscv: allow ramfb on virt
24
hw/misc: Add Microchip PolarFire SoC DDR Memory Controller support
25
hw/riscv: microchip_pfsoc: Connect DDR memory controller modules
26
hw/misc: Add Microchip PolarFire SoC IOSCB module support
27
hw/riscv: microchip_pfsoc: Connect the IOSCB module
28
hw/misc: Add Microchip PolarFire SoC SYSREG module support
29
hw/riscv: microchip_pfsoc: Connect the SYSREG module
30
hw/riscv: microchip_pfsoc: Map the reserved memory at address 0
31
hw/riscv: microchip_pfsoc: Correct DDR memory map
32
hw/riscv: microchip_pfsoc: Hook the I2C1 controller
32
33
33
Bin Meng (3):
34
Xinhao Zhang (1):
34
hw/block: m25p80: Support fast read for SST flashes
35
target/riscv/csr.c : add space before the open parenthesis '('
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
37
36
38
Frank Chang (1):
37
Yifei Jiang (6):
39
target/riscv: fix vs() to return proper error code
38
target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
39
target/riscv: Add basic vmstate description of CPU
40
target/riscv: Add PMP state description
41
target/riscv: Add H extension state description
42
target/riscv: Add V extension state description
43
target/riscv: Add sifive_plic vmstate
40
44
41
Georg Kotheimer (6):
45
include/hw/intc/sifive_plic.h | 1 +
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
46
include/hw/misc/mchp_pfsoc_dmc.h | 56 +++++++++
43
target/riscv: Make VSTIP and VSEIP read-only in hip
47
include/hw/misc/mchp_pfsoc_ioscb.h | 50 ++++++++
44
target/riscv: Use background registers also for MSTATUS_MPV
48
include/hw/misc/mchp_pfsoc_sysreg.h | 39 ++++++
45
target/riscv: Fix read and write accesses to vsip and vsie
49
include/hw/riscv/microchip_pfsoc.h | 18 ++-
46
target/riscv: Add proper two-stage lookup exception detection
50
target/riscv/cpu.h | 24 ++--
47
target/riscv: Prevent lost illegal instruction exceptions
51
target/riscv/cpu_bits.h | 19 +--
52
target/riscv/internals.h | 4 +
53
target/riscv/pmp.h | 2 +
54
hw/intc/sifive_plic.c | 26 +++-
55
hw/misc/mchp_pfsoc_dmc.c | 216 ++++++++++++++++++++++++++++++++
56
hw/misc/mchp_pfsoc_ioscb.c | 242 ++++++++++++++++++++++++++++++++++++
57
hw/misc/mchp_pfsoc_sysreg.c | 99 +++++++++++++++
58
hw/riscv/microchip_pfsoc.c | 125 ++++++++++++++++---
59
hw/riscv/sifive_u.c | 28 +++--
60
hw/riscv/virt.c | 27 ++--
61
target/riscv/cpu.c | 16 +--
62
target/riscv/cpu_helper.c | 35 ++----
63
target/riscv/csr.c | 20 +--
64
target/riscv/machine.c | 196 +++++++++++++++++++++++++++++
65
target/riscv/op_helper.c | 11 +-
66
target/riscv/pmp.c | 29 +++--
67
MAINTAINERS | 6 +
68
hw/misc/Kconfig | 9 ++
69
hw/misc/meson.build | 3 +
70
hw/riscv/Kconfig | 3 +
71
target/riscv/meson.build | 3 +-
72
27 files changed, 1180 insertions(+), 127 deletions(-)
73
create mode 100644 include/hw/misc/mchp_pfsoc_dmc.h
74
create mode 100644 include/hw/misc/mchp_pfsoc_ioscb.h
75
create mode 100644 include/hw/misc/mchp_pfsoc_sysreg.h
76
create mode 100644 hw/misc/mchp_pfsoc_dmc.c
77
create mode 100644 hw/misc/mchp_pfsoc_ioscb.c
78
create mode 100644 hw/misc/mchp_pfsoc_sysreg.c
79
create mode 100644 target/riscv/machine.c
48
80
49
Jim Shu (3):
50
target/riscv: propagate PMP permission to TLB page
51
target/riscv: add log of PMP permission checking
52
target/riscv: flush TLB pages if PMP permission has been changed
53
54
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++
55
docs/system/target-riscv.rst | 1 +
56
include/hw/char/ibex_uart.h | 4 +
57
include/hw/riscv/microchip_pfsoc.h | 1 +
58
include/hw/riscv/virt.h | 2 +
59
target/riscv/cpu.h | 4 +
60
target/riscv/pmp.h | 4 +-
61
hw/block/m25p80.c | 3 +
62
hw/char/ibex_uart.c | 23 +++-
63
hw/riscv/microchip_pfsoc.c | 6 +
64
hw/riscv/virt.c | 33 ++++++
65
target/riscv/cpu.c | 1 +
66
target/riscv/cpu_helper.c | 144 +++++++++++++++--------
67
target/riscv/csr.c | 77 +++++++------
68
target/riscv/pmp.c | 84 ++++++++++----
69
target/riscv/translate.c | 179 +----------------------------
70
hw/riscv/Kconfig | 1 +
71
17 files changed, 367 insertions(+), 289 deletions(-)
72
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
73
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Anup Patel <anup.patel@wdc.com>
2
2
3
According to the specification the "field SPVP of hstatus controls the
3
Extend sifive_u machine to allow passing custom DTB using "-dtb"
4
privilege level of the access" for the hypervisor virtual-machine load
4
command-line parameter. This will help users pass modified DTB
5
and store instructions HLV, HLVX and HSV.
5
or Linux SiFive DTB to sifive_u machine.
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
9
Message-id: 20201022053225.2596110-1-anup.patel@wdc.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
12
hw/riscv/sifive_u.c | 28 ++++++++++++++++++++--------
13
1 file changed, 14 insertions(+), 11 deletions(-)
13
1 file changed, 20 insertions(+), 8 deletions(-)
14
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
17
--- a/hw/riscv/sifive_u.c
18
+++ b/target/riscv/cpu_helper.c
18
+++ b/hw/riscv/sifive_u.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
20
use_background = true;
20
int cpu;
21
uint32_t *cells;
22
char *nodename;
23
+ const char *dtb_filename;
24
char ethclk_names[] = "pclk\0hclk";
25
uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
26
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
27
28
- fdt = s->fdt = create_device_tree(&s->fdt_size);
29
- if (!fdt) {
30
- error_report("create_device_tree() failed");
31
- exit(1);
32
+ dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
33
+ if (dtb_filename) {
34
+ fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
35
+ if (!fdt) {
36
+ error_report("load_device_tree() failed");
37
+ exit(1);
38
+ }
39
+ goto update_bootargs;
40
+ } else {
41
+ fdt = s->fdt = create_device_tree(&s->fdt_size);
42
+ if (!fdt) {
43
+ error_report("create_device_tree() failed");
44
+ exit(1);
45
+ }
21
}
46
}
22
47
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
48
qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
24
+ /* MPRV does not affect the virtual-machine load/store
49
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
25
+ instructions, HLV, HLVX, and HSV. */
50
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
51
qemu_fdt_add_subnode(fdt, "/chosen");
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
52
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
53
- if (cmdline) {
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
54
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
30
mode = get_field(env->mstatus, MSTATUS_MPP);
31
}
32
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
33
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
34
__func__, address, access_type, mmu_idx);
35
36
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
37
- if (get_field(env->mstatus, MSTATUS_MPRV)) {
38
- mode = get_field(env->mstatus, MSTATUS_MPP);
39
+ /* MPRV does not affect the virtual-machine load/store
40
+ instructions, HLV, HLVX, and HSV. */
41
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
42
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
43
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
44
+ get_field(env->mstatus, MSTATUS_MPRV)) {
45
+ mode = get_field(env->mstatus, MSTATUS_MPP);
46
+ if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) {
47
+ two_stage_lookup = true;
48
}
49
}
50
51
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
52
- access_type != MMU_INST_FETCH &&
53
- get_field(env->mstatus, MSTATUS_MPRV) &&
54
- get_field(env->mstatus, MSTATUS_MPV)) {
55
- two_stage_lookup = true;
56
- }
55
- }
57
-
56
-
58
if (riscv_cpu_virt_enabled(env) ||
57
qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
58
60
access_type != MMU_INST_FETCH)) {
59
g_free(nodename);
60
+
61
+update_bootargs:
62
+ if (cmdline) {
63
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
64
+ }
65
}
66
67
static void sifive_u_machine_reset(void *opaque, int n, int level)
61
--
68
--
62
2.30.1
69
2.28.0
63
70
64
71
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Anup Patel <anup.patel@wdc.com>
2
2
3
Allow ramfb on virt. This lets `-device ramfb' work.
3
Extend virt machine to allow passing custom DTB using "-dtb"
4
command-line parameter. This will help users pass modified DTB
5
to virt machine.
4
6
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
9
Message-id: 20201022053225.2596110-2-anup.patel@wdc.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
hw/riscv/virt.c | 3 +++
12
hw/riscv/virt.c | 27 ++++++++++++++++++++-------
12
1 file changed, 3 insertions(+)
13
1 file changed, 20 insertions(+), 7 deletions(-)
13
14
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
17
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
18
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
19
#include "sysemu/sysemu.h"
20
{
20
#include "hw/pci/pci.h"
21
void *fdt;
21
#include "hw/pci-host/gpex.h"
22
int i, cpu, socket;
22
+#include "hw/display/ramfb.h"
23
+ const char *dtb_filename;
23
24
MachineState *mc = MACHINE(s);
24
static const MemMapEntry virt_memmap[] = {
25
uint64_t addr, size;
25
[VIRT_DEBUG] = { 0x0, 0x100 },
26
uint32_t *clint_cells, *plic_cells;
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
27
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
28
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
29
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
29
mc->numa_mem_supported = true;
30
31
- fdt = s->fdt = create_device_tree(&s->fdt_size);
32
- if (!fdt) {
33
- error_report("create_device_tree() failed");
34
- exit(1);
35
+ dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
36
+ if (dtb_filename) {
37
+ fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
38
+ if (!fdt) {
39
+ error_report("load_device_tree() failed");
40
+ exit(1);
41
+ }
42
+ goto update_bootargs;
43
+ } else {
44
+ fdt = s->fdt = create_device_tree(&s->fdt_size);
45
+ if (!fdt) {
46
+ error_report("create_device_tree() failed");
47
+ exit(1);
48
+ }
49
}
50
51
qemu_fdt_setprop_string(fdt, "/", "model", "riscv-virtio,qemu");
52
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
53
54
qemu_fdt_add_subnode(fdt, "/chosen");
55
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name);
56
- if (cmdline) {
57
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
58
- }
59
g_free(name);
60
61
name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base);
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
63
2, flashbase + flashsize, 2, flashsize);
64
qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4);
65
g_free(name);
30
+
66
+
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
67
+update_bootargs:
68
+ if (cmdline) {
69
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
70
+ }
32
}
71
}
33
72
34
static const TypeInfo virt_machine_typeinfo = {
73
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
35
--
74
--
36
2.30.1
75
2.28.0
37
76
38
77
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
4
short of its purpose, as all it checks is whether two-stage address
4
This patch expands mstatus and vsstatus to uint64_t instead of
5
translation either via the hypervisor-load store instructions or the
5
target_ulong so that it can be saved as one unit and reduce some
6
MPRV feature would be allowed.
6
ifdefs in the code.
7
7
8
What we really need instead is whether two-stage address translation was
8
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
9
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
10
we do not have the information to reliably detect this. Therefore, when
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
we raise a memory fault exception we have to record whether two-stage
12
address translation is active.
13
14
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
12
Message-id: 20201026115530.304-2-jiangyifei@huawei.com
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
13
---
19
target/riscv/cpu.h | 4 ++++
14
target/riscv/cpu.h | 24 +++++++++++-------------
20
target/riscv/cpu.c | 1 +
15
target/riscv/cpu_bits.h | 19 ++++---------------
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
16
target/riscv/cpu.c | 8 +++++---
22
3 files changed, 13 insertions(+), 13 deletions(-)
17
target/riscv/cpu_helper.c | 35 +++++++----------------------------
18
target/riscv/csr.c | 18 ++++++++++--------
19
target/riscv/op_helper.c | 11 ++++-------
20
6 files changed, 41 insertions(+), 74 deletions(-)
23
21
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
24
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
26
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
27
target_ulong resetvec;
28
29
target_ulong mhartid;
30
- target_ulong mstatus;
31
+ /*
32
+ * For RV32 this is 32-bit mstatus and 32-bit mstatush.
33
+ * For RV64 this is a 64-bit mstatus.
34
+ */
35
+ uint64_t mstatus;
36
37
target_ulong mip;
38
39
-#ifdef TARGET_RISCV32
40
- target_ulong mstatush;
41
-#endif
42
-
43
uint32_t miclaim;
44
45
target_ulong mie;
46
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
47
uint64_t htimedelta;
48
49
/* Virtual CSRs */
50
- target_ulong vsstatus;
51
+ /*
52
+ * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
53
+ * For RV64 this is a 64-bit vsstatus.
54
+ */
55
+ uint64_t vsstatus;
56
target_ulong vstvec;
57
target_ulong vsscratch;
58
target_ulong vsepc;
59
target_ulong vscause;
60
target_ulong vstval;
61
target_ulong vsatp;
62
-#ifdef TARGET_RISCV32
63
- target_ulong vsstatush;
64
-#endif
65
66
target_ulong mtval2;
67
target_ulong mtinst;
68
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
69
target_ulong scause_hs;
70
target_ulong stval_hs;
29
target_ulong satp_hs;
71
target_ulong satp_hs;
30
uint64_t mstatus_hs;
72
- target_ulong mstatus_hs;
31
73
-#ifdef TARGET_RISCV32
32
+ /* Signals whether the current exception occurred with two-stage address
74
- target_ulong mstatush_hs;
33
+ translation active. */
75
-#endif
34
+ bool two_stage_lookup;
76
+ uint64_t mstatus_hs;
35
+
77
36
target_ulong scounteren;
78
target_ulong scounteren;
37
target_ulong mcounteren;
79
target_ulong mcounteren;
38
80
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/riscv/cpu_bits.h
83
+++ b/target/riscv/cpu_bits.h
84
@@ -XXX,XX +XXX,XX @@
85
#define TARGET_RISCV_CPU_BITS_H
86
87
#define get_field(reg, mask) (((reg) & \
88
- (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
89
-#define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
90
- (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
91
- (target_ulong)(mask)))
92
+ (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
93
+#define set_field(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
94
+ (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
95
+ (uint64_t)(mask)))
96
97
/* Floating point round mode */
98
#define FSR_RD_SHIFT 5
99
@@ -XXX,XX +XXX,XX @@
100
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
101
#define MSTATUS_TW 0x20000000 /* since: priv-1.10 */
102
#define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */
103
-#if defined(TARGET_RISCV64)
104
#define MSTATUS_GVA 0x4000000000ULL
105
#define MSTATUS_MPV 0x8000000000ULL
106
-#elif defined(TARGET_RISCV32)
107
-#define MSTATUS_GVA 0x00000040
108
-#define MSTATUS_MPV 0x00000080
109
-#endif
110
-
111
-#ifdef TARGET_RISCV32
112
-# define MSTATUS_MPV_ISSET(env) get_field(env->mstatush, MSTATUS_MPV)
113
-#else
114
-# define MSTATUS_MPV_ISSET(env) get_field(env->mstatus, MSTATUS_MPV)
115
-#endif
116
117
#define MSTATUS64_UXL 0x0000000300000000ULL
118
#define MSTATUS64_SXL 0x0000000C00000000ULL
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
119
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
121
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
122
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
123
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
124
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
45
env->mcause = 0;
125
#ifndef CONFIG_USER_ONLY
46
env->pc = env->resetvec;
126
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
47
+ env->two_stage_lookup = false;
127
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
128
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
129
#ifdef TARGET_RISCV32
130
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
131
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
132
+ (target_ulong)(env->mstatus >> 32));
48
#endif
133
#endif
49
cs->exception_index = EXCP_NONE;
134
if (riscv_has_ext(env, RVH)) {
50
env->load_res = -1;
135
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
136
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
137
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
138
+ (target_ulong)env->vsstatus);
139
}
140
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ", env->mip);
141
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
142
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
52
index XXXXXXX..XXXXXXX 100644
143
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
144
--- a/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
145
+++ b/target/riscv/cpu_helper.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
146
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
56
g_assert_not_reached();
147
57
}
148
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
58
env->badaddr = address;
149
{
59
+ env->two_stage_lookup = two_stage;
150
- target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
151
- MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
152
+ uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
153
+ MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
154
+ MSTATUS64_UXL;
155
bool current_virt = riscv_cpu_virt_enabled(env);
156
157
g_assert(riscv_has_ext(env, RVH));
158
159
-#if defined(TARGET_RISCV64)
160
- mstatus_mask |= MSTATUS64_UXL;
161
-#endif
162
-
163
if (current_virt) {
164
/* Current V=1 and we are about to change to V=0 */
165
env->vsstatus = env->mstatus & mstatus_mask;
166
env->mstatus &= ~mstatus_mask;
167
env->mstatus |= env->mstatus_hs;
168
169
-#if defined(TARGET_RISCV32)
170
- env->vsstatush = env->mstatush;
171
- env->mstatush |= env->mstatush_hs;
172
-#endif
173
-
174
env->vstvec = env->stvec;
175
env->stvec = env->stvec_hs;
176
177
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
178
env->mstatus &= ~mstatus_mask;
179
env->mstatus |= env->vsstatus;
180
181
-#if defined(TARGET_RISCV32)
182
- env->mstatush_hs = env->mstatush;
183
- env->mstatush |= env->vsstatush;
184
-#endif
185
-
186
env->stvec_hs = env->stvec;
187
env->stvec = env->vstvec;
188
189
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
190
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
191
access_type != MMU_INST_FETCH &&
192
get_field(env->mstatus, MSTATUS_MPRV) &&
193
- MSTATUS_MPV_ISSET(env)) {
194
+ get_field(env->mstatus, MSTATUS_MPV)) {
195
riscv_cpu_set_two_stage_lookup(env, true);
196
}
197
198
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
199
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
200
access_type != MMU_INST_FETCH &&
201
get_field(env->mstatus, MSTATUS_MPRV) &&
202
- MSTATUS_MPV_ISSET(env)) {
203
+ get_field(env->mstatus, MSTATUS_MPV)) {
204
riscv_cpu_set_two_stage_lookup(env, false);
205
}
206
207
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
208
RISCVCPU *cpu = RISCV_CPU(cs);
209
CPURISCVState *env = &cpu->env;
210
bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
211
- target_ulong s;
212
+ uint64_t s;
213
214
/* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
215
* so we mask off the MSB and separate into trap type and cause.
216
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
217
if (riscv_cpu_virt_enabled(env)) {
218
riscv_cpu_swap_hypervisor_regs(env);
219
}
220
-#ifdef TARGET_RISCV32
221
- env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
222
- riscv_cpu_virt_enabled(env));
223
- if (riscv_cpu_virt_enabled(env) && tval) {
224
- env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
225
- }
226
-#else
227
env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
228
- riscv_cpu_virt_enabled(env));
229
+ riscv_cpu_virt_enabled(env));
230
if (riscv_cpu_virt_enabled(env) && tval) {
231
env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
232
}
233
-#endif
234
235
mtval2 = env->guest_phys_fault_addr;
236
237
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/target/riscv/csr.c
240
+++ b/target/riscv/csr.c
241
@@ -XXX,XX +XXX,XX @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
242
243
static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
244
{
245
- target_ulong mstatus = env->mstatus;
246
- target_ulong mask = 0;
247
+ uint64_t mstatus = env->mstatus;
248
+ uint64_t mask = 0;
249
int dirty;
250
251
/* flush tlb on mstatus fields that affect VM */
252
@@ -XXX,XX +XXX,XX @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
253
#ifdef TARGET_RISCV32
254
static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
255
{
256
- *val = env->mstatush;
257
+ *val = env->mstatus >> 32;
258
return 0;
60
}
259
}
61
260
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
261
static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
262
{
64
}
263
- if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
65
264
+ uint64_t valh = (uint64_t)val << 32;
66
env->badaddr = addr;
265
+ uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
266
+
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
267
+ if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
268
tlb_flush(env_cpu(env));
269
}
270
271
- val &= MSTATUS_MPV | MSTATUS_GVA;
272
-
273
- env->mstatush = val;
274
+ env->mstatus = (env->mstatus & ~mask) | (valh & mask);
275
276
return 0;
70
}
277
}
71
278
@@ -XXX,XX +XXX,XX @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
279
73
g_assert_not_reached();
280
static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
74
}
281
{
75
env->badaddr = addr;
282
- env->vsstatus = val;
76
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
283
+ uint64_t mask = (target_ulong)-1;
77
+ riscv_cpu_two_stage_lookup(mmu_idx);
284
+ env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
78
riscv_raise_exception(env, cs->exception_index, retaddr);
285
return 0;
79
}
286
}
80
#endif /* !CONFIG_USER_ONLY */
287
81
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
288
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
82
/* handle the trap in S-mode */
289
index XXXXXXX..XXXXXXX 100644
83
if (riscv_has_ext(env, RVH)) {
290
--- a/target/riscv/op_helper.c
84
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
291
+++ b/target/riscv/op_helper.c
85
- bool two_stage_lookup = false;
292
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
86
293
87
- if (env->priv == PRV_M ||
294
target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
88
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
295
{
89
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
296
- target_ulong prev_priv, prev_virt, mstatus;
90
- get_field(env->hstatus, HSTATUS_HU))) {
297
+ uint64_t mstatus;
91
- two_stage_lookup = true;
298
+ target_ulong prev_priv, prev_virt;
92
- }
299
93
-
300
if (!(env->priv >= PRV_S)) {
94
- if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
301
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
95
+ if (env->two_stage_lookup && write_tval) {
302
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
96
/*
303
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
97
* If we are writing a guest virtual address to stval, set
304
}
98
* this to 1. If we are trapping to VS we will set this to 0
305
99
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
306
- target_ulong mstatus = env->mstatus;
100
riscv_cpu_set_force_hs_excep(env, 0);
307
+ uint64_t mstatus = env->mstatus;
101
} else {
308
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
102
/* Trap into HS mode */
309
- target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
103
- if (!two_stage_lookup) {
310
+ target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
104
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
311
mstatus = set_field(mstatus, MSTATUS_MIE,
105
- riscv_cpu_virt_enabled(env));
312
get_field(mstatus, MSTATUS_MPIE));
106
- }
313
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
107
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
314
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
108
htval = env->guest_phys_fault_addr;
315
-#ifdef TARGET_RISCV32
109
}
316
- env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
110
}
317
-#else
111
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
318
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
112
* RISC-V ISA Specification.
319
-#endif
113
*/
320
env->mstatus = mstatus;
114
321
riscv_cpu_set_mode(env, prev_priv);
115
+ env->two_stage_lookup = false;
322
116
#endif
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
118
}
119
--
323
--
120
2.30.1
324
2.28.0
121
325
122
326
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
3
Add basic CPU state description to the newly created machine.c
4
5
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
8
Message-id: 20201026115530.304-3-jiangyifei@huawei.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
10
---
8
target/riscv/csr.c | 7 ++++---
11
target/riscv/internals.h | 4 +++
9
1 file changed, 4 insertions(+), 3 deletions(-)
12
target/riscv/cpu.c | 8 +----
13
target/riscv/machine.c | 74 ++++++++++++++++++++++++++++++++++++++++
14
target/riscv/meson.build | 3 +-
15
4 files changed, 81 insertions(+), 8 deletions(-)
16
create mode 100644 target/riscv/machine.c
10
17
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
18
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
20
--- a/target/riscv/internals.h
14
+++ b/target/riscv/csr.c
21
+++ b/target/riscv/internals.h
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
22
@@ -XXX,XX +XXX,XX @@ target_ulong fclass_d(uint64_t frs1);
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
23
#define SEW32 2
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
24
#define SEW64 3
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
25
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
26
+#ifndef CONFIG_USER_ONLY
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
27
+extern const VMStateDescription vmstate_riscv_cpu;
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
28
+#endif
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
29
+
23
30
static inline uint64_t nanbox_s(float32 f)
24
static const char valid_vm_1_10_32[16] = {
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
26
target_ulong new_value, target_ulong write_mask)
27
{
31
{
28
int ret = rmw_mip(env, 0, ret_value, new_value,
32
return f | MAKE_64BIT_MASK(32, 32);
29
- write_mask & hip_writable_mask);
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
+ write_mask & hvip_writable_mask);
34
index XXXXXXX..XXXXXXX 100644
31
35
--- a/target/riscv/cpu.c
32
- *ret_value &= hip_writable_mask;
36
+++ b/target/riscv/cpu.c
33
+ *ret_value &= hvip_writable_mask;
37
@@ -XXX,XX +XXX,XX @@
34
38
#include "qemu/ctype.h"
35
return ret;
39
#include "qemu/log.h"
40
#include "cpu.h"
41
+#include "internals.h"
42
#include "exec/exec-all.h"
43
#include "qapi/error.h"
44
#include "qemu/error-report.h"
45
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj)
46
cpu_set_cpustate_pointers(cpu);
36
}
47
}
48
49
-#ifndef CONFIG_USER_ONLY
50
-static const VMStateDescription vmstate_riscv_cpu = {
51
- .name = "cpu",
52
- .unmigratable = 1,
53
-};
54
-#endif
55
-
56
static Property riscv_cpu_properties[] = {
57
DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
58
DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
59
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/target/riscv/machine.c
64
@@ -XXX,XX +XXX,XX @@
65
+/*
66
+ * RISC-V VMState Description
67
+ *
68
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
69
+ *
70
+ * This program is free software; you can redistribute it and/or modify it
71
+ * under the terms and conditions of the GNU General Public License,
72
+ * version 2 or later, as published by the Free Software Foundation.
73
+ *
74
+ * This program is distributed in the hope it will be useful, but WITHOUT
75
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
76
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
77
+ * more details.
78
+ *
79
+ * You should have received a copy of the GNU General Public License along with
80
+ * this program. If not, see <http://www.gnu.org/licenses/>.
81
+ */
82
+
83
+#include "qemu/osdep.h"
84
+#include "cpu.h"
85
+#include "qemu/error-report.h"
86
+#include "sysemu/kvm.h"
87
+#include "migration/cpu.h"
88
+
89
+const VMStateDescription vmstate_riscv_cpu = {
90
+ .name = "cpu",
91
+ .version_id = 1,
92
+ .minimum_version_id = 1,
93
+ .fields = (VMStateField[]) {
94
+ VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
95
+ VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
96
+ VMSTATE_UINTTL(env.pc, RISCVCPU),
97
+ VMSTATE_UINTTL(env.load_res, RISCVCPU),
98
+ VMSTATE_UINTTL(env.load_val, RISCVCPU),
99
+ VMSTATE_UINTTL(env.frm, RISCVCPU),
100
+ VMSTATE_UINTTL(env.badaddr, RISCVCPU),
101
+ VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
102
+ VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
103
+ VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
104
+ VMSTATE_UINTTL(env.misa, RISCVCPU),
105
+ VMSTATE_UINTTL(env.misa_mask, RISCVCPU),
106
+ VMSTATE_UINT32(env.features, RISCVCPU),
107
+ VMSTATE_UINTTL(env.priv, RISCVCPU),
108
+ VMSTATE_UINTTL(env.virt, RISCVCPU),
109
+ VMSTATE_UINTTL(env.resetvec, RISCVCPU),
110
+ VMSTATE_UINTTL(env.mhartid, RISCVCPU),
111
+ VMSTATE_UINT64(env.mstatus, RISCVCPU),
112
+ VMSTATE_UINTTL(env.mip, RISCVCPU),
113
+ VMSTATE_UINT32(env.miclaim, RISCVCPU),
114
+ VMSTATE_UINTTL(env.mie, RISCVCPU),
115
+ VMSTATE_UINTTL(env.mideleg, RISCVCPU),
116
+ VMSTATE_UINTTL(env.sptbr, RISCVCPU),
117
+ VMSTATE_UINTTL(env.satp, RISCVCPU),
118
+ VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
119
+ VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
120
+ VMSTATE_UINTTL(env.medeleg, RISCVCPU),
121
+ VMSTATE_UINTTL(env.stvec, RISCVCPU),
122
+ VMSTATE_UINTTL(env.sepc, RISCVCPU),
123
+ VMSTATE_UINTTL(env.scause, RISCVCPU),
124
+ VMSTATE_UINTTL(env.mtvec, RISCVCPU),
125
+ VMSTATE_UINTTL(env.mepc, RISCVCPU),
126
+ VMSTATE_UINTTL(env.mcause, RISCVCPU),
127
+ VMSTATE_UINTTL(env.mtval, RISCVCPU),
128
+ VMSTATE_UINTTL(env.scounteren, RISCVCPU),
129
+ VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
130
+ VMSTATE_UINTTL(env.sscratch, RISCVCPU),
131
+ VMSTATE_UINTTL(env.mscratch, RISCVCPU),
132
+ VMSTATE_UINT64(env.mfromhost, RISCVCPU),
133
+ VMSTATE_UINT64(env.mtohost, RISCVCPU),
134
+ VMSTATE_UINT64(env.timecmp, RISCVCPU),
135
+
136
+ VMSTATE_END_OF_LIST()
137
+ }
138
+};
139
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/riscv/meson.build
142
+++ b/target/riscv/meson.build
143
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
144
riscv_softmmu_ss = ss.source_set()
145
riscv_softmmu_ss.add(files(
146
'pmp.c',
147
- 'monitor.c'
148
+ 'monitor.c',
149
+ 'machine.c'
150
))
151
152
target_arch += {'riscv': riscv_ss}
37
--
153
--
38
2.30.1
154
2.28.0
39
155
40
156
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
3
In the case of supporting PMP feature, add PMP state description
4
Fix it by propagating PMP permission to TLB page permission.
4
to vmstate_riscv_cpu.
5
5
6
PMP permission checking also use MMU-style API to change TLB permission
6
'vmstate_pmp_addr' and 'num_rules' could be regenerated by
7
and size.
7
pmp_update_rule(). But there exists the problem of updating
8
num_rules repeatedly in pmp_update_rule(). So here extracts
9
pmp_update_rule_addr() and pmp_update_rule_nums() to update
10
'vmstate_pmp_addr' and 'num_rules' respectively.
8
11
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
12
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
13
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
15
Message-id: 20201026115530.304-4-jiangyifei@huawei.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
17
---
14
target/riscv/pmp.h | 4 +-
18
target/riscv/pmp.h | 2 ++
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
19
target/riscv/machine.c | 50 ++++++++++++++++++++++++++++++++++++++++++
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
20
target/riscv/pmp.c | 29 ++++++++++++++----------
17
3 files changed, 125 insertions(+), 43 deletions(-)
21
3 files changed, 70 insertions(+), 11 deletions(-)
18
22
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
23
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
20
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
25
--- a/target/riscv/pmp.h
22
+++ b/target/riscv/pmp.h
26
+++ b/target/riscv/pmp.h
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
27
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
24
target_ulong val);
28
target_ulong size, pmp_priv_t priv, target_ulong mode);
25
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
26
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
27
- target_ulong size, pmp_priv_t priv, target_ulong mode);
28
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
29
+ target_ulong mode);
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
29
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
31
target_ulong *tlb_size);
30
target_ulong *tlb_size);
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
31
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
33
void pmp_update_rule_nums(CPURISCVState *env);
32
+void pmp_update_rule_nums(CPURISCVState *env);
34
uint32_t pmp_get_num_rules(CPURISCVState *env);
35
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
36
33
37
#endif
34
#endif
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
35
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
39
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/machine.c
41
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/machine.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
39
@@ -XXX,XX +XXX,XX @@
43
env->load_res = -1;
40
#include "sysemu/kvm.h"
44
}
41
#include "migration/cpu.h"
45
42
46
+/*
43
+static bool pmp_needed(void *opaque)
47
+ * get_physical_address_pmp - check PMP permission for this physical address
48
+ *
49
+ * Match the PMP region and check permission for this physical address and it's
50
+ * TLB page. Returns 0 if the permission checking was successful
51
+ *
52
+ * @env: CPURISCVState
53
+ * @prot: The returned protection attributes
54
+ * @tlb_size: TLB page size containing addr. It could be modified after PMP
55
+ * permission checking. NULL if not set TLB page for addr.
56
+ * @addr: The physical address to be checked permission
57
+ * @access_type: The type of MMU access
58
+ * @mode: Indicates current privilege level.
59
+ */
60
+static int get_physical_address_pmp(CPURISCVState *env, int *prot,
61
+ target_ulong *tlb_size, hwaddr addr,
62
+ int size, MMUAccessType access_type,
63
+ int mode)
64
+{
44
+{
65
+ pmp_priv_t pmp_priv;
45
+ RISCVCPU *cpu = opaque;
66
+ target_ulong tlb_size_pmp = 0;
46
+ CPURISCVState *env = &cpu->env;
67
+
47
+
68
+ if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
48
+ return riscv_feature(env, RISCV_FEATURE_PMP);
69
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
70
+ return TRANSLATE_SUCCESS;
71
+ }
72
+
73
+ if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
74
+ mode)) {
75
+ *prot = 0;
76
+ return TRANSLATE_PMP_FAIL;
77
+ }
78
+
79
+ *prot = pmp_priv_to_page_prot(pmp_priv);
80
+ if (tlb_size != NULL) {
81
+ if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
82
+ *tlb_size = tlb_size_pmp;
83
+ }
84
+ }
85
+
86
+ return TRANSLATE_SUCCESS;
87
+}
49
+}
88
+
50
+
89
/* get_physical_address - get the physical address for this virtual address
51
+static int pmp_post_load(void *opaque, int version_id)
90
*
52
+{
91
* Do a page table walk to obtain the physical address corresponding to a
53
+ RISCVCPU *cpu = opaque;
92
@@ -XXX,XX +XXX,XX @@ restart:
54
+ CPURISCVState *env = &cpu->env;
93
pte_addr = base + idx * ptesize;
55
+ int i;
94
}
56
+
95
57
+ for (i = 0; i < MAX_RISCV_PMPS; i++) {
96
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
58
+ pmp_update_rule_addr(env, i);
97
- !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
59
+ }
98
- 1 << MMU_DATA_LOAD, PRV_S)) {
60
+ pmp_update_rule_nums(env);
99
+ int pmp_prot;
61
+
100
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
62
+ return 0;
101
+ sizeof(target_ulong),
63
+}
102
+ MMU_DATA_LOAD, PRV_S);
64
+
103
+ if (pmp_ret != TRANSLATE_SUCCESS) {
65
+static const VMStateDescription vmstate_pmp_entry = {
104
return TRANSLATE_PMP_FAIL;
66
+ .name = "cpu/pmp/entry",
105
}
67
+ .version_id = 1,
106
68
+ .minimum_version_id = 1,
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
69
+ .fields = (VMStateField[]) {
108
#ifndef CONFIG_USER_ONLY
70
+ VMSTATE_UINTTL(addr_reg, pmp_entry_t),
109
vaddr im_address;
71
+ VMSTATE_UINT8(cfg_reg, pmp_entry_t),
110
hwaddr pa = 0;
72
+ VMSTATE_END_OF_LIST()
111
- int prot, prot2;
73
+ }
112
+ int prot, prot2, prot_pmp;
74
+};
113
bool pmp_violation = false;
75
+
114
bool first_stage_error = true;
76
+static const VMStateDescription vmstate_pmp = {
115
bool two_stage_lookup = false;
77
+ .name = "cpu/pmp",
116
int ret = TRANSLATE_FAIL;
78
+ .version_id = 1,
117
int mode = mmu_idx;
79
+ .minimum_version_id = 1,
118
- target_ulong tlb_size = 0;
80
+ .needed = pmp_needed,
119
+ /* default TLB page size */
81
+ .post_load = pmp_post_load,
120
+ target_ulong tlb_size = TARGET_PAGE_SIZE;
82
+ .fields = (VMStateField[]) {
121
83
+ VMSTATE_STRUCT_ARRAY(env.pmp_state.pmp, RISCVCPU, MAX_RISCV_PMPS,
122
env->guest_phys_fault_addr = 0;
84
+ 0, vmstate_pmp_entry, pmp_entry_t),
123
85
+ VMSTATE_END_OF_LIST()
124
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
86
+ }
125
87
+};
126
prot &= prot2;
88
+
127
89
const VMStateDescription vmstate_riscv_cpu = {
128
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
90
.name = "cpu",
129
- (ret == TRANSLATE_SUCCESS) &&
91
.version_id = 1,
130
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
92
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
131
- ret = TRANSLATE_PMP_FAIL;
93
VMSTATE_UINT64(env.timecmp, RISCVCPU),
132
+ if (ret == TRANSLATE_SUCCESS) {
94
133
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
95
VMSTATE_END_OF_LIST()
134
+ size, access_type, mode);
96
+ },
135
+ prot &= prot_pmp;
97
+ .subsections = (const VMStateDescription * []) {
136
}
98
+ &vmstate_pmp,
137
99
+ NULL
138
if (ret != TRANSLATE_SUCCESS) {
139
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
140
"%s address=%" VADDR_PRIx " ret %d physical "
141
TARGET_FMT_plx " prot %d\n",
142
__func__, address, ret, pa, prot);
143
- }
144
145
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
146
- (ret == TRANSLATE_SUCCESS) &&
147
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
148
- ret = TRANSLATE_PMP_FAIL;
149
+ if (ret == TRANSLATE_SUCCESS) {
150
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
151
+ size, access_type, mode);
152
+ prot &= prot_pmp;
153
+ }
154
}
100
}
155
+
101
};
156
if (ret == TRANSLATE_PMP_FAIL) {
157
pmp_violation = true;
158
}
159
160
if (ret == TRANSLATE_SUCCESS) {
161
- if (pmp_is_range_in_tlb(env, pa & TARGET_PAGE_MASK, &tlb_size)) {
162
- tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
163
- prot, mmu_idx, tlb_size);
164
- } else {
165
- tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
166
- prot, mmu_idx, TARGET_PAGE_SIZE);
167
- }
168
+ tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
169
+ prot, mmu_idx, tlb_size);
170
return true;
171
} else if (probe) {
172
return false;
173
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
102
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
174
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/pmp.c
104
--- a/target/riscv/pmp.c
176
+++ b/target/riscv/pmp.c
105
+++ b/target/riscv/pmp.c
177
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
106
@@ -XXX,XX +XXX,XX @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
178
return result;
107
}
179
}
108
}
180
109
181
+/*
110
-
182
+ * Check if the address has required RWX privs when no PMP entry is matched.
111
-/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
112
- * end address values.
113
- * This function is called relatively infrequently whereas the check that
114
- * an address is within a pmp rule is called often, so optimise that one
115
- */
116
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
117
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
118
{
119
- int i;
120
-
121
- env->pmp_state.num_rules = 0;
122
-
123
uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
124
target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
125
target_ulong prev_addr = 0u;
126
@@ -XXX,XX +XXX,XX @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
127
128
env->pmp_state.addr[pmp_index].sa = sa;
129
env->pmp_state.addr[pmp_index].ea = ea;
130
+}
131
132
+void pmp_update_rule_nums(CPURISCVState *env)
133
+{
134
+ int i;
135
+
136
+ env->pmp_state.num_rules = 0;
137
for (i = 0; i < MAX_RISCV_PMPS; i++) {
138
const uint8_t a_field =
139
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
140
@@ -XXX,XX +XXX,XX @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
141
}
142
}
143
144
+/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
145
+ * end address values.
146
+ * This function is called relatively infrequently whereas the check that
147
+ * an address is within a pmp rule is called often, so optimise that one
183
+ */
148
+ */
184
+static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
149
+static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
185
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
186
+ target_ulong mode)
187
+{
150
+{
188
+ bool ret;
151
+ pmp_update_rule_addr(env, pmp_index);
189
+
152
+ pmp_update_rule_nums(env);
190
+ if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
191
+ /*
192
+ * Privileged spec v1.10 states if HW doesn't implement any PMP entry
193
+ * or no PMP entry matches an M-Mode access, the access succeeds.
194
+ */
195
+ ret = true;
196
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
197
+ } else {
198
+ /*
199
+ * Other modes are not allowed to succeed if they don't * match a rule,
200
+ * but there are rules. We've checked for no rule earlier in this
201
+ * function.
202
+ */
203
+ ret = false;
204
+ *allowed_privs = 0;
205
+ }
206
+
207
+ return ret;
208
+}
153
+}
209
+
154
+
210
155
static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
211
/*
212
* Public Interface
213
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
214
* Check if the address has required RWX privs to complete desired operation
215
*/
216
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
217
- target_ulong size, pmp_priv_t privs, target_ulong mode)
218
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
219
+ target_ulong mode)
220
{
156
{
221
int i = 0;
157
int result = 0;
222
int ret = -1;
223
int pmp_size = 0;
224
target_ulong s = 0;
225
target_ulong e = 0;
226
- pmp_priv_t allowed_privs = 0;
227
228
/* Short cut if no rules */
229
if (0 == pmp_get_num_rules(env)) {
230
- return (env->priv == PRV_M) ? true : false;
231
+ return pmp_hart_has_privs_default(env, addr, size, privs,
232
+ allowed_privs, mode);
233
}
234
235
if (size == 0) {
236
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
237
* check
238
*/
239
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
240
- allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
241
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
242
if ((mode != PRV_M) || pmp_is_locked(env, i)) {
243
- allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
244
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
245
}
246
247
- if ((privs & allowed_privs) == privs) {
248
- ret = 1;
249
- break;
250
- } else {
251
- ret = 0;
252
- break;
253
- }
254
+ ret = ((privs & *allowed_privs) == privs);
255
+ break;
256
}
257
}
258
259
/* No rule matched */
260
if (ret == -1) {
261
- if (mode == PRV_M) {
262
- ret = 1; /* Privileged spec v1.10 states if no PMP entry matches an
263
- * M-Mode access, the access succeeds */
264
- } else {
265
- ret = 0; /* Other modes are not allowed to succeed if they don't
266
- * match a rule, but there are rules. We've checked for
267
- * no rule earlier in this function. */
268
- }
269
+ return pmp_hart_has_privs_default(env, addr, size, privs,
270
+ allowed_privs, mode);
271
}
272
273
return ret == 1 ? true : false;
274
}
275
276
-
277
/*
278
* Handle a write to a pmpcfg CSP
279
*/
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
281
282
return false;
283
}
284
+
285
+/*
286
+ * Convert PMP privilege to TLB page privilege.
287
+ */
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
289
+{
290
+ int prot = 0;
291
+
292
+ if (pmp_priv & PMP_READ) {
293
+ prot |= PAGE_READ;
294
+ }
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
301
+
302
+ return prot;
303
+}
304
--
158
--
305
2.30.1
159
2.28.0
306
160
307
161
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
In the case of supporting H extension, add H extension description
4
to vmstate_riscv_cpu.
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20201026115530.304-5-jiangyifei@huawei.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/machine.c | 47 ++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 47 insertions(+)
14
15
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/machine.c
18
+++ b/target/riscv/machine.c
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmp = {
20
}
21
};
22
23
+static bool hyper_needed(void *opaque)
24
+{
25
+ RISCVCPU *cpu = opaque;
26
+ CPURISCVState *env = &cpu->env;
27
+
28
+ return riscv_has_ext(env, RVH);
29
+}
30
+
31
+static const VMStateDescription vmstate_hyper = {
32
+ .name = "cpu/hyper",
33
+ .version_id = 1,
34
+ .minimum_version_id = 1,
35
+ .needed = hyper_needed,
36
+ .fields = (VMStateField[]) {
37
+ VMSTATE_UINTTL(env.hstatus, RISCVCPU),
38
+ VMSTATE_UINTTL(env.hedeleg, RISCVCPU),
39
+ VMSTATE_UINTTL(env.hideleg, RISCVCPU),
40
+ VMSTATE_UINTTL(env.hcounteren, RISCVCPU),
41
+ VMSTATE_UINTTL(env.htval, RISCVCPU),
42
+ VMSTATE_UINTTL(env.htinst, RISCVCPU),
43
+ VMSTATE_UINTTL(env.hgatp, RISCVCPU),
44
+ VMSTATE_UINT64(env.htimedelta, RISCVCPU),
45
+
46
+ VMSTATE_UINT64(env.vsstatus, RISCVCPU),
47
+ VMSTATE_UINTTL(env.vstvec, RISCVCPU),
48
+ VMSTATE_UINTTL(env.vsscratch, RISCVCPU),
49
+ VMSTATE_UINTTL(env.vsepc, RISCVCPU),
50
+ VMSTATE_UINTTL(env.vscause, RISCVCPU),
51
+ VMSTATE_UINTTL(env.vstval, RISCVCPU),
52
+ VMSTATE_UINTTL(env.vsatp, RISCVCPU),
53
+
54
+ VMSTATE_UINTTL(env.mtval2, RISCVCPU),
55
+ VMSTATE_UINTTL(env.mtinst, RISCVCPU),
56
+
57
+ VMSTATE_UINTTL(env.stvec_hs, RISCVCPU),
58
+ VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU),
59
+ VMSTATE_UINTTL(env.sepc_hs, RISCVCPU),
60
+ VMSTATE_UINTTL(env.scause_hs, RISCVCPU),
61
+ VMSTATE_UINTTL(env.stval_hs, RISCVCPU),
62
+ VMSTATE_UINTTL(env.satp_hs, RISCVCPU),
63
+ VMSTATE_UINT64(env.mstatus_hs, RISCVCPU),
64
+
65
+ VMSTATE_END_OF_LIST()
66
+ }
67
+};
68
+
69
const VMStateDescription vmstate_riscv_cpu = {
70
.name = "cpu",
71
.version_id = 1,
72
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
73
},
74
.subsections = (const VMStateDescription * []) {
75
&vmstate_pmp,
76
+ &vmstate_hyper,
77
NULL
78
}
79
};
80
--
81
2.28.0
82
83
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
The previous implementation was broken in many ways:
3
In the case of supporting V extension, add V extension description
4
- Used mideleg instead of hideleg to mask accesses
4
to vmstate_riscv_cpu.
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
7
5
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
10
Message-id: 20201026115530.304-6-jiangyifei@huawei.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
13
target/riscv/machine.c | 25 +++++++++++++++++++++++++
14
1 file changed, 34 insertions(+), 34 deletions(-)
14
1 file changed, 25 insertions(+)
15
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
18
--- a/target/riscv/machine.c
19
+++ b/target/riscv/csr.c
19
+++ b/target/riscv/machine.c
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
20
@@ -XXX,XX +XXX,XX @@ static bool hyper_needed(void *opaque)
21
return write_mstatus(env, CSR_MSTATUS, newval);
21
return riscv_has_ext(env, RVH);
22
}
22
}
23
23
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
24
+static bool vector_needed(void *opaque)
25
+{
25
+{
26
+ /* Shift the VS bits to their S bit location in vsie */
26
+ RISCVCPU *cpu = opaque;
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
27
+ CPURISCVState *env = &cpu->env;
28
+ return 0;
28
+
29
+ return riscv_has_ext(env, RVV);
29
+}
30
+}
30
+
31
+
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
32
+static const VMStateDescription vmstate_vector = {
32
{
33
+ .name = "cpu/vector",
33
if (riscv_cpu_virt_enabled(env)) {
34
+ .version_id = 1,
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
35
+ .minimum_version_id = 1,
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
36
+ .needed = vector_needed,
36
+ read_vsie(env, CSR_VSIE, val);
37
+ .fields = (VMStateField[]) {
37
} else {
38
+ VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
38
*val = env->mie & env->mideleg;
39
+ VMSTATE_UINTTL(env.vxrm, RISCVCPU),
40
+ VMSTATE_UINTTL(env.vxsat, RISCVCPU),
41
+ VMSTATE_UINTTL(env.vl, RISCVCPU),
42
+ VMSTATE_UINTTL(env.vstart, RISCVCPU),
43
+ VMSTATE_UINTTL(env.vtype, RISCVCPU),
44
+ VMSTATE_END_OF_LIST()
45
+ }
46
+};
47
+
48
static const VMStateDescription vmstate_hyper = {
49
.name = "cpu/hyper",
50
.version_id = 1,
51
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
52
.subsections = (const VMStateDescription * []) {
53
&vmstate_pmp,
54
&vmstate_hyper,
55
+ &vmstate_vector,
56
NULL
39
}
57
}
40
return 0;
58
};
41
}
42
43
-static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
44
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
45
{
46
- target_ulong newval;
47
+ /* Shift the S bits to their VS bit location in mie */
48
+ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
49
+ ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS);
50
+ return write_mie(env, CSR_MIE, newval);
51
+}
52
53
+static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
54
+{
55
if (riscv_cpu_virt_enabled(env)) {
56
- /* Shift the guests S bits to VS */
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
58
- ((val << 1) & VS_MODE_INTERRUPTS);
59
+ write_vsie(env, CSR_VSIE, val);
60
} else {
61
- newval = (env->mie & ~S_MODE_INTERRUPTS) | (val & S_MODE_INTERRUPTS);
62
+ target_ulong newval = (env->mie & ~S_MODE_INTERRUPTS) |
63
+ (val & S_MODE_INTERRUPTS);
64
+ write_mie(env, CSR_MIE, newval);
65
}
66
67
- return write_mie(env, CSR_MIE, newval);
68
+ return 0;
69
}
70
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
73
return 0;
74
}
75
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
77
+ target_ulong new_value, target_ulong write_mask)
78
+{
79
+ /* Shift the S bits to their VS bit location in mip */
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
82
+ *ret_value &= VS_MODE_INTERRUPTS;
83
+ /* Shift the VS bits to their S bit location in vsip */
84
+ *ret_value >>= 1;
85
+ return ret;
86
+}
87
+
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
89
target_ulong new_value, target_ulong write_mask)
90
{
91
int ret;
92
93
if (riscv_cpu_virt_enabled(env)) {
94
- /* Shift the new values to line up with the VS bits */
95
- ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
96
- (write_mask & sip_writable_mask) << 1 & env->mideleg);
97
- ret &= vsip_writable_mask;
98
- ret >>= 1;
99
+ ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask);
100
} else {
101
ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
102
write_mask & env->mideleg & sip_writable_mask);
103
@@ -XXX,XX +XXX,XX @@ static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
104
return 0;
105
}
106
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
108
- target_ulong new_value, target_ulong write_mask)
109
-{
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
111
- write_mask & env->mideleg & vsip_writable_mask);
112
- return ret;
113
-}
114
-
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
116
-{
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
118
- return 0;
119
-}
120
-
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
122
-{
123
- target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
124
- return write_mie(env, CSR_MIE, newval);
125
-}
126
-
127
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
128
{
129
*val = env->vstvec;
130
--
59
--
131
2.30.1
60
2.28.0
132
61
133
62
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
Add sifive_plic vmstate for supporting sifive_plic migration.
4
further compressed instruction decoding. However, prior to this change,
4
Current vmstate framework only supports one structure parameter
5
we did not raise an illegal instruction exception, if decode_RV32_64C()
5
as num field to describe variable length arrays, so introduce
6
fails to decode the instruction. This means that we skipped illegal
6
num_enables.
7
compressed instructions instead of raising an illegal instruction
8
exception.
9
7
10
Instead of patching decode_RV32_64C(), we can just remove it,
8
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
11
as it is dead code since f330433b363 anyway.
9
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
12
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201026115530.304-7-jiangyifei@huawei.com
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
13
---
19
target/riscv/translate.c | 179 +--------------------------------------
14
include/hw/intc/sifive_plic.h | 1 +
20
1 file changed, 1 insertion(+), 178 deletions(-)
15
hw/intc/sifive_plic.c | 26 +++++++++++++++++++++++++-
16
2 files changed, 26 insertions(+), 1 deletion(-)
21
17
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
20
--- a/include/hw/intc/sifive_plic.h
25
+++ b/target/riscv/translate.c
21
+++ b/include/hw/intc/sifive_plic.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
22
@@ -XXX,XX +XXX,XX @@ struct SiFivePLICState {
27
CPUState *cs;
23
uint32_t num_addrs;
28
} DisasContext;
24
uint32_t num_harts;
29
25
uint32_t bitfield_words;
30
-#ifdef TARGET_RISCV64
26
+ uint32_t num_enables;
31
-/* convert riscv funct3 to qemu memop for load/store */
27
PLICAddr *addr_config;
32
-static const int tcg_memop_lookup[8] = {
28
uint32_t *source_priority;
33
- [0 ... 7] = -1,
29
uint32_t *target_priority;
34
- [0] = MO_SB,
30
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
35
- [1] = MO_TESW,
31
index XXXXXXX..XXXXXXX 100644
36
- [2] = MO_TESL,
32
--- a/hw/intc/sifive_plic.c
37
- [3] = MO_TEQ,
33
+++ b/hw/intc/sifive_plic.c
38
- [4] = MO_UB,
34
@@ -XXX,XX +XXX,XX @@
39
- [5] = MO_TEUW,
35
#include "hw/intc/sifive_plic.h"
40
- [6] = MO_TEUL,
36
#include "target/riscv/cpu.h"
41
-};
37
#include "sysemu/sysemu.h"
42
-#endif
38
+#include "migration/vmstate.h"
43
-
39
44
#ifdef TARGET_RISCV64
40
#define RISCV_DEBUG_PLIC 0
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
41
46
#else
42
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
43
TYPE_SIFIVE_PLIC, plic->aperture_size);
48
ctx->base.is_jmp = DISAS_NORETURN;
44
parse_hart_config(plic);
45
plic->bitfield_words = (plic->num_sources + 31) >> 5;
46
+ plic->num_enables = plic->bitfield_words * plic->num_addrs;
47
plic->source_priority = g_new0(uint32_t, plic->num_sources);
48
plic->target_priority = g_new(uint32_t, plic->num_addrs);
49
plic->pending = g_new0(uint32_t, plic->bitfield_words);
50
plic->claimed = g_new0(uint32_t, plic->bitfield_words);
51
- plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
52
+ plic->enable = g_new0(uint32_t, plic->num_enables);
53
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
54
qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
55
56
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
57
msi_nonbroken = true;
49
}
58
}
50
59
51
-#ifdef TARGET_RISCV64
60
+static const VMStateDescription vmstate_sifive_plic = {
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
61
+ .name = "riscv_sifive_plic",
53
- target_long imm)
62
+ .version_id = 1,
54
-{
63
+ .minimum_version_id = 1,
55
- TCGv t0 = tcg_temp_new();
64
+ .fields = (VMStateField[]) {
56
- TCGv t1 = tcg_temp_new();
65
+ VMSTATE_VARRAY_UINT32(source_priority, SiFivePLICState,
57
- gen_get_gpr(t0, rs1);
66
+ num_sources, 0,
58
- tcg_gen_addi_tl(t0, t0, imm);
67
+ vmstate_info_uint32, uint32_t),
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
68
+ VMSTATE_VARRAY_UINT32(target_priority, SiFivePLICState,
60
-
69
+ num_addrs, 0,
61
- if (memop < 0) {
70
+ vmstate_info_uint32, uint32_t),
62
- gen_exception_illegal(ctx);
71
+ VMSTATE_VARRAY_UINT32(pending, SiFivePLICState, bitfield_words, 0,
63
- return;
72
+ vmstate_info_uint32, uint32_t),
64
- }
73
+ VMSTATE_VARRAY_UINT32(claimed, SiFivePLICState, bitfield_words, 0,
65
-
74
+ vmstate_info_uint32, uint32_t),
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
75
+ VMSTATE_VARRAY_UINT32(enable, SiFivePLICState, num_enables, 0,
67
- gen_set_gpr(rd, t1);
76
+ vmstate_info_uint32, uint32_t),
68
- tcg_temp_free(t0);
77
+ VMSTATE_END_OF_LIST()
69
- tcg_temp_free(t1);
78
+ }
70
-}
79
+};
71
-
80
+
72
-static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
81
static void sifive_plic_class_init(ObjectClass *klass, void *data)
73
- target_long imm)
74
-{
75
- TCGv t0 = tcg_temp_new();
76
- TCGv dat = tcg_temp_new();
77
- gen_get_gpr(t0, rs1);
78
- tcg_gen_addi_tl(t0, t0, imm);
79
- gen_get_gpr(dat, rs2);
80
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
81
-
82
- if (memop < 0) {
83
- gen_exception_illegal(ctx);
84
- return;
85
- }
86
-
87
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
88
- tcg_temp_free(t0);
89
- tcg_temp_free(dat);
90
-}
91
-#endif
92
-
93
#ifndef CONFIG_USER_ONLY
94
/* The states of mstatus_fs are:
95
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
96
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
97
static inline void mark_fs_dirty(DisasContext *ctx) { }
98
#endif
99
100
-#if !defined(TARGET_RISCV64)
101
-static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
102
- int rs1, target_long imm)
103
-{
104
- TCGv t0;
105
-
106
- if (ctx->mstatus_fs == 0) {
107
- gen_exception_illegal(ctx);
108
- return;
109
- }
110
-
111
- t0 = tcg_temp_new();
112
- gen_get_gpr(t0, rs1);
113
- tcg_gen_addi_tl(t0, t0, imm);
114
-
115
- switch (opc) {
116
- case OPC_RISC_FLW:
117
- if (!has_ext(ctx, RVF)) {
118
- goto do_illegal;
119
- }
120
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
121
- /* RISC-V requires NaN-boxing of narrower width floating point values */
122
- tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
123
- break;
124
- case OPC_RISC_FLD:
125
- if (!has_ext(ctx, RVD)) {
126
- goto do_illegal;
127
- }
128
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
129
- break;
130
- do_illegal:
131
- default:
132
- gen_exception_illegal(ctx);
133
- break;
134
- }
135
- tcg_temp_free(t0);
136
-
137
- mark_fs_dirty(ctx);
138
-}
139
-
140
-static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
141
- int rs2, target_long imm)
142
-{
143
- TCGv t0;
144
-
145
- if (ctx->mstatus_fs == 0) {
146
- gen_exception_illegal(ctx);
147
- return;
148
- }
149
-
150
- t0 = tcg_temp_new();
151
- gen_get_gpr(t0, rs1);
152
- tcg_gen_addi_tl(t0, t0, imm);
153
-
154
- switch (opc) {
155
- case OPC_RISC_FSW:
156
- if (!has_ext(ctx, RVF)) {
157
- goto do_illegal;
158
- }
159
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
160
- break;
161
- case OPC_RISC_FSD:
162
- if (!has_ext(ctx, RVD)) {
163
- goto do_illegal;
164
- }
165
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
166
- break;
167
- do_illegal:
168
- default:
169
- gen_exception_illegal(ctx);
170
- break;
171
- }
172
-
173
- tcg_temp_free(t0);
174
-}
175
-#endif
176
-
177
static void gen_set_rm(DisasContext *ctx, int rm)
178
{
82
{
179
TCGv_i32 t0;
83
DeviceClass *dc = DEVICE_CLASS(klass);
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
84
181
tcg_temp_free_i32(t0);
85
device_class_set_props(dc, sifive_plic_properties);
86
dc->realize = sifive_plic_realize;
87
+ dc->vmsd = &vmstate_sifive_plic;
182
}
88
}
183
89
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
90
static const TypeInfo sifive_plic_info = {
185
-{
186
- uint8_t funct3 = extract16(opcode, 13, 3);
187
- uint8_t rd_rs2 = GET_C_RS2S(opcode);
188
- uint8_t rs1s = GET_C_RS1S(opcode);
189
-
190
- switch (funct3) {
191
- case 3:
192
-#if defined(TARGET_RISCV64)
193
- /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
194
- gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
195
- GET_C_LD_IMM(opcode));
196
-#else
197
- /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
198
- gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
199
- GET_C_LW_IMM(opcode));
200
-#endif
201
- break;
202
- case 7:
203
-#if defined(TARGET_RISCV64)
204
- /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
205
- gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
206
- GET_C_LD_IMM(opcode));
207
-#else
208
- /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
209
- gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
210
- GET_C_LW_IMM(opcode));
211
-#endif
212
- break;
213
- }
214
-}
215
-
216
-static void decode_RV32_64C(DisasContext *ctx, uint16_t opcode)
217
-{
218
- uint8_t op = extract16(opcode, 0, 2);
219
-
220
- switch (op) {
221
- case 0:
222
- decode_RV32_64C0(ctx, opcode);
223
- break;
224
- }
225
-}
226
-
227
static int ex_plus_1(DisasContext *ctx, int nf)
228
{
229
return nf + 1;
230
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
231
} else {
232
ctx->pc_succ_insn = ctx->base.pc_next + 2;
233
if (!decode_insn16(ctx, opcode)) {
234
- /* fall back to old decoder */
235
- decode_RV32_64C(ctx, opcode);
236
+ gen_exception_illegal(ctx);
237
}
238
}
239
} else {
240
--
91
--
241
2.30.1
92
2.28.0
242
93
243
94
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
It is not easy to find out the memory map for a specific component
4
debugging.
4
in the PolarFire SoC as the information is scattered in different
5
documents. Add some comments so that people can know where to get
6
such information from the Microchip website.
5
7
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
10
Message-id: 1603863010-15807-2-git-send-email-bmeng.cn@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
13
hw/riscv/microchip_pfsoc.c | 18 ++++++++++++++++++
12
1 file changed, 12 insertions(+)
14
1 file changed, 18 insertions(+)
13
15
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
18
--- a/hw/riscv/microchip_pfsoc.c
17
+++ b/target/riscv/cpu_helper.c
19
+++ b/hw/riscv/microchip_pfsoc.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
@@ -XXX,XX +XXX,XX @@
19
if (ret == TRANSLATE_SUCCESS) {
21
/* GEM version */
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
22
#define GEM_REVISION 0x0107010c
21
size, access_type, mode);
23
22
+
24
+/*
23
+ qemu_log_mask(CPU_LOG_MMU,
25
+ * The complete description of the whole PolarFire SoC memory map is scattered
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
26
+ * in different documents. There are several places to look at for memory maps:
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
27
+ *
26
+ __func__, pa, ret, prot_pmp, tlb_size);
28
+ * 1 Chapter 11 "MSS Memory Map", in the doc "UG0880: PolarFire SoC FPGA
27
+
29
+ * Microprocessor Subsystem (MSS) User Guide", which can be downloaded from
28
prot &= prot_pmp;
30
+ * https://www.microsemi.com/document-portal/doc_download/
29
}
31
+ * 1244570-ug0880-polarfire-soc-fpga-microprocessor-subsystem-mss-user-guide,
30
32
+ * describes the whole picture of the PolarFire SoC memory map.
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
33
+ *
32
if (ret == TRANSLATE_SUCCESS) {
34
+ * 2 A zip file for PolarFire soC memory map, which can be downloaded from
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
35
+ * https://www.microsemi.com/document-portal/doc_download/
34
size, access_type, mode);
36
+ * 1244581-polarfire-soc-register-map, contains the following 2 major parts:
35
+
37
+ * - Register Map/PF_SoC_RegMap_V1_1/pfsoc_regmap.htm
36
+ qemu_log_mask(CPU_LOG_MMU,
38
+ * describes the complete integrated peripherals memory map
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
39
+ * - Register Map/PF_SoC_RegMap_V1_1/MPFS250T/mpfs250t_ioscb_memmap_dri.htm
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
40
+ * describes the complete IOSCB modules memory maps
39
+ __func__, pa, ret, prot_pmp, tlb_size);
41
+ */
40
+
42
static const struct MemmapEntry {
41
prot &= prot_pmp;
43
hwaddr base;
42
}
44
hwaddr size;
43
}
44
--
45
--
45
2.30.1
46
2.28.0
46
47
47
48
diff view generated by jsdifflib
New patch
1
1
From: Bin Meng <bin.meng@windriver.com>
2
3
The PolarFire SoC DDR Memory Controller mainly includes 2 modules,
4
called SGMII PHY module and the CFG module, as documented in the
5
chipset datasheet.
6
7
This creates a single file that groups these 2 modules, providing
8
the minimum functionalities that make the HSS DDR initialization
9
codes happy.
10
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 1603863010-15807-3-git-send-email-bmeng.cn@gmail.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/misc/mchp_pfsoc_dmc.h | 56 ++++++++
17
hw/misc/mchp_pfsoc_dmc.c | 216 +++++++++++++++++++++++++++++++
18
MAINTAINERS | 2 +
19
hw/misc/Kconfig | 3 +
20
hw/misc/meson.build | 1 +
21
5 files changed, 278 insertions(+)
22
create mode 100644 include/hw/misc/mchp_pfsoc_dmc.h
23
create mode 100644 hw/misc/mchp_pfsoc_dmc.c
24
25
diff --git a/include/hw/misc/mchp_pfsoc_dmc.h b/include/hw/misc/mchp_pfsoc_dmc.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/include/hw/misc/mchp_pfsoc_dmc.h
30
@@ -XXX,XX +XXX,XX @@
31
+/*
32
+ * Microchip PolarFire SoC DDR Memory Controller module emulation
33
+ *
34
+ * Copyright (c) 2020 Wind River Systems, Inc.
35
+ *
36
+ * Author:
37
+ * Bin Meng <bin.meng@windriver.com>
38
+ *
39
+ * This program is free software; you can redistribute it and/or
40
+ * modify it under the terms of the GNU General Public License as
41
+ * published by the Free Software Foundation; either version 2 or
42
+ * (at your option) version 3 of the License.
43
+ *
44
+ * This program is distributed in the hope that it will be useful,
45
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47
+ * GNU General Public License for more details.
48
+ *
49
+ * You should have received a copy of the GNU General Public License along
50
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
51
+ */
52
+
53
+#ifndef MCHP_PFSOC_DMC_H
54
+#define MCHP_PFSOC_DMC_H
55
+
56
+/* DDR SGMII PHY module */
57
+
58
+#define MCHP_PFSOC_DDR_SGMII_PHY_REG_SIZE 0x1000
59
+
60
+typedef struct MchpPfSoCDdrSgmiiPhyState {
61
+ SysBusDevice parent;
62
+ MemoryRegion sgmii_phy;
63
+} MchpPfSoCDdrSgmiiPhyState;
64
+
65
+#define TYPE_MCHP_PFSOC_DDR_SGMII_PHY "mchp.pfsoc.ddr_sgmii_phy"
66
+
67
+#define MCHP_PFSOC_DDR_SGMII_PHY(obj) \
68
+ OBJECT_CHECK(MchpPfSoCDdrSgmiiPhyState, (obj), \
69
+ TYPE_MCHP_PFSOC_DDR_SGMII_PHY)
70
+
71
+/* DDR CFG module */
72
+
73
+#define MCHP_PFSOC_DDR_CFG_REG_SIZE 0x40000
74
+
75
+typedef struct MchpPfSoCDdrCfgState {
76
+ SysBusDevice parent;
77
+ MemoryRegion cfg;
78
+} MchpPfSoCDdrCfgState;
79
+
80
+#define TYPE_MCHP_PFSOC_DDR_CFG "mchp.pfsoc.ddr_cfg"
81
+
82
+#define MCHP_PFSOC_DDR_CFG(obj) \
83
+ OBJECT_CHECK(MchpPfSoCDdrCfgState, (obj), \
84
+ TYPE_MCHP_PFSOC_DDR_CFG)
85
+
86
+#endif /* MCHP_PFSOC_DMC_H */
87
diff --git a/hw/misc/mchp_pfsoc_dmc.c b/hw/misc/mchp_pfsoc_dmc.c
88
new file mode 100644
89
index XXXXXXX..XXXXXXX
90
--- /dev/null
91
+++ b/hw/misc/mchp_pfsoc_dmc.c
92
@@ -XXX,XX +XXX,XX @@
93
+/*
94
+ * Microchip PolarFire SoC DDR Memory Controller module emulation
95
+ *
96
+ * Copyright (c) 2020 Wind River Systems, Inc.
97
+ *
98
+ * Author:
99
+ * Bin Meng <bin.meng@windriver.com>
100
+ *
101
+ * This program is free software; you can redistribute it and/or
102
+ * modify it under the terms of the GNU General Public License as
103
+ * published by the Free Software Foundation; either version 2 or
104
+ * (at your option) version 3 of the License.
105
+ *
106
+ * This program is distributed in the hope that it will be useful,
107
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
108
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109
+ * GNU General Public License for more details.
110
+ *
111
+ * You should have received a copy of the GNU General Public License along
112
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
113
+ */
114
+
115
+#include "qemu/osdep.h"
116
+#include "qemu/bitops.h"
117
+#include "qemu/log.h"
118
+#include "qapi/error.h"
119
+#include "hw/hw.h"
120
+#include "hw/sysbus.h"
121
+#include "hw/misc/mchp_pfsoc_dmc.h"
122
+
123
+/* DDR SGMII PHY module */
124
+
125
+#define SGMII_PHY_IOC_REG1 0x208
126
+#define SGMII_PHY_TRAINING_STATUS 0x814
127
+#define SGMII_PHY_DQ_DQS_ERR_DONE 0x834
128
+#define SGMII_PHY_DQDQS_STATUS1 0x84c
129
+#define SGMII_PHY_PVT_STAT 0xc20
130
+
131
+static uint64_t mchp_pfsoc_ddr_sgmii_phy_read(void *opaque, hwaddr offset,
132
+ unsigned size)
133
+{
134
+ uint32_t val = 0;
135
+ static int training_status_bit;
136
+
137
+ switch (offset) {
138
+ case SGMII_PHY_IOC_REG1:
139
+ /* See ddr_pvt_calibration() in HSS */
140
+ val = BIT(4) | BIT(2);
141
+ break;
142
+ case SGMII_PHY_TRAINING_STATUS:
143
+ /*
144
+ * The codes logic emulates the training status change from
145
+ * DDR_TRAINING_IP_SM_BCLKSCLK to DDR_TRAINING_IP_SM_DQ_DQS.
146
+ *
147
+ * See ddr_setup() in mss_ddr.c in the HSS source codes.
148
+ */
149
+ val = 1 << training_status_bit;
150
+ training_status_bit = (training_status_bit + 1) % 5;
151
+ break;
152
+ case SGMII_PHY_DQ_DQS_ERR_DONE:
153
+ /*
154
+ * DDR_TRAINING_IP_SM_VERIFY state in ddr_setup(),
155
+ * check that DQ/DQS training passed without error.
156
+ */
157
+ val = 8;
158
+ break;
159
+ case SGMII_PHY_DQDQS_STATUS1:
160
+ /*
161
+ * DDR_TRAINING_IP_SM_VERIFY state in ddr_setup(),
162
+ * check that DQ/DQS calculated window is above 5 taps.
163
+ */
164
+ val = 0xff;
165
+ break;
166
+ case SGMII_PHY_PVT_STAT:
167
+ /* See sgmii_channel_setup() in HSS */
168
+ val = BIT(14) | BIT(6);
169
+ break;
170
+ default:
171
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
172
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
173
+ __func__, size, offset);
174
+ break;
175
+ }
176
+
177
+ return val;
178
+}
179
+
180
+static void mchp_pfsoc_ddr_sgmii_phy_write(void *opaque, hwaddr offset,
181
+ uint64_t value, unsigned size)
182
+{
183
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
184
+ "(size %d, value 0x%" PRIx64
185
+ ", offset 0x%" HWADDR_PRIx ")\n",
186
+ __func__, size, value, offset);
187
+}
188
+
189
+static const MemoryRegionOps mchp_pfsoc_ddr_sgmii_phy_ops = {
190
+ .read = mchp_pfsoc_ddr_sgmii_phy_read,
191
+ .write = mchp_pfsoc_ddr_sgmii_phy_write,
192
+ .endianness = DEVICE_LITTLE_ENDIAN,
193
+};
194
+
195
+static void mchp_pfsoc_ddr_sgmii_phy_realize(DeviceState *dev, Error **errp)
196
+{
197
+ MchpPfSoCDdrSgmiiPhyState *s = MCHP_PFSOC_DDR_SGMII_PHY(dev);
198
+
199
+ memory_region_init_io(&s->sgmii_phy, OBJECT(dev),
200
+ &mchp_pfsoc_ddr_sgmii_phy_ops, s,
201
+ "mchp.pfsoc.ddr_sgmii_phy",
202
+ MCHP_PFSOC_DDR_SGMII_PHY_REG_SIZE);
203
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sgmii_phy);
204
+}
205
+
206
+static void mchp_pfsoc_ddr_sgmii_phy_class_init(ObjectClass *klass, void *data)
207
+{
208
+ DeviceClass *dc = DEVICE_CLASS(klass);
209
+
210
+ dc->desc = "Microchip PolarFire SoC DDR SGMII PHY module";
211
+ dc->realize = mchp_pfsoc_ddr_sgmii_phy_realize;
212
+}
213
+
214
+static const TypeInfo mchp_pfsoc_ddr_sgmii_phy_info = {
215
+ .name = TYPE_MCHP_PFSOC_DDR_SGMII_PHY,
216
+ .parent = TYPE_SYS_BUS_DEVICE,
217
+ .instance_size = sizeof(MchpPfSoCDdrSgmiiPhyState),
218
+ .class_init = mchp_pfsoc_ddr_sgmii_phy_class_init,
219
+};
220
+
221
+static void mchp_pfsoc_ddr_sgmii_phy_register_types(void)
222
+{
223
+ type_register_static(&mchp_pfsoc_ddr_sgmii_phy_info);
224
+}
225
+
226
+type_init(mchp_pfsoc_ddr_sgmii_phy_register_types)
227
+
228
+/* DDR CFG module */
229
+
230
+#define CFG_MT_DONE_ACK 0x4428
231
+#define CFG_STAT_DFI_INIT_COMPLETE 0x10034
232
+#define CFG_STAT_DFI_TRAINING_COMPLETE 0x10038
233
+
234
+static uint64_t mchp_pfsoc_ddr_cfg_read(void *opaque, hwaddr offset,
235
+ unsigned size)
236
+{
237
+ uint32_t val = 0;
238
+
239
+ switch (offset) {
240
+ case CFG_MT_DONE_ACK:
241
+ /* memory test in MTC_test() */
242
+ val = BIT(0);
243
+ break;
244
+ case CFG_STAT_DFI_INIT_COMPLETE:
245
+ /* DDR_TRAINING_IP_SM_START_CHECK state in ddr_setup() */
246
+ val = BIT(0);
247
+ break;
248
+ case CFG_STAT_DFI_TRAINING_COMPLETE:
249
+ /* DDR_TRAINING_IP_SM_VERIFY state in ddr_setup() */
250
+ val = BIT(0);
251
+ break;
252
+ default:
253
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
254
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
255
+ __func__, size, offset);
256
+ break;
257
+ }
258
+
259
+ return val;
260
+}
261
+
262
+static void mchp_pfsoc_ddr_cfg_write(void *opaque, hwaddr offset,
263
+ uint64_t value, unsigned size)
264
+{
265
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
266
+ "(size %d, value 0x%" PRIx64
267
+ ", offset 0x%" HWADDR_PRIx ")\n",
268
+ __func__, size, value, offset);
269
+}
270
+
271
+static const MemoryRegionOps mchp_pfsoc_ddr_cfg_ops = {
272
+ .read = mchp_pfsoc_ddr_cfg_read,
273
+ .write = mchp_pfsoc_ddr_cfg_write,
274
+ .endianness = DEVICE_LITTLE_ENDIAN,
275
+};
276
+
277
+static void mchp_pfsoc_ddr_cfg_realize(DeviceState *dev, Error **errp)
278
+{
279
+ MchpPfSoCDdrCfgState *s = MCHP_PFSOC_DDR_CFG(dev);
280
+
281
+ memory_region_init_io(&s->cfg, OBJECT(dev),
282
+ &mchp_pfsoc_ddr_cfg_ops, s,
283
+ "mchp.pfsoc.ddr_cfg",
284
+ MCHP_PFSOC_DDR_CFG_REG_SIZE);
285
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->cfg);
286
+}
287
+
288
+static void mchp_pfsoc_ddr_cfg_class_init(ObjectClass *klass, void *data)
289
+{
290
+ DeviceClass *dc = DEVICE_CLASS(klass);
291
+
292
+ dc->desc = "Microchip PolarFire SoC DDR CFG module";
293
+ dc->realize = mchp_pfsoc_ddr_cfg_realize;
294
+}
295
+
296
+static const TypeInfo mchp_pfsoc_ddr_cfg_info = {
297
+ .name = TYPE_MCHP_PFSOC_DDR_CFG,
298
+ .parent = TYPE_SYS_BUS_DEVICE,
299
+ .instance_size = sizeof(MchpPfSoCDdrCfgState),
300
+ .class_init = mchp_pfsoc_ddr_cfg_class_init,
301
+};
302
+
303
+static void mchp_pfsoc_ddr_cfg_register_types(void)
304
+{
305
+ type_register_static(&mchp_pfsoc_ddr_cfg_info);
306
+}
307
+
308
+type_init(mchp_pfsoc_ddr_cfg_register_types)
309
diff --git a/MAINTAINERS b/MAINTAINERS
310
index XXXXXXX..XXXXXXX 100644
311
--- a/MAINTAINERS
312
+++ b/MAINTAINERS
313
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
314
S: Supported
315
F: hw/riscv/microchip_pfsoc.c
316
F: hw/char/mchp_pfsoc_mmuart.c
317
+F: hw/misc/mchp_pfsoc_dmc.c
318
F: include/hw/riscv/microchip_pfsoc.h
319
F: include/hw/char/mchp_pfsoc_mmuart.h
320
+F: include/hw/misc/mchp_pfsoc_dmc.h
321
322
RX Machines
323
-----------
324
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
325
index XXXXXXX..XXXXXXX 100644
326
--- a/hw/misc/Kconfig
327
+++ b/hw/misc/Kconfig
328
@@ -XXX,XX +XXX,XX @@ config MAC_VIA
329
config AVR_POWER
330
bool
331
332
+config MCHP_PFSOC_DMC
333
+ bool
334
+
335
config SIFIVE_TEST
336
bool
337
338
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
339
index XXXXXXX..XXXXXXX 100644
340
--- a/hw/misc/meson.build
341
+++ b/hw/misc/meson.build
342
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM11SCU', if_true: files('arm11scu.c'))
343
softmmu_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c'))
344
345
# RISC-V devices
346
+softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_DMC', if_true: files('mchp_pfsoc_dmc.c'))
347
softmmu_ss.add(when: 'CONFIG_SIFIVE_TEST', if_true: files('sifive_test.c'))
348
softmmu_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('sifive_e_prci.c'))
349
softmmu_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'))
350
--
351
2.28.0
352
353
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
3
Connect DDR SGMII PHY module and CFG module to the PolarFire SoC.
4
the address bytes. Note only SPI mode is supported by SST flashes.
5
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
7
4
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
7
Message-id: 1603863010-15807-4-git-send-email-bmeng.cn@gmail.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
9
---
13
hw/block/m25p80.c | 3 +++
10
include/hw/riscv/microchip_pfsoc.h | 5 +++++
14
1 file changed, 3 insertions(+)
11
hw/riscv/microchip_pfsoc.c | 18 ++++++++++++++++++
12
hw/riscv/Kconfig | 1 +
13
3 files changed, 24 insertions(+)
15
14
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
15
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
17
--- a/include/hw/riscv/microchip_pfsoc.h
19
+++ b/hw/block/m25p80.c
18
+++ b/include/hw/riscv/microchip_pfsoc.h
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
19
@@ -XXX,XX +XXX,XX @@
21
s->needed_bytes = get_addr_length(s);
20
22
switch (get_man(s)) {
21
#include "hw/char/mchp_pfsoc_mmuart.h"
23
/* Dummy cycles - modeled with bytes writes instead of bits */
22
#include "hw/dma/sifive_pdma.h"
24
+ case MAN_SST:
23
+#include "hw/misc/mchp_pfsoc_dmc.h"
25
+ s->needed_bytes += 1;
24
#include "hw/net/cadence_gem.h"
26
+ break;
25
#include "hw/sd/cadence_sdhci.h"
27
case MAN_WINBOND:
26
28
s->needed_bytes += 8;
27
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
29
break;
28
RISCVHartArrayState e_cpus;
29
RISCVHartArrayState u_cpus;
30
DeviceState *plic;
31
+ MchpPfSoCDdrSgmiiPhyState ddr_sgmii_phy;
32
+ MchpPfSoCDdrCfgState ddr_cfg;
33
MchpPfSoCMMUartState *serial0;
34
MchpPfSoCMMUartState *serial1;
35
MchpPfSoCMMUartState *serial2;
36
@@ -XXX,XX +XXX,XX @@ enum {
37
MICROCHIP_PFSOC_MMUART0,
38
MICROCHIP_PFSOC_SYSREG,
39
MICROCHIP_PFSOC_MPUCFG,
40
+ MICROCHIP_PFSOC_DDR_SGMII_PHY,
41
MICROCHIP_PFSOC_EMMC_SD,
42
+ MICROCHIP_PFSOC_DDR_CFG,
43
MICROCHIP_PFSOC_MMUART1,
44
MICROCHIP_PFSOC_MMUART2,
45
MICROCHIP_PFSOC_MMUART3,
46
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/riscv/microchip_pfsoc.c
49
+++ b/hw/riscv/microchip_pfsoc.c
50
@@ -XXX,XX +XXX,XX @@
51
* 4) Cadence eMMC/SDHC controller and an SD card connected to it
52
* 5) SiFive Platform DMA (Direct Memory Access Controller)
53
* 6) GEM (Gigabit Ethernet MAC Controller)
54
+ * 7) DMC (DDR Memory Controller)
55
*
56
* This board currently generates devicetree dynamically that indicates at least
57
* two harts and up to five harts.
58
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
59
[MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
60
[MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
61
[MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
62
+ [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
63
[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
64
+ [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
65
[MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
66
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
67
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
68
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
69
object_initialize_child(obj, "dma-controller", &s->dma,
70
TYPE_SIFIVE_PDMA);
71
72
+ object_initialize_child(obj, "ddr-sgmii-phy", &s->ddr_sgmii_phy,
73
+ TYPE_MCHP_PFSOC_DDR_SGMII_PHY);
74
+ object_initialize_child(obj, "ddr-cfg", &s->ddr_cfg,
75
+ TYPE_MCHP_PFSOC_DDR_CFG);
76
+
77
object_initialize_child(obj, "gem0", &s->gem0, TYPE_CADENCE_GEM);
78
object_initialize_child(obj, "gem1", &s->gem1, TYPE_CADENCE_GEM);
79
80
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
81
memmap[MICROCHIP_PFSOC_MPUCFG].base,
82
memmap[MICROCHIP_PFSOC_MPUCFG].size);
83
84
+ /* DDR SGMII PHY */
85
+ sysbus_realize(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), errp);
86
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), 0,
87
+ memmap[MICROCHIP_PFSOC_DDR_SGMII_PHY].base);
88
+
89
+ /* DDR CFG */
90
+ sysbus_realize(SYS_BUS_DEVICE(&s->ddr_cfg), errp);
91
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_cfg), 0,
92
+ memmap[MICROCHIP_PFSOC_DDR_CFG].base);
93
+
94
/* SDHCI */
95
sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp);
96
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
97
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
98
index XXXXXXX..XXXXXXX 100644
99
--- a/hw/riscv/Kconfig
100
+++ b/hw/riscv/Kconfig
101
@@ -XXX,XX +XXX,XX @@ config IBEX
102
config MICROCHIP_PFSOC
103
bool
104
select CADENCE_SDHCI
105
+ select MCHP_PFSOC_DMC
106
select MCHP_PFSOC_MMUART
107
select MSI_NONBROKEN
108
select SIFIVE_CLINT
30
--
109
--
31
2.30.1
110
2.28.0
32
111
33
112
diff view generated by jsdifflib
New patch
1
1
From: Bin Meng <bin.meng@windriver.com>
2
3
This creates a model for PolarFire SoC IOSCB [1] module. It actually
4
contains lots of sub-modules like various PLLs to control different
5
peripherals. Only the mininum capabilities are emulated to make the
6
HSS DDR memory initialization codes happy. Lots of sub-modules are
7
created as an unimplemented devices.
8
9
[1] PF_SoC_RegMap_V1_1/MPFS250T/mpfs250t_ioscb_memmap_dri.htm in
10
https://www.microsemi.com/document-portal/doc_download/1244581-polarfire-soc-register-map
11
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 1603863010-15807-5-git-send-email-bmeng.cn@gmail.com
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/misc/mchp_pfsoc_ioscb.h | 50 ++++++
18
hw/misc/mchp_pfsoc_ioscb.c | 242 +++++++++++++++++++++++++++++
19
MAINTAINERS | 2 +
20
hw/misc/Kconfig | 3 +
21
hw/misc/meson.build | 1 +
22
5 files changed, 298 insertions(+)
23
create mode 100644 include/hw/misc/mchp_pfsoc_ioscb.h
24
create mode 100644 hw/misc/mchp_pfsoc_ioscb.c
25
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * Microchip PolarFire SoC IOSCB module emulation
34
+ *
35
+ * Copyright (c) 2020 Wind River Systems, Inc.
36
+ *
37
+ * Author:
38
+ * Bin Meng <bin.meng@windriver.com>
39
+ *
40
+ * This program is free software; you can redistribute it and/or
41
+ * modify it under the terms of the GNU General Public License as
42
+ * published by the Free Software Foundation; either version 2 or
43
+ * (at your option) version 3 of the License.
44
+ *
45
+ * This program is distributed in the hope that it will be useful,
46
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ * GNU General Public License for more details.
49
+ *
50
+ * You should have received a copy of the GNU General Public License along
51
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
52
+ */
53
+
54
+#ifndef MCHP_PFSOC_IOSCB_H
55
+#define MCHP_PFSOC_IOSCB_H
56
+
57
+typedef struct MchpPfSoCIoscbState {
58
+ SysBusDevice parent;
59
+ MemoryRegion container;
60
+ MemoryRegion lane01;
61
+ MemoryRegion lane23;
62
+ MemoryRegion ctrl;
63
+ MemoryRegion cfg;
64
+ MemoryRegion pll_mss;
65
+ MemoryRegion cfm_mss;
66
+ MemoryRegion pll_ddr;
67
+ MemoryRegion bc_ddr;
68
+ MemoryRegion io_calib_ddr;
69
+ MemoryRegion pll_sgmii;
70
+ MemoryRegion dll_sgmii;
71
+ MemoryRegion cfm_sgmii;
72
+ MemoryRegion bc_sgmii;
73
+ MemoryRegion io_calib_sgmii;
74
+} MchpPfSoCIoscbState;
75
+
76
+#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
77
+
78
+#define MCHP_PFSOC_IOSCB(obj) \
79
+ OBJECT_CHECK(MchpPfSoCIoscbState, (obj), TYPE_MCHP_PFSOC_IOSCB)
80
+
81
+#endif /* MCHP_PFSOC_IOSCB_H */
82
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
83
new file mode 100644
84
index XXXXXXX..XXXXXXX
85
--- /dev/null
86
+++ b/hw/misc/mchp_pfsoc_ioscb.c
87
@@ -XXX,XX +XXX,XX @@
88
+/*
89
+ * Microchip PolarFire SoC IOSCB module emulation
90
+ *
91
+ * Copyright (c) 2020 Wind River Systems, Inc.
92
+ *
93
+ * Author:
94
+ * Bin Meng <bin.meng@windriver.com>
95
+ *
96
+ * This program is free software; you can redistribute it and/or
97
+ * modify it under the terms of the GNU General Public License as
98
+ * published by the Free Software Foundation; either version 2 or
99
+ * (at your option) version 3 of the License.
100
+ *
101
+ * This program is distributed in the hope that it will be useful,
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104
+ * GNU General Public License for more details.
105
+ *
106
+ * You should have received a copy of the GNU General Public License along
107
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
108
+ */
109
+
110
+#include "qemu/osdep.h"
111
+#include "qemu/bitops.h"
112
+#include "qemu/log.h"
113
+#include "qapi/error.h"
114
+#include "hw/hw.h"
115
+#include "hw/sysbus.h"
116
+#include "hw/misc/mchp_pfsoc_ioscb.h"
117
+
118
+/*
119
+ * The whole IOSCB module registers map into the system address at 0x3000_0000,
120
+ * named as "System Port 0 (AXI-D0)".
121
+ */
122
+#define IOSCB_WHOLE_REG_SIZE 0x10000000
123
+#define IOSCB_SUBMOD_REG_SIZE 0x1000
124
+
125
+/*
126
+ * There are many sub-modules in the IOSCB module.
127
+ * See Microchip PolarFire SoC documentation (Register_Map.zip),
128
+ * Register Map/PF_SoC_RegMap_V1_1/MPFS250T/mpfs250t_ioscb_memmap_dri.htm
129
+ *
130
+ * The following are sub-modules offsets that are of concern.
131
+ */
132
+#define IOSCB_LANE01_BASE 0x06500000
133
+#define IOSCB_LANE23_BASE 0x06510000
134
+#define IOSCB_CTRL_BASE 0x07020000
135
+#define IOSCB_CFG_BASE 0x07080000
136
+#define IOSCB_PLL_MSS_BASE 0x0E001000
137
+#define IOSCB_CFM_MSS_BASE 0x0E002000
138
+#define IOSCB_PLL_DDR_BASE 0x0E010000
139
+#define IOSCB_BC_DDR_BASE 0x0E020000
140
+#define IOSCB_IO_CALIB_DDR_BASE 0x0E040000
141
+#define IOSCB_PLL_SGMII_BASE 0x0E080000
142
+#define IOSCB_DLL_SGMII_BASE 0x0E100000
143
+#define IOSCB_CFM_SGMII_BASE 0x0E200000
144
+#define IOSCB_BC_SGMII_BASE 0x0E400000
145
+#define IOSCB_IO_CALIB_SGMII_BASE 0x0E800000
146
+
147
+static uint64_t mchp_pfsoc_dummy_read(void *opaque, hwaddr offset,
148
+ unsigned size)
149
+{
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
151
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
152
+ __func__, size, offset);
153
+
154
+ return 0;
155
+}
156
+
157
+static void mchp_pfsoc_dummy_write(void *opaque, hwaddr offset,
158
+ uint64_t value, unsigned size)
159
+{
160
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
161
+ "(size %d, value 0x%" PRIx64
162
+ ", offset 0x%" HWADDR_PRIx ")\n",
163
+ __func__, size, value, offset);
164
+}
165
+
166
+static const MemoryRegionOps mchp_pfsoc_dummy_ops = {
167
+ .read = mchp_pfsoc_dummy_read,
168
+ .write = mchp_pfsoc_dummy_write,
169
+ .endianness = DEVICE_LITTLE_ENDIAN,
170
+};
171
+
172
+/* All PLL modules in IOSCB have the same register layout */
173
+
174
+#define PLL_CTRL 0x04
175
+
176
+static uint64_t mchp_pfsoc_pll_read(void *opaque, hwaddr offset,
177
+ unsigned size)
178
+{
179
+ uint32_t val = 0;
180
+
181
+ switch (offset) {
182
+ case PLL_CTRL:
183
+ /* PLL is locked */
184
+ val = BIT(25);
185
+ break;
186
+ default:
187
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
188
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
189
+ __func__, size, offset);
190
+ break;
191
+ }
192
+
193
+ return val;
194
+}
195
+
196
+static const MemoryRegionOps mchp_pfsoc_pll_ops = {
197
+ .read = mchp_pfsoc_pll_read,
198
+ .write = mchp_pfsoc_dummy_write,
199
+ .endianness = DEVICE_LITTLE_ENDIAN,
200
+};
201
+
202
+/* IO_CALIB_DDR submodule */
203
+
204
+#define IO_CALIB_DDR_IOC_REG1 0x08
205
+
206
+static uint64_t mchp_pfsoc_io_calib_ddr_read(void *opaque, hwaddr offset,
207
+ unsigned size)
208
+{
209
+ uint32_t val = 0;
210
+
211
+ switch (offset) {
212
+ case IO_CALIB_DDR_IOC_REG1:
213
+ /* calibration completed */
214
+ val = BIT(2);
215
+ break;
216
+ default:
217
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
218
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
219
+ __func__, size, offset);
220
+ break;
221
+ }
222
+
223
+ return val;
224
+}
225
+
226
+static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = {
227
+ .read = mchp_pfsoc_io_calib_ddr_read,
228
+ .write = mchp_pfsoc_dummy_write,
229
+ .endianness = DEVICE_LITTLE_ENDIAN,
230
+};
231
+
232
+static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
233
+{
234
+ MchpPfSoCIoscbState *s = MCHP_PFSOC_IOSCB(dev);
235
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
236
+
237
+ memory_region_init(&s->container, OBJECT(s),
238
+ "mchp.pfsoc.ioscb", IOSCB_WHOLE_REG_SIZE);
239
+ sysbus_init_mmio(sbd, &s->container);
240
+
241
+ /* add subregions for all sub-modules in IOSCB */
242
+
243
+ memory_region_init_io(&s->lane01, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
244
+ "mchp.pfsoc.ioscb.lane01", IOSCB_SUBMOD_REG_SIZE);
245
+ memory_region_add_subregion(&s->container, IOSCB_LANE01_BASE, &s->lane01);
246
+
247
+ memory_region_init_io(&s->lane23, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
248
+ "mchp.pfsoc.ioscb.lane23", IOSCB_SUBMOD_REG_SIZE);
249
+ memory_region_add_subregion(&s->container, IOSCB_LANE23_BASE, &s->lane23);
250
+
251
+ memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
252
+ "mchp.pfsoc.ioscb.ctrl", IOSCB_SUBMOD_REG_SIZE);
253
+ memory_region_add_subregion(&s->container, IOSCB_CTRL_BASE, &s->ctrl);
254
+
255
+ memory_region_init_io(&s->cfg, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
256
+ "mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
257
+ memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
258
+
259
+ memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
260
+ "mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
261
+ memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, &s->pll_mss);
262
+
263
+ memory_region_init_io(&s->cfm_mss, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
264
+ "mchp.pfsoc.ioscb.cfm_mss", IOSCB_SUBMOD_REG_SIZE);
265
+ memory_region_add_subregion(&s->container, IOSCB_CFM_MSS_BASE, &s->cfm_mss);
266
+
267
+ memory_region_init_io(&s->pll_ddr, OBJECT(s), &mchp_pfsoc_pll_ops, s,
268
+ "mchp.pfsoc.ioscb.pll_ddr", IOSCB_SUBMOD_REG_SIZE);
269
+ memory_region_add_subregion(&s->container, IOSCB_PLL_DDR_BASE, &s->pll_ddr);
270
+
271
+ memory_region_init_io(&s->bc_ddr, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
272
+ "mchp.pfsoc.ioscb.bc_ddr", IOSCB_SUBMOD_REG_SIZE);
273
+ memory_region_add_subregion(&s->container, IOSCB_BC_DDR_BASE, &s->bc_ddr);
274
+
275
+ memory_region_init_io(&s->io_calib_ddr, OBJECT(s),
276
+ &mchp_pfsoc_io_calib_ddr_ops, s,
277
+ "mchp.pfsoc.ioscb.io_calib_ddr",
278
+ IOSCB_SUBMOD_REG_SIZE);
279
+ memory_region_add_subregion(&s->container, IOSCB_IO_CALIB_DDR_BASE,
280
+ &s->io_calib_ddr);
281
+
282
+ memory_region_init_io(&s->pll_sgmii, OBJECT(s), &mchp_pfsoc_pll_ops, s,
283
+ "mchp.pfsoc.ioscb.pll_sgmii", IOSCB_SUBMOD_REG_SIZE);
284
+ memory_region_add_subregion(&s->container, IOSCB_PLL_SGMII_BASE,
285
+ &s->pll_sgmii);
286
+
287
+ memory_region_init_io(&s->dll_sgmii, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
288
+ "mchp.pfsoc.ioscb.dll_sgmii", IOSCB_SUBMOD_REG_SIZE);
289
+ memory_region_add_subregion(&s->container, IOSCB_DLL_SGMII_BASE,
290
+ &s->dll_sgmii);
291
+
292
+ memory_region_init_io(&s->cfm_sgmii, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
293
+ "mchp.pfsoc.ioscb.cfm_sgmii", IOSCB_SUBMOD_REG_SIZE);
294
+ memory_region_add_subregion(&s->container, IOSCB_CFM_SGMII_BASE,
295
+ &s->cfm_sgmii);
296
+
297
+ memory_region_init_io(&s->bc_sgmii, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
298
+ "mchp.pfsoc.ioscb.bc_sgmii", IOSCB_SUBMOD_REG_SIZE);
299
+ memory_region_add_subregion(&s->container, IOSCB_BC_SGMII_BASE,
300
+ &s->bc_sgmii);
301
+
302
+ memory_region_init_io(&s->io_calib_sgmii, OBJECT(s), &mchp_pfsoc_dummy_ops,
303
+ s, "mchp.pfsoc.ioscb.io_calib_sgmii",
304
+ IOSCB_SUBMOD_REG_SIZE);
305
+ memory_region_add_subregion(&s->container, IOSCB_IO_CALIB_SGMII_BASE,
306
+ &s->io_calib_sgmii);
307
+}
308
+
309
+static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, void *data)
310
+{
311
+ DeviceClass *dc = DEVICE_CLASS(klass);
312
+
313
+ dc->desc = "Microchip PolarFire SoC IOSCB modules";
314
+ dc->realize = mchp_pfsoc_ioscb_realize;
315
+}
316
+
317
+static const TypeInfo mchp_pfsoc_ioscb_info = {
318
+ .name = TYPE_MCHP_PFSOC_IOSCB,
319
+ .parent = TYPE_SYS_BUS_DEVICE,
320
+ .instance_size = sizeof(MchpPfSoCIoscbState),
321
+ .class_init = mchp_pfsoc_ioscb_class_init,
322
+};
323
+
324
+static void mchp_pfsoc_ioscb_register_types(void)
325
+{
326
+ type_register_static(&mchp_pfsoc_ioscb_info);
327
+}
328
+
329
+type_init(mchp_pfsoc_ioscb_register_types)
330
diff --git a/MAINTAINERS b/MAINTAINERS
331
index XXXXXXX..XXXXXXX 100644
332
--- a/MAINTAINERS
333
+++ b/MAINTAINERS
334
@@ -XXX,XX +XXX,XX @@ S: Supported
335
F: hw/riscv/microchip_pfsoc.c
336
F: hw/char/mchp_pfsoc_mmuart.c
337
F: hw/misc/mchp_pfsoc_dmc.c
338
+F: hw/misc/mchp_pfsoc_ioscb.c
339
F: include/hw/riscv/microchip_pfsoc.h
340
F: include/hw/char/mchp_pfsoc_mmuart.h
341
F: include/hw/misc/mchp_pfsoc_dmc.h
342
+F: include/hw/misc/mchp_pfsoc_ioscb.h
343
344
RX Machines
345
-----------
346
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
347
index XXXXXXX..XXXXXXX 100644
348
--- a/hw/misc/Kconfig
349
+++ b/hw/misc/Kconfig
350
@@ -XXX,XX +XXX,XX @@ config AVR_POWER
351
config MCHP_PFSOC_DMC
352
bool
353
354
+config MCHP_PFSOC_IOSCB
355
+ bool
356
+
357
config SIFIVE_TEST
358
bool
359
360
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
361
index XXXXXXX..XXXXXXX 100644
362
--- a/hw/misc/meson.build
363
+++ b/hw/misc/meson.build
364
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c'))
365
366
# RISC-V devices
367
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_DMC', if_true: files('mchp_pfsoc_dmc.c'))
368
+softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_IOSCB', if_true: files('mchp_pfsoc_ioscb.c'))
369
softmmu_ss.add(when: 'CONFIG_SIFIVE_TEST', if_true: files('sifive_test.c'))
370
softmmu_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('sifive_e_prci.c'))
371
softmmu_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'))
372
--
373
2.28.0
374
375
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Provides fw_cfg for the virt machine on riscv. This enables
3
Previously IOSCB_CFG was created as an unimplemented device. With
4
using e.g. ramfb later.
4
the new IOSCB model, its memory range is already covered by the
5
IOSCB hence remove the previous unimplemented device creation in
6
the SoC codes.
5
7
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
10
Message-id: 1603863010-15807-6-git-send-email-bmeng.cn@gmail.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
include/hw/riscv/virt.h | 2 ++
13
include/hw/riscv/microchip_pfsoc.h | 4 +++-
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
14
hw/riscv/microchip_pfsoc.c | 13 ++++++++-----
14
hw/riscv/Kconfig | 1 +
15
hw/riscv/Kconfig | 1 +
15
3 files changed, 33 insertions(+)
16
3 files changed, 12 insertions(+), 6 deletions(-)
16
17
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
18
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
20
--- a/include/hw/riscv/microchip_pfsoc.h
20
+++ b/include/hw/riscv/virt.h
21
+++ b/include/hw/riscv/microchip_pfsoc.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
22
@@ -XXX,XX +XXX,XX @@
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
23
#include "hw/char/mchp_pfsoc_mmuart.h"
23
DeviceState *plic[VIRT_SOCKETS_MAX];
24
#include "hw/dma/sifive_pdma.h"
24
PFlashCFI01 *flash[2];
25
#include "hw/misc/mchp_pfsoc_dmc.h"
25
+ FWCfgState *fw_cfg;
26
+#include "hw/misc/mchp_pfsoc_ioscb.h"
26
27
#include "hw/net/cadence_gem.h"
27
int fdt_size;
28
#include "hw/sd/cadence_sdhci.h"
29
30
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
31
DeviceState *plic;
32
MchpPfSoCDdrSgmiiPhyState ddr_sgmii_phy;
33
MchpPfSoCDdrCfgState ddr_cfg;
34
+ MchpPfSoCIoscbState ioscb;
35
MchpPfSoCMMUartState *serial0;
36
MchpPfSoCMMUartState *serial1;
37
MchpPfSoCMMUartState *serial2;
38
@@ -XXX,XX +XXX,XX @@ enum {
39
MICROCHIP_PFSOC_GPIO2,
40
MICROCHIP_PFSOC_ENVM_CFG,
41
MICROCHIP_PFSOC_ENVM_DATA,
42
- MICROCHIP_PFSOC_IOSCB_CFG,
43
+ MICROCHIP_PFSOC_IOSCB,
44
MICROCHIP_PFSOC_DRAM,
28
};
45
};
29
@@ -XXX,XX +XXX,XX @@ enum {
46
30
VIRT_PLIC,
47
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
31
VIRT_UART0,
32
VIRT_VIRTIO,
33
+ VIRT_FW_CFG,
34
VIRT_FLASH,
35
VIRT_DRAM,
36
VIRT_PCIE_MMIO,
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
38
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/virt.c
49
--- a/hw/riscv/microchip_pfsoc.c
40
+++ b/hw/riscv/virt.c
50
+++ b/hw/riscv/microchip_pfsoc.c
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
51
@@ -XXX,XX +XXX,XX @@
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
52
* 5) SiFive Platform DMA (Direct Memory Access Controller)
43
[VIRT_UART0] = { 0x10000000, 0x100 },
53
* 6) GEM (Gigabit Ethernet MAC Controller)
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
54
* 7) DMC (DDR Memory Controller)
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
55
+ * 8) IOSCB modules
46
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
56
*
47
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
57
* This board currently generates devicetree dynamically that indicates at least
48
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
58
* two harts and up to five harts.
49
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
59
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
50
return dev;
60
[MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
61
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
62
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
63
- [MICROCHIP_PFSOC_IOSCB_CFG] = { 0x37080000, 0x1000 },
64
+ [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
65
[MICROCHIP_PFSOC_DRAM] = { 0x80000000, 0x0 },
66
};
67
68
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
69
70
object_initialize_child(obj, "sd-controller", &s->sdhci,
71
TYPE_CADENCE_SDHCI);
72
+
73
+ object_initialize_child(obj, "ioscb", &s->ioscb, TYPE_MCHP_PFSOC_IOSCB);
51
}
74
}
52
75
53
+static FWCfgState *create_fw_cfg(const MachineState *mc)
76
static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
54
+{
77
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
78
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
56
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
79
envm_data);
57
+ FWCfgState *fw_cfg;
80
58
+ char *nodename;
81
- /* IOSCBCFG */
59
+
82
- create_unimplemented_device("microchip.pfsoc.ioscb.cfg",
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
83
- memmap[MICROCHIP_PFSOC_IOSCB_CFG].base,
61
+ &address_space_memory);
84
- memmap[MICROCHIP_PFSOC_IOSCB_CFG].size);
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
85
+ /* IOSCB */
63
+
86
+ sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
64
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
65
+ qemu_fdt_add_subnode(mc->fdt, nodename);
88
+ memmap[MICROCHIP_PFSOC_IOSCB].base);
66
+ qemu_fdt_setprop_string(mc->fdt, nodename,
89
}
67
+ "compatible", "qemu,fw-cfg-mmio");
90
68
+ qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
91
static void microchip_pfsoc_soc_class_init(ObjectClass *oc, void *data)
69
+ 2, base, 2, size);
70
+ qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
71
+ g_free(nodename);
72
+ return fw_cfg;
73
+}
74
+
75
static void virt_machine_init(MachineState *machine)
76
{
77
const MemMapEntry *memmap = virt_memmap;
78
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
79
start_addr = virt_memmap[VIRT_FLASH].base;
80
}
81
82
+ /*
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
85
+ */
86
+ s->fw_cfg = create_fw_cfg(machine);
87
+ rom_set_fw(s->fw_cfg);
88
+
89
/* Compute the fdt load address in dram */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
91
machine->ram_size, machine->fdt);
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
94
--- a/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
96
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
97
select SIFIVE_PLIC
98
select SIFIVE_TEST
99
select VIRTIO_MMIO
100
+ select FW_CFG_DMA
101
102
config SIFIVE_E
103
bool
97
bool
98
select CADENCE_SDHCI
99
select MCHP_PFSOC_DMC
100
+ select MCHP_PFSOC_IOSCB
101
select MCHP_PFSOC_MMUART
102
select MSI_NONBROKEN
103
select SIFIVE_CLINT
104
--
104
--
105
2.30.1
105
2.28.0
106
106
107
107
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
This adds the documentation to describe what is supported for the
3
This creates a minimum model for Microchip PolarFire SoC SYSREG
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
module. It only implements the ENVM_CR register to tell guest
5
software that eNVM is running at the configured divider rate.
5
6
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
9
Message-id: 1603863010-15807-7-git-send-email-bmeng.cn@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
12
include/hw/misc/mchp_pfsoc_sysreg.h | 39 ++++++++++++
12
docs/system/target-riscv.rst | 1 +
13
hw/misc/mchp_pfsoc_sysreg.c | 99 +++++++++++++++++++++++++++++
13
2 files changed, 90 insertions(+)
14
MAINTAINERS | 2 +
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
15
hw/misc/Kconfig | 3 +
15
16
hw/misc/meson.build | 1 +
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
17
5 files changed, 144 insertions(+)
18
create mode 100644 include/hw/misc/mchp_pfsoc_sysreg.h
19
create mode 100644 hw/misc/mchp_pfsoc_sysreg.c
20
21
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
17
new file mode 100644
22
new file mode 100644
18
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
19
--- /dev/null
24
--- /dev/null
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
25
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
21
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
27
+/*
23
+=============================================================
28
+ * Microchip PolarFire SoC SYSREG module emulation
24
+
29
+ *
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
30
+ * Copyright (c) 2020 Wind River Systems, Inc.
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
31
+ *
27
+
32
+ * Author:
28
+For more details about Microchip PolarFire SoC, please see:
33
+ * Bin Meng <bin.meng@windriver.com>
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
34
+ *
30
+
35
+ * This program is free software; you can redistribute it and/or
31
+The Icicle Kit board information can be found here:
36
+ * modify it under the terms of the GNU General Public License as
32
+https://www.microsemi.com/existing-parts/parts/152514
37
+ * published by the Free Software Foundation; either version 2 or
33
+
38
+ * (at your option) version 3 of the License.
34
+Supported devices
39
+ *
35
+-----------------
40
+ * This program is distributed in the hope that it will be useful,
36
+
41
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
+The ``microchip-icicle-kit`` machine supports the following devices:
42
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
+
43
+ * GNU General Public License for more details.
39
+ * 1 E51 core
44
+ *
40
+ * 4 U54 cores
45
+ * You should have received a copy of the GNU General Public License along
41
+ * Core Level Interruptor (CLINT)
46
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
42
+ * Platform-Level Interrupt Controller (PLIC)
47
+ */
43
+ * L2 Loosely Integrated Memory (L2-LIM)
48
+
44
+ * DDR memory controller
49
+#ifndef MCHP_PFSOC_SYSREG_H
45
+ * 5 MMUARTs
50
+#define MCHP_PFSOC_SYSREG_H
46
+ * 1 DMA controller
51
+
47
+ * 2 GEM Ethernet controllers
52
+#define MCHP_PFSOC_SYSREG_REG_SIZE 0x2000
48
+ * 1 SDHC storage controller
53
+
49
+
54
+typedef struct MchpPfSoCSysregState {
50
+Boot options
55
+ SysBusDevice parent;
51
+------------
56
+ MemoryRegion sysreg;
52
+
57
+} MchpPfSoCSysregState;
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
58
+
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
59
+#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
60
+
56
+support direct kernel loading via the -kernel option. One has to load kernel
61
+#define MCHP_PFSOC_SYSREG(obj) \
57
+from U-Boot.
62
+ OBJECT_CHECK(MchpPfSoCSysregState, (obj), \
58
+
63
+ TYPE_MCHP_PFSOC_SYSREG)
59
+The memory is set to 1537 MiB by default which is the minimum required high
64
+
60
+memory size by HSS. A sanity check on ram size is performed in the machine
65
+#endif /* MCHP_PFSOC_SYSREG_H */
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
66
diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c
62
+than 1537 MiB ram is detected.
67
new file mode 100644
63
+
68
index XXXXXXX..XXXXXXX
64
+Boot the machine
69
--- /dev/null
65
+----------------
70
+++ b/hw/misc/mchp_pfsoc_sysreg.c
66
+
71
@@ -XXX,XX +XXX,XX @@
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
72
+/*
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
73
+ * Microchip PolarFire SoC SYSREG module emulation
69
+in the HSS source tree:
74
+ *
70
+
75
+ * Copyright (c) 2020 Wind River Systems, Inc.
71
+.. code-block:: bash
76
+ *
72
+
77
+ * Author:
73
+ $ export CROSS_COMPILE=riscv64-linux-
78
+ * Bin Meng <bin.meng@windriver.com>
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
79
+ *
75
+ $ make BOARD=mpfs-icicle-kit-es
80
+ * This program is free software; you can redistribute it and/or
76
+
81
+ * modify it under the terms of the GNU General Public License as
77
+Download the official SD card image released by Microchip and prepare it for
82
+ * published by the Free Software Foundation; either version 2 or
78
+QEMU usage:
83
+ * (at your option) version 3 of the License.
79
+
84
+ *
80
+.. code-block:: bash
85
+ * This program is distributed in the hope that it will be useful,
81
+
86
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
87
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
88
+ * GNU General Public License for more details.
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
89
+ *
85
+
90
+ * You should have received a copy of the GNU General Public License along
86
+Then we can boot the machine by:
91
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
87
+
92
+ */
88
+.. code-block:: bash
93
+
89
+
94
+#include "qemu/osdep.h"
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
95
+#include "qemu/bitops.h"
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
96
+#include "qemu/log.h"
92
+ -nic user,model=cadence_gem \
97
+#include "qapi/error.h"
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
98
+#include "hw/hw.h"
94
+ -display none -serial stdio \
99
+#include "hw/sysbus.h"
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
100
+#include "hw/misc/mchp_pfsoc_sysreg.h"
96
+ -serial chardev:serial1
101
+
97
+
102
+#define ENVM_CR 0xb8
98
+With above command line, current terminal session will be used for the first
103
+
99
+serial port. Open another terminal window, and use `minicom` to connect the
104
+static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
100
+second serial port.
105
+ unsigned size)
101
+
106
+{
102
+.. code-block:: bash
107
+ uint32_t val = 0;
103
+
108
+
104
+ $ minicom -D unix\#serial1.sock
109
+ switch (offset) {
105
+
110
+ case ENVM_CR:
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
111
+ /* Indicate the eNVM is running at the configured divider rate */
107
+second serial port. U-Boot will automatically load the Linux kernel from
112
+ val = BIT(6);
108
+the SD card image.
113
+ break;
109
+
114
+ default:
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
115
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
116
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
117
+ __func__, size, offset);
118
+ break;
119
+ }
120
+
121
+ return val;
122
+}
123
+
124
+static void mchp_pfsoc_sysreg_write(void *opaque, hwaddr offset,
125
+ uint64_t value, unsigned size)
126
+{
127
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
128
+ "(size %d, value 0x%" PRIx64
129
+ ", offset 0x%" HWADDR_PRIx ")\n",
130
+ __func__, size, value, offset);
131
+}
132
+
133
+static const MemoryRegionOps mchp_pfsoc_sysreg_ops = {
134
+ .read = mchp_pfsoc_sysreg_read,
135
+ .write = mchp_pfsoc_sysreg_write,
136
+ .endianness = DEVICE_LITTLE_ENDIAN,
137
+};
138
+
139
+static void mchp_pfsoc_sysreg_realize(DeviceState *dev, Error **errp)
140
+{
141
+ MchpPfSoCSysregState *s = MCHP_PFSOC_SYSREG(dev);
142
+
143
+ memory_region_init_io(&s->sysreg, OBJECT(dev),
144
+ &mchp_pfsoc_sysreg_ops, s,
145
+ "mchp.pfsoc.sysreg",
146
+ MCHP_PFSOC_SYSREG_REG_SIZE);
147
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysreg);
148
+}
149
+
150
+static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, void *data)
151
+{
152
+ DeviceClass *dc = DEVICE_CLASS(klass);
153
+
154
+ dc->desc = "Microchip PolarFire SoC SYSREG module";
155
+ dc->realize = mchp_pfsoc_sysreg_realize;
156
+}
157
+
158
+static const TypeInfo mchp_pfsoc_sysreg_info = {
159
+ .name = TYPE_MCHP_PFSOC_SYSREG,
160
+ .parent = TYPE_SYS_BUS_DEVICE,
161
+ .instance_size = sizeof(MchpPfSoCSysregState),
162
+ .class_init = mchp_pfsoc_sysreg_class_init,
163
+};
164
+
165
+static void mchp_pfsoc_sysreg_register_types(void)
166
+{
167
+ type_register_static(&mchp_pfsoc_sysreg_info);
168
+}
169
+
170
+type_init(mchp_pfsoc_sysreg_register_types)
171
diff --git a/MAINTAINERS b/MAINTAINERS
112
index XXXXXXX..XXXXXXX 100644
172
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/system/target-riscv.rst
173
--- a/MAINTAINERS
114
+++ b/docs/system/target-riscv.rst
174
+++ b/MAINTAINERS
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
175
@@ -XXX,XX +XXX,XX @@ F: hw/riscv/microchip_pfsoc.c
116
.. toctree::
176
F: hw/char/mchp_pfsoc_mmuart.c
117
:maxdepth: 1
177
F: hw/misc/mchp_pfsoc_dmc.c
118
178
F: hw/misc/mchp_pfsoc_ioscb.c
119
+ riscv/microchip-icicle-kit
179
+F: hw/misc/mchp_pfsoc_sysreg.c
120
riscv/sifive_u
180
F: include/hw/riscv/microchip_pfsoc.h
121
181
F: include/hw/char/mchp_pfsoc_mmuart.h
122
RISC-V CPU features
182
F: include/hw/misc/mchp_pfsoc_dmc.h
183
F: include/hw/misc/mchp_pfsoc_ioscb.h
184
+F: include/hw/misc/mchp_pfsoc_sysreg.h
185
186
RX Machines
187
-----------
188
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
189
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/misc/Kconfig
191
+++ b/hw/misc/Kconfig
192
@@ -XXX,XX +XXX,XX @@ config MCHP_PFSOC_DMC
193
config MCHP_PFSOC_IOSCB
194
bool
195
196
+config MCHP_PFSOC_SYSREG
197
+ bool
198
+
199
config SIFIVE_TEST
200
bool
201
202
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
203
index XXXXXXX..XXXXXXX 100644
204
--- a/hw/misc/meson.build
205
+++ b/hw/misc/meson.build
206
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c'))
207
# RISC-V devices
208
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_DMC', if_true: files('mchp_pfsoc_dmc.c'))
209
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_IOSCB', if_true: files('mchp_pfsoc_ioscb.c'))
210
+softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_SYSREG', if_true: files('mchp_pfsoc_sysreg.c'))
211
softmmu_ss.add(when: 'CONFIG_SIFIVE_TEST', if_true: files('sifive_test.c'))
212
softmmu_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('sifive_e_prci.c'))
213
softmmu_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'))
123
--
214
--
124
2.30.1
215
2.28.0
125
216
126
217
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The current condition for the use of background registers only
3
Previously SYSREG was created as an unimplemented device. Now that
4
considers the hypervisor load and store instructions,
4
we have a simple SYSREG module, connect it.
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
6
5
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
8
Message-id: 1603863010-15807-8-git-send-email-bmeng.cn@gmail.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
10
---
12
target/riscv/cpu_helper.c | 2 +-
11
include/hw/riscv/microchip_pfsoc.h | 2 ++
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
hw/riscv/microchip_pfsoc.c | 9 ++++++---
13
hw/riscv/Kconfig | 1 +
14
3 files changed, 9 insertions(+), 3 deletions(-)
14
15
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
--- a/include/hw/riscv/microchip_pfsoc.h
18
+++ b/target/riscv/cpu_helper.c
19
+++ b/include/hw/riscv/microchip_pfsoc.h
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
@@ -XXX,XX +XXX,XX @@
20
* was called. Background registers will be used if the guest has
21
#include "hw/dma/sifive_pdma.h"
21
* forced a two stage translation to be on (in HS or M mode).
22
#include "hw/misc/mchp_pfsoc_dmc.h"
22
*/
23
#include "hw/misc/mchp_pfsoc_ioscb.h"
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
24
+#include "hw/misc/mchp_pfsoc_sysreg.h"
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
25
#include "hw/net/cadence_gem.h"
25
use_background = true;
26
#include "hw/sd/cadence_sdhci.h"
27
28
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
29
MchpPfSoCMMUartState *serial2;
30
MchpPfSoCMMUartState *serial3;
31
MchpPfSoCMMUartState *serial4;
32
+ MchpPfSoCSysregState sysreg;
33
SiFivePDMAState dma;
34
CadenceGEMState gem0;
35
CadenceGEMState gem1;
36
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/microchip_pfsoc.c
39
+++ b/hw/riscv/microchip_pfsoc.c
40
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
41
object_initialize_child(obj, "dma-controller", &s->dma,
42
TYPE_SIFIVE_PDMA);
43
44
+ object_initialize_child(obj, "sysreg", &s->sysreg,
45
+ TYPE_MCHP_PFSOC_SYSREG);
46
+
47
object_initialize_child(obj, "ddr-sgmii-phy", &s->ddr_sgmii_phy,
48
TYPE_MCHP_PFSOC_DDR_SGMII_PHY);
49
object_initialize_child(obj, "ddr-cfg", &s->ddr_cfg,
50
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
26
}
51
}
27
52
53
/* SYSREG */
54
- create_unimplemented_device("microchip.pfsoc.sysreg",
55
- memmap[MICROCHIP_PFSOC_SYSREG].base,
56
- memmap[MICROCHIP_PFSOC_SYSREG].size);
57
+ sysbus_realize(SYS_BUS_DEVICE(&s->sysreg), errp);
58
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
59
+ memmap[MICROCHIP_PFSOC_SYSREG].base);
60
61
/* MPUCFG */
62
create_unimplemented_device("microchip.pfsoc.mpucfg",
63
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/riscv/Kconfig
66
+++ b/hw/riscv/Kconfig
67
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
68
select MCHP_PFSOC_DMC
69
select MCHP_PFSOC_IOSCB
70
select MCHP_PFSOC_MMUART
71
+ select MCHP_PFSOC_SYSREG
72
select MSI_NONBROKEN
73
select SIFIVE_CLINT
74
select SIFIVE_PDMA
28
--
75
--
29
2.30.1
76
2.28.0
30
77
31
78
diff view generated by jsdifflib
1
From: Alexander Wagner <alexander.wagner@ulal.de>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
3
Somehow HSS needs to access address 0 [1] for the DDR calibration data
4
the newest received byte. The rx_level variable is added to allow the use of
4
which is in the chipset's reserved memory. Let's map it.
5
the existing OpenTitan driver libraries.
6
5
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
6
[1] See the config_copy() calls in various places in ddr_setup() in
7
the HSS source codes.
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
11
Message-id: 1603863010-15807-9-git-send-email-bmeng.cn@gmail.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
include/hw/char/ibex_uart.h | 4 ++++
14
include/hw/riscv/microchip_pfsoc.h | 1 +
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
15
hw/riscv/microchip_pfsoc.c | 11 ++++++++++-
14
2 files changed, 22 insertions(+), 5 deletions(-)
16
2 files changed, 11 insertions(+), 1 deletion(-)
15
17
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
18
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
20
--- a/include/hw/riscv/microchip_pfsoc.h
19
+++ b/include/hw/char/ibex_uart.h
21
+++ b/include/hw/riscv/microchip_pfsoc.h
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
22
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipIcicleKitState {
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
23
TYPE_MICROCHIP_ICICLE_KIT_MACHINE)
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
24
23
REG32(FIFO_STATUS, 0x20)
25
enum {
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
26
+ MICROCHIP_PFSOC_RSVD0,
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
27
MICROCHIP_PFSOC_DEBUG,
26
REG32(OVRD, 0x24)
28
MICROCHIP_PFSOC_E51_DTIM,
27
REG32(VAL, 0x28)
29
MICROCHIP_PFSOC_BUSERR_UNIT0,
28
REG32(TIMEOUT_CTRL, 0x2c)
30
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
31
index XXXXXXX..XXXXXXX 100644
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
32
--- a/hw/riscv/microchip_pfsoc.c
31
uint32_t tx_level;
33
+++ b/hw/riscv/microchip_pfsoc.c
32
34
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
33
+ uint32_t rx_level;
35
hwaddr base;
36
hwaddr size;
37
} microchip_pfsoc_memmap[] = {
38
- [MICROCHIP_PFSOC_DEBUG] = { 0x0, 0x1000 },
39
+ [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
40
+ [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
41
[MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
42
[MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
43
[MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
44
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
45
MicrochipPFSoCState *s = MICROCHIP_PFSOC(dev);
46
const struct MemmapEntry *memmap = microchip_pfsoc_memmap;
47
MemoryRegion *system_memory = get_system_memory();
48
+ MemoryRegion *rsvd0_mem = g_new(MemoryRegion, 1);
49
MemoryRegion *e51_dtim_mem = g_new(MemoryRegion, 1);
50
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
51
MemoryRegion *envm_data = g_new(MemoryRegion, 1);
52
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
53
qdev_realize(DEVICE(&s->e_cluster), NULL, &error_abort);
54
qdev_realize(DEVICE(&s->u_cluster), NULL, &error_abort);
55
56
+ /* Reserved Memory at address 0 */
57
+ memory_region_init_ram(rsvd0_mem, NULL, "microchip.pfsoc.rsvd0_mem",
58
+ memmap[MICROCHIP_PFSOC_RSVD0].size, &error_fatal);
59
+ memory_region_add_subregion(system_memory,
60
+ memmap[MICROCHIP_PFSOC_RSVD0].base,
61
+ rsvd0_mem);
34
+
62
+
35
QEMUTimer *fifo_trigger_handle;
63
/* E51 DTIM */
36
uint64_t char_tx_time;
64
memory_region_init_ram(e51_dtim_mem, NULL, "microchip.pfsoc.e51_dtim_mem",
37
65
memmap[MICROCHIP_PFSOC_E51_DTIM].size, &error_fatal);
38
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/char/ibex_uart.c
41
+++ b/hw/char/ibex_uart.c
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
43
{
44
IbexUartState *s = opaque;
45
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
49
return 1;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
53
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
56
+ /* The RXFULL is set after receiving a single byte
57
+ * as the FIFO buffers are not yet implemented.
58
+ */
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
60
+ s->rx_level += 1;
61
62
if (size > rx_fifo_level) {
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
65
s->uart_timeout_ctrl = 0x00000000;
66
67
s->tx_level = 0;
68
+ s->rx_level = 0;
69
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
71
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
73
74
case R_RDATA:
75
retvalue = s->uart_rdata;
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
78
qemu_chr_fe_accept_input(&s->chr);
79
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
82
+ s->rx_level -= 1;
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
84
+ if (s->rx_level == 0) {
85
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
86
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
87
+ }
88
}
89
break;
90
case R_WDATA:
91
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
92
case R_FIFO_STATUS:
93
retvalue = s->uart_fifo_status;
94
95
- retvalue |= s->tx_level & 0x1F;
96
+ retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
97
+ retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
98
99
qemu_log_mask(LOG_UNIMP,
100
"%s: RX fifos are not supported\n", __func__);
101
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
102
s->uart_fifo_ctrl = value;
103
104
if (value & R_FIFO_CTRL_RXRST_MASK) {
105
+ s->rx_level = 0;
106
qemu_log_mask(LOG_UNIMP,
107
"%s: RX fifos are not supported\n", __func__);
108
}
109
--
66
--
110
2.30.1
67
2.28.0
111
68
112
69
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
If PMP permission of any address has been changed by updating PMP entry,
3
When system memory is larger than 1 GiB (high memory), PolarFire SoC
4
flush all TLB pages to prevent from getting old permission.
4
maps it at address 0x10_0000_0000. Address 0xC000_0000 and above is
5
aliased to the same 1 GiB low memory with different cache attributes.
5
6
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
At present QEMU maps the system memory contiguously from 0x8000_0000.
8
This corrects the wrong QEMU logic. Note address 0x14_0000_0000 is
9
the alias to the high memory, and even physical memory is only 1 GiB,
10
the HSS codes still tries to probe the high memory alias address.
11
It seems there is no issue on the real hardware, so we will have to
12
take that into the consideration in our emulation. Due to this, we
13
we increase the default system memory size to 1537 MiB (the minimum
14
required high memory size by HSS) so that user gets notified an error
15
when less than 1537 MiB is specified.
16
17
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
19
Message-id: 20201101170538.3732-1-bmeng.cn@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
21
---
11
target/riscv/pmp.c | 4 ++++
22
include/hw/riscv/microchip_pfsoc.h | 5 ++-
12
1 file changed, 4 insertions(+)
23
hw/riscv/microchip_pfsoc.c | 50 ++++++++++++++++++++++++++----
24
2 files changed, 48 insertions(+), 7 deletions(-)
13
25
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
26
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
15
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
28
--- a/include/hw/riscv/microchip_pfsoc.h
17
+++ b/target/riscv/pmp.c
29
+++ b/include/hw/riscv/microchip_pfsoc.h
18
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ enum {
19
#include "qapi/error.h"
31
MICROCHIP_PFSOC_ENVM_CFG,
20
#include "cpu.h"
32
MICROCHIP_PFSOC_ENVM_DATA,
21
#include "trace.h"
33
MICROCHIP_PFSOC_IOSCB,
22
+#include "exec/exec-all.h"
34
- MICROCHIP_PFSOC_DRAM,
23
35
+ MICROCHIP_PFSOC_DRAM_LO,
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
36
+ MICROCHIP_PFSOC_DRAM_LO_ALIAS,
25
uint8_t val);
37
+ MICROCHIP_PFSOC_DRAM_HI,
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
38
+ MICROCHIP_PFSOC_DRAM_HI_ALIAS
27
cfg_val = (val >> 8 * i) & 0xff;
39
};
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
40
29
}
41
enum {
42
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/riscv/microchip_pfsoc.c
45
+++ b/hw/riscv/microchip_pfsoc.c
46
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
47
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
48
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
49
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
50
- [MICROCHIP_PFSOC_DRAM] = { 0x80000000, 0x0 },
51
+ [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
52
+ [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
53
+ [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
54
+ [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
55
};
56
57
static void microchip_pfsoc_soc_instance_init(Object *obj)
58
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
59
const struct MemmapEntry *memmap = microchip_pfsoc_memmap;
60
MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(machine);
61
MemoryRegion *system_memory = get_system_memory();
62
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
63
+ MemoryRegion *mem_low = g_new(MemoryRegion, 1);
64
+ MemoryRegion *mem_low_alias = g_new(MemoryRegion, 1);
65
+ MemoryRegion *mem_high = g_new(MemoryRegion, 1);
66
+ MemoryRegion *mem_high_alias = g_new(MemoryRegion, 1);
67
+ uint64_t mem_high_size;
68
DriveInfo *dinfo = drive_get_next(IF_SD);
69
70
/* Sanity check on RAM size */
71
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
72
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
73
74
/* Register RAM */
75
- memory_region_init_ram(main_mem, NULL, "microchip.icicle.kit.ram",
76
- machine->ram_size, &error_fatal);
77
+ memory_region_init_ram(mem_low, NULL, "microchip.icicle.kit.ram_low",
78
+ memmap[MICROCHIP_PFSOC_DRAM_LO].size,
79
+ &error_fatal);
80
+ memory_region_init_alias(mem_low_alias, NULL,
81
+ "microchip.icicle.kit.ram_low.alias",
82
+ mem_low, 0,
83
+ memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].size);
84
+ memory_region_add_subregion(system_memory,
85
+ memmap[MICROCHIP_PFSOC_DRAM_LO].base,
86
+ mem_low);
87
memory_region_add_subregion(system_memory,
88
- memmap[MICROCHIP_PFSOC_DRAM].base, main_mem);
89
+ memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].base,
90
+ mem_low_alias);
30
+
91
+
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
92
+ mem_high_size = machine->ram_size - 1 * GiB;
32
+ tlb_flush(env_cpu(env));
93
+
94
+ memory_region_init_ram(mem_high, NULL, "microchip.icicle.kit.ram_high",
95
+ mem_high_size, &error_fatal);
96
+ memory_region_init_alias(mem_high_alias, NULL,
97
+ "microchip.icicle.kit.ram_high.alias",
98
+ mem_high, 0, mem_high_size);
99
+ memory_region_add_subregion(system_memory,
100
+ memmap[MICROCHIP_PFSOC_DRAM_HI].base,
101
+ mem_high);
102
+ memory_region_add_subregion(system_memory,
103
+ memmap[MICROCHIP_PFSOC_DRAM_HI_ALIAS].base,
104
+ mem_high_alias);
105
106
/* Load the firmware */
107
riscv_find_and_load_firmware(machine, BIOS_FILENAME, RESET_VECTOR, NULL);
108
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data)
109
MICROCHIP_PFSOC_COMPUTE_CPU_COUNT;
110
mc->min_cpus = MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT + 1;
111
mc->default_cpus = mc->min_cpus;
112
- mc->default_ram_size = 1 * GiB;
113
+
114
+ /*
115
+ * Map 513 MiB high memory, the mimimum required high memory size, because
116
+ * HSS will do memory test against the high memory address range regardless
117
+ * of physical memory installed.
118
+ *
119
+ * See memory_tests() in mss_ddr.c in the HSS source code.
120
+ */
121
+ mc->default_ram_size = 1537 * MiB;
33
}
122
}
34
123
35
124
static const TypeInfo microchip_icicle_kit_machine_typeinfo = {
36
--
125
--
37
2.30.1
126
2.28.0
38
127
39
128
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
The latest SD card image [1] released by Microchip ships a Linux
4
been updated to use a register mapped at 0x4f000000 instead of a
4
kernel with built-in PolarFire SoC I2C driver support. The device
5
GPIO to control whether eMMC or SD card is to be used. With this
5
tree file includes the description for the I2C1 node hence kernel
6
support the same HSS image can be used for both eMMC and SD card
6
tries to probe the I2C1 device during boot.
7
boot flow, while previously two different board configurations were
8
used. This is undocumented but one can take a look at the HSS code
9
HSS_MMCInit() in services/mmc/mmc_api.c.
10
7
11
With this commit, HSS image built from 2020.12 release boots again.
8
It is enough to create an unimplemented device for I2C1 to allow
9
the kernel to continue booting to the shell.
10
11
[1] ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
12
12
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
15
Message-id: 1603863010-15807-11-git-send-email-bmeng.cn@gmail.com
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
17
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
18
include/hw/riscv/microchip_pfsoc.h | 1 +
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
20
2 files changed, 7 insertions(+)
20
2 files changed, 7 insertions(+)
21
21
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
23
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
24
--- a/include/hw/riscv/microchip_pfsoc.h
25
+++ b/include/hw/riscv/microchip_pfsoc.h
25
+++ b/include/hw/riscv/microchip_pfsoc.h
26
@@ -XXX,XX +XXX,XX @@ enum {
26
@@ -XXX,XX +XXX,XX @@ enum {
27
MICROCHIP_PFSOC_ENVM_DATA,
27
MICROCHIP_PFSOC_MMUART2,
28
MICROCHIP_PFSOC_QSPI_XIP,
28
MICROCHIP_PFSOC_MMUART3,
29
MICROCHIP_PFSOC_IOSCB,
29
MICROCHIP_PFSOC_MMUART4,
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
30
+ MICROCHIP_PFSOC_I2C1,
31
MICROCHIP_PFSOC_DRAM_LO,
31
MICROCHIP_PFSOC_GEM0,
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
32
MICROCHIP_PFSOC_GEM1,
33
MICROCHIP_PFSOC_DRAM_HI,
33
MICROCHIP_PFSOC_GPIO0,
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
35
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/riscv/microchip_pfsoc.c
36
--- a/hw/riscv/microchip_pfsoc.c
37
+++ b/hw/riscv/microchip_pfsoc.c
37
+++ b/hw/riscv/microchip_pfsoc.c
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
38
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
39
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
40
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
41
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
42
+ [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
43
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
44
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
45
[MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
47
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
48
serial_hd(4));
49
49
50
+ /* eMMC/SD mux */
50
+ /* I2C1 */
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
51
+ create_unimplemented_device("microchip.pfsoc.i2c1",
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
52
+ memmap[MICROCHIP_PFSOC_I2C1].base,
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
53
+ memmap[MICROCHIP_PFSOC_I2C1].size);
54
+
54
+
55
/* QSPI Flash */
55
/* GEMs */
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
56
57
"microchip.pfsoc.qspi_xip",
57
nd = &nd_table[0];
58
--
58
--
59
2.30.1
59
2.28.0
60
60
61
61
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Xinhao Zhang <zhangxinhao1@huawei.com>
2
2
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
3
Fix code style. Space required before the open parenthesis '('.
4
is not enabled.
5
4
6
If -1 is returned, exception will be raised and cs->exception_index will
5
Signed-off-by: Xinhao Zhang <zhangxinhao1@huawei.com>
7
be set to the negative return value. The exception will then be treated
6
Signed-off-by: Kai Deng <dengkai1@huawei.com>
8
as an instruction access fault instead of illegal instruction fault.
7
Reported-by: Euler Robot <euler.robot@huawei.com>
9
8
Reviewed-by: Bin Meng <bin.meng@windriver.com>
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
10
Message-id: 20201030004815.4172849-1-zhangxinhao1@huawei.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
12
---
16
target/riscv/csr.c | 2 +-
13
target/riscv/csr.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
15
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
18
--- a/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
20
@@ -XXX,XX +XXX,XX @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
24
if (env->misa & RVV) {
21
if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
25
return 0;
22
return -RISCV_EXCP_ILLEGAL_INST;
26
}
23
} else {
27
- return -1;
24
- if((val ^ env->satp) & SATP_ASID) {
28
+ return -RISCV_EXCP_ILLEGAL_INST;
25
+ if ((val ^ env->satp) & SATP_ASID) {
29
}
26
tlb_flush(env_cpu(env));
30
27
}
31
static int ctr(CPURISCVState *env, int csrno)
28
env->satp = val;
32
--
29
--
33
2.30.1
30
2.28.0
34
31
35
32
diff view generated by jsdifflib