1
The following changes since commit c95bd5ff1660883d15ad6e0005e4c8571604f51a:
1
The following changes since commit 361d5397355276e3007825cc17217c1e4d4320f7:
2
2
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-fixes-20210322' into staging (2021-03-22 14:26:13 +0000)
3
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2023-07-17 15:49:27 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210322-2
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230719-1
8
8
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
9
for you to fetch changes up to 32be32509987fbe42cf5c2fd3cea3c2ad6eae179:
10
10
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
11
target/riscv: Fix LMUL check to use VLEN (2023-07-19 14:37:26 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 6.0
14
Fourth RISC-V PR for 8.1
15
15
16
This PR includes:
16
* Fix LMUL check to use VLEN
17
- Fix for vector CSR access
17
* Fix typo field in NUMA error_report
18
- Improvements to the Ibex UART device
18
* check priv_ver before auto-enable zca/zcd/zcf
19
- PMP improvements and bug fixes
19
* Fix disas output of upper immediates
20
- Hypervisor extension bug fixes
20
* tidy CPU firmware section
21
- ramfb support for the virt machine
22
- Fast read support for SST flash
23
- Improvements to the microchip_pfsoc machine
24
21
25
----------------------------------------------------------------
22
----------------------------------------------------------------
26
Alexander Wagner (1):
23
Christoph Müllner (1):
27
hw/char: disable ibex uart receive if the buffer is full
24
riscv/disas: Fix disas output of upper immediates
28
25
29
Asherah Connor (2):
26
Daniel Henrique Barboza (2):
30
hw/riscv: Add fw_cfg support to virt
27
docs/system/target-riscv.rst: tidy CPU firmware section
31
hw/riscv: allow ramfb on virt
28
target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf
32
29
33
Bin Meng (3):
30
Rob Bradford (1):
34
hw/block: m25p80: Support fast read for SST flashes
31
target/riscv: Fix LMUL check to use VLEN
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
37
32
38
Frank Chang (1):
33
Zhao Liu (1):
39
target/riscv: fix vs() to return proper error code
34
hw/riscv: Fix typo field in error_report
40
35
41
Georg Kotheimer (6):
36
docs/system/target-riscv.rst | 24 ++++++++++++++++--------
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
37
disas/riscv.h | 2 ++
43
target/riscv: Make VSTIP and VSEIP read-only in hip
38
disas/riscv.c | 19 ++++++++++++++++---
44
target/riscv: Use background registers also for MSTATUS_MPV
39
hw/riscv/numa.c | 4 ++--
45
target/riscv: Fix read and write accesses to vsip and vsie
40
target/riscv/cpu.c | 3 ++-
46
target/riscv: Add proper two-stage lookup exception detection
41
target/riscv/vector_helper.c | 4 ++--
47
target/riscv: Prevent lost illegal instruction exceptions
42
6 files changed, 40 insertions(+), 16 deletions(-)
48
43
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
Deleted patch
1
From: Frank Chang <frank.chang@sifive.com>
2
1
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
4
is not enabled.
5
6
If -1 is returned, exception will be raised and cs->exception_index will
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>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/csr.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
24
if (env->misa & RVV) {
25
return 0;
26
}
27
- return -1;
28
+ return -RISCV_EXCP_ILLEGAL_INST;
29
}
30
31
static int ctr(CPURISCVState *env, int csrno)
32
--
33
2.30.1
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Wagner <alexander.wagner@ulal.de>
2
1
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
4
the newest received byte. The rx_level variable is added to allow the use of
5
the existing OpenTitan driver libraries.
6
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/char/ibex_uart.h | 4 ++++
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
14
2 files changed, 22 insertions(+), 5 deletions(-)
15
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
19
+++ b/include/hw/char/ibex_uart.h
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
23
REG32(FIFO_STATUS, 0x20)
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
26
REG32(OVRD, 0x24)
27
REG32(VAL, 0x28)
28
REG32(TIMEOUT_CTRL, 0x2c)
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
31
uint32_t tx_level;
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
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/char/ibex_uart.c
41
+++ b/hw/char/ibex_uart.c
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
43
{
44
IbexUartState *s = opaque;
45
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
49
return 1;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
53
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
56
+ /* The RXFULL is set after receiving a single byte
57
+ * as the FIFO buffers are not yet implemented.
58
+ */
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
60
+ s->rx_level += 1;
61
62
if (size > rx_fifo_level) {
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
65
s->uart_timeout_ctrl = 0x00000000;
66
67
s->tx_level = 0;
68
+ s->rx_level = 0;
69
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
71
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
73
74
case R_RDATA:
75
retvalue = s->uart_rdata;
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
78
qemu_chr_fe_accept_input(&s->chr);
79
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
82
+ s->rx_level -= 1;
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
84
+ if (s->rx_level == 0) {
85
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
86
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
87
+ }
88
}
89
break;
90
case R_WDATA:
91
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
92
case R_FIFO_STATUS:
93
retvalue = s->uart_fifo_status;
94
95
- retvalue |= s->tx_level & 0x1F;
96
+ retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
97
+ retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
98
99
qemu_log_mask(LOG_UNIMP,
100
"%s: RX fifos are not supported\n", __func__);
101
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
102
s->uart_fifo_ctrl = value;
103
104
if (value & R_FIFO_CTRL_RXRST_MASK) {
105
+ s->rx_level = 0;
106
qemu_log_mask(LOG_UNIMP,
107
"%s: RX fifos are not supported\n", __func__);
108
}
109
--
110
2.30.1
111
112
diff view generated by jsdifflib
Deleted patch
1
From: Jim Shu <cwshu@andestech.com>
2
1
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
4
Fix it by propagating PMP permission to TLB page permission.
5
6
PMP permission checking also use MMU-style API to change TLB permission
7
and size.
8
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/pmp.h | 4 +-
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
17
3 files changed, 125 insertions(+), 43 deletions(-)
18
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
22
+++ b/target/riscv/pmp.h
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
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);
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
31
target_ulong *tlb_size);
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
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);
36
37
#endif
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
43
env->load_res = -1;
44
}
45
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)
64
+{
65
+ pmp_priv_t pmp_priv;
66
+ target_ulong tlb_size_pmp = 0;
67
+
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;
87
+}
88
+
89
/* get_physical_address - get the physical address for this virtual address
90
*
91
* Do a page table walk to obtain the physical address corresponding to a
92
@@ -XXX,XX +XXX,XX @@ restart:
93
pte_addr = base + idx * ptesize;
94
}
95
96
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
97
- !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
98
- 1 << MMU_DATA_LOAD, PRV_S)) {
99
+ int pmp_prot;
100
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
101
+ sizeof(target_ulong),
102
+ MMU_DATA_LOAD, PRV_S);
103
+ if (pmp_ret != TRANSLATE_SUCCESS) {
104
return TRANSLATE_PMP_FAIL;
105
}
106
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
108
#ifndef CONFIG_USER_ONLY
109
vaddr im_address;
110
hwaddr pa = 0;
111
- int prot, prot2;
112
+ int prot, prot2, prot_pmp;
113
bool pmp_violation = false;
114
bool first_stage_error = true;
115
bool two_stage_lookup = false;
116
int ret = TRANSLATE_FAIL;
117
int mode = mmu_idx;
118
- target_ulong tlb_size = 0;
119
+ /* default TLB page size */
120
+ target_ulong tlb_size = TARGET_PAGE_SIZE;
121
122
env->guest_phys_fault_addr = 0;
123
124
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
125
126
prot &= prot2;
127
128
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
129
- (ret == TRANSLATE_SUCCESS) &&
130
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
131
- ret = TRANSLATE_PMP_FAIL;
132
+ if (ret == TRANSLATE_SUCCESS) {
133
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
134
+ size, access_type, mode);
135
+ prot &= prot_pmp;
136
}
137
138
if (ret != TRANSLATE_SUCCESS) {
139
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
140
"%s address=%" VADDR_PRIx " ret %d physical "
141
TARGET_FMT_plx " prot %d\n",
142
__func__, address, ret, pa, prot);
143
- }
144
145
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
146
- (ret == TRANSLATE_SUCCESS) &&
147
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
148
- ret = TRANSLATE_PMP_FAIL;
149
+ if (ret == TRANSLATE_SUCCESS) {
150
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
151
+ size, access_type, mode);
152
+ prot &= prot_pmp;
153
+ }
154
}
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;
173
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/pmp.c
176
+++ b/target/riscv/pmp.c
177
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
178
return result;
179
}
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
276
-
277
/*
278
* Handle a write to a pmpcfg CSP
279
*/
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
281
282
return false;
283
}
284
+
285
+/*
286
+ * Convert PMP privilege to TLB page privilege.
287
+ */
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
289
+{
290
+ int prot = 0;
291
+
292
+ if (pmp_priv & PMP_READ) {
293
+ prot |= PAGE_READ;
294
+ }
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
301
+
302
+ return prot;
303
+}
304
--
305
2.30.1
306
307
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This adds the documentation to describe what is supported for the
3
This is how the content of the "RISC-V CPU firmware" section is
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
displayed after the html is generated:
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
"When using the sifive_u or virt machine there are three different
7
firmware boot options: 1. -bios default - This is the default behaviour
8
if no -bios option is included. (...) 3. -bios <file> - Tells QEMU to
9
load the specified file as the firmware."
10
11
It's all in the same paragraph, in a numbered list, and no special
12
formatting for the options.
13
14
Tidy it a bit by adding line breaks between items and its description.
15
Remove the numbered list. And apply formatting for the options cited in
16
the middle of the text.
17
18
Cc: qemu-trivial@nongnu.org
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
21
Message-Id: <20230712143728.383528-1-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
23
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
24
docs/system/target-riscv.rst | 24 ++++++++++++++++--------
12
docs/system/target-riscv.rst | 1 +
25
1 file changed, 16 insertions(+), 8 deletions(-)
13
2 files changed, 90 insertions(+)
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
15
26
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
21
@@ -XXX,XX +XXX,XX @@
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
23
+=============================================================
24
+
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
27
+
28
+For more details about Microchip PolarFire SoC, please see:
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
30
+
31
+The Icicle Kit board information can be found here:
32
+https://www.microsemi.com/existing-parts/parts/152514
33
+
34
+Supported devices
35
+-----------------
36
+
37
+The ``microchip-icicle-kit`` machine supports the following devices:
38
+
39
+ * 1 E51 core
40
+ * 4 U54 cores
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
49
+
50
+Boot options
51
+------------
52
+
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.
58
+
59
+The memory is set to 1537 MiB by default which is the minimum required high
60
+memory size by HSS. A sanity check on ram size is performed in the machine
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
62
+than 1537 MiB ram is detected.
63
+
64
+Boot the machine
65
+----------------
66
+
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
69
+in the HSS source tree:
70
+
71
+.. code-block:: bash
72
+
73
+ $ export CROSS_COMPILE=riscv64-linux-
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
75
+ $ make BOARD=mpfs-icicle-kit-es
76
+
77
+Download the official SD card image released by Microchip and prepare it for
78
+QEMU usage:
79
+
80
+.. code-block:: bash
81
+
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
85
+
86
+Then we can boot the machine by:
87
+
88
+.. code-block:: bash
89
+
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
92
+ -nic user,model=cadence_gem \
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
94
+ -display none -serial stdio \
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
96
+ -serial chardev:serial1
97
+
98
+With above command line, current terminal session will be used for the first
99
+serial port. Open another terminal window, and use `minicom` to connect the
100
+second serial port.
101
+
102
+.. code-block:: bash
103
+
104
+ $ minicom -D unix\#serial1.sock
105
+
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
107
+second serial port. U-Boot will automatically load the Linux kernel from
108
+the SD card image.
109
+
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
27
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
112
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/system/target-riscv.rst
29
--- a/docs/system/target-riscv.rst
114
+++ b/docs/system/target-riscv.rst
30
+++ b/docs/system/target-riscv.rst
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
31
@@ -XXX,XX +XXX,XX @@ RISC-V CPU firmware
116
.. toctree::
32
117
:maxdepth: 1
33
When using the ``sifive_u`` or ``virt`` machine there are three different
118
34
firmware boot options:
119
+ riscv/microchip-icicle-kit
35
-1. ``-bios default`` - This is the default behaviour if no -bios option
120
riscv/sifive_u
36
-is included. This option will load the default OpenSBI firmware automatically.
121
37
-The firmware is included with the QEMU release and no user interaction is
122
RISC-V CPU features
38
-required. All a user needs to do is specify the kernel they want to boot
39
-with the -kernel option
40
-2. ``-bios none`` - QEMU will not automatically load any firmware. It is up
41
-to the user to load all the images they need.
42
-3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmware.
43
+
44
+* ``-bios default``
45
+
46
+This is the default behaviour if no ``-bios`` option is included. This option
47
+will load the default OpenSBI firmware automatically. The firmware is included
48
+with the QEMU release and no user interaction is required. All a user needs to
49
+do is specify the kernel they want to boot with the ``-kernel`` option
50
+
51
+* ``-bios none``
52
+
53
+QEMU will not automatically load any firmware. It is up to the user to load all
54
+the images they need.
55
+
56
+* ``-bios <file>``
57
+
58
+Tells QEMU to load the specified file as the firmware.
123
--
59
--
124
2.30.1
60
2.40.1
125
126
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
The GNU assembler produces the following output for instructions
4
further compressed instruction decoding. However, prior to this change,
4
with upper immediates:
5
we did not raise an illegal instruction exception, if decode_RV32_64C()
5
00002597 auipc a1,0x2
6
fails to decode the instruction. This means that we skipped illegal
6
000024b7 lui s1,0x2
7
compressed instructions instead of raising an illegal instruction
7
6409 lui s0,0x2 # c.lui
8
exception.
9
8
10
Instead of patching decode_RV32_64C(), we can just remove it,
9
The immediate operands of upper immediates are not shifted.
11
as it is dead code since f330433b363 anyway.
12
10
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
11
However, the QEMU disassembler prints them shifted:
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
00002597 auipc a1,8192
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
000024b7 lui s1,8192
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
14
6409 lui s0,8192 # c.lui
15
16
The current implementation extracts the immediate bits and shifts the by 12,
17
so the internal representation of the immediate is the actual immediate.
18
However, the immediates are later printed using rv_fmt_rd_imm or
19
rv_fmt_rd_offset, which don't undo the shift.
20
21
Let's fix this by using specific output formats for instructions
22
with upper immediates, that take care of the shift.
23
24
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
25
Acked-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-Id: <20230711075051.1531007-1-christoph.muellner@vrull.eu>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
28
---
19
target/riscv/translate.c | 179 +--------------------------------------
29
disas/riscv.h | 2 ++
20
1 file changed, 1 insertion(+), 178 deletions(-)
30
disas/riscv.c | 19 ++++++++++++++++---
31
2 files changed, 18 insertions(+), 3 deletions(-)
21
32
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
33
diff --git a/disas/riscv.h b/disas/riscv.h
23
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
35
--- a/disas/riscv.h
25
+++ b/target/riscv/translate.c
36
+++ b/disas/riscv.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
@@ -XXX,XX +XXX,XX @@ enum {
27
CPUState *cs;
38
#define rv_fmt_pred_succ "O\tp,s"
28
} DisasContext;
39
#define rv_fmt_rs1_rs2 "O\t1,2"
29
40
#define rv_fmt_rd_imm "O\t0,i"
30
-#ifdef TARGET_RISCV64
41
+#define rv_fmt_rd_uimm "O\t0,Ui"
31
-/* convert riscv funct3 to qemu memop for load/store */
42
#define rv_fmt_rd_offset "O\t0,o"
32
-static const int tcg_memop_lookup[8] = {
43
+#define rv_fmt_rd_uoffset "O\t0,Uo"
33
- [0 ... 7] = -1,
44
#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
34
- [0] = MO_SB,
45
#define rv_fmt_frd_rs1 "O\t3,1"
35
- [1] = MO_TESW,
46
#define rv_fmt_frd_rs1_rs2 "O\t3,1,2"
36
- [2] = MO_TESL,
47
diff --git a/disas/riscv.c b/disas/riscv.c
37
- [3] = MO_TEQ,
48
index XXXXXXX..XXXXXXX 100644
38
- [4] = MO_UB,
49
--- a/disas/riscv.c
39
- [5] = MO_TEUW,
50
+++ b/disas/riscv.c
40
- [6] = MO_TEUL,
51
@@ -XXX,XX +XXX,XX @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
41
-};
52
42
-#endif
53
const rv_opcode_data rvi_opcode_data[] = {
43
-
54
{ "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
44
#ifdef TARGET_RISCV64
55
- { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
56
- { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
46
#else
57
+ { "lui", rv_codec_u, rv_fmt_rd_uimm, NULL, 0, 0, 0 },
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
58
+ { "auipc", rv_codec_u, rv_fmt_rd_uoffset, NULL, 0, 0, 0 },
48
ctx->base.is_jmp = DISAS_NORETURN;
59
{ "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
49
}
60
{ "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
50
61
{ "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
51
-#ifdef TARGET_RISCV64
62
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data rvi_opcode_data[] = {
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
63
rv_op_addi },
53
- target_long imm)
64
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
54
-{
65
rv_op_addi, rv_op_addi, rvcd_imm_nz },
55
- TCGv t0 = tcg_temp_new();
66
- { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
56
- TCGv t1 = tcg_temp_new();
67
+ { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui, rv_op_lui,
57
- gen_get_gpr(t0, rs1);
68
rv_op_lui, rvcd_imm_nz },
58
- tcg_gen_addi_tl(t0, t0, imm);
69
{ "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
70
rv_op_srli, rv_op_srli, rvcd_imm_nz },
60
-
71
@@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
61
- if (memop < 0) {
72
dec->pc + dec->imm);
62
- gen_exception_illegal(ctx);
73
append(buf, tmp, buflen);
63
- return;
74
break;
64
- }
75
+ case 'U':
65
-
76
+ fmt++;
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
77
+ snprintf(tmp, sizeof(tmp), "%d", dec->imm >> 12);
67
- gen_set_gpr(rd, t1);
78
+ append(buf, tmp, buflen);
68
- tcg_temp_free(t0);
79
+ if (*fmt == 'o') {
69
- tcg_temp_free(t1);
80
+ while (strlen(buf) < tab * 2) {
70
-}
81
+ append(buf, " ", buflen);
71
-
82
+ }
72
-static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
83
+ snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
73
- target_long imm)
84
+ dec->pc + dec->imm);
74
-{
85
+ append(buf, tmp, buflen);
75
- TCGv t0 = tcg_temp_new();
86
+ }
76
- TCGv dat = tcg_temp_new();
87
+ break;
77
- gen_get_gpr(t0, rs1);
88
case 'c': {
78
- tcg_gen_addi_tl(t0, t0, imm);
89
const char *name = csr_name(dec->imm & 0xfff);
79
- gen_get_gpr(dat, rs2);
90
if (name) {
80
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
81
-
82
- if (memop < 0) {
83
- gen_exception_illegal(ctx);
84
- return;
85
- }
86
-
87
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
88
- tcg_temp_free(t0);
89
- tcg_temp_free(dat);
90
-}
91
-#endif
92
-
93
#ifndef CONFIG_USER_ONLY
94
/* The states of mstatus_fs are:
95
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
96
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
97
static inline void mark_fs_dirty(DisasContext *ctx) { }
98
#endif
99
100
-#if !defined(TARGET_RISCV64)
101
-static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
102
- int rs1, target_long imm)
103
-{
104
- TCGv t0;
105
-
106
- if (ctx->mstatus_fs == 0) {
107
- gen_exception_illegal(ctx);
108
- return;
109
- }
110
-
111
- t0 = tcg_temp_new();
112
- gen_get_gpr(t0, rs1);
113
- tcg_gen_addi_tl(t0, t0, imm);
114
-
115
- switch (opc) {
116
- case OPC_RISC_FLW:
117
- if (!has_ext(ctx, RVF)) {
118
- goto do_illegal;
119
- }
120
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
121
- /* RISC-V requires NaN-boxing of narrower width floating point values */
122
- tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
123
- break;
124
- case OPC_RISC_FLD:
125
- if (!has_ext(ctx, RVD)) {
126
- goto do_illegal;
127
- }
128
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
129
- break;
130
- do_illegal:
131
- default:
132
- gen_exception_illegal(ctx);
133
- break;
134
- }
135
- tcg_temp_free(t0);
136
-
137
- mark_fs_dirty(ctx);
138
-}
139
-
140
-static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
141
- int rs2, target_long imm)
142
-{
143
- TCGv t0;
144
-
145
- if (ctx->mstatus_fs == 0) {
146
- gen_exception_illegal(ctx);
147
- return;
148
- }
149
-
150
- t0 = tcg_temp_new();
151
- gen_get_gpr(t0, rs1);
152
- tcg_gen_addi_tl(t0, t0, imm);
153
-
154
- switch (opc) {
155
- case OPC_RISC_FSW:
156
- if (!has_ext(ctx, RVF)) {
157
- goto do_illegal;
158
- }
159
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
160
- break;
161
- case OPC_RISC_FSD:
162
- if (!has_ext(ctx, RVD)) {
163
- goto do_illegal;
164
- }
165
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
166
- break;
167
- do_illegal:
168
- default:
169
- gen_exception_illegal(ctx);
170
- break;
171
- }
172
-
173
- tcg_temp_free(t0);
174
-}
175
-#endif
176
-
177
static void gen_set_rm(DisasContext *ctx, int rm)
178
{
179
TCGv_i32 t0;
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
181
tcg_temp_free_i32(t0);
182
}
183
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 {
240
--
91
--
241
2.30.1
92
2.40.1
242
93
243
94
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
Commit bd30559568 made changes in how we're checking and disabling
4
short of its purpose, as all it checks is whether two-stage address
4
extensions based on env->priv_ver. One of the changes was to move the
5
translation either via the hypervisor-load store instructions or the
5
extension disablement code to the end of realize(), being able to
6
MPRV feature would be allowed.
6
disable extensions after we've auto-enabled some of them.
7
7
8
What we really need instead is whether two-stage address translation was
8
An unfortunate side effect of this change started to happen with CPUs
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
9
that has an older priv version, like sifive-u54. Starting on commit
10
we do not have the information to reliably detect this. Therefore, when
10
2288a5ce43e5 we're auto-enabling zca, zcd and zcf if RVC is enabled,
11
we raise a memory fault exception we have to record whether two-stage
11
but these extensions are priv version 1.12.0. When running a cpu that
12
address translation is active.
12
has an older priv ver (like sifive-u54) the user is spammed with
13
warnings like these:
13
14
14
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
15
qemu-system-riscv64: warning: disabling zca extension for hart 0x0000000000000000 because privilege spec version does not match
16
qemu-system-riscv64: warning: disabling zcd extension for hart 0x0000000000000000 because privilege spec version does not match
17
18
The warnings are part of the code that disables the extension, but in this
19
case we're throwing user warnings for stuff that we enabled on our own,
20
without user intervention. Users are left wondering what they did wrong.
21
22
A quick 8.1 fix for this nuisance is to check the CPU priv spec before
23
auto-enabling zca/zcd/zcf. A more appropriate fix will include a more
24
robust framework that will account for both priv_ver and user choice
25
when auto-enabling/disabling extensions, but for 8.1 we'll make it do
26
with this simple check.
27
28
It's also worth noticing that this is the only case where we're
29
auto-enabling extensions based on a criteria (in this case RVC) that
30
doesn't match the priv spec of the extensions we're enabling. There's no
31
need for more 8.1 band-aids.
32
33
Cc: Conor Dooley <conor@kernel.org>
34
Fixes: 2288a5ce43e5 ("target/riscv: add cfg properties for Zc* extension")
35
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
36
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
37
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
38
Tested-by: Conor Dooley <conor.dooley@microchip.com>
39
Message-Id: <20230717154141.60898-1-dbarboza@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
40
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
41
---
19
target/riscv/cpu.h | 4 ++++
42
target/riscv/cpu.c | 3 ++-
20
target/riscv/cpu.c | 1 +
43
1 file changed, 2 insertions(+), 1 deletion(-)
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
22
3 files changed, 13 insertions(+), 13 deletions(-)
23
44
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
29
target_ulong satp_hs;
30
uint64_t mstatus_hs;
31
32
+ /* Signals whether the current exception occurred with two-stage address
33
+ translation active. */
34
+ bool two_stage_lookup;
35
+
36
target_ulong scounteren;
37
target_ulong mcounteren;
38
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
45
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
47
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
48
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
49
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
50
}
45
env->mcause = 0;
46
env->pc = env->resetvec;
47
+ env->two_stage_lookup = false;
48
#endif
49
cs->exception_index = EXCP_NONE;
50
env->load_res = -1;
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
56
g_assert_not_reached();
57
}
51
}
58
env->badaddr = address;
52
59
+ env->two_stage_lookup = two_stage;
53
- if (riscv_has_ext(env, RVC)) {
60
}
54
+ /* zca, zcd and zcf has a PRIV 1.12.0 restriction */
61
55
+ if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
56
cpu->cfg.ext_zca = true;
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
57
if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
64
}
58
cpu->cfg.ext_zcf = true;
65
66
env->badaddr = addr;
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
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
- }
93
-
94
- if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
95
+ if (env->two_stage_lookup && write_tval) {
96
/*
97
* If we are writing a guest virtual address to stval, set
98
* this to 1. If we are trapping to VS we will set this to 0
99
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
100
riscv_cpu_set_force_hs_excep(env, 0);
101
} else {
102
/* Trap into HS mode */
103
- if (!two_stage_lookup) {
104
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
105
- riscv_cpu_virt_enabled(env));
106
- }
107
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
108
htval = env->guest_phys_fault_addr;
109
}
110
}
111
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
112
* RISC-V ISA Specification.
113
*/
114
115
+ env->two_stage_lookup = false;
116
#endif
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
118
}
119
--
59
--
120
2.30.1
60
2.40.1
121
122
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Zhao Liu <zhao1.liu@intel.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
"smp.cpus" means the number of online CPUs and "smp.max_cpus" means the
4
been updated to use a register mapped at 0x4f000000 instead of a
4
total number of CPUs.
5
GPIO to control whether eMMC or SD card is to be used. With this
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.
10
5
11
With this commit, HSS image built from 2020.12 release boots again.
6
riscv_numa_get_default_cpu_node_id() checks "smp.cpus" and the
7
"available CPUs" description in the next error message also indicates
8
online CPUs.
12
9
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
So report "smp.cpus" in error_report() instand of "smp.max_cpus".
11
12
Since "smp.cpus" is "unsigned int", use "%u".
13
14
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
16
Message-Id: <20230718080712.503333-1-zhao1.liu@linux.intel.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
19
hw/riscv/numa.c | 4 ++--
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
20
1 file changed, 2 insertions(+), 2 deletions(-)
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/hw/riscv/numa.c b/hw/riscv/numa.c
23
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
24
--- a/hw/riscv/numa.c
25
+++ b/include/hw/riscv/microchip_pfsoc.h
25
+++ b/hw/riscv/numa.c
26
@@ -XXX,XX +XXX,XX @@ enum {
26
@@ -XXX,XX +XXX,XX @@ int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx)
27
MICROCHIP_PFSOC_ENVM_DATA,
27
28
MICROCHIP_PFSOC_QSPI_XIP,
28
if (ms->numa_state->num_nodes > ms->smp.cpus) {
29
MICROCHIP_PFSOC_IOSCB,
29
error_report("Number of NUMA nodes (%d)"
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
30
- " cannot exceed the number of available CPUs (%d).",
31
MICROCHIP_PFSOC_DRAM_LO,
31
- ms->numa_state->num_nodes, ms->smp.max_cpus);
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
32
+ " cannot exceed the number of available CPUs (%u).",
33
MICROCHIP_PFSOC_DRAM_HI,
33
+ ms->numa_state->num_nodes, ms->smp.cpus);
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
34
exit(EXIT_FAILURE);
35
index XXXXXXX..XXXXXXX 100644
35
}
36
--- a/hw/riscv/microchip_pfsoc.c
36
if (ms->numa_state->num_nodes) {
37
+++ b/hw/riscv/microchip_pfsoc.c
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
49
50
+ /* eMMC/SD mux */
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
54
+
55
/* QSPI Flash */
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
57
"microchip.pfsoc.qspi_xip",
58
--
37
--
59
2.30.1
38
2.40.1
60
61
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
The previous check was failing with:
4
debugging.
5
4
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
5
VLEN=128 ELEN = 64 SEW = 16 and LMUL = 1/8 which is a
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
valid combination.
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
7
8
Fix the check to allow valid combinations when VLEN is a multiple of
9
ELEN.
10
11
From the specification:
12
13
"In general, the requirement is to support LMUL ≥ SEWMIN/ELEN, where
14
SEWMIN is the narrowest supported SEW value and ELEN is the widest
15
supported SEW value. In the standard extensions, SEWMIN=8. For standard
16
vector extensions with ELEN=32, fractional LMULs of 1/2 and 1/4 must be
17
supported. For standard vector extensions with ELEN=64, fractional LMULs
18
of 1/2, 1/4, and 1/8 must be supported." Elsewhere in the specification
19
it makes clear that VLEN>=ELEN.
20
21
From inspection this new check allows:
22
23
VLEN=ELEN=64 1/2, 1/4, 1/8 for SEW >=8
24
VLEN=ELEN=32 1/2, 1/4 for SEW >=8
25
26
Fixes: d9b7609a1fb2 ("target/riscv: rvv-1.0: configure instructions")
27
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
28
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
29
Message-Id: <20230718131316.12283-2-rbradford@rivosinc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
31
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
32
target/riscv/vector_helper.c | 4 ++--
12
1 file changed, 12 insertions(+)
33
1 file changed, 2 insertions(+), 2 deletions(-)
13
34
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
35
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
39
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
19
if (ret == TRANSLATE_SUCCESS) {
40
xlen - 1 - R_VTYPE_RESERVED_SHIFT);
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
41
21
size, access_type, mode);
42
if (lmul & 4) {
22
+
43
- /* Fractional LMUL. */
23
+ qemu_log_mask(CPU_LOG_MMU,
44
+ /* Fractional LMUL - check LMUL * VLEN >= SEW */
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
45
if (lmul == 4 ||
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
46
- cpu->cfg.elen >> (8 - lmul) < sew) {
26
+ __func__, pa, ret, prot_pmp, tlb_size);
47
+ cpu->cfg.vlen >> (8 - lmul) < sew) {
27
+
48
vill = true;
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
}
49
}
43
}
50
}
44
--
51
--
45
2.30.1
52
2.40.1
46
53
47
54
diff view generated by jsdifflib
Deleted patch
1
From: Jim Shu <cwshu@andestech.com>
2
1
3
If PMP permission of any address has been changed by updating PMP entry,
4
flush all TLB pages to prevent from getting old permission.
5
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/pmp.c | 4 ++++
12
1 file changed, 4 insertions(+)
13
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
17
+++ b/target/riscv/pmp.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "qapi/error.h"
20
#include "cpu.h"
21
#include "trace.h"
22
+#include "exec/exec-all.h"
23
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
25
uint8_t val);
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
27
cfg_val = (val >> 8 * i) & 0xff;
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
29
}
30
+
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
32
+ tlb_flush(env_cpu(env));
33
}
34
35
36
--
37
2.30.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
1
3
According to the specification the "field SPVP of hstatus controls the
4
privilege level of the access" for the hypervisor virtual-machine load
5
and store instructions HLV, HLVX and HSV.
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
13
1 file changed, 14 insertions(+), 11 deletions(-)
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
use_background = true;
21
}
22
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
24
+ /* MPRV does not affect the virtual-machine load/store
25
+ instructions, HLV, HLVX, and HSV. */
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
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;
56
- }
57
-
58
if (riscv_cpu_virt_enabled(env) ||
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
60
access_type != MMU_INST_FETCH)) {
61
--
62
2.30.1
63
64
diff view generated by jsdifflib
Deleted patch
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
1
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/csr.c | 7 ++++---
9
1 file changed, 4 insertions(+), 3 deletions(-)
10
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
14
+++ b/target/riscv/csr.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
23
24
static const char valid_vm_1_10_32[16] = {
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
26
target_ulong new_value, target_ulong write_mask)
27
{
28
int ret = rmw_mip(env, 0, ret_value, new_value,
29
- write_mask & hip_writable_mask);
30
+ write_mask & hvip_writable_mask);
31
32
- *ret_value &= hip_writable_mask;
33
+ *ret_value &= hvip_writable_mask;
34
35
return ret;
36
}
37
--
38
2.30.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
1
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.
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu_helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
* was called. Background registers will be used if the guest has
21
* forced a two stage translation to be on (in HS or M mode).
22
*/
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
25
use_background = true;
26
}
27
28
--
29
2.30.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Asherah Connor <ashe@kivikakk.ee>
2
1
3
Provides fw_cfg for the virt machine on riscv. This enables
4
using e.g. ramfb later.
5
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/riscv/virt.h | 2 ++
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
14
hw/riscv/Kconfig | 1 +
15
3 files changed, 33 insertions(+)
16
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
20
+++ b/include/hw/riscv/virt.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
23
DeviceState *plic[VIRT_SOCKETS_MAX];
24
PFlashCFI01 *flash[2];
25
+ FWCfgState *fw_cfg;
26
27
int fdt_size;
28
};
29
@@ -XXX,XX +XXX,XX @@ enum {
30
VIRT_PLIC,
31
VIRT_UART0,
32
VIRT_VIRTIO,
33
+ VIRT_FW_CFG,
34
VIRT_FLASH,
35
VIRT_DRAM,
36
VIRT_PCIE_MMIO,
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/virt.c
40
+++ b/hw/riscv/virt.c
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
43
[VIRT_UART0] = { 0x10000000, 0x100 },
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
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;
59
+
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
61
+ &address_space_memory);
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
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;
80
}
81
82
+ /*
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
85
+ */
86
+ s->fw_cfg = create_fw_cfg(machine);
87
+ rom_set_fw(s->fw_cfg);
88
+
89
/* Compute the fdt load address in dram */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
91
machine->ram_size, machine->fdt);
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
97
select SIFIVE_PLIC
98
select SIFIVE_TEST
99
select VIRTIO_MMIO
100
+ select FW_CFG_DMA
101
102
config SIFIVE_E
103
bool
104
--
105
2.30.1
106
107
diff view generated by jsdifflib
Deleted patch
1
From: Asherah Connor <ashe@kivikakk.ee>
2
1
3
Allow ramfb on virt. This lets `-device ramfb' work.
4
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/virt.c | 3 +++
12
1 file changed, 3 insertions(+)
13
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "sysemu/sysemu.h"
20
#include "hw/pci/pci.h"
21
#include "hw/pci-host/gpex.h"
22
+#include "hw/display/ramfb.h"
23
24
static const MemMapEntry virt_memmap[] = {
25
[VIRT_DEBUG] = { 0x0, 0x100 },
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
29
mc->numa_mem_supported = true;
30
+
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
32
}
33
34
static const TypeInfo virt_machine_typeinfo = {
35
--
36
2.30.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
2
1
3
The previous implementation was broken in many ways:
4
- Used mideleg instead of hideleg to mask accesses
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
7
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
14
1 file changed, 34 insertions(+), 34 deletions(-)
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
21
return write_mstatus(env, CSR_MSTATUS, newval);
22
}
23
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
25
+{
26
+ /* Shift the VS bits to their S bit location in vsie */
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
28
+ return 0;
29
+}
30
+
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
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)
54
+{
55
if (riscv_cpu_virt_enabled(env)) {
56
- /* Shift the guests S bits to VS */
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
58
- ((val << 1) & VS_MODE_INTERRUPTS);
59
+ write_vsie(env, CSR_VSIE, val);
60
} else {
61
- newval = (env->mie & ~S_MODE_INTERRUPTS) | (val & S_MODE_INTERRUPTS);
62
+ target_ulong newval = (env->mie & ~S_MODE_INTERRUPTS) |
63
+ (val & S_MODE_INTERRUPTS);
64
+ write_mie(env, CSR_MIE, newval);
65
}
66
67
- return write_mie(env, CSR_MIE, newval);
68
+ return 0;
69
}
70
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
73
return 0;
74
}
75
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
77
+ target_ulong new_value, target_ulong write_mask)
78
+{
79
+ /* Shift the S bits to their VS bit location in mip */
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
82
+ *ret_value &= VS_MODE_INTERRUPTS;
83
+ /* Shift the VS bits to their S bit location in vsip */
84
+ *ret_value >>= 1;
85
+ return ret;
86
+}
87
+
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
89
target_ulong new_value, target_ulong write_mask)
90
{
91
int ret;
92
93
if (riscv_cpu_virt_enabled(env)) {
94
- /* Shift the new values to line up with the VS bits */
95
- ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
96
- (write_mask & sip_writable_mask) << 1 & env->mideleg);
97
- ret &= vsip_writable_mask;
98
- ret >>= 1;
99
+ ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask);
100
} else {
101
ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
102
write_mask & env->mideleg & sip_writable_mask);
103
@@ -XXX,XX +XXX,XX @@ static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
104
return 0;
105
}
106
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
108
- target_ulong new_value, target_ulong write_mask)
109
-{
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
111
- write_mask & env->mideleg & vsip_writable_mask);
112
- return ret;
113
-}
114
-
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
116
-{
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
118
- return 0;
119
-}
120
-
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
122
-{
123
- target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
124
- return write_mie(env, CSR_MIE, newval);
125
-}
126
-
127
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
128
{
129
*val = env->vstvec;
130
--
131
2.30.1
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bin.meng@windriver.com>
2
1
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
4
the address bytes. Note only SPI mode is supported by SST flashes.
5
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
7
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/block/m25p80.c | 3 +++
14
1 file changed, 3 insertions(+)
15
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
19
+++ b/hw/block/m25p80.c
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
21
s->needed_bytes = get_addr_length(s);
22
switch (get_man(s)) {
23
/* Dummy cycles - modeled with bytes writes instead of bits */
24
+ case MAN_SST:
25
+ s->needed_bytes += 1;
26
+ break;
27
case MAN_WINBOND:
28
s->needed_bytes += 8;
29
break;
30
--
31
2.30.1
32
33
diff view generated by jsdifflib