1
The following changes since commit d0ac9a61474cf594d19082bc8976247e984ea9a3:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2021-06-21' into staging (2021-06-24 09:31:26 +0100)
3
The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1:
4
5
Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210624-2
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122
8
10
9
for you to fetch changes up to 3ef6434409c575e11faf537ce50ca05426c78940:
11
for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3:
10
12
11
hw/riscv: OpenTitan: Connect the mtime and mtimecmp timer (2021-06-24 05:00:13 -0700)
13
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
Third RISC-V PR for 6.1 release
16
Seventh RISC-V PR for QEMU 6.2
15
17
16
- Fix MISA in the DisasContext
18
- Deprecate IF_NONE for SiFive OTP
17
- Fix GDB CSR XML generation
19
- Don't reset SiFive OTP content
18
- QOMify the SiFive UART
19
- Add support for the OpenTitan timer
20
20
21
----------------------------------------------------------------
21
----------------------------------------------------------------
22
Alistair Francis (4):
22
Philippe Mathieu-Daudé (1):
23
target/riscv: Use target_ulong for the DisasContext misa
23
hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset
24
hw/char/ibex_uart: Make the register layout private
25
hw/timer: Initial commit of Ibex Timer
26
hw/riscv: OpenTitan: Connect the mtime and mtimecmp timer
27
24
28
Bin Meng (1):
25
Thomas Huth (1):
29
target/riscv: gdbstub: Fix dynamic CSR XML generation
26
hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE
30
27
31
Lukas Jünger (2):
28
docs/about/deprecated.rst | 6 ++++++
32
hw/char: Consistent function names for sifive_uart
29
hw/misc/sifive_u_otp.c | 22 +++++++++++++---------
33
hw/char: QOMify sifive_uart
30
2 files changed, 19 insertions(+), 9 deletions(-)
34
31
35
include/hw/char/ibex_uart.h | 37 -----
36
include/hw/char/sifive_uart.h | 11 +-
37
include/hw/riscv/opentitan.h | 5 +-
38
include/hw/timer/ibex_timer.h | 52 +++++++
39
hw/char/ibex_uart.c | 37 +++++
40
hw/char/sifive_uart.c | 152 +++++++++++++++++----
41
hw/riscv/opentitan.c | 14 +-
42
hw/timer/ibex_timer.c | 305 ++++++++++++++++++++++++++++++++++++++++++
43
target/riscv/gdbstub.c | 2 +-
44
target/riscv/translate.c | 2 +-
45
MAINTAINERS | 6 +-
46
hw/timer/meson.build | 1 +
47
12 files changed, 543 insertions(+), 81 deletions(-)
48
create mode 100644 include/hw/timer/ibex_timer.h
49
create mode 100644 hw/timer/ibex_timer.c
50
diff view generated by jsdifflib
Deleted patch
1
The is_32bit() check in translate.c expects a 64-bit guest to have a
2
64-bit misa value otherwise the macro check won't work. This patches
3
fixes that and fixes a Coverity issue at the same time.
4
1
5
Fixes: CID 1453107
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: c00176c7518c2a7b4de3eec320b6a683ab56f705.1622435221.git.alistair.francis@wdc.com
9
---
10
target/riscv/translate.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/translate.c
16
+++ b/target/riscv/translate.c
17
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
18
bool virt_enabled;
19
uint32_t opcode;
20
uint32_t mstatus_fs;
21
- uint32_t misa;
22
+ target_ulong misa;
23
uint32_t mem_idx;
24
/* Remember the rounding mode encoded in the previous fp instruction,
25
which we have already installed into env->fp_status. Or -1 for
26
--
27
2.31.1
28
29
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Since commit 605def6eeee5 ("target/riscv: Use the RISCVException enum for CSR operations")
3
Configuring a drive with "if=none" is meant for creation of a backend
4
the CSR predicate() function was changed to return RISCV_EXCP_NONE
4
only, it should not get automatically assigned to a device frontend.
5
instead of 0 for a valid CSR, but it forgot to update the dynamic
5
Use "if=pflash" for the One-Time-Programmable device instead (like
6
CSR XML generation codes in gdbstub.
6
it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c).
7
7
8
Fixes: 605def6eeee5 ("target/riscv: Use the RISCVException enum for CSR operations")
8
Since the old way of configuring the device has already been published
9
Reported-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
9
with the previous QEMU versions, we cannot remove this immediately, but
10
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
have to deprecate it and support it for at least two more releases.
11
Tested-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
11
12
Signed-off-by: Thomas Huth <thuth@redhat.com>
13
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210615085133.389887-1-bmeng.cn@gmail.com
16
Message-id: 20211119102549.217755-1-thuth@redhat.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
18
---
16
target/riscv/gdbstub.c | 2 +-
19
docs/about/deprecated.rst | 6 ++++++
17
1 file changed, 1 insertion(+), 1 deletion(-)
20
hw/misc/sifive_u_otp.c | 9 ++++++++-
21
2 files changed, 14 insertions(+), 1 deletion(-)
18
22
19
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
23
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
20
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/gdbstub.c
25
--- a/docs/about/deprecated.rst
22
+++ b/target/riscv/gdbstub.c
26
+++ b/docs/about/deprecated.rst
23
@@ -XXX,XX +XXX,XX @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
27
@@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
24
28
However, short-form booleans are deprecated and full explicit ``arg_name=on``
25
for (i = 0; i < CSR_TABLE_SIZE; i++) {
29
form is preferred.
26
predicate = csr_ops[i].predicate;
30
27
- if (predicate && !predicate(env, i)) {
31
+``-drive if=none`` for the sifive_u OTP device (since 6.2)
28
+ if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
32
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
29
if (csr_ops[i].name) {
33
+
30
g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
34
+Using ``-drive if=none`` to configure the OTP device of the sifive_u
31
} else {
35
+RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
36
+
37
38
QEMU Machine Protocol (QMP) commands
39
------------------------------------
40
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/sifive_u_otp.c
43
+++ b/hw/misc/sifive_u_otp.c
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
45
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
46
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
47
48
- dinfo = drive_get_next(IF_NONE);
49
+ dinfo = drive_get_next(IF_PFLASH);
50
+ if (!dinfo) {
51
+ dinfo = drive_get_next(IF_NONE);
52
+ if (dinfo) {
53
+ warn_report("using \"-drive if=none\" for the OTP is deprecated, "
54
+ "use \"-drive if=pflash\" instead.");
55
+ }
56
+ }
57
if (dinfo) {
58
int ret;
59
uint64_t perm;
32
--
60
--
33
2.31.1
61
2.31.1
34
62
35
63
diff view generated by jsdifflib
1
From: Lukas Jünger <lukas.juenger@greensocs.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This cleans up function names in the SiFive UART model.
3
Once a "One Time Programmable" is programmed, it shouldn't be reset.
4
4
5
Signed-off-by: Lukas Jünger <lukas.juenger@greensocs.com>
5
Do not re-initialize the OTP content in the DeviceReset handler,
6
initialize it once in the DeviceRealize one.
7
8
Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP")
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
11
Message-Id: <20211119104757.331579-1-f4bug@amsat.org>
8
Message-id: 20210616092326.59639-2-lukas.juenger@greensocs.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
13
---
11
hw/char/sifive_uart.c | 46 ++++++++++++++++++++++---------------------
14
hw/misc/sifive_u_otp.c | 13 +++++--------
12
1 file changed, 24 insertions(+), 22 deletions(-)
15
1 file changed, 5 insertions(+), 8 deletions(-)
13
16
14
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
17
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/sifive_uart.c
19
--- a/hw/misc/sifive_u_otp.c
17
+++ b/hw/char/sifive_uart.c
20
+++ b/hw/misc/sifive_u_otp.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
19
*/
22
20
23
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
21
/* Returns the state of the IP (interrupt pending) register */
24
error_setg(errp, "failed to read the initial flash content");
22
-static uint64_t uart_ip(SiFiveUARTState *s)
25
+ return;
23
+static uint64_t sifive_uart_ip(SiFiveUARTState *s)
26
}
24
{
27
}
25
uint64_t ret = 0;
28
}
26
29
-}
27
@@ -XXX,XX +XXX,XX @@ static uint64_t uart_ip(SiFiveUARTState *s)
30
-
28
return ret;
31
-static void sifive_u_otp_reset(DeviceState *dev)
32
-{
33
- SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
34
35
/* Initialize all fuses' initial value to 0xFFs */
36
memset(s->fuse, 0xff, sizeof(s->fuse));
37
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev)
38
serial_data = s->serial;
39
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
40
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
41
- error_report("write error index<%d>", index);
42
+ error_setg(errp, "failed to write index<%d>", index);
43
+ return;
44
}
45
46
serial_data = ~(s->serial);
47
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
48
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
49
- error_report("write error index<%d>", index + 1);
50
+ error_setg(errp, "failed to write index<%d>", index + 1);
51
+ return;
52
}
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
56
57
device_class_set_props(dc, sifive_u_otp_properties);
58
dc->realize = sifive_u_otp_realize;
59
- dc->reset = sifive_u_otp_reset;
29
}
60
}
30
61
31
-static void update_irq(SiFiveUARTState *s)
62
static const TypeInfo sifive_u_otp_info = {
32
+static void sifive_uart_update_irq(SiFiveUARTState *s)
33
{
34
int cond = 0;
35
if ((s->ie & SIFIVE_UART_IE_TXWM) ||
36
@@ -XXX,XX +XXX,XX @@ static void update_irq(SiFiveUARTState *s)
37
}
38
39
static uint64_t
40
-uart_read(void *opaque, hwaddr addr, unsigned int size)
41
+sifive_uart_read(void *opaque, hwaddr addr, unsigned int size)
42
{
43
SiFiveUARTState *s = opaque;
44
unsigned char r;
45
@@ -XXX,XX +XXX,XX @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
46
memmove(s->rx_fifo, s->rx_fifo + 1, s->rx_fifo_len - 1);
47
s->rx_fifo_len--;
48
qemu_chr_fe_accept_input(&s->chr);
49
- update_irq(s);
50
+ sifive_uart_update_irq(s);
51
return r;
52
}
53
return 0x80000000;
54
@@ -XXX,XX +XXX,XX @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
55
case SIFIVE_UART_IE:
56
return s->ie;
57
case SIFIVE_UART_IP:
58
- return uart_ip(s);
59
+ return sifive_uart_ip(s);
60
case SIFIVE_UART_TXCTRL:
61
return s->txctrl;
62
case SIFIVE_UART_RXCTRL:
63
@@ -XXX,XX +XXX,XX @@ uart_read(void *opaque, hwaddr addr, unsigned int size)
64
}
65
66
static void
67
-uart_write(void *opaque, hwaddr addr,
68
- uint64_t val64, unsigned int size)
69
+sifive_uart_write(void *opaque, hwaddr addr,
70
+ uint64_t val64, unsigned int size)
71
{
72
SiFiveUARTState *s = opaque;
73
uint32_t value = val64;
74
@@ -XXX,XX +XXX,XX @@ uart_write(void *opaque, hwaddr addr,
75
switch (addr) {
76
case SIFIVE_UART_TXFIFO:
77
qemu_chr_fe_write(&s->chr, &ch, 1);
78
- update_irq(s);
79
+ sifive_uart_update_irq(s);
80
return;
81
case SIFIVE_UART_IE:
82
s->ie = val64;
83
- update_irq(s);
84
+ sifive_uart_update_irq(s);
85
return;
86
case SIFIVE_UART_TXCTRL:
87
s->txctrl = val64;
88
@@ -XXX,XX +XXX,XX @@ uart_write(void *opaque, hwaddr addr,
89
__func__, (int)addr, (int)value);
90
}
91
92
-static const MemoryRegionOps uart_ops = {
93
- .read = uart_read,
94
- .write = uart_write,
95
+static const MemoryRegionOps sifive_uart_ops = {
96
+ .read = sifive_uart_read,
97
+ .write = sifive_uart_write,
98
.endianness = DEVICE_NATIVE_ENDIAN,
99
.valid = {
100
.min_access_size = 4,
101
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps uart_ops = {
102
}
103
};
104
105
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
106
+static void sifive_uart_rx(void *opaque, const uint8_t *buf, int size)
107
{
108
SiFiveUARTState *s = opaque;
109
110
@@ -XXX,XX +XXX,XX @@ static void uart_rx(void *opaque, const uint8_t *buf, int size)
111
}
112
s->rx_fifo[s->rx_fifo_len++] = *buf;
113
114
- update_irq(s);
115
+ sifive_uart_update_irq(s);
116
}
117
118
-static int uart_can_rx(void *opaque)
119
+static int sifive_uart_can_rx(void *opaque)
120
{
121
SiFiveUARTState *s = opaque;
122
123
return s->rx_fifo_len < sizeof(s->rx_fifo);
124
}
125
126
-static void uart_event(void *opaque, QEMUChrEvent event)
127
+static void sifive_uart_event(void *opaque, QEMUChrEvent event)
128
{
129
}
130
131
-static int uart_be_change(void *opaque)
132
+static int sifive_uart_be_change(void *opaque)
133
{
134
SiFiveUARTState *s = opaque;
135
136
- qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
137
- uart_be_change, s, NULL, true);
138
+ qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
139
+ sifive_uart_event, sifive_uart_be_change, s,
140
+ NULL, true);
141
142
return 0;
143
}
144
@@ -XXX,XX +XXX,XX @@ SiFiveUARTState *sifive_uart_create(MemoryRegion *address_space, hwaddr base,
145
SiFiveUARTState *s = g_malloc0(sizeof(SiFiveUARTState));
146
s->irq = irq;
147
qemu_chr_fe_init(&s->chr, chr, &error_abort);
148
- qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, uart_event,
149
- uart_be_change, s, NULL, true);
150
- memory_region_init_io(&s->mmio, NULL, &uart_ops, s,
151
+ qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
152
+ sifive_uart_event, sifive_uart_be_change, s,
153
+ NULL, true);
154
+ memory_region_init_io(&s->mmio, NULL, &sifive_uart_ops, s,
155
TYPE_SIFIVE_UART, SIFIVE_UART_MAX);
156
memory_region_add_subregion(address_space, base, &s->mmio);
157
return s;
158
--
63
--
159
2.31.1
64
2.31.1
160
65
161
66
diff view generated by jsdifflib
Deleted patch
1
From: Lukas Jünger <lukas.juenger@greensocs.com>
2
1
3
This QOMifies the SiFive UART model. Migration and reset have been
4
implemented.
5
6
Signed-off-by: Lukas Jünger <lukas.juenger@greensocs.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210616092326.59639-3-lukas.juenger@greensocs.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/char/sifive_uart.h | 11 ++--
13
hw/char/sifive_uart.c | 114 +++++++++++++++++++++++++++++++---
14
2 files changed, 109 insertions(+), 16 deletions(-)
15
16
diff --git a/include/hw/char/sifive_uart.h b/include/hw/char/sifive_uart.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/sifive_uart.h
19
+++ b/include/hw/char/sifive_uart.h
20
@@ -XXX,XX +XXX,XX @@
21
#define HW_SIFIVE_UART_H
22
23
#include "chardev/char-fe.h"
24
+#include "hw/qdev-properties.h"
25
#include "hw/sysbus.h"
26
#include "qom/object.h"
27
28
@@ -XXX,XX +XXX,XX @@ enum {
29
30
#define SIFIVE_UART_GET_TXCNT(txctrl) ((txctrl >> 16) & 0x7)
31
#define SIFIVE_UART_GET_RXCNT(rxctrl) ((rxctrl >> 16) & 0x7)
32
+#define SIFIVE_UART_RX_FIFO_SIZE 8
33
34
#define TYPE_SIFIVE_UART "riscv.sifive.uart"
35
-
36
-typedef struct SiFiveUARTState SiFiveUARTState;
37
-DECLARE_INSTANCE_CHECKER(SiFiveUARTState, SIFIVE_UART,
38
- TYPE_SIFIVE_UART)
39
+OBJECT_DECLARE_SIMPLE_TYPE(SiFiveUARTState, SIFIVE_UART)
40
41
struct SiFiveUARTState {
42
/*< private >*/
43
@@ -XXX,XX +XXX,XX @@ struct SiFiveUARTState {
44
qemu_irq irq;
45
MemoryRegion mmio;
46
CharBackend chr;
47
- uint8_t rx_fifo[8];
48
- unsigned int rx_fifo_len;
49
+ uint8_t rx_fifo[SIFIVE_UART_RX_FIFO_SIZE];
50
+ uint8_t rx_fifo_len;
51
uint32_t ie;
52
uint32_t ip;
53
uint32_t txctrl;
54
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/char/sifive_uart.c
57
+++ b/hw/char/sifive_uart.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "qemu/osdep.h"
60
#include "qapi/error.h"
61
#include "qemu/log.h"
62
+#include "migration/vmstate.h"
63
#include "chardev/char.h"
64
#include "chardev/char-fe.h"
65
#include "hw/irq.h"
66
#include "hw/char/sifive_uart.h"
67
+#include "hw/qdev-properties-system.h"
68
69
/*
70
* Not yet implemented:
71
@@ -XXX,XX +XXX,XX @@ static int sifive_uart_be_change(void *opaque)
72
return 0;
73
}
74
75
+static Property sifive_uart_properties[] = {
76
+ DEFINE_PROP_CHR("chardev", SiFiveUARTState, chr),
77
+ DEFINE_PROP_END_OF_LIST(),
78
+};
79
+
80
+static void sifive_uart_init(Object *obj)
81
+{
82
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
83
+ SiFiveUARTState *s = SIFIVE_UART(obj);
84
+
85
+ memory_region_init_io(&s->mmio, OBJECT(s), &sifive_uart_ops, s,
86
+ TYPE_SIFIVE_UART, SIFIVE_UART_MAX);
87
+ sysbus_init_mmio(sbd, &s->mmio);
88
+ sysbus_init_irq(sbd, &s->irq);
89
+}
90
+
91
+static void sifive_uart_realize(DeviceState *dev, Error **errp)
92
+{
93
+ SiFiveUARTState *s = SIFIVE_UART(dev);
94
+
95
+ qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
96
+ sifive_uart_event, sifive_uart_be_change, s,
97
+ NULL, true);
98
+
99
+}
100
+
101
+static void sifive_uart_reset_enter(Object *obj, ResetType type)
102
+{
103
+ SiFiveUARTState *s = SIFIVE_UART(obj);
104
+ s->ie = 0;
105
+ s->ip = 0;
106
+ s->txctrl = 0;
107
+ s->rxctrl = 0;
108
+ s->div = 0;
109
+ s->rx_fifo_len = 0;
110
+}
111
+
112
+static void sifive_uart_reset_hold(Object *obj)
113
+{
114
+ SiFiveUARTState *s = SIFIVE_UART(obj);
115
+ qemu_irq_lower(s->irq);
116
+}
117
+
118
+static const VMStateDescription vmstate_sifive_uart = {
119
+ .name = TYPE_SIFIVE_UART,
120
+ .version_id = 1,
121
+ .minimum_version_id = 1,
122
+ .fields = (VMStateField[]) {
123
+ VMSTATE_UINT8_ARRAY(rx_fifo, SiFiveUARTState,
124
+ SIFIVE_UART_RX_FIFO_SIZE),
125
+ VMSTATE_UINT8(rx_fifo_len, SiFiveUARTState),
126
+ VMSTATE_UINT32(ie, SiFiveUARTState),
127
+ VMSTATE_UINT32(ip, SiFiveUARTState),
128
+ VMSTATE_UINT32(txctrl, SiFiveUARTState),
129
+ VMSTATE_UINT32(rxctrl, SiFiveUARTState),
130
+ VMSTATE_UINT32(div, SiFiveUARTState),
131
+ VMSTATE_END_OF_LIST()
132
+ },
133
+};
134
+
135
+
136
+static void sifive_uart_class_init(ObjectClass *oc, void *data)
137
+{
138
+ DeviceClass *dc = DEVICE_CLASS(oc);
139
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
140
+
141
+ dc->realize = sifive_uart_realize;
142
+ dc->vmsd = &vmstate_sifive_uart;
143
+ rc->phases.enter = sifive_uart_reset_enter;
144
+ rc->phases.hold = sifive_uart_reset_hold;
145
+ device_class_set_props(dc, sifive_uart_properties);
146
+}
147
+
148
+static const TypeInfo sifive_uart_info = {
149
+ .name = TYPE_SIFIVE_UART,
150
+ .parent = TYPE_SYS_BUS_DEVICE,
151
+ .instance_size = sizeof(SiFiveUARTState),
152
+ .instance_init = sifive_uart_init,
153
+ .class_init = sifive_uart_class_init,
154
+};
155
+
156
+static void sifive_uart_register_types(void)
157
+{
158
+ type_register_static(&sifive_uart_info);
159
+}
160
+
161
+type_init(sifive_uart_register_types)
162
+
163
/*
164
* Create UART device.
165
*/
166
SiFiveUARTState *sifive_uart_create(MemoryRegion *address_space, hwaddr base,
167
Chardev *chr, qemu_irq irq)
168
{
169
- SiFiveUARTState *s = g_malloc0(sizeof(SiFiveUARTState));
170
- s->irq = irq;
171
- qemu_chr_fe_init(&s->chr, chr, &error_abort);
172
- qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
173
- sifive_uart_event, sifive_uart_be_change, s,
174
- NULL, true);
175
- memory_region_init_io(&s->mmio, NULL, &sifive_uart_ops, s,
176
- TYPE_SIFIVE_UART, SIFIVE_UART_MAX);
177
- memory_region_add_subregion(address_space, base, &s->mmio);
178
- return s;
179
+ DeviceState *dev;
180
+ SysBusDevice *s;
181
+ SiFiveUARTState *r;
182
+
183
+ dev = qdev_new("riscv.sifive.uart");
184
+ s = SYS_BUS_DEVICE(dev);
185
+ qdev_prop_set_chr(dev, "chardev", chr);
186
+ sysbus_realize_and_unref(s, &error_fatal);
187
+ memory_region_add_subregion(address_space, base,
188
+ sysbus_mmio_get_region(s, 0));
189
+ sysbus_connect_irq(s, 0, irq);
190
+
191
+ r = SIFIVE_UART(dev);
192
+ return r;
193
}
194
--
195
2.31.1
196
197
diff view generated by jsdifflib
Deleted patch
1
We don't need to expose the register layout in the public header, so
2
don't.
3
1
4
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
Message-id: c437f570b2b30ab4170387a3ba2fad7d116a4986.1624001156.git.alistair.francis@wdc.com
7
---
8
include/hw/char/ibex_uart.h | 37 -------------------------------------
9
hw/char/ibex_uart.c | 37 +++++++++++++++++++++++++++++++++++++
10
2 files changed, 37 insertions(+), 37 deletions(-)
11
12
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/char/ibex_uart.h
15
+++ b/include/hw/char/ibex_uart.h
16
@@ -XXX,XX +XXX,XX @@
17
#include "qemu/timer.h"
18
#include "qom/object.h"
19
20
-REG32(INTR_STATE, 0x00)
21
- FIELD(INTR_STATE, TX_WATERMARK, 0, 1)
22
- FIELD(INTR_STATE, RX_WATERMARK, 1, 1)
23
- FIELD(INTR_STATE, TX_EMPTY, 2, 1)
24
- FIELD(INTR_STATE, RX_OVERFLOW, 3, 1)
25
-REG32(INTR_ENABLE, 0x04)
26
-REG32(INTR_TEST, 0x08)
27
-REG32(CTRL, 0x0C)
28
- FIELD(CTRL, TX_ENABLE, 0, 1)
29
- FIELD(CTRL, RX_ENABLE, 1, 1)
30
- FIELD(CTRL, NF, 2, 1)
31
- FIELD(CTRL, SLPBK, 4, 1)
32
- FIELD(CTRL, LLPBK, 5, 1)
33
- FIELD(CTRL, PARITY_EN, 6, 1)
34
- FIELD(CTRL, PARITY_ODD, 7, 1)
35
- FIELD(CTRL, RXBLVL, 8, 2)
36
- FIELD(CTRL, NCO, 16, 16)
37
-REG32(STATUS, 0x10)
38
- FIELD(STATUS, TXFULL, 0, 1)
39
- FIELD(STATUS, RXFULL, 1, 1)
40
- FIELD(STATUS, TXEMPTY, 2, 1)
41
- FIELD(STATUS, RXIDLE, 4, 1)
42
- FIELD(STATUS, RXEMPTY, 5, 1)
43
-REG32(RDATA, 0x14)
44
-REG32(WDATA, 0x18)
45
-REG32(FIFO_CTRL, 0x1c)
46
- FIELD(FIFO_CTRL, RXRST, 0, 1)
47
- FIELD(FIFO_CTRL, TXRST, 1, 1)
48
- FIELD(FIFO_CTRL, RXILVL, 2, 3)
49
- FIELD(FIFO_CTRL, TXILVL, 5, 2)
50
-REG32(FIFO_STATUS, 0x20)
51
- FIELD(FIFO_STATUS, TXLVL, 0, 5)
52
- FIELD(FIFO_STATUS, RXLVL, 16, 5)
53
-REG32(OVRD, 0x24)
54
-REG32(VAL, 0x28)
55
-REG32(TIMEOUT_CTRL, 0x2c)
56
-
57
#define IBEX_UART_TX_FIFO_SIZE 16
58
#define IBEX_UART_CLOCK 50000000 /* 50MHz clock */
59
60
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/char/ibex_uart.c
63
+++ b/hw/char/ibex_uart.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "qemu/log.h"
66
#include "qemu/module.h"
67
68
+REG32(INTR_STATE, 0x00)
69
+ FIELD(INTR_STATE, TX_WATERMARK, 0, 1)
70
+ FIELD(INTR_STATE, RX_WATERMARK, 1, 1)
71
+ FIELD(INTR_STATE, TX_EMPTY, 2, 1)
72
+ FIELD(INTR_STATE, RX_OVERFLOW, 3, 1)
73
+REG32(INTR_ENABLE, 0x04)
74
+REG32(INTR_TEST, 0x08)
75
+REG32(CTRL, 0x0C)
76
+ FIELD(CTRL, TX_ENABLE, 0, 1)
77
+ FIELD(CTRL, RX_ENABLE, 1, 1)
78
+ FIELD(CTRL, NF, 2, 1)
79
+ FIELD(CTRL, SLPBK, 4, 1)
80
+ FIELD(CTRL, LLPBK, 5, 1)
81
+ FIELD(CTRL, PARITY_EN, 6, 1)
82
+ FIELD(CTRL, PARITY_ODD, 7, 1)
83
+ FIELD(CTRL, RXBLVL, 8, 2)
84
+ FIELD(CTRL, NCO, 16, 16)
85
+REG32(STATUS, 0x10)
86
+ FIELD(STATUS, TXFULL, 0, 1)
87
+ FIELD(STATUS, RXFULL, 1, 1)
88
+ FIELD(STATUS, TXEMPTY, 2, 1)
89
+ FIELD(STATUS, RXIDLE, 4, 1)
90
+ FIELD(STATUS, RXEMPTY, 5, 1)
91
+REG32(RDATA, 0x14)
92
+REG32(WDATA, 0x18)
93
+REG32(FIFO_CTRL, 0x1c)
94
+ FIELD(FIFO_CTRL, RXRST, 0, 1)
95
+ FIELD(FIFO_CTRL, TXRST, 1, 1)
96
+ FIELD(FIFO_CTRL, RXILVL, 2, 3)
97
+ FIELD(FIFO_CTRL, TXILVL, 5, 2)
98
+REG32(FIFO_STATUS, 0x20)
99
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
100
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
101
+REG32(OVRD, 0x24)
102
+REG32(VAL, 0x28)
103
+REG32(TIMEOUT_CTRL, 0x2c)
104
+
105
static void ibex_uart_update_irqs(IbexUartState *s)
106
{
107
if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_WATERMARK_MASK) {
108
--
109
2.31.1
110
111
diff view generated by jsdifflib
Deleted patch
1
Add support for the Ibex timer. This is used with the RISC-V
2
mtime/mtimecmp similar to the SiFive CLINT.
3
1
4
We currently don't support changing the prescale or the timervalue.
5
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 716fdea2244515ce86a2c46fe69467d013c03147.1624001156.git.alistair.francis@wdc.com
9
---
10
include/hw/timer/ibex_timer.h | 52 ++++++
11
hw/timer/ibex_timer.c | 305 ++++++++++++++++++++++++++++++++++
12
MAINTAINERS | 6 +-
13
hw/timer/meson.build | 1 +
14
4 files changed, 360 insertions(+), 4 deletions(-)
15
create mode 100644 include/hw/timer/ibex_timer.h
16
create mode 100644 hw/timer/ibex_timer.c
17
18
diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/include/hw/timer/ibex_timer.h
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QEMU lowRISC Ibex Timer device
26
+ *
27
+ * Copyright (c) 2021 Western Digital
28
+ *
29
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
30
+ * of this software and associated documentation files (the "Software"), to deal
31
+ * in the Software without restriction, including without limitation the rights
32
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
+ * copies of the Software, and to permit persons to whom the Software is
34
+ * furnished to do so, subject to the following conditions:
35
+ *
36
+ * The above copyright notice and this permission notice shall be included in
37
+ * all copies or substantial portions of the Software.
38
+ *
39
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
42
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
+ * THE SOFTWARE.
46
+ */
47
+
48
+#ifndef HW_IBEX_TIMER_H
49
+#define HW_IBEX_TIMER_H
50
+
51
+#include "hw/sysbus.h"
52
+
53
+#define TYPE_IBEX_TIMER "ibex-timer"
54
+OBJECT_DECLARE_SIMPLE_TYPE(IbexTimerState, IBEX_TIMER)
55
+
56
+struct IbexTimerState {
57
+ /* <private> */
58
+ SysBusDevice parent_obj;
59
+
60
+ /* <public> */
61
+ MemoryRegion mmio;
62
+
63
+ uint32_t timer_ctrl;
64
+ uint32_t timer_cfg0;
65
+ uint32_t timer_compare_lower0;
66
+ uint32_t timer_compare_upper0;
67
+ uint32_t timer_intr_enable;
68
+ uint32_t timer_intr_state;
69
+ uint32_t timer_intr_test;
70
+
71
+ uint32_t timebase_freq;
72
+
73
+ qemu_irq irq;
74
+};
75
+#endif /* HW_IBEX_TIMER_H */
76
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
77
new file mode 100644
78
index XXXXXXX..XXXXXXX
79
--- /dev/null
80
+++ b/hw/timer/ibex_timer.c
81
@@ -XXX,XX +XXX,XX @@
82
+/*
83
+ * QEMU lowRISC Ibex Timer device
84
+ *
85
+ * Copyright (c) 2021 Western Digital
86
+ *
87
+ * For details check the documentation here:
88
+ * https://docs.opentitan.org/hw/ip/rv_timer/doc/
89
+ *
90
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
91
+ * of this software and associated documentation files (the "Software"), to deal
92
+ * in the Software without restriction, including without limitation the rights
93
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
94
+ * copies of the Software, and to permit persons to whom the Software is
95
+ * furnished to do so, subject to the following conditions:
96
+ *
97
+ * The above copyright notice and this permission notice shall be included in
98
+ * all copies or substantial portions of the Software.
99
+ *
100
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
101
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
102
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
103
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
104
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
106
+ * THE SOFTWARE.
107
+ */
108
+
109
+#include "qemu/osdep.h"
110
+#include "qemu/log.h"
111
+#include "qemu/timer.h"
112
+#include "hw/timer/ibex_timer.h"
113
+#include "hw/irq.h"
114
+#include "hw/qdev-properties.h"
115
+#include "target/riscv/cpu.h"
116
+#include "migration/vmstate.h"
117
+
118
+REG32(CTRL, 0x00)
119
+ FIELD(CTRL, ACTIVE, 0, 1)
120
+REG32(CFG0, 0x100)
121
+ FIELD(CFG0, PRESCALE, 0, 12)
122
+ FIELD(CFG0, STEP, 16, 8)
123
+REG32(LOWER0, 0x104)
124
+REG32(UPPER0, 0x108)
125
+REG32(COMPARE_LOWER0, 0x10C)
126
+REG32(COMPARE_UPPER0, 0x110)
127
+REG32(INTR_ENABLE, 0x114)
128
+ FIELD(INTR_ENABLE, IE_0, 0, 1)
129
+REG32(INTR_STATE, 0x118)
130
+ FIELD(INTR_STATE, IS_0, 0, 1)
131
+REG32(INTR_TEST, 0x11C)
132
+ FIELD(INTR_TEST, T_0, 0, 1)
133
+
134
+static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
135
+{
136
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
137
+ timebase_freq, NANOSECONDS_PER_SECOND);
138
+}
139
+
140
+static void ibex_timer_update_irqs(IbexTimerState *s)
141
+{
142
+ CPUState *cs = qemu_get_cpu(0);
143
+ RISCVCPU *cpu = RISCV_CPU(cs);
144
+ uint64_t value = s->timer_compare_lower0 |
145
+ ((uint64_t)s->timer_compare_upper0 << 32);
146
+ uint64_t next, diff;
147
+ uint64_t now = cpu_riscv_read_rtc(s->timebase_freq);
148
+
149
+ if (!(s->timer_ctrl & R_CTRL_ACTIVE_MASK)) {
150
+ /* Timer isn't active */
151
+ return;
152
+ }
153
+
154
+ /* Update the CPUs mtimecmp */
155
+ cpu->env.timecmp = value;
156
+
157
+ if (cpu->env.timecmp <= now) {
158
+ /*
159
+ * If the mtimecmp was in the past raise the interrupt now.
160
+ */
161
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
162
+ if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
163
+ s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
164
+ qemu_set_irq(s->irq, true);
165
+ }
166
+ return;
167
+ }
168
+
169
+ /* Setup a timer to trigger the interrupt in the future */
170
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
171
+ qemu_set_irq(s->irq, false);
172
+
173
+ diff = cpu->env.timecmp - now;
174
+ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
175
+ muldiv64(diff,
176
+ NANOSECONDS_PER_SECOND,
177
+ s->timebase_freq);
178
+
179
+ if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
180
+ /* We overflowed the timer, just set it as large as we can */
181
+ timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
182
+ } else {
183
+ timer_mod(cpu->env.timer, next);
184
+ }
185
+}
186
+
187
+static void ibex_timer_cb(void *opaque)
188
+{
189
+ IbexTimerState *s = opaque;
190
+ CPUState *cs = qemu_get_cpu(0);
191
+ RISCVCPU *cpu = RISCV_CPU(cs);
192
+
193
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
194
+ if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
195
+ s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
196
+ qemu_set_irq(s->irq, true);
197
+ }
198
+}
199
+
200
+static void ibex_timer_reset(DeviceState *dev)
201
+{
202
+ IbexTimerState *s = IBEX_TIMER(dev);
203
+
204
+ CPUState *cpu = qemu_get_cpu(0);
205
+ CPURISCVState *env = cpu->env_ptr;
206
+ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
207
+ &ibex_timer_cb, s);
208
+ env->timecmp = 0;
209
+
210
+ s->timer_ctrl = 0x00000000;
211
+ s->timer_cfg0 = 0x00010000;
212
+ s->timer_compare_lower0 = 0xFFFFFFFF;
213
+ s->timer_compare_upper0 = 0xFFFFFFFF;
214
+ s->timer_intr_enable = 0x00000000;
215
+ s->timer_intr_state = 0x00000000;
216
+ s->timer_intr_test = 0x00000000;
217
+
218
+ ibex_timer_update_irqs(s);
219
+}
220
+
221
+static uint64_t ibex_timer_read(void *opaque, hwaddr addr,
222
+ unsigned int size)
223
+{
224
+ IbexTimerState *s = opaque;
225
+ uint64_t now = cpu_riscv_read_rtc(s->timebase_freq);
226
+ uint64_t retvalue = 0;
227
+
228
+ switch (addr >> 2) {
229
+ case R_CTRL:
230
+ retvalue = s->timer_ctrl;
231
+ break;
232
+ case R_CFG0:
233
+ retvalue = s->timer_cfg0;
234
+ break;
235
+ case R_LOWER0:
236
+ retvalue = now;
237
+ break;
238
+ case R_UPPER0:
239
+ retvalue = now >> 32;
240
+ break;
241
+ case R_COMPARE_LOWER0:
242
+ retvalue = s->timer_compare_lower0;
243
+ break;
244
+ case R_COMPARE_UPPER0:
245
+ retvalue = s->timer_compare_upper0;
246
+ break;
247
+ case R_INTR_ENABLE:
248
+ retvalue = s->timer_intr_enable;
249
+ break;
250
+ case R_INTR_STATE:
251
+ retvalue = s->timer_intr_state;
252
+ break;
253
+ case R_INTR_TEST:
254
+ retvalue = s->timer_intr_test;
255
+ break;
256
+ default:
257
+ qemu_log_mask(LOG_GUEST_ERROR,
258
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
259
+ return 0;
260
+ }
261
+
262
+ return retvalue;
263
+}
264
+
265
+static void ibex_timer_write(void *opaque, hwaddr addr,
266
+ uint64_t val64, unsigned int size)
267
+{
268
+ IbexTimerState *s = opaque;
269
+ uint32_t val = val64;
270
+
271
+ switch (addr >> 2) {
272
+ case R_CTRL:
273
+ s->timer_ctrl = val;
274
+ break;
275
+ case R_CFG0:
276
+ qemu_log_mask(LOG_UNIMP, "Changing prescale or step not supported");
277
+ s->timer_cfg0 = val;
278
+ break;
279
+ case R_LOWER0:
280
+ qemu_log_mask(LOG_UNIMP, "Changing timer value is not supported");
281
+ break;
282
+ case R_UPPER0:
283
+ qemu_log_mask(LOG_UNIMP, "Changing timer value is not supported");
284
+ break;
285
+ case R_COMPARE_LOWER0:
286
+ s->timer_compare_lower0 = val;
287
+ ibex_timer_update_irqs(s);
288
+ break;
289
+ case R_COMPARE_UPPER0:
290
+ s->timer_compare_upper0 = val;
291
+ ibex_timer_update_irqs(s);
292
+ break;
293
+ case R_INTR_ENABLE:
294
+ s->timer_intr_enable = val;
295
+ break;
296
+ case R_INTR_STATE:
297
+ /* Write 1 to clear */
298
+ s->timer_intr_state &= ~val;
299
+ break;
300
+ case R_INTR_TEST:
301
+ s->timer_intr_test = val;
302
+ if (s->timer_intr_enable &
303
+ s->timer_intr_test &
304
+ R_INTR_ENABLE_IE_0_MASK) {
305
+ s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
306
+ qemu_set_irq(s->irq, true);
307
+ }
308
+ break;
309
+ default:
310
+ qemu_log_mask(LOG_GUEST_ERROR,
311
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
312
+ }
313
+}
314
+
315
+static const MemoryRegionOps ibex_timer_ops = {
316
+ .read = ibex_timer_read,
317
+ .write = ibex_timer_write,
318
+ .endianness = DEVICE_NATIVE_ENDIAN,
319
+ .impl.min_access_size = 4,
320
+ .impl.max_access_size = 4,
321
+};
322
+
323
+static int ibex_timer_post_load(void *opaque, int version_id)
324
+{
325
+ IbexTimerState *s = opaque;
326
+
327
+ ibex_timer_update_irqs(s);
328
+ return 0;
329
+}
330
+
331
+static const VMStateDescription vmstate_ibex_timer = {
332
+ .name = TYPE_IBEX_TIMER,
333
+ .version_id = 1,
334
+ .minimum_version_id = 1,
335
+ .post_load = ibex_timer_post_load,
336
+ .fields = (VMStateField[]) {
337
+ VMSTATE_UINT32(timer_ctrl, IbexTimerState),
338
+ VMSTATE_UINT32(timer_cfg0, IbexTimerState),
339
+ VMSTATE_UINT32(timer_compare_lower0, IbexTimerState),
340
+ VMSTATE_UINT32(timer_compare_upper0, IbexTimerState),
341
+ VMSTATE_UINT32(timer_intr_enable, IbexTimerState),
342
+ VMSTATE_UINT32(timer_intr_state, IbexTimerState),
343
+ VMSTATE_UINT32(timer_intr_test, IbexTimerState),
344
+ VMSTATE_END_OF_LIST()
345
+ }
346
+};
347
+
348
+static Property ibex_timer_properties[] = {
349
+ DEFINE_PROP_UINT32("timebase-freq", IbexTimerState, timebase_freq, 10000),
350
+ DEFINE_PROP_END_OF_LIST(),
351
+};
352
+
353
+static void ibex_timer_init(Object *obj)
354
+{
355
+ IbexTimerState *s = IBEX_TIMER(obj);
356
+
357
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
358
+
359
+ memory_region_init_io(&s->mmio, obj, &ibex_timer_ops, s,
360
+ TYPE_IBEX_TIMER, 0x400);
361
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
362
+}
363
+
364
+static void ibex_timer_class_init(ObjectClass *klass, void *data)
365
+{
366
+ DeviceClass *dc = DEVICE_CLASS(klass);
367
+
368
+ dc->reset = ibex_timer_reset;
369
+ dc->vmsd = &vmstate_ibex_timer;
370
+ device_class_set_props(dc, ibex_timer_properties);
371
+}
372
+
373
+static const TypeInfo ibex_timer_info = {
374
+ .name = TYPE_IBEX_TIMER,
375
+ .parent = TYPE_SYS_BUS_DEVICE,
376
+ .instance_size = sizeof(IbexTimerState),
377
+ .instance_init = ibex_timer_init,
378
+ .class_init = ibex_timer_class_init,
379
+};
380
+
381
+static void ibex_timer_register_types(void)
382
+{
383
+ type_register_static(&ibex_timer_info);
384
+}
385
+
386
+type_init(ibex_timer_register_types)
387
diff --git a/MAINTAINERS b/MAINTAINERS
388
index XXXXXXX..XXXXXXX 100644
389
--- a/MAINTAINERS
390
+++ b/MAINTAINERS
391
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <Alistair.Francis@wdc.com>
392
L: qemu-riscv@nongnu.org
393
S: Supported
394
F: hw/riscv/opentitan.c
395
-F: hw/char/ibex_uart.c
396
-F: hw/intc/ibex_plic.c
397
+F: hw/*/ibex_*.c
398
F: include/hw/riscv/opentitan.h
399
-F: include/hw/char/ibex_uart.h
400
-F: include/hw/intc/ibex_plic.h
401
+F: include/hw/*/ibex_*.h
402
403
Microchip PolarFire SoC Icicle Kit
404
M: Bin Meng <bin.meng@windriver.com>
405
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
406
index XXXXXXX..XXXXXXX 100644
407
--- a/hw/timer/meson.build
408
+++ b/hw/timer/meson.build
409
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SSE_COUNTER', if_true: files('sse-counter.c'))
410
softmmu_ss.add(when: 'CONFIG_SSE_TIMER', if_true: files('sse-timer.c'))
411
softmmu_ss.add(when: 'CONFIG_STM32F2XX_TIMER', if_true: files('stm32f2xx_timer.c'))
412
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_timer.c'))
413
+specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_timer.c'))
414
415
specific_ss.add(when: 'CONFIG_AVR_TIMER16', if_true: files('avr_timer16.c'))
416
--
417
2.31.1
418
419
diff view generated by jsdifflib
Deleted patch
1
Connect the Ibex timer to the OpenTitan machine. The timer can trigger
2
the RISC-V MIE interrupt as well as a custom device interrupt.
3
1
4
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
Message-id: 5e7f4e9b4537f863bcb8db1264b840b56ef2a929.1624001156.git.alistair.francis@wdc.com
7
---
8
include/hw/riscv/opentitan.h | 5 ++++-
9
hw/riscv/opentitan.c | 14 +++++++++++---
10
2 files changed, 15 insertions(+), 4 deletions(-)
11
12
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/riscv/opentitan.h
15
+++ b/include/hw/riscv/opentitan.h
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/riscv/riscv_hart.h"
18
#include "hw/intc/ibex_plic.h"
19
#include "hw/char/ibex_uart.h"
20
+#include "hw/timer/ibex_timer.h"
21
#include "qom/object.h"
22
23
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
24
@@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState {
25
RISCVHartArrayState cpus;
26
IbexPlicState plic;
27
IbexUartState uart;
28
+ IbexTimerState timer;
29
30
MemoryRegion flash_mem;
31
MemoryRegion rom;
32
@@ -XXX,XX +XXX,XX @@ enum {
33
IBEX_DEV_SPI,
34
IBEX_DEV_I2C,
35
IBEX_DEV_PATTGEN,
36
- IBEX_DEV_RV_TIMER,
37
+ IBEX_DEV_TIMER,
38
IBEX_DEV_SENSOR_CTRL,
39
IBEX_DEV_OTP_CTRL,
40
IBEX_DEV_PWRMGR,
41
@@ -XXX,XX +XXX,XX @@ enum {
42
};
43
44
enum {
45
+ IBEX_TIMER_TIMEREXPIRED0_0 = 125,
46
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
47
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
48
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
49
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/riscv/opentitan.c
52
+++ b/hw/riscv/opentitan.c
53
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
54
[IBEX_DEV_SPI] = { 0x40050000, 0x1000 },
55
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
56
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
57
- [IBEX_DEV_RV_TIMER] = { 0x40100000, 0x1000 },
58
+ [IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
59
[IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
60
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
61
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
62
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_init(Object *obj)
63
object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
64
65
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
66
+
67
+ object_initialize_child(obj, "timer", &s->timer, TYPE_IBEX_TIMER);
68
}
69
70
static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
71
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
72
3, qdev_get_gpio_in(DEVICE(&s->plic),
73
IBEX_UART0_RX_OVERFLOW_IRQ));
74
75
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer), errp)) {
76
+ return;
77
+ }
78
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer), 0, memmap[IBEX_DEV_TIMER].base);
79
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
80
+ 0, qdev_get_gpio_in(DEVICE(&s->plic),
81
+ IBEX_TIMER_TIMEREXPIRED0_0));
82
+
83
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
84
memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
85
create_unimplemented_device("riscv.lowrisc.ibex.spi",
86
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
87
memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size);
88
create_unimplemented_device("riscv.lowrisc.ibex.pattgen",
89
memmap[IBEX_DEV_PATTGEN].base, memmap[IBEX_DEV_PATTGEN].size);
90
- create_unimplemented_device("riscv.lowrisc.ibex.rv_timer",
91
- memmap[IBEX_DEV_RV_TIMER].base, memmap[IBEX_DEV_RV_TIMER].size);
92
create_unimplemented_device("riscv.lowrisc.ibex.sensor_ctrl",
93
memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
94
create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
95
--
96
2.31.1
97
98
diff view generated by jsdifflib