1
The following changes since commit c0444009147aa935d52d5acfc6b70094bb42b0dd:
1
The following changes since commit c95bd5ff1660883d15ad6e0005e4c8571604f51a:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qmp-2020-10-27' into staging (2020-10-29 10:03:32 +0000)
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-fixes-20210322' into staging (2021-03-22 14:26:13 +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-20201029
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210322-2
8
8
9
for you to fetch changes up to e041badcd4ac644a67f02f8765095a5ff7a24d47:
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
10
10
11
hw/riscv: microchip_pfsoc: Hook the I2C1 controller (2020-10-29 07:11:14 -0700)
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
This series adds support for migration to RISC-V QEMU and expands the
14
RISC-V PR for 6.0
15
Microchip PFSoC to allow unmodified HSS and Linux boots.
15
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
16
24
17
----------------------------------------------------------------
25
----------------------------------------------------------------
18
Anup Patel (2):
26
Alexander Wagner (1):
19
hw/riscv: sifive_u: Allow passing custom DTB
27
hw/char: disable ibex uart receive if the buffer is full
20
hw/riscv: virt: Allow passing custom DTB
21
28
22
Bin Meng (10):
29
Asherah Connor (2):
23
hw/riscv: microchip_pfsoc: Document where to look at the SoC memory maps
30
hw/riscv: Add fw_cfg support to virt
24
hw/misc: Add Microchip PolarFire SoC DDR Memory Controller support
31
hw/riscv: allow ramfb on virt
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
33
32
34
Yifei Jiang (6):
33
Bin Meng (3):
35
target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
34
hw/block: m25p80: Support fast read for SST flashes
36
target/riscv: Add basic vmstate description of CPU
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
37
target/riscv: Add PMP state description
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
38
target/riscv: Add H extension state description
39
target/riscv: Add V extension state description
40
target/riscv: Add sifive_plic vmstate
41
37
42
include/hw/intc/sifive_plic.h | 1 +
38
Frank Chang (1):
43
include/hw/misc/mchp_pfsoc_dmc.h | 56 +++++++++
39
target/riscv: fix vs() to return proper error code
44
include/hw/misc/mchp_pfsoc_ioscb.h | 50 ++++++++
45
include/hw/misc/mchp_pfsoc_sysreg.h | 39 ++++++
46
include/hw/riscv/microchip_pfsoc.h | 18 ++-
47
target/riscv/cpu.h | 24 ++--
48
target/riscv/cpu_bits.h | 19 +--
49
target/riscv/internals.h | 4 +
50
target/riscv/pmp.h | 2 +
51
hw/intc/sifive_plic.c | 26 +++-
52
hw/misc/mchp_pfsoc_dmc.c | 216 ++++++++++++++++++++++++++++++++
53
hw/misc/mchp_pfsoc_ioscb.c | 242 ++++++++++++++++++++++++++++++++++++
54
hw/misc/mchp_pfsoc_sysreg.c | 99 +++++++++++++++
55
hw/riscv/microchip_pfsoc.c | 123 +++++++++++++++---
56
hw/riscv/sifive_u.c | 28 +++--
57
hw/riscv/virt.c | 27 ++--
58
target/riscv/cpu.c | 16 +--
59
target/riscv/cpu_helper.c | 35 ++----
60
target/riscv/csr.c | 18 +--
61
target/riscv/machine.c | 196 +++++++++++++++++++++++++++++
62
target/riscv/op_helper.c | 11 +-
63
target/riscv/pmp.c | 29 +++--
64
MAINTAINERS | 6 +
65
hw/misc/Kconfig | 9 ++
66
hw/misc/meson.build | 3 +
67
hw/riscv/Kconfig | 3 +
68
target/riscv/meson.build | 3 +-
69
27 files changed, 1177 insertions(+), 126 deletions(-)
70
create mode 100644 include/hw/misc/mchp_pfsoc_dmc.h
71
create mode 100644 include/hw/misc/mchp_pfsoc_ioscb.h
72
create mode 100644 include/hw/misc/mchp_pfsoc_sysreg.h
73
create mode 100644 hw/misc/mchp_pfsoc_dmc.c
74
create mode 100644 hw/misc/mchp_pfsoc_ioscb.c
75
create mode 100644 hw/misc/mchp_pfsoc_sysreg.c
76
create mode 100644 target/riscv/machine.c
77
40
41
Georg Kotheimer (6):
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
43
target/riscv: Make VSTIP and VSEIP read-only in hip
44
target/riscv: Use background registers also for MSTATUS_MPV
45
target/riscv: Fix read and write accesses to vsip and vsie
46
target/riscv: Add proper two-stage lookup exception detection
47
target/riscv: Prevent lost illegal instruction exceptions
48
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: Yifei Jiang <jiangyifei@huawei.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
In the case of supporting V extension, add V extension description
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
4
to vmstate_riscv_cpu.
4
is not enabled.
5
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
If -1 is returned, exception will be raised and cs->exception_index will
7
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
7
be set to the negative return value. The exception will then be treated
8
as an instruction access fault instead of illegal instruction fault.
9
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20201026115530.304-6-jiangyifei@huawei.com
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
target/riscv/machine.c | 25 +++++++++++++++++++++++++
16
target/riscv/csr.c | 2 +-
14
1 file changed, 25 insertions(+)
17
1 file changed, 1 insertion(+), 1 deletion(-)
15
18
16
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/machine.c
21
--- a/target/riscv/csr.c
19
+++ b/target/riscv/machine.c
22
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static bool hyper_needed(void *opaque)
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
21
return riscv_has_ext(env, RVH);
24
if (env->misa & RVV) {
25
return 0;
26
}
27
- return -1;
28
+ return -RISCV_EXCP_ILLEGAL_INST;
22
}
29
}
23
30
24
+static bool vector_needed(void *opaque)
31
static int ctr(CPURISCVState *env, int csrno)
25
+{
26
+ RISCVCPU *cpu = opaque;
27
+ CPURISCVState *env = &cpu->env;
28
+
29
+ return riscv_has_ext(env, RVV);
30
+}
31
+
32
+static const VMStateDescription vmstate_vector = {
33
+ .name = "cpu/vector",
34
+ .version_id = 1,
35
+ .minimum_version_id = 1,
36
+ .needed = vector_needed,
37
+ .fields = (VMStateField[]) {
38
+ VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
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
57
}
58
};
59
--
32
--
60
2.28.0
33
2.30.1
61
34
62
35
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Alexander Wagner <alexander.wagner@ulal.de>
2
2
3
When system memory is larger than 1 GiB (high memory), PolarFire SoC
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
4
maps it at address 0x10_0000_0000. Address 0xC000_0000 and above is
4
the newest received byte. The rx_level variable is added to allow the use of
5
aliased to the same 1 GiB low memory with different cache attributes.
5
the existing OpenTitan driver libraries.
6
6
7
At present QEMU maps the system memory contiguously from 0x8000_0000.
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
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 2 GiB so that user gets
14
notified an error when less than 2 GiB is specified.
15
16
Signed-off-by: Bin Meng <bin.meng@windriver.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-id: 1603863010-15807-10-git-send-email-bmeng.cn@gmail.com
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
11
---
21
include/hw/riscv/microchip_pfsoc.h | 5 +++-
12
include/hw/char/ibex_uart.h | 4 ++++
22
hw/riscv/microchip_pfsoc.c | 48 ++++++++++++++++++++++++++----
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
23
2 files changed, 46 insertions(+), 7 deletions(-)
14
2 files changed, 22 insertions(+), 5 deletions(-)
24
15
25
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/riscv/microchip_pfsoc.h
18
--- a/include/hw/char/ibex_uart.h
28
+++ b/include/hw/riscv/microchip_pfsoc.h
19
+++ b/include/hw/char/ibex_uart.h
29
@@ -XXX,XX +XXX,XX @@ enum {
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
30
MICROCHIP_PFSOC_ENVM_CFG,
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
31
MICROCHIP_PFSOC_ENVM_DATA,
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
32
MICROCHIP_PFSOC_IOSCB,
23
REG32(FIFO_STATUS, 0x20)
33
- MICROCHIP_PFSOC_DRAM,
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
34
+ MICROCHIP_PFSOC_DRAM_LO,
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
35
+ MICROCHIP_PFSOC_DRAM_LO_ALIAS,
26
REG32(OVRD, 0x24)
36
+ MICROCHIP_PFSOC_DRAM_HI,
27
REG32(VAL, 0x28)
37
+ MICROCHIP_PFSOC_DRAM_HI_ALIAS
28
REG32(TIMEOUT_CTRL, 0x2c)
38
};
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
39
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
40
enum {
31
uint32_t tx_level;
41
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
32
33
+ uint32_t rx_level;
34
+
35
QEMUTimer *fifo_trigger_handle;
36
uint64_t char_tx_time;
37
38
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
42
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/riscv/microchip_pfsoc.c
40
--- a/hw/char/ibex_uart.c
44
+++ b/hw/riscv/microchip_pfsoc.c
41
+++ b/hw/char/ibex_uart.c
45
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
46
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
43
{
47
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
44
IbexUartState *s = opaque;
48
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
45
49
- [MICROCHIP_PFSOC_DRAM] = { 0x80000000, 0x0 },
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
50
+ [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
51
+ [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
52
+ [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
49
return 1;
53
+ [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
50
}
54
};
51
55
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
56
static void microchip_pfsoc_soc_instance_init(Object *obj)
53
57
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
58
const struct MemmapEntry *memmap = microchip_pfsoc_memmap;
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
59
MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(machine);
56
+ /* The RXFULL is set after receiving a single byte
60
MemoryRegion *system_memory = get_system_memory();
57
+ * as the FIFO buffers are not yet implemented.
61
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
62
+ MemoryRegion *mem_low = g_new(MemoryRegion, 1);
63
+ MemoryRegion *mem_low_alias = g_new(MemoryRegion, 1);
64
+ MemoryRegion *mem_high = g_new(MemoryRegion, 1);
65
+ MemoryRegion *mem_high_alias = g_new(MemoryRegion, 1);
66
+ uint64_t mem_high_size;
67
DriveInfo *dinfo = drive_get_next(IF_SD);
68
69
/* Sanity check on RAM size */
70
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
71
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
72
73
/* Register RAM */
74
- memory_region_init_ram(main_mem, NULL, "microchip.icicle.kit.ram",
75
- machine->ram_size, &error_fatal);
76
+ memory_region_init_ram(mem_low, NULL, "microchip.icicle.kit.ram_low",
77
+ memmap[MICROCHIP_PFSOC_DRAM_LO].size,
78
+ &error_fatal);
79
+ memory_region_init_alias(mem_low_alias, NULL,
80
+ "microchip.icicle.kit.ram_low.alias",
81
+ mem_low, 0,
82
+ memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].size);
83
+ memory_region_add_subregion(system_memory,
84
+ memmap[MICROCHIP_PFSOC_DRAM_LO].base,
85
+ mem_low);
86
+ memory_region_add_subregion(system_memory,
87
+ memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].base,
88
+ mem_low_alias);
89
+
90
+ /*
91
+ * Map 1 GiB high memory because HSS will do memory test against the high
92
+ * memory address range regardless of physical memory installed.
93
+ *
94
+ * See memory_tests() in mss_ddr.c in the HSS source code.
95
+ */
58
+ */
96
+ mem_high_size = machine->ram_size - 1 * GiB;
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
97
+
60
+ s->rx_level += 1;
98
+ memory_region_init_ram(mem_high, NULL, "microchip.icicle.kit.ram_high",
61
99
+ mem_high_size, &error_fatal);
62
if (size > rx_fifo_level) {
100
+ memory_region_init_alias(mem_high_alias, NULL,
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
101
+ "microchip.icicle.kit.ram_high.alias",
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
102
+ mem_high, 0, mem_high_size);
65
s->uart_timeout_ctrl = 0x00000000;
103
+ memory_region_add_subregion(system_memory,
66
104
+ memmap[MICROCHIP_PFSOC_DRAM_HI].base,
67
s->tx_level = 0;
105
+ mem_high);
68
+ s->rx_level = 0;
106
memory_region_add_subregion(system_memory,
69
107
- memmap[MICROCHIP_PFSOC_DRAM].base, main_mem);
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
108
+ memmap[MICROCHIP_PFSOC_DRAM_HI_ALIAS].base,
71
109
+ mem_high_alias);
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
110
73
111
/* Load the firmware */
74
case R_RDATA:
112
riscv_find_and_load_firmware(machine, BIOS_FILENAME, RESET_VECTOR, NULL);
75
retvalue = s->uart_rdata;
113
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data)
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
114
MICROCHIP_PFSOC_COMPUTE_CPU_COUNT;
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
115
mc->min_cpus = MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT + 1;
78
qemu_chr_fe_accept_input(&s->chr);
116
mc->default_cpus = mc->min_cpus;
79
117
- mc->default_ram_size = 1 * GiB;
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
118
+ mc->default_ram_size = 2 * GiB;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
119
}
82
+ s->rx_level -= 1;
120
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
121
static const TypeInfo microchip_icicle_kit_machine_typeinfo = {
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
}
122
--
109
--
123
2.28.0
110
2.30.1
124
111
125
112
diff view generated by jsdifflib
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
From: Jim Shu <cwshu@andestech.com>
2
2
3
In the case of supporting PMP feature, add PMP state description
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
4
to vmstate_riscv_cpu.
4
Fix it by propagating PMP permission to TLB page permission.
5
5
6
'vmstate_pmp_addr' and 'num_rules' could be regenerated by
6
PMP permission checking also use MMU-style API to change TLB permission
7
pmp_update_rule(). But there exists the problem of updating
7
and size.
8
num_rules repeatedly in pmp_update_rule(). So here extracts
8
9
pmp_update_rule_addr() and pmp_update_rule_nums() to update
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
10
'vmstate_pmp_addr' and 'num_rules' respectively.
11
12
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
13
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20201026115530.304-4-jiangyifei@huawei.com
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
13
---
18
target/riscv/pmp.h | 2 ++
14
target/riscv/pmp.h | 4 +-
19
target/riscv/machine.c | 50 ++++++++++++++++++++++++++++++++++++++++++
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
20
target/riscv/pmp.c | 29 ++++++++++++++----------
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
21
3 files changed, 70 insertions(+), 11 deletions(-)
17
3 files changed, 125 insertions(+), 43 deletions(-)
22
18
23
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
24
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/pmp.h
21
--- a/target/riscv/pmp.h
26
+++ b/target/riscv/pmp.h
22
+++ b/target/riscv/pmp.h
27
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
28
target_ulong size, pmp_priv_t priv, target_ulong mode);
24
target_ulong val);
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);
29
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
30
target_ulong *tlb_size);
31
target_ulong *tlb_size);
31
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
32
+void pmp_update_rule_nums(CPURISCVState *env);
33
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);
33
36
34
#endif
37
#endif
35
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/machine.c
40
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/machine.c
41
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
40
#include "sysemu/kvm.h"
43
env->load_res = -1;
41
#include "migration/cpu.h"
44
}
42
45
43
+static bool pmp_needed(void *opaque)
46
+/*
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)
44
+{
64
+{
45
+ RISCVCPU *cpu = opaque;
65
+ pmp_priv_t pmp_priv;
46
+ CPURISCVState *env = &cpu->env;
66
+ target_ulong tlb_size_pmp = 0;
47
+
67
+
48
+ return riscv_feature(env, RISCV_FEATURE_PMP);
68
+ if (!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;
49
+}
87
+}
50
+
88
+
51
+static int pmp_post_load(void *opaque, int version_id)
89
/* get_physical_address - get the physical address for this virtual address
52
+{
90
*
53
+ RISCVCPU *cpu = opaque;
91
* Do a page table walk to obtain the physical address corresponding to a
54
+ CPURISCVState *env = &cpu->env;
92
@@ -XXX,XX +XXX,XX @@ restart:
55
+ int i;
93
pte_addr = base + idx * ptesize;
56
+
94
}
57
+ for (i = 0; i < MAX_RISCV_PMPS; i++) {
95
58
+ pmp_update_rule_addr(env, i);
96
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
59
+ }
97
- !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
60
+ pmp_update_rule_nums(env);
98
- 1 << MMU_DATA_LOAD, PRV_S)) {
61
+
99
+ int pmp_prot;
62
+ return 0;
100
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
63
+}
101
+ sizeof(target_ulong),
64
+
102
+ MMU_DATA_LOAD, PRV_S);
65
+static const VMStateDescription vmstate_pmp_entry = {
103
+ if (pmp_ret != TRANSLATE_SUCCESS) {
66
+ .name = "cpu/pmp/entry",
104
return TRANSLATE_PMP_FAIL;
67
+ .version_id = 1,
105
}
68
+ .minimum_version_id = 1,
106
69
+ .fields = (VMStateField[]) {
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
70
+ VMSTATE_UINTTL(addr_reg, pmp_entry_t),
108
#ifndef CONFIG_USER_ONLY
71
+ VMSTATE_UINT8(cfg_reg, pmp_entry_t),
109
vaddr im_address;
72
+ VMSTATE_END_OF_LIST()
110
hwaddr pa = 0;
73
+ }
111
- int prot, prot2;
74
+};
112
+ int prot, prot2, prot_pmp;
75
+
113
bool pmp_violation = false;
76
+static const VMStateDescription vmstate_pmp = {
114
bool first_stage_error = true;
77
+ .name = "cpu/pmp",
115
bool two_stage_lookup = false;
78
+ .version_id = 1,
116
int ret = TRANSLATE_FAIL;
79
+ .minimum_version_id = 1,
117
int mode = mmu_idx;
80
+ .needed = pmp_needed,
118
- target_ulong tlb_size = 0;
81
+ .post_load = pmp_post_load,
119
+ /* default TLB page size */
82
+ .fields = (VMStateField[]) {
120
+ target_ulong tlb_size = TARGET_PAGE_SIZE;
83
+ VMSTATE_STRUCT_ARRAY(env.pmp_state.pmp, RISCVCPU, MAX_RISCV_PMPS,
121
84
+ 0, vmstate_pmp_entry, pmp_entry_t),
122
env->guest_phys_fault_addr = 0;
85
+ VMSTATE_END_OF_LIST()
123
86
+ }
124
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
87
+};
125
88
+
126
prot &= prot2;
89
const VMStateDescription vmstate_riscv_cpu = {
127
90
.name = "cpu",
128
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
91
.version_id = 1,
129
- (ret == TRANSLATE_SUCCESS) &&
92
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
130
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
93
VMSTATE_UINT64(env.timecmp, RISCVCPU),
131
- ret = TRANSLATE_PMP_FAIL;
94
132
+ if (ret == TRANSLATE_SUCCESS) {
95
VMSTATE_END_OF_LIST()
133
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
96
+ },
134
+ size, access_type, mode);
97
+ .subsections = (const VMStateDescription * []) {
135
+ prot &= prot_pmp;
98
+ &vmstate_pmp,
136
}
99
+ NULL
137
100
}
138
if (ret != TRANSLATE_SUCCESS) {
101
};
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
}
155
+
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;
102
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
173
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
103
index XXXXXXX..XXXXXXX 100644
174
index XXXXXXX..XXXXXXX 100644
104
--- a/target/riscv/pmp.c
175
--- a/target/riscv/pmp.c
105
+++ b/target/riscv/pmp.c
176
+++ b/target/riscv/pmp.c
106
@@ -XXX,XX +XXX,XX @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
177
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
107
}
178
return result;
108
}
179
}
109
180
181
+/*
182
+ * Check if the address has required RWX privs when no PMP entry is matched.
183
+ */
184
+static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
185
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
186
+ target_ulong mode)
187
+{
188
+ bool ret;
189
+
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
+}
209
+
210
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
{
221
int i = 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
110
-
276
-
111
-/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
277
/*
112
- * end address values.
278
* Handle a write to a pmpcfg CSP
113
- * This function is called relatively infrequently whereas the check that
279
*/
114
- * an address is within a pmp rule is called often, so optimise that one
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
115
- */
281
116
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
282
return false;
117
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
283
}
118
{
284
+
119
- int i;
285
+/*
120
-
286
+ * Convert PMP privilege to TLB page privilege.
121
- env->pmp_state.num_rules = 0;
287
+ */
122
-
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
123
uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
289
+{
124
target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
290
+ int prot = 0;
125
target_ulong prev_addr = 0u;
291
+
126
@@ -XXX,XX +XXX,XX @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
292
+ if (pmp_priv & PMP_READ) {
127
293
+ prot |= PAGE_READ;
128
env->pmp_state.addr[pmp_index].sa = sa;
294
+ }
129
env->pmp_state.addr[pmp_index].ea = ea;
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;
130
+}
303
+}
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
148
+ */
149
+static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
150
+{
151
+ pmp_update_rule_addr(env, pmp_index);
152
+ pmp_update_rule_nums(env);
153
+}
154
+
155
static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
156
{
157
int result = 0;
158
--
304
--
159
2.28.0
305
2.30.1
160
306
161
307
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Jim Shu <cwshu@andestech.com>
2
2
3
Somehow HSS needs to access address 0 [1] for the DDR calibration data
3
Like MMU translation, add qemu log of PMP permission checking for
4
which is in the chipset's reserved memory. Let's map it.
4
debugging.
5
5
6
[1] See the config_copy() calls in various places in ddr_setup() in
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
the HSS source codes.
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1603863010-15807-9-git-send-email-bmeng.cn@gmail.com
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
10
---
14
include/hw/riscv/microchip_pfsoc.h | 1 +
11
target/riscv/cpu_helper.c | 12 ++++++++++++
15
hw/riscv/microchip_pfsoc.c | 11 ++++++++++-
12
1 file changed, 12 insertions(+)
16
2 files changed, 11 insertions(+), 1 deletion(-)
17
13
18
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/riscv/microchip_pfsoc.h
16
--- a/target/riscv/cpu_helper.c
21
+++ b/include/hw/riscv/microchip_pfsoc.h
17
+++ b/target/riscv/cpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipIcicleKitState {
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
23
TYPE_MICROCHIP_ICICLE_KIT_MACHINE)
19
if (ret == TRANSLATE_SUCCESS) {
24
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
25
enum {
21
size, access_type, mode);
26
+ MICROCHIP_PFSOC_RSVD0,
27
MICROCHIP_PFSOC_DEBUG,
28
MICROCHIP_PFSOC_E51_DTIM,
29
MICROCHIP_PFSOC_BUSERR_UNIT0,
30
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/microchip_pfsoc.c
33
+++ b/hw/riscv/microchip_pfsoc.c
34
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
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);
62
+
22
+
63
/* E51 DTIM */
23
+ qemu_log_mask(CPU_LOG_MMU,
64
memory_region_init_ram(e51_dtim_mem, NULL, "microchip.pfsoc.e51_dtim_mem",
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
65
memmap[MICROCHIP_PFSOC_E51_DTIM].size, &error_fatal);
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
26
+ __func__, pa, ret, prot_pmp, tlb_size);
27
+
28
prot &= prot_pmp;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
32
if (ret == TRANSLATE_SUCCESS) {
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
34
size, access_type, mode);
35
+
36
+ qemu_log_mask(CPU_LOG_MMU,
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
39
+ __func__, pa, ret, prot_pmp, tlb_size);
40
+
41
prot &= prot_pmp;
42
}
43
}
66
--
44
--
67
2.28.0
45
2.30.1
68
46
69
47
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Jim Shu <cwshu@andestech.com>
2
2
3
Previously IOSCB_CFG was created as an unimplemented device. With
3
If PMP permission of any address has been changed by updating PMP entry,
4
the new IOSCB model, its memory range is already covered by the
4
flush all TLB pages to prevent from getting old permission.
5
IOSCB hence remove the previous unimplemented device creation in
6
the SoC codes.
7
5
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1603863010-15807-6-git-send-email-bmeng.cn@gmail.com
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
include/hw/riscv/microchip_pfsoc.h | 4 +++-
11
target/riscv/pmp.c | 4 ++++
14
hw/riscv/microchip_pfsoc.c | 13 ++++++++-----
12
1 file changed, 4 insertions(+)
15
hw/riscv/Kconfig | 1 +
16
3 files changed, 12 insertions(+), 6 deletions(-)
17
13
18
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/riscv/microchip_pfsoc.h
16
--- a/target/riscv/pmp.c
21
+++ b/include/hw/riscv/microchip_pfsoc.h
17
+++ b/target/riscv/pmp.c
22
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
23
#include "hw/char/mchp_pfsoc_mmuart.h"
19
#include "qapi/error.h"
24
#include "hw/dma/sifive_pdma.h"
20
#include "cpu.h"
25
#include "hw/misc/mchp_pfsoc_dmc.h"
21
#include "trace.h"
26
+#include "hw/misc/mchp_pfsoc_ioscb.h"
22
+#include "exec/exec-all.h"
27
#include "hw/net/cadence_gem.h"
23
28
#include "hw/sd/cadence_sdhci.h"
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
29
25
uint8_t val);
30
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
31
DeviceState *plic;
27
cfg_val = (val >> 8 * i) & 0xff;
32
MchpPfSoCDdrSgmiiPhyState ddr_sgmii_phy;
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
33
MchpPfSoCDdrCfgState ddr_cfg;
29
}
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,
45
};
46
47
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/riscv/microchip_pfsoc.c
50
+++ b/hw/riscv/microchip_pfsoc.c
51
@@ -XXX,XX +XXX,XX @@
52
* 5) SiFive Platform DMA (Direct Memory Access Controller)
53
* 6) GEM (Gigabit Ethernet MAC Controller)
54
* 7) DMC (DDR Memory Controller)
55
+ * 8) IOSCB modules
56
*
57
* This board currently generates devicetree dynamically that indicates at least
58
* two harts and up to five harts.
59
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
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
+
30
+
73
+ object_initialize_child(obj, "ioscb", &s->ioscb, TYPE_MCHP_PFSOC_IOSCB);
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
32
+ tlb_flush(env_cpu(env));
74
}
33
}
75
34
76
static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
35
77
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
78
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
79
envm_data);
80
81
- /* IOSCBCFG */
82
- create_unimplemented_device("microchip.pfsoc.ioscb.cfg",
83
- memmap[MICROCHIP_PFSOC_IOSCB_CFG].base,
84
- memmap[MICROCHIP_PFSOC_IOSCB_CFG].size);
85
+ /* IOSCB */
86
+ sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
88
+ memmap[MICROCHIP_PFSOC_IOSCB].base);
89
}
90
91
static void microchip_pfsoc_soc_class_init(ObjectClass *oc, void *data)
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
96
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
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
--
36
--
105
2.28.0
37
2.30.1
106
38
107
39
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
Extend sifive_u machine to allow passing custom DTB using "-dtb"
3
According to the specification the "field SPVP of hstatus controls the
4
command-line parameter. This will help users pass modified DTB
4
privilege level of the access" for the hypervisor virtual-machine load
5
or Linux SiFive DTB to sifive_u machine.
5
and store instructions HLV, HLVX and HSV.
6
6
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20201022053225.2596110-1-anup.patel@wdc.com
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
hw/riscv/sifive_u.c | 28 ++++++++++++++++++++--------
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
13
1 file changed, 20 insertions(+), 8 deletions(-)
13
1 file changed, 14 insertions(+), 11 deletions(-)
14
14
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_u.c
17
--- a/target/riscv/cpu_helper.c
18
+++ b/hw/riscv/sifive_u.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
int cpu;
20
use_background = true;
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
+ }
46
}
21
}
47
22
48
qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
49
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
24
+ /* MPRV does not affect the virtual-machine load/store
50
25
+ instructions, HLV, HLVX, and HSV. */
51
qemu_fdt_add_subnode(fdt, "/chosen");
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
52
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
53
- if (cmdline) {
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
54
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
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;
55
- }
56
- }
56
-
57
-
57
qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
58
if (riscv_cpu_virt_enabled(env) ||
58
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
59
g_free(nodename);
60
access_type != MMU_INST_FETCH)) {
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)
68
--
61
--
69
2.28.0
62
2.30.1
70
63
71
64
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
This creates a minimum model for Microchip PolarFire SoC SYSREG
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
4
module. It only implements the ENVM_CR register to tell guest
5
software that eNVM is running at the configured divider rate.
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1603863010-15807-7-git-send-email-bmeng.cn@gmail.com
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
7
---
12
include/hw/misc/mchp_pfsoc_sysreg.h | 39 ++++++++++++
8
target/riscv/csr.c | 7 ++++---
13
hw/misc/mchp_pfsoc_sysreg.c | 99 +++++++++++++++++++++++++++++
9
1 file changed, 4 insertions(+), 3 deletions(-)
14
MAINTAINERS | 2 +
15
hw/misc/Kconfig | 3 +
16
hw/misc/meson.build | 1 +
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
10
21
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
22
new file mode 100644
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
26
@@ -XXX,XX +XXX,XX @@
27
+/*
28
+ * Microchip PolarFire SoC SYSREG module emulation
29
+ *
30
+ * Copyright (c) 2020 Wind River Systems, Inc.
31
+ *
32
+ * Author:
33
+ * Bin Meng <bin.meng@windriver.com>
34
+ *
35
+ * This program is free software; you can redistribute it and/or
36
+ * modify it under the terms of the GNU General Public License as
37
+ * published by the Free Software Foundation; either version 2 or
38
+ * (at your option) version 3 of the License.
39
+ *
40
+ * This program is distributed in the hope that it will be useful,
41
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43
+ * GNU General Public License for more details.
44
+ *
45
+ * You should have received a copy of the GNU General Public License along
46
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
47
+ */
48
+
49
+#ifndef MCHP_PFSOC_SYSREG_H
50
+#define MCHP_PFSOC_SYSREG_H
51
+
52
+#define MCHP_PFSOC_SYSREG_REG_SIZE 0x2000
53
+
54
+typedef struct MchpPfSoCSysregState {
55
+ SysBusDevice parent;
56
+ MemoryRegion sysreg;
57
+} MchpPfSoCSysregState;
58
+
59
+#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
60
+
61
+#define MCHP_PFSOC_SYSREG(obj) \
62
+ OBJECT_CHECK(MchpPfSoCSysregState, (obj), \
63
+ TYPE_MCHP_PFSOC_SYSREG)
64
+
65
+#endif /* MCHP_PFSOC_SYSREG_H */
66
diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c
67
new file mode 100644
68
index XXXXXXX..XXXXXXX
69
--- /dev/null
70
+++ b/hw/misc/mchp_pfsoc_sysreg.c
71
@@ -XXX,XX +XXX,XX @@
72
+/*
73
+ * Microchip PolarFire SoC SYSREG module emulation
74
+ *
75
+ * Copyright (c) 2020 Wind River Systems, Inc.
76
+ *
77
+ * Author:
78
+ * Bin Meng <bin.meng@windriver.com>
79
+ *
80
+ * This program is free software; you can redistribute it and/or
81
+ * modify it under the terms of the GNU General Public License as
82
+ * published by the Free Software Foundation; either version 2 or
83
+ * (at your option) version 3 of the License.
84
+ *
85
+ * This program is distributed in the hope that it will be useful,
86
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
87
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88
+ * GNU General Public License for more details.
89
+ *
90
+ * You should have received a copy of the GNU General Public License along
91
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "qemu/bitops.h"
96
+#include "qemu/log.h"
97
+#include "qapi/error.h"
98
+#include "hw/hw.h"
99
+#include "hw/sysbus.h"
100
+#include "hw/misc/mchp_pfsoc_sysreg.h"
101
+
102
+#define ENVM_CR 0xb8
103
+
104
+static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
105
+ unsigned size)
106
+{
107
+ uint32_t val = 0;
108
+
109
+ switch (offset) {
110
+ case ENVM_CR:
111
+ /* Indicate the eNVM is running at the configured divider rate */
112
+ val = BIT(6);
113
+ break;
114
+ default:
115
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
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
172
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
173
--- a/MAINTAINERS
13
--- a/target/riscv/csr.c
174
+++ b/MAINTAINERS
14
+++ b/target/riscv/csr.c
175
@@ -XXX,XX +XXX,XX @@ F: hw/riscv/microchip_pfsoc.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
176
F: hw/char/mchp_pfsoc_mmuart.c
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
177
F: hw/misc/mchp_pfsoc_dmc.c
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
178
F: hw/misc/mchp_pfsoc_ioscb.c
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
179
+F: hw/misc/mchp_pfsoc_sysreg.c
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
180
F: include/hw/riscv/microchip_pfsoc.h
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
181
F: include/hw/char/mchp_pfsoc_mmuart.h
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
182
F: include/hw/misc/mchp_pfsoc_dmc.h
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
183
F: include/hw/misc/mchp_pfsoc_ioscb.h
23
184
+F: include/hw/misc/mchp_pfsoc_sysreg.h
24
static const char valid_vm_1_10_32[16] = {
185
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
186
RX Machines
26
target_ulong new_value, target_ulong write_mask)
187
-----------
27
{
188
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
28
int ret = rmw_mip(env, 0, ret_value, new_value,
189
index XXXXXXX..XXXXXXX 100644
29
- write_mask & hip_writable_mask);
190
--- a/hw/misc/Kconfig
30
+ write_mask & hvip_writable_mask);
191
+++ b/hw/misc/Kconfig
31
192
@@ -XXX,XX +XXX,XX @@ config MCHP_PFSOC_DMC
32
- *ret_value &= hip_writable_mask;
193
config MCHP_PFSOC_IOSCB
33
+ *ret_value &= hvip_writable_mask;
194
bool
34
195
35
return ret;
196
+config MCHP_PFSOC_SYSREG
36
}
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'))
214
--
37
--
215
2.28.0
38
2.30.1
216
39
217
40
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
Connect DDR SGMII PHY module and CFG module to the PolarFire SoC.
3
The current condition for the use of background registers only
4
considers the hypervisor load and store instructions,
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
4
6
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 1603863010-15807-4-git-send-email-bmeng.cn@gmail.com
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
11
---
10
include/hw/riscv/microchip_pfsoc.h | 5 +++++
12
target/riscv/cpu_helper.c | 2 +-
11
hw/riscv/microchip_pfsoc.c | 18 ++++++++++++++++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
hw/riscv/Kconfig | 1 +
13
3 files changed, 24 insertions(+)
14
14
15
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/riscv/microchip_pfsoc.h
17
--- a/target/riscv/cpu_helper.c
18
+++ b/include/hw/riscv/microchip_pfsoc.h
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
20
* was called. Background registers will be used if the guest has
21
#include "hw/char/mchp_pfsoc_mmuart.h"
21
* forced a two stage translation to be on (in HS or M mode).
22
#include "hw/dma/sifive_pdma.h"
22
*/
23
+#include "hw/misc/mchp_pfsoc_dmc.h"
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
24
#include "hw/net/cadence_gem.h"
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
25
#include "hw/sd/cadence_sdhci.h"
25
use_background = true;
26
26
}
27
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
27
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
109
--
28
--
110
2.28.0
29
2.30.1
111
30
112
31
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Asherah Connor <ashe@kivikakk.ee>
2
2
3
Previously SYSREG was created as an unimplemented device. Now that
3
Provides fw_cfg for the virt machine on riscv. This enables
4
we have a simple SYSREG module, connect it.
4
using e.g. ramfb later.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
7
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: 1603863010-15807-8-git-send-email-bmeng.cn@gmail.com
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
include/hw/riscv/microchip_pfsoc.h | 2 ++
12
include/hw/riscv/virt.h | 2 ++
12
hw/riscv/microchip_pfsoc.c | 9 ++++++---
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
13
hw/riscv/Kconfig | 1 +
14
hw/riscv/Kconfig | 1 +
14
3 files changed, 9 insertions(+), 3 deletions(-)
15
3 files changed, 33 insertions(+)
15
16
16
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/microchip_pfsoc.h
19
--- a/include/hw/riscv/virt.h
19
+++ b/include/hw/riscv/microchip_pfsoc.h
20
+++ b/include/hw/riscv/virt.h
20
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
21
#include "hw/dma/sifive_pdma.h"
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
22
#include "hw/misc/mchp_pfsoc_dmc.h"
23
DeviceState *plic[VIRT_SOCKETS_MAX];
23
#include "hw/misc/mchp_pfsoc_ioscb.h"
24
PFlashCFI01 *flash[2];
24
+#include "hw/misc/mchp_pfsoc_sysreg.h"
25
+ FWCfgState *fw_cfg;
25
#include "hw/net/cadence_gem.h"
26
26
#include "hw/sd/cadence_sdhci.h"
27
int fdt_size;
27
28
};
28
@@ -XXX,XX +XXX,XX @@ typedef struct MicrochipPFSoCState {
29
@@ -XXX,XX +XXX,XX @@ enum {
29
MchpPfSoCMMUartState *serial2;
30
VIRT_PLIC,
30
MchpPfSoCMMUartState *serial3;
31
VIRT_UART0,
31
MchpPfSoCMMUartState *serial4;
32
VIRT_VIRTIO,
32
+ MchpPfSoCSysregState sysreg;
33
+ VIRT_FW_CFG,
33
SiFivePDMAState dma;
34
VIRT_FLASH,
34
CadenceGEMState gem0;
35
VIRT_DRAM,
35
CadenceGEMState gem1;
36
VIRT_PCIE_MMIO,
36
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
37
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/microchip_pfsoc.c
39
--- a/hw/riscv/virt.c
39
+++ b/hw/riscv/microchip_pfsoc.c
40
+++ b/hw/riscv/virt.c
40
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
41
object_initialize_child(obj, "dma-controller", &s->dma,
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
42
TYPE_SIFIVE_PDMA);
43
[VIRT_UART0] = { 0x10000000, 0x100 },
43
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
44
+ object_initialize_child(obj, "sysreg", &s->sysreg,
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
45
+ TYPE_MCHP_PFSOC_SYSREG);
46
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
47
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
48
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
49
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
50
return dev;
51
}
52
53
+static FWCfgState *create_fw_cfg(const MachineState *mc)
54
+{
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
56
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
57
+ FWCfgState *fw_cfg;
58
+ char *nodename;
46
+
59
+
47
object_initialize_child(obj, "ddr-sgmii-phy", &s->ddr_sgmii_phy,
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
48
TYPE_MCHP_PFSOC_DDR_SGMII_PHY);
61
+ &address_space_memory);
49
object_initialize_child(obj, "ddr-cfg", &s->ddr_cfg,
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
50
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
63
+
64
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
65
+ qemu_fdt_add_subnode(mc->fdt, nodename);
66
+ qemu_fdt_setprop_string(mc->fdt, nodename,
67
+ "compatible", "qemu,fw-cfg-mmio");
68
+ qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
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;
51
}
80
}
52
81
53
/* SYSREG */
82
+ /*
54
- create_unimplemented_device("microchip.pfsoc.sysreg",
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
55
- memmap[MICROCHIP_PFSOC_SYSREG].base,
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
56
- memmap[MICROCHIP_PFSOC_SYSREG].size);
85
+ */
57
+ sysbus_realize(SYS_BUS_DEVICE(&s->sysreg), errp);
86
+ s->fw_cfg = create_fw_cfg(machine);
58
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
87
+ rom_set_fw(s->fw_cfg);
59
+ memmap[MICROCHIP_PFSOC_SYSREG].base);
88
+
60
89
/* Compute the fdt load address in dram */
61
/* MPUCFG */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
62
create_unimplemented_device("microchip.pfsoc.mpucfg",
91
machine->ram_size, machine->fdt);
63
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
64
index XXXXXXX..XXXXXXX 100644
93
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/riscv/Kconfig
94
--- a/hw/riscv/Kconfig
66
+++ b/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
67
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
68
select MCHP_PFSOC_DMC
97
select SIFIVE_PLIC
69
select MCHP_PFSOC_IOSCB
98
select SIFIVE_TEST
70
select MCHP_PFSOC_MMUART
99
select VIRTIO_MMIO
71
+ select MCHP_PFSOC_SYSREG
100
+ select FW_CFG_DMA
72
select MSI_NONBROKEN
101
73
select SIFIVE_CLINT
102
config SIFIVE_E
74
select SIFIVE_PDMA
103
bool
75
--
104
--
76
2.28.0
105
2.30.1
77
106
78
107
diff view generated by jsdifflib
1
From: Anup Patel <anup.patel@wdc.com>
1
From: Asherah Connor <ashe@kivikakk.ee>
2
2
3
Extend virt machine to allow passing custom DTB using "-dtb"
3
Allow ramfb on virt. This lets `-device ramfb' work.
4
command-line parameter. This will help users pass modified DTB
5
to virt machine.
6
4
7
Signed-off-by: Anup Patel <anup.patel@wdc.com>
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20201022053225.2596110-2-anup.patel@wdc.com
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
10
---
12
hw/riscv/virt.c | 27 ++++++++++++++++++++-------
11
hw/riscv/virt.c | 3 +++
13
1 file changed, 20 insertions(+), 7 deletions(-)
12
1 file changed, 3 insertions(+)
14
13
15
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/virt.c
16
--- a/hw/riscv/virt.c
18
+++ b/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
19
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
18
@@ -XXX,XX +XXX,XX @@
20
{
19
#include "sysemu/sysemu.h"
21
void *fdt;
20
#include "hw/pci/pci.h"
22
int i, cpu, socket;
21
#include "hw/pci-host/gpex.h"
23
+ const char *dtb_filename;
22
+#include "hw/display/ramfb.h"
24
MachineState *mc = MACHINE(s);
23
25
uint64_t addr, size;
24
static const MemMapEntry virt_memmap[] = {
26
uint32_t *clint_cells, *plic_cells;
25
[VIRT_DEBUG] = { 0x0, 0x100 },
27
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
28
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
29
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
30
29
mc->numa_mem_supported = true;
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);
66
+
30
+
67
+update_bootargs:
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
68
+ if (cmdline) {
69
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
70
+ }
71
}
32
}
72
33
73
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
34
static const TypeInfo virt_machine_typeinfo = {
74
--
35
--
75
2.28.0
36
2.30.1
76
37
77
38
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
This creates a model for PolarFire SoC IOSCB [1] module. It actually
3
The previous implementation was broken in many ways:
4
contains lots of sub-modules like various PLLs to control different
4
- Used mideleg instead of hideleg to mask accesses
5
peripherals. Only the mininum capabilities are emulated to make the
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
6
HSS DDR memory initialization codes happy. Lots of sub-modules are
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
7
created as an unimplemented devices.
8
7
9
[1] PF_SoC_RegMap_V1_1/MPFS250T/mpfs250t_ioscb_memmap_dri.htm in
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
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>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 1603863010-15807-5-git-send-email-bmeng.cn@gmail.com
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
include/hw/misc/mchp_pfsoc_ioscb.h | 50 ++++++
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
18
hw/misc/mchp_pfsoc_ioscb.c | 242 +++++++++++++++++++++++++++++
14
1 file changed, 34 insertions(+), 34 deletions(-)
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
15
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
27
new file mode 100644
17
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX
18
--- a/target/riscv/csr.c
29
--- /dev/null
19
+++ b/target/riscv/csr.c
30
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
31
@@ -XXX,XX +XXX,XX @@
21
return write_mstatus(env, CSR_MSTATUS, newval);
32
+/*
22
}
33
+ * Microchip PolarFire SoC IOSCB module emulation
23
34
+ *
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
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
+{
25
+{
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
26
+ /* Shift the VS bits to their S bit location in vsie */
151
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
152
+ __func__, size, offset);
153
+
154
+ return 0;
28
+ return 0;
155
+}
29
+}
156
+
30
+
157
+static void mchp_pfsoc_dummy_write(void *opaque, hwaddr offset,
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
158
+ uint64_t value, unsigned size)
32
{
33
if (riscv_cpu_virt_enabled(env)) {
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
36
+ read_vsie(env, CSR_VSIE, val);
37
} else {
38
*val = env->mie & env->mideleg;
39
}
40
return 0;
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)
159
+{
54
+{
160
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
55
if (riscv_cpu_virt_enabled(env)) {
161
+ "(size %d, value 0x%" PRIx64
56
- /* Shift the guests S bits to VS */
162
+ ", offset 0x%" HWADDR_PRIx ")\n",
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
163
+ __func__, size, value, offset);
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;
164
+}
86
+}
165
+
87
+
166
+static const MemoryRegionOps mchp_pfsoc_dummy_ops = {
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
167
+ .read = mchp_pfsoc_dummy_read,
89
target_ulong new_value, target_ulong write_mask)
168
+ .write = mchp_pfsoc_dummy_write,
90
{
169
+ .endianness = DEVICE_LITTLE_ENDIAN,
91
int ret;
170
+};
92
171
+
93
if (riscv_cpu_virt_enabled(env)) {
172
+/* All PLL modules in IOSCB have the same register layout */
94
- /* Shift the new values to line up with the VS bits */
173
+
95
- ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
174
+#define PLL_CTRL 0x04
96
- (write_mask & sip_writable_mask) << 1 & env->mideleg);
175
+
97
- ret &= vsip_writable_mask;
176
+static uint64_t mchp_pfsoc_pll_read(void *opaque, hwaddr offset,
98
- ret >>= 1;
177
+ unsigned size)
99
+ ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask);
178
+{
100
} else {
179
+ uint32_t val = 0;
101
ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
180
+
102
write_mask & env->mideleg & sip_writable_mask);
181
+ switch (offset) {
103
@@ -XXX,XX +XXX,XX @@ static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
182
+ case PLL_CTRL:
104
return 0;
183
+ /* PLL is locked */
105
}
184
+ val = BIT(25);
106
185
+ break;
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
186
+ default:
108
- target_ulong new_value, target_ulong write_mask)
187
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
109
-{
188
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
189
+ __func__, size, offset);
111
- write_mask & env->mideleg & vsip_writable_mask);
190
+ break;
112
- return ret;
191
+ }
113
-}
192
+
114
-
193
+ return val;
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
194
+}
116
-{
195
+
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
196
+static const MemoryRegionOps mchp_pfsoc_pll_ops = {
118
- return 0;
197
+ .read = mchp_pfsoc_pll_read,
119
-}
198
+ .write = mchp_pfsoc_dummy_write,
120
-
199
+ .endianness = DEVICE_LITTLE_ENDIAN,
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
200
+};
122
-{
201
+
123
- target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
202
+/* IO_CALIB_DDR submodule */
124
- return write_mie(env, CSR_MIE, newval);
203
+
125
-}
204
+#define IO_CALIB_DDR_IOC_REG1 0x08
126
-
205
+
127
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
206
+static uint64_t mchp_pfsoc_io_calib_ddr_read(void *opaque, hwaddr offset,
128
{
207
+ unsigned size)
129
*val = env->vstvec;
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
--
130
--
373
2.28.0
131
2.30.1
374
132
375
133
diff view generated by jsdifflib
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
4
This patch expands mstatus and vsstatus to uint64_t instead of
4
short of its purpose, as all it checks is whether two-stage address
5
target_ulong so that it can be saved as one unit and reduce some
5
translation either via the hypervisor-load store instructions or the
6
ifdefs in the code.
6
MPRV feature would be allowed.
7
7
8
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
8
What we really need instead is whether two-stage address translation was
9
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
10
we do not have the information to reliably detect this. Therefore, when
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>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20201026115530.304-2-jiangyifei@huawei.com
13
---
18
---
14
target/riscv/cpu.h | 24 +++++++++++-------------
19
target/riscv/cpu.h | 4 ++++
15
target/riscv/cpu_bits.h | 19 ++++---------------
20
target/riscv/cpu.c | 1 +
16
target/riscv/cpu.c | 8 +++++---
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
17
target/riscv/cpu_helper.c | 35 +++++++----------------------------
22
3 files changed, 13 insertions(+), 13 deletions(-)
18
target/riscv/csr.c | 18 ++++++++++--------
19
target/riscv/op_helper.c | 11 ++++-------
20
6 files changed, 41 insertions(+), 74 deletions(-)
21
23
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
26
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
28
@@ -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;
71
target_ulong satp_hs;
29
target_ulong satp_hs;
72
- target_ulong mstatus_hs;
30
uint64_t mstatus_hs;
73
-#ifdef TARGET_RISCV32
31
74
- target_ulong mstatush_hs;
32
+ /* Signals whether the current exception occurred with two-stage address
75
-#endif
33
+ translation active. */
76
+ uint64_t mstatus_hs;
34
+ bool two_stage_lookup;
77
35
+
78
target_ulong scounteren;
36
target_ulong scounteren;
79
target_ulong mcounteren;
37
target_ulong mcounteren;
80
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
38
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
119
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
120
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
121
--- a/target/riscv/cpu.c
41
--- a/target/riscv/cpu.c
122
+++ b/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
123
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
124
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
125
#ifndef CONFIG_USER_ONLY
45
env->mcause = 0;
126
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
46
env->pc = env->resetvec;
127
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
47
+ env->two_stage_lookup = false;
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));
133
#endif
48
#endif
134
if (riscv_has_ext(env, RVH)) {
49
cs->exception_index = EXCP_NONE;
135
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
50
env->load_res = -1;
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);
142
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
143
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
144
--- a/target/riscv/cpu_helper.c
53
--- a/target/riscv/cpu_helper.c
145
+++ b/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
146
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
147
56
g_assert_not_reached();
148
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
57
}
149
{
58
env->badaddr = address;
150
- target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
59
+ env->two_stage_lookup = two_stage;
151
- MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
60
}
152
+ uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
61
153
+ MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
154
+ MSTATUS64_UXL;
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
155
bool current_virt = riscv_cpu_virt_enabled(env);
64
}
156
65
157
g_assert(riscv_has_ext(env, RVH));
66
env->badaddr = addr;
158
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
159
-#if defined(TARGET_RISCV64)
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
160
- mstatus_mask |= MSTATUS64_UXL;
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
161
-#endif
70
}
71
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
73
g_assert_not_reached();
74
}
75
env->badaddr = addr;
76
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
77
+ riscv_cpu_two_stage_lookup(mmu_idx);
78
riscv_raise_exception(env, cs->exception_index, retaddr);
79
}
80
#endif /* !CONFIG_USER_ONLY */
81
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
82
/* handle the trap in S-mode */
83
if (riscv_has_ext(env, RVH)) {
84
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
85
- bool two_stage_lookup = false;
86
87
- if (env->priv == PRV_M ||
88
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
89
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
90
- get_field(env->hstatus, HSTATUS_HU))) {
91
- two_stage_lookup = true;
92
- }
162
-
93
-
163
if (current_virt) {
94
- if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
164
/* Current V=1 and we are about to change to V=0 */
95
+ if (env->two_stage_lookup && write_tval) {
165
env->vsstatus = env->mstatus & mstatus_mask;
96
/*
166
env->mstatus &= ~mstatus_mask;
97
* If we are writing a guest virtual address to stval, set
167
env->mstatus |= env->mstatus_hs;
98
* this to 1. If we are trapping to VS we will set this to 0
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)
99
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
208
RISCVCPU *cpu = RISCV_CPU(cs);
100
riscv_cpu_set_force_hs_excep(env, 0);
209
CPURISCVState *env = &cpu->env;
101
} else {
210
bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
102
/* Trap into HS mode */
211
- target_ulong s;
103
- if (!two_stage_lookup) {
212
+ uint64_t s;
104
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
213
105
- riscv_cpu_virt_enabled(env));
214
/* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
106
- }
215
* so we mask off the MSB and separate into trap type and cause.
107
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
108
htval = env->guest_phys_fault_addr;
109
}
110
}
216
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
111
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
217
if (riscv_cpu_virt_enabled(env)) {
112
* RISC-V ISA Specification.
218
riscv_cpu_swap_hypervisor_regs(env);
113
*/
219
}
114
220
-#ifdef TARGET_RISCV32
115
+ env->two_stage_lookup = false;
221
- env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
116
#endif
222
- riscv_cpu_virt_enabled(env));
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
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;
259
}
118
}
260
261
static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
262
{
263
- if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
264
+ uint64_t valh = (uint64_t)val << 32;
265
+ uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
266
+
267
+ if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
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;
277
}
278
@@ -XXX,XX +XXX,XX @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
279
280
static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
281
{
282
- env->vsstatus = val;
283
+ uint64_t mask = (target_ulong)-1;
284
+ env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
285
return 0;
286
}
287
288
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/target/riscv/op_helper.c
291
+++ b/target/riscv/op_helper.c
292
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
293
294
target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
295
{
296
- target_ulong prev_priv, prev_virt, mstatus;
297
+ uint64_t mstatus;
298
+ target_ulong prev_priv, prev_virt;
299
300
if (!(env->priv >= PRV_S)) {
301
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
302
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
303
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
304
}
305
306
- target_ulong mstatus = env->mstatus;
307
+ uint64_t mstatus = env->mstatus;
308
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
309
- target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
310
+ target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
311
mstatus = set_field(mstatus, MSTATUS_MIE,
312
get_field(mstatus, MSTATUS_MPIE));
313
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
314
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
315
-#ifdef TARGET_RISCV32
316
- env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
317
-#else
318
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
319
-#endif
320
env->mstatus = mstatus;
321
riscv_cpu_set_mode(env, prev_priv);
322
323
--
119
--
324
2.28.0
120
2.30.1
325
121
326
122
diff view generated by jsdifflib
Deleted patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
1
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20201026115530.304-3-jiangyifei@huawei.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/internals.h | 4 +++
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
17
18
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/internals.h
21
+++ b/target/riscv/internals.h
22
@@ -XXX,XX +XXX,XX @@ target_ulong fclass_d(uint64_t frs1);
23
#define SEW32 2
24
#define SEW64 3
25
26
+#ifndef CONFIG_USER_ONLY
27
+extern const VMStateDescription vmstate_riscv_cpu;
28
+#endif
29
+
30
static inline uint64_t nanbox_s(float32 f)
31
{
32
return f | MAKE_64BIT_MASK(32, 32);
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@
38
#include "qemu/ctype.h"
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);
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}
153
--
154
2.28.0
155
156
diff view generated by jsdifflib
Deleted patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
1
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: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
It is not easy to find out the memory map for a specific component
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
4
in the PolarFire SoC as the information is scattered in different
4
the address bytes. Note only SPI mode is supported by SST flashes.
5
documents. Add some comments so that people can know where to get
5
6
such information from the Microchip website.
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
7
7
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1603863010-15807-2-git-send-email-bmeng.cn@gmail.com
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
hw/riscv/microchip_pfsoc.c | 18 ++++++++++++++++++
13
hw/block/m25p80.c | 3 +++
14
1 file changed, 18 insertions(+)
14
1 file changed, 3 insertions(+)
15
15
16
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/microchip_pfsoc.c
18
--- a/hw/block/m25p80.c
19
+++ b/hw/riscv/microchip_pfsoc.c
19
+++ b/hw/block/m25p80.c
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
21
/* GEM version */
21
s->needed_bytes = get_addr_length(s);
22
#define GEM_REVISION 0x0107010c
22
switch (get_man(s)) {
23
23
/* Dummy cycles - modeled with bytes writes instead of bits */
24
+/*
24
+ case MAN_SST:
25
+ * The complete description of the whole PolarFire SoC memory map is scattered
25
+ s->needed_bytes += 1;
26
+ * in different documents. There are several places to look at for memory maps:
26
+ break;
27
+ *
27
case MAN_WINBOND:
28
+ * 1 Chapter 11 "MSS Memory Map", in the doc "UG0880: PolarFire SoC FPGA
28
s->needed_bytes += 8;
29
+ * Microprocessor Subsystem (MSS) User Guide", which can be downloaded from
29
break;
30
+ * https://www.microsemi.com/document-portal/doc_download/
31
+ * 1244570-ug0880-polarfire-soc-fpga-microprocessor-subsystem-mss-user-guide,
32
+ * describes the whole picture of the PolarFire SoC memory map.
33
+ *
34
+ * 2 A zip file for PolarFire soC memory map, which can be downloaded from
35
+ * https://www.microsemi.com/document-portal/doc_download/
36
+ * 1244581-polarfire-soc-register-map, contains the following 2 major parts:
37
+ * - Register Map/PF_SoC_RegMap_V1_1/pfsoc_regmap.htm
38
+ * describes the complete integrated peripherals memory map
39
+ * - Register Map/PF_SoC_RegMap_V1_1/MPFS250T/mpfs250t_ioscb_memmap_dri.htm
40
+ * describes the complete IOSCB modules memory maps
41
+ */
42
static const struct MemmapEntry {
43
hwaddr base;
44
hwaddr size;
45
--
30
--
46
2.28.0
31
2.30.1
47
32
48
33
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The latest SD card image [1] released by Microchip ships a Linux
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
4
kernel with built-in PolarFire SoC I2C driver support. The device
4
been updated to use a register mapped at 0x4f000000 instead of a
5
tree file includes the description for the I2C1 node hence kernel
5
GPIO to control whether eMMC or SD card is to be used. With this
6
tries to probe the I2C1 device during boot.
6
support the same HSS image can be used for both eMMC and SD card
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.
7
10
8
It is enough to create an unimplemented device for I2C1 to allow
11
With this commit, HSS image built from 2020.12 release boots again.
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: 1603863010-15807-11-git-send-email-bmeng.cn@gmail.com
15
Message-id: 20210322075248.136255-1-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_MMUART2,
27
MICROCHIP_PFSOC_ENVM_DATA,
28
MICROCHIP_PFSOC_MMUART3,
28
MICROCHIP_PFSOC_QSPI_XIP,
29
MICROCHIP_PFSOC_MMUART4,
29
MICROCHIP_PFSOC_IOSCB,
30
+ MICROCHIP_PFSOC_I2C1,
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
31
MICROCHIP_PFSOC_GEM0,
31
MICROCHIP_PFSOC_DRAM_LO,
32
MICROCHIP_PFSOC_GEM1,
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
33
MICROCHIP_PFSOC_GPIO0,
33
MICROCHIP_PFSOC_DRAM_HI,
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 struct MemmapEntry {
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
39
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
40
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
41
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
42
+ [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
43
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
44
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
45
[MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
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
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
48
serial_hd(4));
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
49
49
50
+ /* I2C1 */
50
+ /* eMMC/SD mux */
51
+ create_unimplemented_device("microchip.pfsoc.i2c1",
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
52
+ memmap[MICROCHIP_PFSOC_I2C1].base,
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
53
+ memmap[MICROCHIP_PFSOC_I2C1].size);
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
54
+
54
+
55
/* GEMs */
55
/* QSPI Flash */
56
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
57
nd = &nd_table[0];
57
"microchip.pfsoc.qspi_xip",
58
--
58
--
59
2.28.0
59
2.30.1
60
60
61
61
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The PolarFire SoC DDR Memory Controller mainly includes 2 modules,
3
This adds the documentation to describe what is supported for the
4
called SGMII PHY module and the CFG module, as documented in the
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
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
5
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 1603863010-15807-3-git-send-email-bmeng.cn@gmail.com
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
10
---
16
include/hw/misc/mchp_pfsoc_dmc.h | 56 ++++++++
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
17
hw/misc/mchp_pfsoc_dmc.c | 216 +++++++++++++++++++++++++++++++
12
docs/system/target-riscv.rst | 1 +
18
MAINTAINERS | 2 +
13
2 files changed, 90 insertions(+)
19
hw/misc/Kconfig | 3 +
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
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
15
25
diff --git a/include/hw/misc/mchp_pfsoc_dmc.h b/include/hw/misc/mchp_pfsoc_dmc.h
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
26
new file mode 100644
17
new file mode 100644
27
index XXXXXXX..XXXXXXX
18
index XXXXXXX..XXXXXXX
28
--- /dev/null
19
--- /dev/null
29
+++ b/include/hw/misc/mchp_pfsoc_dmc.h
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
30
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
31
+/*
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
32
+ * Microchip PolarFire SoC DDR Memory Controller module emulation
23
+=============================================================
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
+
24
+
53
+#ifndef MCHP_PFSOC_DMC_H
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
54
+#define MCHP_PFSOC_DMC_H
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
55
+
27
+
56
+/* DDR SGMII PHY module */
28
+For more details about Microchip PolarFire SoC, please see:
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
57
+
30
+
58
+#define MCHP_PFSOC_DDR_SGMII_PHY_REG_SIZE 0x1000
31
+The Icicle Kit board information can be found here:
32
+https://www.microsemi.com/existing-parts/parts/152514
59
+
33
+
60
+typedef struct MchpPfSoCDdrSgmiiPhyState {
34
+Supported devices
61
+ SysBusDevice parent;
35
+-----------------
62
+ MemoryRegion sgmii_phy;
63
+} MchpPfSoCDdrSgmiiPhyState;
64
+
36
+
65
+#define TYPE_MCHP_PFSOC_DDR_SGMII_PHY "mchp.pfsoc.ddr_sgmii_phy"
37
+The ``microchip-icicle-kit`` machine supports the following devices:
66
+
38
+
67
+#define MCHP_PFSOC_DDR_SGMII_PHY(obj) \
39
+ * 1 E51 core
68
+ OBJECT_CHECK(MchpPfSoCDdrSgmiiPhyState, (obj), \
40
+ * 4 U54 cores
69
+ TYPE_MCHP_PFSOC_DDR_SGMII_PHY)
41
+ * Core Level Interruptor (CLINT)
42
+ * Platform-Level Interrupt Controller (PLIC)
43
+ * L2 Loosely Integrated Memory (L2-LIM)
44
+ * DDR memory controller
45
+ * 5 MMUARTs
46
+ * 1 DMA controller
47
+ * 2 GEM Ethernet controllers
48
+ * 1 SDHC storage controller
70
+
49
+
71
+/* DDR CFG module */
50
+Boot options
51
+------------
72
+
52
+
73
+#define MCHP_PFSOC_DDR_CFG_REG_SIZE 0x40000
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
56
+support direct kernel loading via the -kernel option. One has to load kernel
57
+from U-Boot.
74
+
58
+
75
+typedef struct MchpPfSoCDdrCfgState {
59
+The memory is set to 1537 MiB by default which is the minimum required high
76
+ SysBusDevice parent;
60
+memory size by HSS. A sanity check on ram size is performed in the machine
77
+ MemoryRegion cfg;
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
78
+} MchpPfSoCDdrCfgState;
62
+than 1537 MiB ram is detected.
79
+
63
+
80
+#define TYPE_MCHP_PFSOC_DDR_CFG "mchp.pfsoc.ddr_cfg"
64
+Boot the machine
65
+----------------
81
+
66
+
82
+#define MCHP_PFSOC_DDR_CFG(obj) \
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
83
+ OBJECT_CHECK(MchpPfSoCDdrCfgState, (obj), \
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
84
+ TYPE_MCHP_PFSOC_DDR_CFG)
69
+in the HSS source tree:
85
+
70
+
86
+#endif /* MCHP_PFSOC_DMC_H */
71
+.. code-block:: bash
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
+
72
+
115
+#include "qemu/osdep.h"
73
+ $ export CROSS_COMPILE=riscv64-linux-
116
+#include "qemu/bitops.h"
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
117
+#include "qemu/log.h"
75
+ $ make BOARD=mpfs-icicle-kit-es
118
+#include "qapi/error.h"
119
+#include "hw/hw.h"
120
+#include "hw/sysbus.h"
121
+#include "hw/misc/mchp_pfsoc_dmc.h"
122
+
76
+
123
+/* DDR SGMII PHY module */
77
+Download the official SD card image released by Microchip and prepare it for
78
+QEMU usage:
124
+
79
+
125
+#define SGMII_PHY_IOC_REG1 0x208
80
+.. code-block:: bash
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
+
81
+
131
+static uint64_t mchp_pfsoc_ddr_sgmii_phy_read(void *opaque, hwaddr offset,
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
132
+ unsigned size)
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
133
+{
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
134
+ uint32_t val = 0;
135
+ static int training_status_bit;
136
+
85
+
137
+ switch (offset) {
86
+Then we can boot the machine by:
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
+
87
+
177
+ return val;
88
+.. code-block:: bash
178
+}
179
+
89
+
180
+static void mchp_pfsoc_ddr_sgmii_phy_write(void *opaque, hwaddr offset,
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
181
+ uint64_t value, unsigned size)
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
182
+{
92
+ -nic user,model=cadence_gem \
183
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
184
+ "(size %d, value 0x%" PRIx64
94
+ -display none -serial stdio \
185
+ ", offset 0x%" HWADDR_PRIx ")\n",
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
186
+ __func__, size, value, offset);
96
+ -serial chardev:serial1
187
+}
188
+
97
+
189
+static const MemoryRegionOps mchp_pfsoc_ddr_sgmii_phy_ops = {
98
+With above command line, current terminal session will be used for the first
190
+ .read = mchp_pfsoc_ddr_sgmii_phy_read,
99
+serial port. Open another terminal window, and use `minicom` to connect the
191
+ .write = mchp_pfsoc_ddr_sgmii_phy_write,
100
+second serial port.
192
+ .endianness = DEVICE_LITTLE_ENDIAN,
193
+};
194
+
101
+
195
+static void mchp_pfsoc_ddr_sgmii_phy_realize(DeviceState *dev, Error **errp)
102
+.. code-block:: bash
196
+{
197
+ MchpPfSoCDdrSgmiiPhyState *s = MCHP_PFSOC_DDR_SGMII_PHY(dev);
198
+
103
+
199
+ memory_region_init_io(&s->sgmii_phy, OBJECT(dev),
104
+ $ minicom -D unix\#serial1.sock
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
+
105
+
206
+static void mchp_pfsoc_ddr_sgmii_phy_class_init(ObjectClass *klass, void *data)
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
207
+{
107
+second serial port. U-Boot will automatically load the Linux kernel from
208
+ DeviceClass *dc = DEVICE_CLASS(klass);
108
+the SD card image.
209
+
109
+
210
+ dc->desc = "Microchip PolarFire SoC DDR SGMII PHY module";
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
211
+ dc->realize = mchp_pfsoc_ddr_sgmii_phy_realize;
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
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
112
index XXXXXXX..XXXXXXX 100644
311
--- a/MAINTAINERS
113
--- a/docs/system/target-riscv.rst
312
+++ b/MAINTAINERS
114
+++ b/docs/system/target-riscv.rst
313
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
314
S: Supported
116
.. toctree::
315
F: hw/riscv/microchip_pfsoc.c
117
:maxdepth: 1
316
F: hw/char/mchp_pfsoc_mmuart.c
118
317
+F: hw/misc/mchp_pfsoc_dmc.c
119
+ riscv/microchip-icicle-kit
318
F: include/hw/riscv/microchip_pfsoc.h
120
riscv/sifive_u
319
F: include/hw/char/mchp_pfsoc_mmuart.h
121
320
+F: include/hw/misc/mchp_pfsoc_dmc.h
122
RISC-V CPU features
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
--
123
--
351
2.28.0
124
2.30.1
352
125
353
126
diff view generated by jsdifflib
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
2
3
Add sifive_plic vmstate for supporting sifive_plic migration.
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
4
Current vmstate framework only supports one structure parameter
4
further compressed instruction decoding. However, prior to this change,
5
as num field to describe variable length arrays, so introduce
5
we did not raise an illegal instruction exception, if decode_RV32_64C()
6
num_enables.
6
fails to decode the instruction. This means that we skipped illegal
7
7
compressed instructions instead of raising an illegal instruction
8
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
8
exception.
9
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
9
10
Instead of patching decode_RV32_64C(), we can just remove it,
11
as it is dead code since f330433b363 anyway.
12
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20201026115530.304-7-jiangyifei@huawei.com
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
18
---
14
include/hw/intc/sifive_plic.h | 1 +
19
target/riscv/translate.c | 179 +--------------------------------------
15
hw/intc/sifive_plic.c | 26 +++++++++++++++++++++++++-
20
1 file changed, 1 insertion(+), 178 deletions(-)
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
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/intc/sifive_plic.h
24
--- a/target/riscv/translate.c
21
+++ b/include/hw/intc/sifive_plic.h
25
+++ b/target/riscv/translate.c
22
@@ -XXX,XX +XXX,XX @@ struct SiFivePLICState {
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
23
uint32_t num_addrs;
27
CPUState *cs;
24
uint32_t num_harts;
28
} DisasContext;
25
uint32_t bitfield_words;
29
26
+ uint32_t num_enables;
30
-#ifdef TARGET_RISCV64
27
PLICAddr *addr_config;
31
-/* convert riscv funct3 to qemu memop for load/store */
28
uint32_t *source_priority;
32
-static const int tcg_memop_lookup[8] = {
29
uint32_t *target_priority;
33
- [0 ... 7] = -1,
30
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
34
- [0] = MO_SB,
31
index XXXXXXX..XXXXXXX 100644
35
- [1] = MO_TESW,
32
--- a/hw/intc/sifive_plic.c
36
- [2] = MO_TESL,
33
+++ b/hw/intc/sifive_plic.c
37
- [3] = MO_TEQ,
34
@@ -XXX,XX +XXX,XX @@
38
- [4] = MO_UB,
35
#include "hw/intc/sifive_plic.h"
39
- [5] = MO_TEUW,
36
#include "target/riscv/cpu.h"
40
- [6] = MO_TEUL,
37
#include "sysemu/sysemu.h"
41
-};
38
+#include "migration/vmstate.h"
42
-#endif
39
43
-
40
#define RISCV_DEBUG_PLIC 0
44
#ifdef TARGET_RISCV64
41
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
42
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
46
#else
43
TYPE_SIFIVE_PLIC, plic->aperture_size);
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
44
parse_hart_config(plic);
48
ctx->base.is_jmp = DISAS_NORETURN;
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;
58
}
49
}
59
50
60
+static const VMStateDescription vmstate_sifive_plic = {
51
-#ifdef TARGET_RISCV64
61
+ .name = "riscv_sifive_plic",
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
62
+ .version_id = 1,
53
- target_long imm)
63
+ .minimum_version_id = 1,
54
-{
64
+ .fields = (VMStateField[]) {
55
- TCGv t0 = tcg_temp_new();
65
+ VMSTATE_VARRAY_UINT32(source_priority, SiFivePLICState,
56
- TCGv t1 = tcg_temp_new();
66
+ num_sources, 0,
57
- gen_get_gpr(t0, rs1);
67
+ vmstate_info_uint32, uint32_t),
58
- tcg_gen_addi_tl(t0, t0, imm);
68
+ VMSTATE_VARRAY_UINT32(target_priority, SiFivePLICState,
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
69
+ num_addrs, 0,
60
-
70
+ vmstate_info_uint32, uint32_t),
61
- if (memop < 0) {
71
+ VMSTATE_VARRAY_UINT32(pending, SiFivePLICState, bitfield_words, 0,
62
- gen_exception_illegal(ctx);
72
+ vmstate_info_uint32, uint32_t),
63
- return;
73
+ VMSTATE_VARRAY_UINT32(claimed, SiFivePLICState, bitfield_words, 0,
64
- }
74
+ vmstate_info_uint32, uint32_t),
65
-
75
+ VMSTATE_VARRAY_UINT32(enable, SiFivePLICState, num_enables, 0,
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
76
+ vmstate_info_uint32, uint32_t),
67
- gen_set_gpr(rd, t1);
77
+ VMSTATE_END_OF_LIST()
68
- tcg_temp_free(t0);
78
+ }
69
- tcg_temp_free(t1);
79
+};
70
-}
80
+
71
-
81
static void sifive_plic_class_init(ObjectClass *klass, void *data)
72
-static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
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)
82
{
178
{
83
DeviceClass *dc = DEVICE_CLASS(klass);
179
TCGv_i32 t0;
84
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
85
device_class_set_props(dc, sifive_plic_properties);
181
tcg_temp_free_i32(t0);
86
dc->realize = sifive_plic_realize;
87
+ dc->vmsd = &vmstate_sifive_plic;
88
}
182
}
89
183
90
static const TypeInfo sifive_plic_info = {
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
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 {
91
--
240
--
92
2.28.0
241
2.30.1
93
242
94
243
diff view generated by jsdifflib