1
Latest arm queue, a mixed bag of features and bug fixes.
1
First pullreq for 6.0: mostly my v8.1M work, plus some other
2
bits and pieces. (I still have a lot of stuff in my to-review
3
folder, which I may or may not get to before the Christmas break...)
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit cbf01142b2aef0c0b4e995cecd7e79d342bbc47e:
8
The following changes since commit 5e7b204dbfae9a562fc73684986f936b97f63877:
7
9
8
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20200115' into staging (2020-01-17 12:13:17 +0000)
10
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-12-09 20:08:54 +0000)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200117-1
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201210
13
15
14
for you to fetch changes up to 1a1fbc6cbb34c26d43d8360c66c1d21681af14a9:
16
for you to fetch changes up to 71f916be1c7e9ede0e37d9cabc781b5a9e8638ff:
15
17
16
target/arm: Set ISSIs16Bit in make_issinfo (2020-01-17 14:27:16 +0000)
18
hw/arm/armv7m: Correct typo in QOM object name (2020-12-10 11:44:56 +0000)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
Add model of the Netduino Plus 2 board
21
target-arm queue:
20
Some allwinner-a10 code cleanup
22
* hw/arm/smmuv3: Fix up L1STD_SPAN decoding
21
New test cases for cubieboard
23
* xlnx-zynqmp: Support Xilinx ZynqMP CAN controllers
22
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
24
* sbsa-ref: allow to use Cortex-A53/57/72 cpus
23
i.MX: add an emulation for RNGC device
25
* Various minor code cleanups
24
target/arm: adjust program counter for wfi exception in AArch32
26
* hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
25
arm/gicv3: update virtual irq state after IAR register read
27
* Implement more pieces of ARMv8.1M support
26
Set IL bit correctly for syndrome information for data aborts
27
28
28
----------------------------------------------------------------
29
----------------------------------------------------------------
29
Alistair Francis (4):
30
Alex Chen (4):
30
hw/misc: Add the STM32F4xx Sysconfig device
31
i.MX25: Fix bad printf format specifiers
31
hw/misc: Add the STM32F4xx EXTI device
32
i.MX31: Fix bad printf format specifiers
32
hw/arm: Add the STM32F4xx SoC
33
i.MX6: Fix bad printf format specifiers
33
hw/arm: Add the Netduino Plus 2
34
i.MX6ul: Fix bad printf format specifiers
34
35
35
Jeff Kubascik (3):
36
Havard Skinnemoen (1):
36
target/arm: adjust program counter for wfi exception in AArch32
37
tests/qtest/npcm7xx_rng-test: dump random data on failure
37
arm/gicv3: update virtual irq state after IAR register read
38
target/arm: Return correct IL bit in merge_syn_data_abort
39
38
40
Martin Kaiser (1):
39
Kunkun Jiang (1):
41
i.MX: add an emulation for RNGC
40
hw/arm/smmuv3: Fix up L1STD_SPAN decoding
42
41
43
Masahiro Yamada (1):
42
Marcin Juszkiewicz (1):
44
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
43
sbsa-ref: allow to use Cortex-A53/57/72 cpus
45
44
46
Philippe Mathieu-Daudé (5):
45
Peter Maydell (25):
47
tests/boot_linux_console: Add initrd test for the CubieBoard
46
hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
48
tests/boot_linux_console: Add a SD card test for the CubieBoard
47
target/arm: Implement v8.1M PXN extension
49
hw/arm/allwinner-a10: Move SoC definitions out of header
48
target/arm: Don't clobber ID_PFR1.Security on M-profile cores
50
hw/arm/allwinner-a10: Simplify by passing IRQs with qdev_pass_gpios()
49
target/arm: Implement VSCCLRM insn
51
hw/arm/allwinner-a10: Remove local qemu_irq variables
50
target/arm: Implement CLRM instruction
51
target/arm: Enforce M-profile VMRS/VMSR register restrictions
52
target/arm: Refactor M-profile VMSR/VMRS handling
53
target/arm: Move general-use constant expanders up in translate.c
54
target/arm: Implement VLDR/VSTR system register
55
target/arm: Implement M-profile FPSCR_nzcvqc
56
target/arm: Use new FPCR_NZCV_MASK constant
57
target/arm: Factor out preserve-fp-state from full_vfp_access_check()
58
target/arm: Implement FPCXT_S fp system register
59
hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
60
target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry
61
target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures
62
target/arm: Implement v8.1M REVIDR register
63
target/arm: Implement new v8.1M NOCP check for exception return
64
target/arm: Implement new v8.1M VLLDM and VLSTM encodings
65
hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
66
target/arm: Implement CCR_S.TRD behaviour for SG insns
67
hw/intc/armv7m_nvic: Fix "return from inactive handler" check
68
target/arm: Implement M-profile "minimal RAS implementation"
69
hw/intc/armv7m_nvic: Implement read/write for RAS register block
70
hw/arm/armv7m: Correct typo in QOM object name
52
71
53
Richard Henderson (1):
72
Vikram Garhwal (4):
54
target/arm: Set ISSIs16Bit in make_issinfo
73
hw/net/can: Introduce Xilinx ZynqMP CAN controller
74
xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
75
tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
76
MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller
55
77
56
hw/arm/Makefile.objs | 2 +
78
meson.build | 1 +
57
hw/misc/Makefile.objs | 3 +
79
hw/arm/smmuv3-internal.h | 2 +-
58
include/hw/arm/allwinner-a10.h | 7 -
80
hw/net/can/trace.h | 1 +
59
include/hw/arm/fsl-imx25.h | 5 +
81
include/hw/arm/xlnx-zynqmp.h | 8 +
60
include/hw/arm/stm32f405_soc.h | 73 ++++++++
82
include/hw/intc/armv7m_nvic.h | 2 +
61
include/hw/misc/imx_rngc.h | 35 ++++
83
include/hw/net/xlnx-zynqmp-can.h | 78 +++
62
include/hw/misc/stm32f4xx_exti.h | 60 +++++++
84
target/arm/cpu.h | 46 ++
63
include/hw/misc/stm32f4xx_syscfg.h | 61 +++++++
85
target/arm/m-nocp.decode | 10 +-
64
hw/arm/allwinner-a10.c | 39 +++--
86
target/arm/t32.decode | 10 +-
65
hw/arm/fsl-imx25.c | 11 ++
87
target/arm/vfp.decode | 14 +
66
hw/arm/netduinoplus2.c | 52 ++++++
88
hw/arm/armv7m.c | 4 +-
67
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
89
hw/arm/sbsa-ref.c | 23 +-
68
hw/intc/arm_gicv3_cpuif.c | 3 +
90
hw/arm/xlnx-zcu102.c | 20 +
69
hw/misc/imx_rngc.c | 278 ++++++++++++++++++++++++++++++
91
hw/arm/xlnx-zynqmp.c | 34 ++
70
hw/misc/stm32f4xx_exti.c | 188 ++++++++++++++++++++
92
hw/intc/armv7m_nvic.c | 246 ++++++--
71
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++
93
hw/misc/imx25_ccm.c | 12 +-
72
target/arm/arm-semi.c | 5 +-
94
hw/misc/imx31_ccm.c | 14 +-
73
target/arm/op_helper.c | 7 +-
95
hw/misc/imx6_ccm.c | 20 +-
74
target/arm/tlb_helper.c | 2 +-
96
hw/misc/imx6_src.c | 2 +-
75
target/arm/translate.c | 3 +
97
hw/misc/imx6ul_ccm.c | 4 +-
76
MAINTAINERS | 14 ++
98
hw/misc/imx_ccm.c | 4 +-
77
default-configs/arm-softmmu.mak | 1 +
99
hw/net/can/xlnx-zynqmp-can.c | 1161 ++++++++++++++++++++++++++++++++++++++
78
hw/arm/Kconfig | 10 ++
100
target/arm/cpu.c | 5 +-
79
hw/misc/Kconfig | 6 +
101
target/arm/helper.c | 7 +-
80
hw/misc/trace-events | 11 ++
102
target/arm/m_helper.c | 130 ++++-
81
tests/acceptance/boot_linux_console.py | 85 ++++++++++
103
target/arm/translate.c | 105 +++-
82
26 files changed, 1405 insertions(+), 29 deletions(-)
104
tests/qtest/npcm7xx_rng-test.c | 12 +
83
create mode 100644 include/hw/arm/stm32f405_soc.h
105
tests/qtest/xlnx-can-test.c | 360 ++++++++++++
84
create mode 100644 include/hw/misc/imx_rngc.h
106
MAINTAINERS | 8 +
85
create mode 100644 include/hw/misc/stm32f4xx_exti.h
107
hw/Kconfig | 1 +
86
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
108
hw/net/can/meson.build | 1 +
87
create mode 100644 hw/arm/netduinoplus2.c
109
hw/net/can/trace-events | 9 +
88
create mode 100644 hw/arm/stm32f405_soc.c
110
target/arm/translate-vfp.c.inc | 511 ++++++++++++++++-
89
create mode 100644 hw/misc/imx_rngc.c
111
tests/qtest/meson.build | 1 +
90
create mode 100644 hw/misc/stm32f4xx_exti.c
112
34 files changed, 2713 insertions(+), 153 deletions(-)
91
create mode 100644 hw/misc/stm32f4xx_syscfg.c
113
create mode 100644 hw/net/can/trace.h
114
create mode 100644 include/hw/net/xlnx-zynqmp-can.h
115
create mode 100644 hw/net/can/xlnx-zynqmp-can.c
116
create mode 100644 tests/qtest/xlnx-can-test.c
117
create mode 100644 hw/net/can/trace-events
92
118
diff view generated by jsdifflib
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
From: Kunkun Jiang <jiangkunkun@huawei.com>
2
2
3
The IAR0/IAR1 register is used to acknowledge an interrupt - a read of the
3
Accroding to the SMMUv3 spec, the SPAN field of Level1 Stream Table
4
register activates the highest priority pending interrupt and provides its
4
Descriptor is 5 bits([4:0]).
5
interrupt ID. Activating an interrupt can change the CPU's virtual interrupt
6
state - this change makes sure the virtual irq state is updated.
7
5
8
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
6
Fixes: 9bde7f0674f(hw/arm/smmuv3: Implement translate callback)
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
10
Message-id: 20200113154607.97032-1-jeff.kubascik@dornerworks.com
8
Message-id: 20201124023711.1184-1-jiangkunkun@huawei.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Acked-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/intc/arm_gicv3_cpuif.c | 3 +++
13
hw/arm/smmuv3-internal.h | 2 +-
14
1 file changed, 3 insertions(+)
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
15
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
16
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
18
--- a/hw/arm/smmuv3-internal.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
19
+++ b/hw/arm/smmuv3-internal.h
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
20
@@ -XXX,XX +XXX,XX @@ static inline uint64_t l1std_l2ptr(STEDesc *desc)
21
21
return hi << 32 | lo;
22
trace_gicv3_icv_iar_read(ri->crm == 8 ? 0 : 1,
23
gicv3_redist_affid(cs), intid);
24
+
25
+ gicv3_cpuif_virt_update(cs);
26
+
27
return intid;
28
}
22
}
29
23
24
-#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 4))
25
+#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
26
27
#endif
30
--
28
--
31
2.20.1
29
2.20.1
32
30
33
31
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
3
The Xilinx ZynqMP CAN controller is developed based on SocketCAN, QEMU CAN bus
4
implementation. Bus connection and socketCAN connection for each CAN module
5
can be set through command lines.
6
7
Example for using single CAN:
8
-object can-bus,id=canbus0 \
9
-machine xlnx-zcu102.canbus0=canbus0 \
10
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0
11
12
Example for connecting both CAN to same virtual CAN on host machine:
13
-object can-bus,id=canbus0 -object can-bus,id=canbus1 \
14
-machine xlnx-zcu102.canbus0=canbus0 \
15
-machine xlnx-zcu102.canbus1=canbus1 \
16
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0 \
17
-object can-host-socketcan,id=socketcan1,if=vcan0,canbus=canbus1
18
19
To create virtual CAN on the host machine, please check the QEMU CAN docs:
20
https://github.com/qemu/qemu/blob/master/docs/can.txt
21
22
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
23
Message-id: 1605728926-352690-2-git-send-email-fnu.vikram@xilinx.com
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 49b01423a09cef2ca832ff73a84a996568f1a8fc.1576658572.git.alistair@alistair23.me
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
26
---
8
hw/misc/Makefile.objs | 1 +
27
meson.build | 1 +
9
include/hw/misc/stm32f4xx_syscfg.h | 61 ++++++++++
28
hw/net/can/trace.h | 1 +
10
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++++++++++++
29
include/hw/net/xlnx-zynqmp-can.h | 78 ++
11
default-configs/arm-softmmu.mak | 1 +
30
hw/net/can/xlnx-zynqmp-can.c | 1161 ++++++++++++++++++++++++++++++
12
hw/arm/Kconfig | 9 ++
31
hw/Kconfig | 1 +
13
hw/misc/Kconfig | 3 +
32
hw/net/can/meson.build | 1 +
14
hw/misc/trace-events | 6 +
33
hw/net/can/trace-events | 9 +
15
7 files changed, 252 insertions(+)
34
7 files changed, 1252 insertions(+)
16
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
35
create mode 100644 hw/net/can/trace.h
17
create mode 100644 hw/misc/stm32f4xx_syscfg.c
36
create mode 100644 include/hw/net/xlnx-zynqmp-can.h
37
create mode 100644 hw/net/can/xlnx-zynqmp-can.c
38
create mode 100644 hw/net/can/trace-events
18
39
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
40
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
42
--- a/meson.build
22
+++ b/hw/misc/Makefile.objs
43
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
44
@@ -XXX,XX +XXX,XX @@ if have_system
24
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
45
'hw/misc',
25
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
46
'hw/misc/macio',
26
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
47
'hw/net',
27
+common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
48
+ 'hw/net/can',
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
49
'hw/nvram',
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
50
'hw/pci',
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
51
'hw/pci-host',
31
diff --git a/include/hw/misc/stm32f4xx_syscfg.h b/include/hw/misc/stm32f4xx_syscfg.h
52
diff --git a/hw/net/can/trace.h b/hw/net/can/trace.h
32
new file mode 100644
53
new file mode 100644
33
index XXXXXXX..XXXXXXX
54
index XXXXXXX..XXXXXXX
34
--- /dev/null
55
--- /dev/null
35
+++ b/include/hw/misc/stm32f4xx_syscfg.h
56
+++ b/hw/net/can/trace.h
57
@@ -0,0 +1 @@
58
+#include "trace/trace-hw_net_can.h"
59
diff --git a/include/hw/net/xlnx-zynqmp-can.h b/include/hw/net/xlnx-zynqmp-can.h
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/include/hw/net/xlnx-zynqmp-can.h
36
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
37
+/*
65
+/*
38
+ * STM32F4xx SYSCFG
66
+ * QEMU model of the Xilinx ZynqMP CAN controller.
39
+ *
67
+ *
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
68
+ * Copyright (c) 2020 Xilinx Inc.
69
+ *
70
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
71
+ *
72
+ * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
73
+ * Pavel Pisa.
41
+ *
74
+ *
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
75
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ * of this software and associated documentation files (the "Software"), to deal
76
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
77
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
78
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
...
...
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
89
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
90
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
91
+ * THE SOFTWARE.
59
+ */
92
+ */
60
+
93
+
61
+#ifndef HW_STM_SYSCFG_H
94
+#ifndef XLNX_ZYNQMP_CAN_H
62
+#define HW_STM_SYSCFG_H
95
+#define XLNX_ZYNQMP_CAN_H
63
+
96
+
64
+#include "hw/sysbus.h"
97
+#include "hw/register.h"
65
+#include "hw/hw.h"
98
+#include "net/can_emu.h"
66
+
99
+#include "net/can_host.h"
67
+#define SYSCFG_MEMRMP 0x00
100
+#include "qemu/fifo32.h"
68
+#define SYSCFG_PMC 0x04
101
+#include "hw/ptimer.h"
69
+#define SYSCFG_EXTICR1 0x08
102
+#include "hw/qdev-clock.h"
70
+#define SYSCFG_EXTICR2 0x0C
103
+
71
+#define SYSCFG_EXTICR3 0x10
104
+#define TYPE_XLNX_ZYNQMP_CAN "xlnx.zynqmp-can"
72
+#define SYSCFG_EXTICR4 0x14
105
+
73
+#define SYSCFG_CMPCR 0x20
106
+#define XLNX_ZYNQMP_CAN(obj) \
74
+
107
+ OBJECT_CHECK(XlnxZynqMPCANState, (obj), TYPE_XLNX_ZYNQMP_CAN)
75
+#define TYPE_STM32F4XX_SYSCFG "stm32f4xx-syscfg"
108
+
76
+#define STM32F4XX_SYSCFG(obj) \
109
+#define MAX_CAN_CTRLS 2
77
+ OBJECT_CHECK(STM32F4xxSyscfgState, (obj), TYPE_STM32F4XX_SYSCFG)
110
+#define XLNX_ZYNQMP_CAN_R_MAX (0x84 / 4)
78
+
111
+#define MAILBOX_CAPACITY 64
79
+#define SYSCFG_NUM_EXTICR 4
112
+#define CAN_TIMER_MAX 0XFFFFUL
80
+
113
+#define CAN_DEFAULT_CLOCK (24 * 1000 * 1000)
81
+typedef struct {
114
+
82
+ /* <private> */
115
+/* Each CAN_FRAME will have 4 * 32bit size. */
83
+ SysBusDevice parent_obj;
116
+#define CAN_FRAME_SIZE 4
84
+
117
+#define RXFIFO_SIZE (MAILBOX_CAPACITY * CAN_FRAME_SIZE)
85
+ /* <public> */
118
+
86
+ MemoryRegion mmio;
119
+typedef struct XlnxZynqMPCANState {
87
+
120
+ SysBusDevice parent_obj;
88
+ uint32_t syscfg_memrmp;
121
+ MemoryRegion iomem;
89
+ uint32_t syscfg_pmc;
122
+
90
+ uint32_t syscfg_exticr[SYSCFG_NUM_EXTICR];
123
+ qemu_irq irq;
91
+ uint32_t syscfg_cmpcr;
124
+
92
+
125
+ CanBusClientState bus_client;
93
+ qemu_irq irq;
126
+ CanBusState *canbus;
94
+ qemu_irq gpio_out[16];
127
+
95
+} STM32F4xxSyscfgState;
128
+ struct {
129
+ uint32_t ext_clk_freq;
130
+ } cfg;
131
+
132
+ RegisterInfo reg_info[XLNX_ZYNQMP_CAN_R_MAX];
133
+ uint32_t regs[XLNX_ZYNQMP_CAN_R_MAX];
134
+
135
+ Fifo32 rx_fifo;
136
+ Fifo32 tx_fifo;
137
+ Fifo32 txhpb_fifo;
138
+
139
+ ptimer_state *can_timer;
140
+} XlnxZynqMPCANState;
96
+
141
+
97
+#endif
142
+#endif
98
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
143
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
99
new file mode 100644
144
new file mode 100644
100
index XXXXXXX..XXXXXXX
145
index XXXXXXX..XXXXXXX
101
--- /dev/null
146
--- /dev/null
102
+++ b/hw/misc/stm32f4xx_syscfg.c
147
+++ b/hw/net/can/xlnx-zynqmp-can.c
103
@@ -XXX,XX +XXX,XX @@
148
@@ -XXX,XX +XXX,XX @@
104
+/*
149
+/*
105
+ * STM32F4xx SYSCFG
150
+ * QEMU model of the Xilinx ZynqMP CAN controller.
151
+ * This implementation is based on the following datasheet:
152
+ * https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
106
+ *
153
+ *
107
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
154
+ * Copyright (c) 2020 Xilinx Inc.
155
+ *
156
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
157
+ *
158
+ * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
159
+ * Pavel Pisa
108
+ *
160
+ *
109
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
161
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
110
+ * of this software and associated documentation files (the "Software"), to deal
162
+ * of this software and associated documentation files (the "Software"), to deal
111
+ * in the Software without restriction, including without limitation the rights
163
+ * in the Software without restriction, including without limitation the rights
112
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
164
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
...
...
124
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
176
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
125
+ * THE SOFTWARE.
177
+ * THE SOFTWARE.
126
+ */
178
+ */
127
+
179
+
128
+#include "qemu/osdep.h"
180
+#include "qemu/osdep.h"
181
+#include "hw/sysbus.h"
182
+#include "hw/register.h"
183
+#include "hw/irq.h"
184
+#include "qapi/error.h"
185
+#include "qemu/bitops.h"
129
+#include "qemu/log.h"
186
+#include "qemu/log.h"
187
+#include "qemu/cutils.h"
188
+#include "sysemu/sysemu.h"
189
+#include "migration/vmstate.h"
190
+#include "hw/qdev-properties.h"
191
+#include "net/can_emu.h"
192
+#include "net/can_host.h"
193
+#include "qemu/event_notifier.h"
194
+#include "qom/object_interfaces.h"
195
+#include "hw/net/xlnx-zynqmp-can.h"
130
+#include "trace.h"
196
+#include "trace.h"
131
+#include "hw/irq.h"
197
+
132
+#include "migration/vmstate.h"
198
+#ifndef XLNX_ZYNQMP_CAN_ERR_DEBUG
133
+#include "hw/misc/stm32f4xx_syscfg.h"
199
+#define XLNX_ZYNQMP_CAN_ERR_DEBUG 0
134
+
200
+#endif
135
+static void stm32f4xx_syscfg_reset(DeviceState *dev)
201
+
136
+{
202
+#define MAX_DLC 8
137
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(dev);
203
+#undef ERROR
138
+
204
+
139
+ s->syscfg_memrmp = 0x00000000;
205
+REG32(SOFTWARE_RESET_REGISTER, 0x0)
140
+ s->syscfg_pmc = 0x00000000;
206
+ FIELD(SOFTWARE_RESET_REGISTER, CEN, 1, 1)
141
+ s->syscfg_exticr[0] = 0x00000000;
207
+ FIELD(SOFTWARE_RESET_REGISTER, SRST, 0, 1)
142
+ s->syscfg_exticr[1] = 0x00000000;
208
+REG32(MODE_SELECT_REGISTER, 0x4)
143
+ s->syscfg_exticr[2] = 0x00000000;
209
+ FIELD(MODE_SELECT_REGISTER, SNOOP, 2, 1)
144
+ s->syscfg_exticr[3] = 0x00000000;
210
+ FIELD(MODE_SELECT_REGISTER, LBACK, 1, 1)
145
+ s->syscfg_cmpcr = 0x00000000;
211
+ FIELD(MODE_SELECT_REGISTER, SLEEP, 0, 1)
146
+}
212
+REG32(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, 0x8)
147
+
213
+ FIELD(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, BRP, 0, 8)
148
+static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
214
+REG32(ARBITRATION_PHASE_BIT_TIMING_REGISTER, 0xc)
149
+{
215
+ FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, SJW, 7, 2)
150
+ STM32F4xxSyscfgState *s = opaque;
216
+ FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS2, 4, 3)
151
+ int icrreg = irq / 4;
217
+ FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS1, 0, 4)
152
+ int startbit = (irq & 3) * 4;
218
+REG32(ERROR_COUNTER_REGISTER, 0x10)
153
+ uint8_t config = config = irq / 16;
219
+ FIELD(ERROR_COUNTER_REGISTER, REC, 8, 8)
154
+
220
+ FIELD(ERROR_COUNTER_REGISTER, TEC, 0, 8)
155
+ trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
221
+REG32(ERROR_STATUS_REGISTER, 0x14)
156
+
222
+ FIELD(ERROR_STATUS_REGISTER, ACKER, 4, 1)
157
+ g_assert(icrreg < SYSCFG_NUM_EXTICR);
223
+ FIELD(ERROR_STATUS_REGISTER, BERR, 3, 1)
158
+
224
+ FIELD(ERROR_STATUS_REGISTER, STER, 2, 1)
159
+ if (extract32(s->syscfg_exticr[icrreg], startbit, 4) == config) {
225
+ FIELD(ERROR_STATUS_REGISTER, FMER, 1, 1)
160
+ qemu_set_irq(s->gpio_out[irq], level);
226
+ FIELD(ERROR_STATUS_REGISTER, CRCER, 0, 1)
161
+ trace_stm32f4xx_pulse_exti(irq);
227
+REG32(STATUS_REGISTER, 0x18)
162
+ }
228
+ FIELD(STATUS_REGISTER, SNOOP, 12, 1)
163
+}
229
+ FIELD(STATUS_REGISTER, ACFBSY, 11, 1)
164
+
230
+ FIELD(STATUS_REGISTER, TXFLL, 10, 1)
165
+static uint64_t stm32f4xx_syscfg_read(void *opaque, hwaddr addr,
231
+ FIELD(STATUS_REGISTER, TXBFLL, 9, 1)
166
+ unsigned int size)
232
+ FIELD(STATUS_REGISTER, ESTAT, 7, 2)
167
+{
233
+ FIELD(STATUS_REGISTER, ERRWRN, 6, 1)
168
+ STM32F4xxSyscfgState *s = opaque;
234
+ FIELD(STATUS_REGISTER, BBSY, 5, 1)
169
+
235
+ FIELD(STATUS_REGISTER, BIDLE, 4, 1)
170
+ trace_stm32f4xx_syscfg_read(addr);
236
+ FIELD(STATUS_REGISTER, NORMAL, 3, 1)
171
+
237
+ FIELD(STATUS_REGISTER, SLEEP, 2, 1)
172
+ switch (addr) {
238
+ FIELD(STATUS_REGISTER, LBACK, 1, 1)
173
+ case SYSCFG_MEMRMP:
239
+ FIELD(STATUS_REGISTER, CONFIG, 0, 1)
174
+ return s->syscfg_memrmp;
240
+REG32(INTERRUPT_STATUS_REGISTER, 0x1c)
175
+ case SYSCFG_PMC:
241
+ FIELD(INTERRUPT_STATUS_REGISTER, TXFEMP, 14, 1)
176
+ return s->syscfg_pmc;
242
+ FIELD(INTERRUPT_STATUS_REGISTER, TXFWMEMP, 13, 1)
177
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
243
+ FIELD(INTERRUPT_STATUS_REGISTER, RXFWMFLL, 12, 1)
178
+ return s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4];
244
+ FIELD(INTERRUPT_STATUS_REGISTER, WKUP, 11, 1)
179
+ case SYSCFG_CMPCR:
245
+ FIELD(INTERRUPT_STATUS_REGISTER, SLP, 10, 1)
180
+ return s->syscfg_cmpcr;
246
+ FIELD(INTERRUPT_STATUS_REGISTER, BSOFF, 9, 1)
181
+ default:
247
+ FIELD(INTERRUPT_STATUS_REGISTER, ERROR, 8, 1)
182
+ qemu_log_mask(LOG_GUEST_ERROR,
248
+ FIELD(INTERRUPT_STATUS_REGISTER, RXNEMP, 7, 1)
183
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
249
+ FIELD(INTERRUPT_STATUS_REGISTER, RXOFLW, 6, 1)
250
+ FIELD(INTERRUPT_STATUS_REGISTER, RXUFLW, 5, 1)
251
+ FIELD(INTERRUPT_STATUS_REGISTER, RXOK, 4, 1)
252
+ FIELD(INTERRUPT_STATUS_REGISTER, TXBFLL, 3, 1)
253
+ FIELD(INTERRUPT_STATUS_REGISTER, TXFLL, 2, 1)
254
+ FIELD(INTERRUPT_STATUS_REGISTER, TXOK, 1, 1)
255
+ FIELD(INTERRUPT_STATUS_REGISTER, ARBLST, 0, 1)
256
+REG32(INTERRUPT_ENABLE_REGISTER, 0x20)
257
+ FIELD(INTERRUPT_ENABLE_REGISTER, ETXFEMP, 14, 1)
258
+ FIELD(INTERRUPT_ENABLE_REGISTER, ETXFWMEMP, 13, 1)
259
+ FIELD(INTERRUPT_ENABLE_REGISTER, ERXFWMFLL, 12, 1)
260
+ FIELD(INTERRUPT_ENABLE_REGISTER, EWKUP, 11, 1)
261
+ FIELD(INTERRUPT_ENABLE_REGISTER, ESLP, 10, 1)
262
+ FIELD(INTERRUPT_ENABLE_REGISTER, EBSOFF, 9, 1)
263
+ FIELD(INTERRUPT_ENABLE_REGISTER, EERROR, 8, 1)
264
+ FIELD(INTERRUPT_ENABLE_REGISTER, ERXNEMP, 7, 1)
265
+ FIELD(INTERRUPT_ENABLE_REGISTER, ERXOFLW, 6, 1)
266
+ FIELD(INTERRUPT_ENABLE_REGISTER, ERXUFLW, 5, 1)
267
+ FIELD(INTERRUPT_ENABLE_REGISTER, ERXOK, 4, 1)
268
+ FIELD(INTERRUPT_ENABLE_REGISTER, ETXBFLL, 3, 1)
269
+ FIELD(INTERRUPT_ENABLE_REGISTER, ETXFLL, 2, 1)
270
+ FIELD(INTERRUPT_ENABLE_REGISTER, ETXOK, 1, 1)
271
+ FIELD(INTERRUPT_ENABLE_REGISTER, EARBLST, 0, 1)
272
+REG32(INTERRUPT_CLEAR_REGISTER, 0x24)
273
+ FIELD(INTERRUPT_CLEAR_REGISTER, CTXFEMP, 14, 1)
274
+ FIELD(INTERRUPT_CLEAR_REGISTER, CTXFWMEMP, 13, 1)
275
+ FIELD(INTERRUPT_CLEAR_REGISTER, CRXFWMFLL, 12, 1)
276
+ FIELD(INTERRUPT_CLEAR_REGISTER, CWKUP, 11, 1)
277
+ FIELD(INTERRUPT_CLEAR_REGISTER, CSLP, 10, 1)
278
+ FIELD(INTERRUPT_CLEAR_REGISTER, CBSOFF, 9, 1)
279
+ FIELD(INTERRUPT_CLEAR_REGISTER, CERROR, 8, 1)
280
+ FIELD(INTERRUPT_CLEAR_REGISTER, CRXNEMP, 7, 1)
281
+ FIELD(INTERRUPT_CLEAR_REGISTER, CRXOFLW, 6, 1)
282
+ FIELD(INTERRUPT_CLEAR_REGISTER, CRXUFLW, 5, 1)
283
+ FIELD(INTERRUPT_CLEAR_REGISTER, CRXOK, 4, 1)
284
+ FIELD(INTERRUPT_CLEAR_REGISTER, CTXBFLL, 3, 1)
285
+ FIELD(INTERRUPT_CLEAR_REGISTER, CTXFLL, 2, 1)
286
+ FIELD(INTERRUPT_CLEAR_REGISTER, CTXOK, 1, 1)
287
+ FIELD(INTERRUPT_CLEAR_REGISTER, CARBLST, 0, 1)
288
+REG32(TIMESTAMP_REGISTER, 0x28)
289
+ FIELD(TIMESTAMP_REGISTER, CTS, 0, 1)
290
+REG32(WIR, 0x2c)
291
+ FIELD(WIR, EW, 8, 8)
292
+ FIELD(WIR, FW, 0, 8)
293
+REG32(TXFIFO_ID, 0x30)
294
+ FIELD(TXFIFO_ID, IDH, 21, 11)
295
+ FIELD(TXFIFO_ID, SRRRTR, 20, 1)
296
+ FIELD(TXFIFO_ID, IDE, 19, 1)
297
+ FIELD(TXFIFO_ID, IDL, 1, 18)
298
+ FIELD(TXFIFO_ID, RTR, 0, 1)
299
+REG32(TXFIFO_DLC, 0x34)
300
+ FIELD(TXFIFO_DLC, DLC, 28, 4)
301
+REG32(TXFIFO_DATA1, 0x38)
302
+ FIELD(TXFIFO_DATA1, DB0, 24, 8)
303
+ FIELD(TXFIFO_DATA1, DB1, 16, 8)
304
+ FIELD(TXFIFO_DATA1, DB2, 8, 8)
305
+ FIELD(TXFIFO_DATA1, DB3, 0, 8)
306
+REG32(TXFIFO_DATA2, 0x3c)
307
+ FIELD(TXFIFO_DATA2, DB4, 24, 8)
308
+ FIELD(TXFIFO_DATA2, DB5, 16, 8)
309
+ FIELD(TXFIFO_DATA2, DB6, 8, 8)
310
+ FIELD(TXFIFO_DATA2, DB7, 0, 8)
311
+REG32(TXHPB_ID, 0x40)
312
+ FIELD(TXHPB_ID, IDH, 21, 11)
313
+ FIELD(TXHPB_ID, SRRRTR, 20, 1)
314
+ FIELD(TXHPB_ID, IDE, 19, 1)
315
+ FIELD(TXHPB_ID, IDL, 1, 18)
316
+ FIELD(TXHPB_ID, RTR, 0, 1)
317
+REG32(TXHPB_DLC, 0x44)
318
+ FIELD(TXHPB_DLC, DLC, 28, 4)
319
+REG32(TXHPB_DATA1, 0x48)
320
+ FIELD(TXHPB_DATA1, DB0, 24, 8)
321
+ FIELD(TXHPB_DATA1, DB1, 16, 8)
322
+ FIELD(TXHPB_DATA1, DB2, 8, 8)
323
+ FIELD(TXHPB_DATA1, DB3, 0, 8)
324
+REG32(TXHPB_DATA2, 0x4c)
325
+ FIELD(TXHPB_DATA2, DB4, 24, 8)
326
+ FIELD(TXHPB_DATA2, DB5, 16, 8)
327
+ FIELD(TXHPB_DATA2, DB6, 8, 8)
328
+ FIELD(TXHPB_DATA2, DB7, 0, 8)
329
+REG32(RXFIFO_ID, 0x50)
330
+ FIELD(RXFIFO_ID, IDH, 21, 11)
331
+ FIELD(RXFIFO_ID, SRRRTR, 20, 1)
332
+ FIELD(RXFIFO_ID, IDE, 19, 1)
333
+ FIELD(RXFIFO_ID, IDL, 1, 18)
334
+ FIELD(RXFIFO_ID, RTR, 0, 1)
335
+REG32(RXFIFO_DLC, 0x54)
336
+ FIELD(RXFIFO_DLC, DLC, 28, 4)
337
+ FIELD(RXFIFO_DLC, RXT, 0, 16)
338
+REG32(RXFIFO_DATA1, 0x58)
339
+ FIELD(RXFIFO_DATA1, DB0, 24, 8)
340
+ FIELD(RXFIFO_DATA1, DB1, 16, 8)
341
+ FIELD(RXFIFO_DATA1, DB2, 8, 8)
342
+ FIELD(RXFIFO_DATA1, DB3, 0, 8)
343
+REG32(RXFIFO_DATA2, 0x5c)
344
+ FIELD(RXFIFO_DATA2, DB4, 24, 8)
345
+ FIELD(RXFIFO_DATA2, DB5, 16, 8)
346
+ FIELD(RXFIFO_DATA2, DB6, 8, 8)
347
+ FIELD(RXFIFO_DATA2, DB7, 0, 8)
348
+REG32(AFR, 0x60)
349
+ FIELD(AFR, UAF4, 3, 1)
350
+ FIELD(AFR, UAF3, 2, 1)
351
+ FIELD(AFR, UAF2, 1, 1)
352
+ FIELD(AFR, UAF1, 0, 1)
353
+REG32(AFMR1, 0x64)
354
+ FIELD(AFMR1, AMIDH, 21, 11)
355
+ FIELD(AFMR1, AMSRR, 20, 1)
356
+ FIELD(AFMR1, AMIDE, 19, 1)
357
+ FIELD(AFMR1, AMIDL, 1, 18)
358
+ FIELD(AFMR1, AMRTR, 0, 1)
359
+REG32(AFIR1, 0x68)
360
+ FIELD(AFIR1, AIIDH, 21, 11)
361
+ FIELD(AFIR1, AISRR, 20, 1)
362
+ FIELD(AFIR1, AIIDE, 19, 1)
363
+ FIELD(AFIR1, AIIDL, 1, 18)
364
+ FIELD(AFIR1, AIRTR, 0, 1)
365
+REG32(AFMR2, 0x6c)
366
+ FIELD(AFMR2, AMIDH, 21, 11)
367
+ FIELD(AFMR2, AMSRR, 20, 1)
368
+ FIELD(AFMR2, AMIDE, 19, 1)
369
+ FIELD(AFMR2, AMIDL, 1, 18)
370
+ FIELD(AFMR2, AMRTR, 0, 1)
371
+REG32(AFIR2, 0x70)
372
+ FIELD(AFIR2, AIIDH, 21, 11)
373
+ FIELD(AFIR2, AISRR, 20, 1)
374
+ FIELD(AFIR2, AIIDE, 19, 1)
375
+ FIELD(AFIR2, AIIDL, 1, 18)
376
+ FIELD(AFIR2, AIRTR, 0, 1)
377
+REG32(AFMR3, 0x74)
378
+ FIELD(AFMR3, AMIDH, 21, 11)
379
+ FIELD(AFMR3, AMSRR, 20, 1)
380
+ FIELD(AFMR3, AMIDE, 19, 1)
381
+ FIELD(AFMR3, AMIDL, 1, 18)
382
+ FIELD(AFMR3, AMRTR, 0, 1)
383
+REG32(AFIR3, 0x78)
384
+ FIELD(AFIR3, AIIDH, 21, 11)
385
+ FIELD(AFIR3, AISRR, 20, 1)
386
+ FIELD(AFIR3, AIIDE, 19, 1)
387
+ FIELD(AFIR3, AIIDL, 1, 18)
388
+ FIELD(AFIR3, AIRTR, 0, 1)
389
+REG32(AFMR4, 0x7c)
390
+ FIELD(AFMR4, AMIDH, 21, 11)
391
+ FIELD(AFMR4, AMSRR, 20, 1)
392
+ FIELD(AFMR4, AMIDE, 19, 1)
393
+ FIELD(AFMR4, AMIDL, 1, 18)
394
+ FIELD(AFMR4, AMRTR, 0, 1)
395
+REG32(AFIR4, 0x80)
396
+ FIELD(AFIR4, AIIDH, 21, 11)
397
+ FIELD(AFIR4, AISRR, 20, 1)
398
+ FIELD(AFIR4, AIIDE, 19, 1)
399
+ FIELD(AFIR4, AIIDL, 1, 18)
400
+ FIELD(AFIR4, AIRTR, 0, 1)
401
+
402
+static void can_update_irq(XlnxZynqMPCANState *s)
403
+{
404
+ uint32_t irq;
405
+
406
+ /* Watermark register interrupts. */
407
+ if ((fifo32_num_free(&s->tx_fifo) / CAN_FRAME_SIZE) >
408
+ ARRAY_FIELD_EX32(s->regs, WIR, EW)) {
409
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFWMEMP, 1);
410
+ }
411
+
412
+ if ((fifo32_num_used(&s->rx_fifo) / CAN_FRAME_SIZE) >
413
+ ARRAY_FIELD_EX32(s->regs, WIR, FW)) {
414
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXFWMFLL, 1);
415
+ }
416
+
417
+ /* RX Interrupts. */
418
+ if (fifo32_num_used(&s->rx_fifo) >= CAN_FRAME_SIZE) {
419
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXNEMP, 1);
420
+ }
421
+
422
+ /* TX interrupts. */
423
+ if (fifo32_is_empty(&s->tx_fifo)) {
424
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFEMP, 1);
425
+ }
426
+
427
+ if (fifo32_is_full(&s->tx_fifo)) {
428
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFLL, 1);
429
+ }
430
+
431
+ if (fifo32_is_full(&s->txhpb_fifo)) {
432
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXBFLL, 1);
433
+ }
434
+
435
+ irq = s->regs[R_INTERRUPT_STATUS_REGISTER];
436
+ irq &= s->regs[R_INTERRUPT_ENABLE_REGISTER];
437
+
438
+ trace_xlnx_can_update_irq(s->regs[R_INTERRUPT_STATUS_REGISTER],
439
+ s->regs[R_INTERRUPT_ENABLE_REGISTER], irq);
440
+ qemu_set_irq(s->irq, irq);
441
+}
442
+
443
+static void can_ier_post_write(RegisterInfo *reg, uint64_t val)
444
+{
445
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
446
+
447
+ can_update_irq(s);
448
+}
449
+
450
+static uint64_t can_icr_pre_write(RegisterInfo *reg, uint64_t val)
451
+{
452
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
453
+
454
+ s->regs[R_INTERRUPT_STATUS_REGISTER] &= ~val;
455
+ can_update_irq(s);
456
+
457
+ return 0;
458
+}
459
+
460
+static void can_config_reset(XlnxZynqMPCANState *s)
461
+{
462
+ /* Reset all the configuration registers. */
463
+ register_reset(&s->reg_info[R_SOFTWARE_RESET_REGISTER]);
464
+ register_reset(&s->reg_info[R_MODE_SELECT_REGISTER]);
465
+ register_reset(
466
+ &s->reg_info[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER]);
467
+ register_reset(&s->reg_info[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER]);
468
+ register_reset(&s->reg_info[R_STATUS_REGISTER]);
469
+ register_reset(&s->reg_info[R_INTERRUPT_STATUS_REGISTER]);
470
+ register_reset(&s->reg_info[R_INTERRUPT_ENABLE_REGISTER]);
471
+ register_reset(&s->reg_info[R_INTERRUPT_CLEAR_REGISTER]);
472
+ register_reset(&s->reg_info[R_WIR]);
473
+}
474
+
475
+static void can_config_mode(XlnxZynqMPCANState *s)
476
+{
477
+ register_reset(&s->reg_info[R_ERROR_COUNTER_REGISTER]);
478
+ register_reset(&s->reg_info[R_ERROR_STATUS_REGISTER]);
479
+
480
+ /* Put XlnxZynqMPCAN in configuration mode. */
481
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 1);
482
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP, 0);
483
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP, 0);
484
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, BSOFF, 0);
485
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ERROR, 0);
486
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 0);
487
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 0);
488
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 0);
489
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ARBLST, 0);
490
+
491
+ can_update_irq(s);
492
+}
493
+
494
+static void update_status_register_mode_bits(XlnxZynqMPCANState *s)
495
+{
496
+ bool sleep_status = ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP);
497
+ bool sleep_mode = ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP);
498
+ /* Wake up interrupt bit. */
499
+ bool wakeup_irq_val = sleep_status && (sleep_mode == 0);
500
+ /* Sleep interrupt bit. */
501
+ bool sleep_irq_val = sleep_mode && (sleep_status == 0);
502
+
503
+ /* Clear previous core mode status bits. */
504
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 0);
505
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 0);
506
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 0);
507
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 0);
508
+
509
+ /* set current mode bit and generate irqs accordingly. */
510
+ if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, LBACK)) {
511
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 1);
512
+ } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP)) {
513
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 1);
514
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP,
515
+ sleep_irq_val);
516
+ } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SNOOP)) {
517
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 1);
518
+ } else {
519
+ /*
520
+ * If all bits are zero then XlnxZynqMPCAN is set in normal mode.
521
+ */
522
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
523
+ /* Set wakeup interrupt bit. */
524
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP,
525
+ wakeup_irq_val);
526
+ }
527
+
528
+ can_update_irq(s);
529
+}
530
+
531
+static void can_exit_sleep_mode(XlnxZynqMPCANState *s)
532
+{
533
+ ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, 0);
534
+ update_status_register_mode_bits(s);
535
+}
536
+
537
+static void generate_frame(qemu_can_frame *frame, uint32_t *data)
538
+{
539
+ frame->can_id = data[0];
540
+ frame->can_dlc = FIELD_EX32(data[1], TXFIFO_DLC, DLC);
541
+
542
+ frame->data[0] = FIELD_EX32(data[2], TXFIFO_DATA1, DB3);
543
+ frame->data[1] = FIELD_EX32(data[2], TXFIFO_DATA1, DB2);
544
+ frame->data[2] = FIELD_EX32(data[2], TXFIFO_DATA1, DB1);
545
+ frame->data[3] = FIELD_EX32(data[2], TXFIFO_DATA1, DB0);
546
+
547
+ frame->data[4] = FIELD_EX32(data[3], TXFIFO_DATA2, DB7);
548
+ frame->data[5] = FIELD_EX32(data[3], TXFIFO_DATA2, DB6);
549
+ frame->data[6] = FIELD_EX32(data[3], TXFIFO_DATA2, DB5);
550
+ frame->data[7] = FIELD_EX32(data[3], TXFIFO_DATA2, DB4);
551
+}
552
+
553
+static bool tx_ready_check(XlnxZynqMPCANState *s)
554
+{
555
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
556
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
557
+
558
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer data while"
559
+ " data while controller is in reset mode.\n",
560
+ path);
561
+ return false;
562
+ }
563
+
564
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
565
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
566
+
567
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer"
568
+ " data while controller is in configuration mode. Reset"
569
+ " the core so operations can start fresh.\n",
570
+ path);
571
+ return false;
572
+ }
573
+
574
+ if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
575
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
576
+
577
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer"
578
+ " data while controller is in SNOOP MODE.\n",
579
+ path);
580
+ return false;
581
+ }
582
+
583
+ return true;
584
+}
585
+
586
+static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
587
+{
588
+ qemu_can_frame frame;
589
+ uint32_t data[CAN_FRAME_SIZE];
590
+ int i;
591
+ bool can_tx = tx_ready_check(s);
592
+
593
+ if (!can_tx) {
594
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
595
+
596
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is not enabled for data"
597
+ " transfer.\n", path);
598
+ can_update_irq(s);
599
+ return;
600
+ }
601
+
602
+ while (!fifo32_is_empty(fifo)) {
603
+ for (i = 0; i < CAN_FRAME_SIZE; i++) {
604
+ data[i] = fifo32_pop(fifo);
605
+ }
606
+
607
+ if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
608
+ /*
609
+ * Controller is in loopback. In Loopback mode, the CAN core
610
+ * transmits a recessive bitstream on to the XlnxZynqMPCAN Bus.
611
+ * Any message transmitted is looped back to the RX line and
612
+ * acknowledged. The XlnxZynqMPCAN core receives any message
613
+ * that it transmits.
614
+ */
615
+ if (fifo32_is_full(&s->rx_fifo)) {
616
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
617
+ } else {
618
+ for (i = 0; i < CAN_FRAME_SIZE; i++) {
619
+ fifo32_push(&s->rx_fifo, data[i]);
620
+ }
621
+
622
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
623
+ }
624
+ } else {
625
+ /* Normal mode Tx. */
626
+ generate_frame(&frame, data);
627
+
628
+ trace_xlnx_can_tx_data(frame.can_id, frame.can_dlc,
629
+ frame.data[0], frame.data[1],
630
+ frame.data[2], frame.data[3],
631
+ frame.data[4], frame.data[5],
632
+ frame.data[6], frame.data[7]);
633
+ can_bus_client_send(&s->bus_client, &frame, 1);
634
+ }
635
+ }
636
+
637
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 1);
638
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, TXBFLL, 0);
639
+
640
+ if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) {
641
+ can_exit_sleep_mode(s);
642
+ }
643
+
644
+ can_update_irq(s);
645
+}
646
+
647
+static uint64_t can_srr_pre_write(RegisterInfo *reg, uint64_t val)
648
+{
649
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
650
+
651
+ ARRAY_FIELD_DP32(s->regs, SOFTWARE_RESET_REGISTER, CEN,
652
+ FIELD_EX32(val, SOFTWARE_RESET_REGISTER, CEN));
653
+
654
+ if (FIELD_EX32(val, SOFTWARE_RESET_REGISTER, SRST)) {
655
+ trace_xlnx_can_reset(val);
656
+
657
+ /* First, core will do software reset then will enter in config mode. */
658
+ can_config_reset(s);
659
+ }
660
+
661
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
662
+ can_config_mode(s);
663
+ } else {
664
+ /*
665
+ * Leave config mode. Now XlnxZynqMPCAN core will enter normal,
666
+ * sleep, snoop or loopback mode depending upon LBACK, SLEEP, SNOOP
667
+ * register states.
668
+ */
669
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 0);
670
+
671
+ ptimer_transaction_begin(s->can_timer);
672
+ ptimer_set_count(s->can_timer, 0);
673
+ ptimer_transaction_commit(s->can_timer);
674
+
675
+ /* XlnxZynqMPCAN is out of config mode. It will send pending data. */
676
+ transfer_fifo(s, &s->txhpb_fifo);
677
+ transfer_fifo(s, &s->tx_fifo);
678
+ }
679
+
680
+ update_status_register_mode_bits(s);
681
+
682
+ return s->regs[R_SOFTWARE_RESET_REGISTER];
683
+}
684
+
685
+static uint64_t can_msr_pre_write(RegisterInfo *reg, uint64_t val)
686
+{
687
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
688
+ uint8_t multi_mode;
689
+
690
+ /*
691
+ * Multiple mode set check. This is done to make sure user doesn't set
692
+ * multiple modes.
693
+ */
694
+ multi_mode = FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK) +
695
+ FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP) +
696
+ FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP);
697
+
698
+ if (multi_mode > 1) {
699
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
700
+
701
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to config"
702
+ " several modes simultaneously. One mode will be selected"
703
+ " according to their priority: LBACK > SLEEP > SNOOP.\n",
704
+ path);
705
+ }
706
+
707
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
708
+ /* We are in configuration mode, any mode can be selected. */
709
+ s->regs[R_MODE_SELECT_REGISTER] = val;
710
+ } else {
711
+ bool sleep_mode_bit = FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP);
712
+
713
+ ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, sleep_mode_bit);
714
+
715
+ if (FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK)) {
716
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
717
+
718
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to set"
719
+ " LBACK mode without setting CEN bit as 0.\n",
720
+ path);
721
+ } else if (FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP)) {
722
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
723
+
724
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to set"
725
+ " SNOOP mode without setting CEN bit as 0.\n",
726
+ path);
727
+ }
728
+
729
+ update_status_register_mode_bits(s);
730
+ }
731
+
732
+ return s->regs[R_MODE_SELECT_REGISTER];
733
+}
734
+
735
+static uint64_t can_brpr_pre_write(RegisterInfo *reg, uint64_t val)
736
+{
737
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
738
+
739
+ /* Only allow writes when in config mode. */
740
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
741
+ return s->regs[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER];
742
+ }
743
+
744
+ return val;
745
+}
746
+
747
+static uint64_t can_btr_pre_write(RegisterInfo *reg, uint64_t val)
748
+{
749
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
750
+
751
+ /* Only allow writes when in config mode. */
752
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
753
+ return s->regs[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER];
754
+ }
755
+
756
+ return val;
757
+}
758
+
759
+static uint64_t can_tcr_pre_write(RegisterInfo *reg, uint64_t val)
760
+{
761
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
762
+
763
+ if (FIELD_EX32(val, TIMESTAMP_REGISTER, CTS)) {
764
+ ptimer_transaction_begin(s->can_timer);
765
+ ptimer_set_count(s->can_timer, 0);
766
+ ptimer_transaction_commit(s->can_timer);
767
+ }
768
+
769
+ return 0;
770
+}
771
+
772
+static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame)
773
+{
774
+ bool filter_pass = false;
775
+ uint16_t timestamp = 0;
776
+
777
+ /* If no filter is enabled. Message will be stored in FIFO. */
778
+ if (!((ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) |
779
+ (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) |
780
+ (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) |
781
+ (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)))) {
782
+ filter_pass = true;
783
+ }
784
+
785
+ /*
786
+ * Messages that pass any of the acceptance filters will be stored in
787
+ * the RX FIFO.
788
+ */
789
+ if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) {
790
+ uint32_t id_masked = s->regs[R_AFMR1] & frame->can_id;
791
+ uint32_t filter_id_masked = s->regs[R_AFMR1] & s->regs[R_AFIR1];
792
+
793
+ if (filter_id_masked == id_masked) {
794
+ filter_pass = true;
795
+ }
796
+ }
797
+
798
+ if (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) {
799
+ uint32_t id_masked = s->regs[R_AFMR2] & frame->can_id;
800
+ uint32_t filter_id_masked = s->regs[R_AFMR2] & s->regs[R_AFIR2];
801
+
802
+ if (filter_id_masked == id_masked) {
803
+ filter_pass = true;
804
+ }
805
+ }
806
+
807
+ if (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) {
808
+ uint32_t id_masked = s->regs[R_AFMR3] & frame->can_id;
809
+ uint32_t filter_id_masked = s->regs[R_AFMR3] & s->regs[R_AFIR3];
810
+
811
+ if (filter_id_masked == id_masked) {
812
+ filter_pass = true;
813
+ }
814
+ }
815
+
816
+ if (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
817
+ uint32_t id_masked = s->regs[R_AFMR4] & frame->can_id;
818
+ uint32_t filter_id_masked = s->regs[R_AFMR4] & s->regs[R_AFIR4];
819
+
820
+ if (filter_id_masked == id_masked) {
821
+ filter_pass = true;
822
+ }
823
+ }
824
+
825
+ if (!filter_pass) {
826
+ trace_xlnx_can_rx_fifo_filter_reject(frame->can_id, frame->can_dlc);
827
+ return;
828
+ }
829
+
830
+ /* Store the message in fifo if it passed through any of the filters. */
831
+ if (filter_pass && frame->can_dlc <= MAX_DLC) {
832
+
833
+ if (fifo32_is_full(&s->rx_fifo)) {
834
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
835
+ } else {
836
+ timestamp = CAN_TIMER_MAX - ptimer_get_count(s->can_timer);
837
+
838
+ fifo32_push(&s->rx_fifo, frame->can_id);
839
+
840
+ fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DLC_DLC_SHIFT,
841
+ R_RXFIFO_DLC_DLC_LENGTH,
842
+ frame->can_dlc) |
843
+ deposit32(0, R_RXFIFO_DLC_RXT_SHIFT,
844
+ R_RXFIFO_DLC_RXT_LENGTH,
845
+ timestamp));
846
+
847
+ /* First 32 bit of the data. */
848
+ fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT,
849
+ R_TXFIFO_DATA1_DB3_LENGTH,
850
+ frame->data[0]) |
851
+ deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT,
852
+ R_TXFIFO_DATA1_DB2_LENGTH,
853
+ frame->data[1]) |
854
+ deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT,
855
+ R_TXFIFO_DATA1_DB1_LENGTH,
856
+ frame->data[2]) |
857
+ deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT,
858
+ R_TXFIFO_DATA1_DB0_LENGTH,
859
+ frame->data[3]));
860
+ /* Last 32 bit of the data. */
861
+ fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT,
862
+ R_TXFIFO_DATA2_DB7_LENGTH,
863
+ frame->data[4]) |
864
+ deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT,
865
+ R_TXFIFO_DATA2_DB6_LENGTH,
866
+ frame->data[5]) |
867
+ deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT,
868
+ R_TXFIFO_DATA2_DB5_LENGTH,
869
+ frame->data[6]) |
870
+ deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT,
871
+ R_TXFIFO_DATA2_DB4_LENGTH,
872
+ frame->data[7]));
873
+
874
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
875
+ trace_xlnx_can_rx_data(frame->can_id, frame->can_dlc,
876
+ frame->data[0], frame->data[1],
877
+ frame->data[2], frame->data[3],
878
+ frame->data[4], frame->data[5],
879
+ frame->data[6], frame->data[7]);
880
+ }
881
+
882
+ can_update_irq(s);
883
+ }
884
+}
885
+
886
+static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val)
887
+{
888
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
889
+
890
+ if (!fifo32_is_empty(&s->rx_fifo)) {
891
+ val = fifo32_pop(&s->rx_fifo);
892
+ } else {
893
+ ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
894
+ }
895
+
896
+ can_update_irq(s);
897
+ return val;
898
+}
899
+
900
+static void can_filter_enable_post_write(RegisterInfo *reg, uint64_t val)
901
+{
902
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
903
+
904
+ if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1) &&
905
+ ARRAY_FIELD_EX32(s->regs, AFR, UAF2) &&
906
+ ARRAY_FIELD_EX32(s->regs, AFR, UAF3) &&
907
+ ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
908
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 1);
909
+ } else {
910
+ ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 0);
911
+ }
912
+}
913
+
914
+static uint64_t can_filter_mask_pre_write(RegisterInfo *reg, uint64_t val)
915
+{
916
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
917
+ uint32_t reg_idx = (reg->access->addr) / 4;
918
+ uint32_t filter_number = (reg_idx - R_AFMR1) / 2;
919
+
920
+ /* modify an acceptance filter, the corresponding UAF bit should be '0'. */
921
+ if (!(s->regs[R_AFR] & (1 << filter_number))) {
922
+ s->regs[reg_idx] = val;
923
+
924
+ trace_xlnx_can_filter_mask_pre_write(filter_number, s->regs[reg_idx]);
925
+ } else {
926
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
927
+
928
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d"
929
+ " mask is not set as corresponding UAF bit is not 0.\n",
930
+ path, filter_number + 1);
931
+ }
932
+
933
+ return s->regs[reg_idx];
934
+}
935
+
936
+static uint64_t can_filter_id_pre_write(RegisterInfo *reg, uint64_t val)
937
+{
938
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
939
+ uint32_t reg_idx = (reg->access->addr) / 4;
940
+ uint32_t filter_number = (reg_idx - R_AFIR1) / 2;
941
+
942
+ if (!(s->regs[R_AFR] & (1 << filter_number))) {
943
+ s->regs[reg_idx] = val;
944
+
945
+ trace_xlnx_can_filter_id_pre_write(filter_number, s->regs[reg_idx]);
946
+ } else {
947
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
948
+
949
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d"
950
+ " id is not set as corresponding UAF bit is not 0.\n",
951
+ path, filter_number + 1);
952
+ }
953
+
954
+ return s->regs[reg_idx];
955
+}
956
+
957
+static void can_tx_post_write(RegisterInfo *reg, uint64_t val)
958
+{
959
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
960
+
961
+ bool is_txhpb = reg->access->addr > A_TXFIFO_DATA2;
962
+
963
+ bool initiate_transfer = (reg->access->addr == A_TXFIFO_DATA2) ||
964
+ (reg->access->addr == A_TXHPB_DATA2);
965
+
966
+ Fifo32 *f = is_txhpb ? &s->txhpb_fifo : &s->tx_fifo;
967
+
968
+ if (!fifo32_is_full(f)) {
969
+ fifo32_push(f, val);
970
+ } else {
971
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
972
+
973
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: TX FIFO is full.\n", path);
974
+ }
975
+
976
+ /* Initiate the message send if TX register is written. */
977
+ if (initiate_transfer &&
978
+ ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
979
+ transfer_fifo(s, f);
980
+ }
981
+
982
+ can_update_irq(s);
983
+}
984
+
985
+static const RegisterAccessInfo can_regs_info[] = {
986
+ { .name = "SOFTWARE_RESET_REGISTER",
987
+ .addr = A_SOFTWARE_RESET_REGISTER,
988
+ .rsvd = 0xfffffffc,
989
+ .pre_write = can_srr_pre_write,
990
+ },{ .name = "MODE_SELECT_REGISTER",
991
+ .addr = A_MODE_SELECT_REGISTER,
992
+ .rsvd = 0xfffffff8,
993
+ .pre_write = can_msr_pre_write,
994
+ },{ .name = "ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER",
995
+ .addr = A_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER,
996
+ .rsvd = 0xffffff00,
997
+ .pre_write = can_brpr_pre_write,
998
+ },{ .name = "ARBITRATION_PHASE_BIT_TIMING_REGISTER",
999
+ .addr = A_ARBITRATION_PHASE_BIT_TIMING_REGISTER,
1000
+ .rsvd = 0xfffffe00,
1001
+ .pre_write = can_btr_pre_write,
1002
+ },{ .name = "ERROR_COUNTER_REGISTER",
1003
+ .addr = A_ERROR_COUNTER_REGISTER,
1004
+ .rsvd = 0xffff0000,
1005
+ .ro = 0xffffffff,
1006
+ },{ .name = "ERROR_STATUS_REGISTER",
1007
+ .addr = A_ERROR_STATUS_REGISTER,
1008
+ .rsvd = 0xffffffe0,
1009
+ .w1c = 0x1f,
1010
+ },{ .name = "STATUS_REGISTER", .addr = A_STATUS_REGISTER,
1011
+ .reset = 0x1,
1012
+ .rsvd = 0xffffe000,
1013
+ .ro = 0x1fff,
1014
+ },{ .name = "INTERRUPT_STATUS_REGISTER",
1015
+ .addr = A_INTERRUPT_STATUS_REGISTER,
1016
+ .reset = 0x6000,
1017
+ .rsvd = 0xffff8000,
1018
+ .ro = 0x7fff,
1019
+ },{ .name = "INTERRUPT_ENABLE_REGISTER",
1020
+ .addr = A_INTERRUPT_ENABLE_REGISTER,
1021
+ .rsvd = 0xffff8000,
1022
+ .post_write = can_ier_post_write,
1023
+ },{ .name = "INTERRUPT_CLEAR_REGISTER",
1024
+ .addr = A_INTERRUPT_CLEAR_REGISTER,
1025
+ .rsvd = 0xffff8000,
1026
+ .pre_write = can_icr_pre_write,
1027
+ },{ .name = "TIMESTAMP_REGISTER",
1028
+ .addr = A_TIMESTAMP_REGISTER,
1029
+ .rsvd = 0xfffffffe,
1030
+ .pre_write = can_tcr_pre_write,
1031
+ },{ .name = "WIR", .addr = A_WIR,
1032
+ .reset = 0x3f3f,
1033
+ .rsvd = 0xffff0000,
1034
+ },{ .name = "TXFIFO_ID", .addr = A_TXFIFO_ID,
1035
+ .post_write = can_tx_post_write,
1036
+ },{ .name = "TXFIFO_DLC", .addr = A_TXFIFO_DLC,
1037
+ .rsvd = 0xfffffff,
1038
+ .post_write = can_tx_post_write,
1039
+ },{ .name = "TXFIFO_DATA1", .addr = A_TXFIFO_DATA1,
1040
+ .post_write = can_tx_post_write,
1041
+ },{ .name = "TXFIFO_DATA2", .addr = A_TXFIFO_DATA2,
1042
+ .post_write = can_tx_post_write,
1043
+ },{ .name = "TXHPB_ID", .addr = A_TXHPB_ID,
1044
+ .post_write = can_tx_post_write,
1045
+ },{ .name = "TXHPB_DLC", .addr = A_TXHPB_DLC,
1046
+ .rsvd = 0xfffffff,
1047
+ .post_write = can_tx_post_write,
1048
+ },{ .name = "TXHPB_DATA1", .addr = A_TXHPB_DATA1,
1049
+ .post_write = can_tx_post_write,
1050
+ },{ .name = "TXHPB_DATA2", .addr = A_TXHPB_DATA2,
1051
+ .post_write = can_tx_post_write,
1052
+ },{ .name = "RXFIFO_ID", .addr = A_RXFIFO_ID,
1053
+ .ro = 0xffffffff,
1054
+ .post_read = can_rxfifo_pre_read,
1055
+ },{ .name = "RXFIFO_DLC", .addr = A_RXFIFO_DLC,
1056
+ .rsvd = 0xfff0000,
1057
+ .post_read = can_rxfifo_pre_read,
1058
+ },{ .name = "RXFIFO_DATA1", .addr = A_RXFIFO_DATA1,
1059
+ .post_read = can_rxfifo_pre_read,
1060
+ },{ .name = "RXFIFO_DATA2", .addr = A_RXFIFO_DATA2,
1061
+ .post_read = can_rxfifo_pre_read,
1062
+ },{ .name = "AFR", .addr = A_AFR,
1063
+ .rsvd = 0xfffffff0,
1064
+ .post_write = can_filter_enable_post_write,
1065
+ },{ .name = "AFMR1", .addr = A_AFMR1,
1066
+ .pre_write = can_filter_mask_pre_write,
1067
+ },{ .name = "AFIR1", .addr = A_AFIR1,
1068
+ .pre_write = can_filter_id_pre_write,
1069
+ },{ .name = "AFMR2", .addr = A_AFMR2,
1070
+ .pre_write = can_filter_mask_pre_write,
1071
+ },{ .name = "AFIR2", .addr = A_AFIR2,
1072
+ .pre_write = can_filter_id_pre_write,
1073
+ },{ .name = "AFMR3", .addr = A_AFMR3,
1074
+ .pre_write = can_filter_mask_pre_write,
1075
+ },{ .name = "AFIR3", .addr = A_AFIR3,
1076
+ .pre_write = can_filter_id_pre_write,
1077
+ },{ .name = "AFMR4", .addr = A_AFMR4,
1078
+ .pre_write = can_filter_mask_pre_write,
1079
+ },{ .name = "AFIR4", .addr = A_AFIR4,
1080
+ .pre_write = can_filter_id_pre_write,
1081
+ }
1082
+};
1083
+
1084
+static void xlnx_zynqmp_can_ptimer_cb(void *opaque)
1085
+{
1086
+ /* No action required on the timer rollover. */
1087
+}
1088
+
1089
+static const MemoryRegionOps can_ops = {
1090
+ .read = register_read_memory,
1091
+ .write = register_write_memory,
1092
+ .endianness = DEVICE_LITTLE_ENDIAN,
1093
+ .valid = {
1094
+ .min_access_size = 4,
1095
+ .max_access_size = 4,
1096
+ },
1097
+};
1098
+
1099
+static void xlnx_zynqmp_can_reset_init(Object *obj, ResetType type)
1100
+{
1101
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
1102
+ unsigned int i;
1103
+
1104
+ for (i = R_RXFIFO_ID; i < ARRAY_SIZE(s->reg_info); ++i) {
1105
+ register_reset(&s->reg_info[i]);
1106
+ }
1107
+
1108
+ ptimer_transaction_begin(s->can_timer);
1109
+ ptimer_set_count(s->can_timer, 0);
1110
+ ptimer_transaction_commit(s->can_timer);
1111
+}
1112
+
1113
+static void xlnx_zynqmp_can_reset_hold(Object *obj)
1114
+{
1115
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
1116
+ unsigned int i;
1117
+
1118
+ for (i = 0; i < R_RXFIFO_ID; ++i) {
1119
+ register_reset(&s->reg_info[i]);
1120
+ }
1121
+
1122
+ /*
1123
+ * Reset FIFOs when CAN model is reset. This will clear the fifo writes
1124
+ * done by post_write which gets called from register_reset function,
1125
+ * post_write handle will not be able to trigger tx because CAN will be
1126
+ * disabled when software_reset_register is cleared first.
1127
+ */
1128
+ fifo32_reset(&s->rx_fifo);
1129
+ fifo32_reset(&s->tx_fifo);
1130
+ fifo32_reset(&s->txhpb_fifo);
1131
+}
1132
+
1133
+static bool xlnx_zynqmp_can_can_receive(CanBusClientState *client)
1134
+{
1135
+ XlnxZynqMPCANState *s = container_of(client, XlnxZynqMPCANState,
1136
+ bus_client);
1137
+
1138
+ if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
1139
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1140
+
1141
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is in reset state.\n",
1142
+ path);
1143
+ return false;
1144
+ }
1145
+
1146
+ if ((ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) == 0) {
1147
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1148
+
1149
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is disabled. Incoming"
1150
+ " messages will be discarded.\n", path);
1151
+ return false;
1152
+ }
1153
+
1154
+ return true;
1155
+}
1156
+
1157
+static ssize_t xlnx_zynqmp_can_receive(CanBusClientState *client,
1158
+ const qemu_can_frame *buf, size_t buf_size) {
1159
+ XlnxZynqMPCANState *s = container_of(client, XlnxZynqMPCANState,
1160
+ bus_client);
1161
+ const qemu_can_frame *frame = buf;
1162
+
1163
+ if (buf_size <= 0) {
1164
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1165
+
1166
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Error in the data received.\n",
1167
+ path);
184
+ return 0;
1168
+ return 0;
185
+ }
1169
+ }
186
+}
1170
+
187
+
1171
+ if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
188
+static void stm32f4xx_syscfg_write(void *opaque, hwaddr addr,
1172
+ /* Snoop Mode: Just keep the data. no response back. */
189
+ uint64_t val64, unsigned int size)
1173
+ update_rx_fifo(s, frame);
190
+{
1174
+ } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
191
+ STM32F4xxSyscfgState *s = opaque;
1175
+ /*
192
+ uint32_t value = val64;
1176
+ * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
193
+
1177
+ * up state.
194
+ trace_stm32f4xx_syscfg_write(value, addr);
1178
+ */
195
+
1179
+ can_exit_sleep_mode(s);
196
+ switch (addr) {
1180
+ update_rx_fifo(s, frame);
197
+ case SYSCFG_MEMRMP:
1181
+ } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) == 0) {
198
+ qemu_log_mask(LOG_UNIMP,
1182
+ update_rx_fifo(s, frame);
199
+ "%s: Changing the memory mapping isn't supported " \
1183
+ } else {
200
+ "in QEMU\n", __func__);
1184
+ /*
201
+ return;
1185
+ * XlnxZynqMPCAN will not participate in normal bus communication
202
+ case SYSCFG_PMC:
1186
+ * and will not receive any messages transmitted by other CAN nodes.
203
+ qemu_log_mask(LOG_UNIMP,
1187
+ */
204
+ "%s: Changing the memory mapping isn't supported " \
1188
+ trace_xlnx_can_rx_discard(s->regs[R_STATUS_REGISTER]);
205
+ "in QEMU\n", __func__);
1189
+ }
206
+ return;
1190
+
207
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
1191
+ return 1;
208
+ s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4] = (value & 0xFFFF);
1192
+}
209
+ return;
1193
+
210
+ case SYSCFG_CMPCR:
1194
+static CanBusClientInfo can_xilinx_bus_client_info = {
211
+ s->syscfg_cmpcr = value;
1195
+ .can_receive = xlnx_zynqmp_can_can_receive,
212
+ return;
1196
+ .receive = xlnx_zynqmp_can_receive,
213
+ default:
214
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
216
+ }
217
+}
218
+
219
+static const MemoryRegionOps stm32f4xx_syscfg_ops = {
220
+ .read = stm32f4xx_syscfg_read,
221
+ .write = stm32f4xx_syscfg_write,
222
+ .endianness = DEVICE_NATIVE_ENDIAN,
223
+};
1197
+};
224
+
1198
+
225
+static void stm32f4xx_syscfg_init(Object *obj)
1199
+static int xlnx_zynqmp_can_connect_to_bus(XlnxZynqMPCANState *s,
226
+{
1200
+ CanBusState *bus)
227
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(obj);
1201
+{
228
+
1202
+ s->bus_client.info = &can_xilinx_bus_client_info;
1203
+
1204
+ if (can_bus_insert_client(bus, &s->bus_client) < 0) {
1205
+ return -1;
1206
+ }
1207
+ return 0;
1208
+}
1209
+
1210
+static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
1211
+{
1212
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(dev);
1213
+
1214
+ if (s->canbus) {
1215
+ if (xlnx_zynqmp_can_connect_to_bus(s, s->canbus) < 0) {
1216
+ g_autofree char *path = object_get_canonical_path(OBJECT(s));
1217
+
1218
+ error_setg(errp, "%s: xlnx_zynqmp_can_connect_to_bus"
1219
+ " failed.", path);
1220
+ return;
1221
+ }
1222
+ }
1223
+
1224
+ /* Create RX FIFO, TXFIFO, TXHPB storage. */
1225
+ fifo32_create(&s->rx_fifo, RXFIFO_SIZE);
1226
+ fifo32_create(&s->tx_fifo, RXFIFO_SIZE);
1227
+ fifo32_create(&s->txhpb_fifo, CAN_FRAME_SIZE);
1228
+
1229
+ /* Allocate a new timer. */
1230
+ s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
1231
+ PTIMER_POLICY_DEFAULT);
1232
+
1233
+ ptimer_transaction_begin(s->can_timer);
1234
+
1235
+ ptimer_set_freq(s->can_timer, s->cfg.ext_clk_freq);
1236
+ ptimer_set_limit(s->can_timer, CAN_TIMER_MAX, 1);
1237
+ ptimer_run(s->can_timer, 0);
1238
+ ptimer_transaction_commit(s->can_timer);
1239
+}
1240
+
1241
+static void xlnx_zynqmp_can_init(Object *obj)
1242
+{
1243
+ XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
1244
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1245
+
1246
+ RegisterInfoArray *reg_array;
1247
+
1248
+ memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_CAN,
1249
+ XLNX_ZYNQMP_CAN_R_MAX * 4);
1250
+ reg_array = register_init_block32(DEVICE(obj), can_regs_info,
1251
+ ARRAY_SIZE(can_regs_info),
1252
+ s->reg_info, s->regs,
1253
+ &can_ops,
1254
+ XLNX_ZYNQMP_CAN_ERR_DEBUG,
1255
+ XLNX_ZYNQMP_CAN_R_MAX * 4);
1256
+
1257
+ memory_region_add_subregion(&s->iomem, 0x00, &reg_array->mem);
1258
+ sysbus_init_mmio(sbd, &s->iomem);
229
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
1259
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
230
+
1260
+}
231
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_syscfg_ops, s,
1261
+
232
+ TYPE_STM32F4XX_SYSCFG, 0x400);
1262
+static const VMStateDescription vmstate_can = {
233
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
1263
+ .name = TYPE_XLNX_ZYNQMP_CAN,
234
+
235
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_syscfg_set_irq, 16 * 9);
236
+ qdev_init_gpio_out(DEVICE(obj), s->gpio_out, 16);
237
+}
238
+
239
+static const VMStateDescription vmstate_stm32f4xx_syscfg = {
240
+ .name = TYPE_STM32F4XX_SYSCFG,
241
+ .version_id = 1,
1264
+ .version_id = 1,
242
+ .minimum_version_id = 1,
1265
+ .minimum_version_id = 1,
243
+ .fields = (VMStateField[]) {
1266
+ .fields = (VMStateField[]) {
244
+ VMSTATE_UINT32(syscfg_memrmp, STM32F4xxSyscfgState),
1267
+ VMSTATE_FIFO32(rx_fifo, XlnxZynqMPCANState),
245
+ VMSTATE_UINT32(syscfg_pmc, STM32F4xxSyscfgState),
1268
+ VMSTATE_FIFO32(tx_fifo, XlnxZynqMPCANState),
246
+ VMSTATE_UINT32_ARRAY(syscfg_exticr, STM32F4xxSyscfgState,
1269
+ VMSTATE_FIFO32(txhpb_fifo, XlnxZynqMPCANState),
247
+ SYSCFG_NUM_EXTICR),
1270
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPCANState, XLNX_ZYNQMP_CAN_R_MAX),
248
+ VMSTATE_UINT32(syscfg_cmpcr, STM32F4xxSyscfgState),
1271
+ VMSTATE_PTIMER(can_timer, XlnxZynqMPCANState),
249
+ VMSTATE_END_OF_LIST()
1272
+ VMSTATE_END_OF_LIST(),
250
+ }
1273
+ }
251
+};
1274
+};
252
+
1275
+
253
+static void stm32f4xx_syscfg_class_init(ObjectClass *klass, void *data)
1276
+static Property xlnx_zynqmp_can_properties[] = {
1277
+ DEFINE_PROP_UINT32("ext_clk_freq", XlnxZynqMPCANState, cfg.ext_clk_freq,
1278
+ CAN_DEFAULT_CLOCK),
1279
+ DEFINE_PROP_LINK("canbus", XlnxZynqMPCANState, canbus, TYPE_CAN_BUS,
1280
+ CanBusState *),
1281
+ DEFINE_PROP_END_OF_LIST(),
1282
+};
1283
+
1284
+static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
254
+{
1285
+{
255
+ DeviceClass *dc = DEVICE_CLASS(klass);
1286
+ DeviceClass *dc = DEVICE_CLASS(klass);
256
+
1287
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
257
+ dc->reset = stm32f4xx_syscfg_reset;
1288
+
258
+ dc->vmsd = &vmstate_stm32f4xx_syscfg;
1289
+ rc->phases.enter = xlnx_zynqmp_can_reset_init;
259
+}
1290
+ rc->phases.hold = xlnx_zynqmp_can_reset_hold;
260
+
1291
+ dc->realize = xlnx_zynqmp_can_realize;
261
+static const TypeInfo stm32f4xx_syscfg_info = {
1292
+ device_class_set_props(dc, xlnx_zynqmp_can_properties);
262
+ .name = TYPE_STM32F4XX_SYSCFG,
1293
+ dc->vmsd = &vmstate_can;
1294
+}
1295
+
1296
+static const TypeInfo can_info = {
1297
+ .name = TYPE_XLNX_ZYNQMP_CAN,
263
+ .parent = TYPE_SYS_BUS_DEVICE,
1298
+ .parent = TYPE_SYS_BUS_DEVICE,
264
+ .instance_size = sizeof(STM32F4xxSyscfgState),
1299
+ .instance_size = sizeof(XlnxZynqMPCANState),
265
+ .instance_init = stm32f4xx_syscfg_init,
1300
+ .class_init = xlnx_zynqmp_can_class_init,
266
+ .class_init = stm32f4xx_syscfg_class_init,
1301
+ .instance_init = xlnx_zynqmp_can_init,
267
+};
1302
+};
268
+
1303
+
269
+static void stm32f4xx_syscfg_register_types(void)
1304
+static void can_register_types(void)
270
+{
1305
+{
271
+ type_register_static(&stm32f4xx_syscfg_info);
1306
+ type_register_static(&can_info);
272
+}
1307
+}
273
+
1308
+
274
+type_init(stm32f4xx_syscfg_register_types)
1309
+type_init(can_register_types)
275
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
1310
diff --git a/hw/Kconfig b/hw/Kconfig
276
index XXXXXXX..XXXXXXX 100644
1311
index XXXXXXX..XXXXXXX 100644
277
--- a/default-configs/arm-softmmu.mak
1312
--- a/hw/Kconfig
278
+++ b/default-configs/arm-softmmu.mak
1313
+++ b/hw/Kconfig
279
@@ -XXX,XX +XXX,XX @@ CONFIG_Z2=y
1314
@@ -XXX,XX +XXX,XX @@ config XILINX_AXI
280
CONFIG_COLLIE=y
1315
config XLNX_ZYNQMP
281
CONFIG_ASPEED_SOC=y
1316
bool
282
CONFIG_NETDUINO2=y
1317
select REGISTER
283
+CONFIG_NETDUINOPLUS2=y
1318
+ select CAN_BUS
284
CONFIG_MPS2=y
1319
diff --git a/hw/net/can/meson.build b/hw/net/can/meson.build
285
CONFIG_RASPI=y
286
CONFIG_DIGIC=y
287
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
288
index XXXXXXX..XXXXXXX 100644
1320
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/arm/Kconfig
1321
--- a/hw/net/can/meson.build
290
+++ b/hw/arm/Kconfig
1322
+++ b/hw/net/can/meson.build
291
@@ -XXX,XX +XXX,XX @@ config NETDUINO2
1323
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_pcm3680_pci.c'))
292
bool
1324
softmmu_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_mioe3680_pci.c'))
293
select STM32F205_SOC
1325
softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_core.c'))
294
1326
softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD_PCI', if_true: files('ctucan_pci.c'))
295
+config NETDUINOPLUS2
1327
+softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-can.c'))
296
+ bool
1328
diff --git a/hw/net/can/trace-events b/hw/net/can/trace-events
297
+ select STM32F405_SOC
1329
new file mode 100644
298
+
1330
index XXXXXXX..XXXXXXX
299
config NSERIES
1331
--- /dev/null
300
bool
1332
+++ b/hw/net/can/trace-events
301
select OMAP
1333
@@ -XXX,XX +XXX,XX @@
302
@@ -XXX,XX +XXX,XX @@ config STM32F205_SOC
1334
+# xlnx-zynqmp-can.c
303
select STM32F2XX_ADC
1335
+xlnx_can_update_irq(uint32_t isr, uint32_t ier, uint32_t irq) "ISR: 0x%08x IER: 0x%08x IRQ: 0x%08x"
304
select STM32F2XX_SPI
1336
+xlnx_can_reset(uint32_t val) "Resetting controller with value = 0x%08x"
305
1337
+xlnx_can_rx_fifo_filter_reject(uint32_t id, uint8_t dlc) "Frame: ID: 0x%08x DLC: 0x%02x"
306
+config STM32F405_SOC
1338
+xlnx_can_filter_id_pre_write(uint8_t filter_num, uint32_t value) "Filter%d ID: 0x%08x"
307
+ bool
1339
+xlnx_can_filter_mask_pre_write(uint8_t filter_num, uint32_t value) "Filter%d MASK: 0x%08x"
308
+ select ARM_V7M
1340
+xlnx_can_tx_data(uint32_t id, uint8_t dlc, uint8_t db0, uint8_t db1, uint8_t db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) "Frame: ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"
309
+ select STM32F4XX_SYSCFG
1341
+xlnx_can_rx_data(uint32_t id, uint32_t dlc, uint8_t db0, uint8_t db1, uint8_t db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) "Frame: ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"
310
+
1342
+xlnx_can_rx_discard(uint32_t status) "Controller is not enabled for bus communication. Status Register: 0x%08x"
311
config XLNX_ZYNQMP_ARM
312
bool
313
select AHCI
314
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
315
index XXXXXXX..XXXXXXX 100644
316
--- a/hw/misc/Kconfig
317
+++ b/hw/misc/Kconfig
318
@@ -XXX,XX +XXX,XX @@ config IMX
319
config STM32F2XX_SYSCFG
320
bool
321
322
+config STM32F4XX_SYSCFG
323
+ bool
324
+
325
config MIPS_ITU
326
bool
327
328
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
329
index XXXXXXX..XXXXXXX 100644
330
--- a/hw/misc/trace-events
331
+++ b/hw/misc/trace-events
332
@@ -XXX,XX +XXX,XX @@ mos6522_set_sr_int(void) "set sr_int"
333
mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64
334
mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x"
335
336
+# stm32f4xx_syscfg
337
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d"
338
+stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
339
+stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
340
+stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
341
+
342
# tz-mpc.c
343
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
344
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
345
--
1343
--
346
2.20.1
1344
2.20.1
347
1345
348
1346
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
3
Connect CAN0 and CAN1 on the ZynqMP.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
5
Message-id: 1d145c4c13e5fa140caf131232a6f524c88fcd72.1576658572.git.alistair@alistair23.me
5
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
8
Message-id: 1605728926-352690-3-git-send-email-fnu.vikram@xilinx.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/arm/Makefile.objs | 1 +
11
include/hw/arm/xlnx-zynqmp.h | 8 ++++++++
9
include/hw/arm/stm32f405_soc.h | 73 ++++++++
12
hw/arm/xlnx-zcu102.c | 20 ++++++++++++++++++++
10
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
13
hw/arm/xlnx-zynqmp.c | 34 ++++++++++++++++++++++++++++++++++
11
MAINTAINERS | 8 +
14
3 files changed, 62 insertions(+)
12
4 files changed, 384 insertions(+)
13
create mode 100644 include/hw/arm/stm32f405_soc.h
14
create mode 100644 hw/arm/stm32f405_soc.c
15
15
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/Makefile.objs
18
--- a/include/hw/arm/xlnx-zynqmp.h
19
+++ b/hw/arm/Makefile.objs
19
+++ b/include/hw/arm/xlnx-zynqmp.h
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_STRONGARM) += strongarm.o
21
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
22
obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
23
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
24
+obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
25
obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
26
obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
27
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
28
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/arm/stm32f405_soc.h
33
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
34
+/*
21
#include "hw/intc/arm_gic.h"
35
+ * STM32F405 SoC
22
#include "hw/net/cadence_gem.h"
36
+ *
23
#include "hw/char/cadence_uart.h"
37
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
24
+#include "hw/net/xlnx-zynqmp-can.h"
38
+ *
25
#include "hw/ide/ahci.h"
39
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
26
#include "hw/sd/sdhci.h"
40
+ * of this software and associated documentation files (the "Software"), to deal
27
#include "hw/ssi/xilinx_spips.h"
41
+ * in the Software without restriction, including without limitation the rights
28
@@ -XXX,XX +XXX,XX @@
42
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
#include "hw/cpu/cluster.h"
43
+ * copies of the Software, and to permit persons to whom the Software is
30
#include "target/arm/cpu.h"
44
+ * furnished to do so, subject to the following conditions:
31
#include "qom/object.h"
45
+ *
32
+#include "net/can_emu.h"
46
+ * The above copyright notice and this permission notice shall be included in
33
47
+ * all copies or substantial portions of the Software.
34
#define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
48
+ *
35
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
49
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
50
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
#define XLNX_ZYNQMP_NUM_RPU_CPUS 2
51
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
38
#define XLNX_ZYNQMP_NUM_GEMS 4
52
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
#define XLNX_ZYNQMP_NUM_UARTS 2
53
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+#define XLNX_ZYNQMP_NUM_CAN 2
54
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41
+#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000)
55
+ * THE SOFTWARE.
42
#define XLNX_ZYNQMP_NUM_SDHCI 2
56
+ */
43
#define XLNX_ZYNQMP_NUM_SPIS 2
44
#define XLNX_ZYNQMP_NUM_GDMA_CH 8
45
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
46
47
CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
48
CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
49
+ XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
50
SysbusAHCIState sata;
51
SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
52
XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
53
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
54
bool virt;
55
/* Has the RPU subsystem? */
56
bool has_rpu;
57
+
57
+
58
+#ifndef HW_ARM_STM32F405_SOC_H
58
+ /* CAN bus. */
59
+#define HW_ARM_STM32F405_SOC_H
59
+ CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
60
};
61
62
#endif
63
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/xlnx-zcu102.c
66
+++ b/hw/arm/xlnx-zcu102.c
67
@@ -XXX,XX +XXX,XX @@
68
#include "sysemu/qtest.h"
69
#include "sysemu/device_tree.h"
70
#include "qom/object.h"
71
+#include "net/can_emu.h"
72
73
struct XlnxZCU102 {
74
MachineState parent_obj;
75
@@ -XXX,XX +XXX,XX @@ struct XlnxZCU102 {
76
bool secure;
77
bool virt;
78
79
+ CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
60
+
80
+
61
+#include "hw/misc/stm32f4xx_syscfg.h"
81
struct arm_boot_info binfo;
62
+#include "hw/timer/stm32f2xx_timer.h"
82
};
63
+#include "hw/char/stm32f2xx_usart.h"
83
64
+#include "hw/adc/stm32f2xx_adc.h"
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_init(MachineState *machine)
65
+#include "hw/misc/stm32f4xx_exti.h"
85
object_property_set_bool(OBJECT(&s->soc), "virtualization", s->virt,
66
+#include "hw/or-irq.h"
86
&error_fatal);
67
+#include "hw/ssi/stm32f2xx_spi.h"
87
68
+#include "hw/arm/armv7m.h"
88
+ for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
89
+ gchar *bus_name = g_strdup_printf("canbus%d", i);
69
+
90
+
70
+#define TYPE_STM32F405_SOC "stm32f405-soc"
91
+ object_property_set_link(OBJECT(&s->soc), bus_name,
71
+#define STM32F405_SOC(obj) \
92
+ OBJECT(s->canbus[i]), &error_fatal);
72
+ OBJECT_CHECK(STM32F405State, (obj), TYPE_STM32F405_SOC)
93
+ g_free(bus_name);
73
+
74
+#define STM_NUM_USARTS 7
75
+#define STM_NUM_TIMERS 4
76
+#define STM_NUM_ADCS 6
77
+#define STM_NUM_SPIS 6
78
+
79
+#define FLASH_BASE_ADDRESS 0x08000000
80
+#define FLASH_SIZE (1024 * 1024)
81
+#define SRAM_BASE_ADDRESS 0x20000000
82
+#define SRAM_SIZE (192 * 1024)
83
+
84
+typedef struct STM32F405State {
85
+ /*< private >*/
86
+ SysBusDevice parent_obj;
87
+ /*< public >*/
88
+
89
+ char *cpu_type;
90
+
91
+ ARMv7MState armv7m;
92
+
93
+ STM32F4xxSyscfgState syscfg;
94
+ STM32F4xxExtiState exti;
95
+ STM32F2XXUsartState usart[STM_NUM_USARTS];
96
+ STM32F2XXTimerState timer[STM_NUM_TIMERS];
97
+ qemu_or_irq adc_irqs;
98
+ STM32F2XXADCState adc[STM_NUM_ADCS];
99
+ STM32F2XXSPIState spi[STM_NUM_SPIS];
100
+
101
+ MemoryRegion sram;
102
+ MemoryRegion flash;
103
+ MemoryRegion flash_alias;
104
+} STM32F405State;
105
+
106
+#endif
107
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/hw/arm/stm32f405_soc.c
112
@@ -XXX,XX +XXX,XX @@
113
+/*
114
+ * STM32F405 SoC
115
+ *
116
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
117
+ *
118
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
119
+ * of this software and associated documentation files (the "Software"), to deal
120
+ * in the Software without restriction, including without limitation the rights
121
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
122
+ * copies of the Software, and to permit persons to whom the Software is
123
+ * furnished to do so, subject to the following conditions:
124
+ *
125
+ * The above copyright notice and this permission notice shall be included in
126
+ * all copies or substantial portions of the Software.
127
+ *
128
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
129
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
130
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
131
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
132
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
133
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
134
+ * THE SOFTWARE.
135
+ */
136
+
137
+#include "qemu/osdep.h"
138
+#include "qapi/error.h"
139
+#include "qemu-common.h"
140
+#include "exec/address-spaces.h"
141
+#include "sysemu/sysemu.h"
142
+#include "hw/arm/stm32f405_soc.h"
143
+#include "hw/misc/unimp.h"
144
+
145
+#define SYSCFG_ADD 0x40013800
146
+static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, 0x40004800,
147
+ 0x40004C00, 0x40005000, 0x40011400,
148
+ 0x40007800, 0x40007C00 };
149
+/* At the moment only Timer 2 to 5 are modelled */
150
+static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
151
+ 0x40000800, 0x40000C00 };
152
+#define ADC_ADDR 0x40012000
153
+static const uint32_t spi_addr[] = { 0x40013000, 0x40003800, 0x40003C00,
154
+ 0x40013400, 0x40015000, 0x40015400 };
155
+#define EXTI_ADDR 0x40013C00
156
+
157
+#define SYSCFG_IRQ 71
158
+static const int usart_irq[] = { 37, 38, 39, 52, 53, 71, 82, 83 };
159
+static const int timer_irq[] = { 28, 29, 30, 50 };
160
+#define ADC_IRQ 18
161
+static const int spi_irq[] = { 35, 36, 51, 0, 0, 0 };
162
+static const int exti_irq[] = { 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
163
+ 40, 40, 40, 40, 40} ;
164
+
165
+
166
+static void stm32f405_soc_initfn(Object *obj)
167
+{
168
+ STM32F405State *s = STM32F405_SOC(obj);
169
+ int i;
170
+
171
+ sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
172
+ TYPE_ARMV7M);
173
+
174
+ sysbus_init_child_obj(obj, "syscfg", &s->syscfg, sizeof(s->syscfg),
175
+ TYPE_STM32F4XX_SYSCFG);
176
+
177
+ for (i = 0; i < STM_NUM_USARTS; i++) {
178
+ sysbus_init_child_obj(obj, "usart[*]", &s->usart[i],
179
+ sizeof(s->usart[i]), TYPE_STM32F2XX_USART);
180
+ }
94
+ }
181
+
95
+
182
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
96
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
183
+ sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
97
184
+ sizeof(s->timer[i]), TYPE_STM32F2XX_TIMER);
98
/* Create and plug in the SD cards */
99
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
100
s->secure = false;
101
/* Default to virt (EL2) being disabled */
102
s->virt = false;
103
+ object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
104
+ (Object **)&s->canbus[0],
105
+ object_property_allow_set_link,
106
+ 0);
107
+
108
+ object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
109
+ (Object **)&s->canbus[1],
110
+ object_property_allow_set_link,
111
+ 0);
112
}
113
114
static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
115
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/arm/xlnx-zynqmp.c
118
+++ b/hw/arm/xlnx-zynqmp.c
119
@@ -XXX,XX +XXX,XX @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
120
21, 22,
121
};
122
123
+static const uint64_t can_addr[XLNX_ZYNQMP_NUM_CAN] = {
124
+ 0xFF060000, 0xFF070000,
125
+};
126
+
127
+static const int can_intr[XLNX_ZYNQMP_NUM_CAN] = {
128
+ 23, 24,
129
+};
130
+
131
static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
132
0xFF160000, 0xFF170000,
133
};
134
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
135
TYPE_CADENCE_UART);
136
}
137
138
+ for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
139
+ object_initialize_child(obj, "can[*]", &s->can[i],
140
+ TYPE_XLNX_ZYNQMP_CAN);
185
+ }
141
+ }
186
+
142
+
187
+ for (i = 0; i < STM_NUM_ADCS; i++) {
143
object_initialize_child(obj, "sata", &s->sata, TYPE_SYSBUS_AHCI);
188
+ sysbus_init_child_obj(obj, "adc[*]", &s->adc[i], sizeof(s->adc[i]),
144
189
+ TYPE_STM32F2XX_ADC);
145
for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
190
+ }
146
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
147
gic_spi[uart_intr[i]]);
148
}
149
150
+ for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
151
+ object_property_set_int(OBJECT(&s->can[i]), "ext_clk_freq",
152
+ XLNX_ZYNQMP_CAN_REF_CLK, &error_abort);
191
+
153
+
192
+ for (i = 0; i < STM_NUM_SPIS; i++) {
154
+ object_property_set_link(OBJECT(&s->can[i]), "canbus",
193
+ sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
155
+ OBJECT(s->canbus[i]), &error_fatal);
194
+ TYPE_STM32F2XX_SPI);
195
+ }
196
+
156
+
197
+ sysbus_init_child_obj(obj, "exti", &s->exti, sizeof(s->exti),
157
+ sysbus_realize(SYS_BUS_DEVICE(&s->can[i]), &err);
198
+ TYPE_STM32F4XX_EXTI);
158
+ if (err) {
199
+}
200
+
201
+static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
202
+{
203
+ STM32F405State *s = STM32F405_SOC(dev_soc);
204
+ MemoryRegion *system_memory = get_system_memory();
205
+ DeviceState *dev, *armv7m;
206
+ SysBusDevice *busdev;
207
+ Error *err = NULL;
208
+ int i;
209
+
210
+ memory_region_init_ram(&s->flash, NULL, "STM32F405.flash", FLASH_SIZE,
211
+ &err);
212
+ if (err != NULL) {
213
+ error_propagate(errp, err);
214
+ return;
215
+ }
216
+ memory_region_init_alias(&s->flash_alias, NULL, "STM32F405.flash.alias",
217
+ &s->flash, 0, FLASH_SIZE);
218
+
219
+ memory_region_set_readonly(&s->flash, true);
220
+ memory_region_set_readonly(&s->flash_alias, true);
221
+
222
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
223
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
224
+
225
+ memory_region_init_ram(&s->sram, NULL, "STM32F405.sram", SRAM_SIZE,
226
+ &err);
227
+ if (err != NULL) {
228
+ error_propagate(errp, err);
229
+ return;
230
+ }
231
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
232
+
233
+ armv7m = DEVICE(&s->armv7m);
234
+ qdev_prop_set_uint32(armv7m, "num-irq", 96);
235
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
236
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
237
+ object_property_set_link(OBJECT(&s->armv7m), OBJECT(system_memory),
238
+ "memory", &error_abort);
239
+ object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
240
+ if (err != NULL) {
241
+ error_propagate(errp, err);
242
+ return;
243
+ }
244
+
245
+ /* System configuration controller */
246
+ dev = DEVICE(&s->syscfg);
247
+ object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
248
+ if (err != NULL) {
249
+ error_propagate(errp, err);
250
+ return;
251
+ }
252
+ busdev = SYS_BUS_DEVICE(dev);
253
+ sysbus_mmio_map(busdev, 0, SYSCFG_ADD);
254
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, SYSCFG_IRQ));
255
+
256
+ /* Attach UART (uses USART registers) and USART controllers */
257
+ for (i = 0; i < STM_NUM_USARTS; i++) {
258
+ dev = DEVICE(&(s->usart[i]));
259
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
260
+ object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
261
+ if (err != NULL) {
262
+ error_propagate(errp, err);
159
+ error_propagate(errp, err);
263
+ return;
160
+ return;
264
+ }
161
+ }
265
+ busdev = SYS_BUS_DEVICE(dev);
162
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->can[i]), 0, can_addr[i]);
266
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
163
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->can[i]), 0,
267
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
164
+ gic_spi[can_intr[i]]);
268
+ }
165
+ }
269
+
166
+
270
+ /* Timer 2 to 5 */
167
object_property_set_int(OBJECT(&s->sata), "num-ports", SATA_NUM_PORTS,
271
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
168
&error_abort);
272
+ dev = DEVICE(&(s->timer[i]));
169
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sata), errp)) {
273
+ qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
170
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
274
+ object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
171
DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
275
+ if (err != NULL) {
172
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
276
+ error_propagate(errp, err);
173
MemoryRegion *),
277
+ return;
174
+ DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
278
+ }
175
+ CanBusState *),
279
+ busdev = SYS_BUS_DEVICE(dev);
176
+ DEFINE_PROP_LINK("canbus1", XlnxZynqMPState, canbus[1], TYPE_CAN_BUS,
280
+ sysbus_mmio_map(busdev, 0, timer_addr[i]);
177
+ CanBusState *),
281
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, timer_irq[i]));
178
DEFINE_PROP_END_OF_LIST()
282
+ }
179
};
283
+
180
284
+ /* ADC device, the IRQs are ORed together */
285
+ object_initialize_child(OBJECT(s), "adc-orirq", &s->adc_irqs,
286
+ sizeof(s->adc_irqs), TYPE_OR_IRQ,
287
+ &err, NULL);
288
+ if (err != NULL) {
289
+ error_propagate(errp, err);
290
+ return;
291
+ }
292
+ object_property_set_int(OBJECT(&s->adc_irqs), STM_NUM_ADCS,
293
+ "num-lines", &err);
294
+ object_property_set_bool(OBJECT(&s->adc_irqs), true, "realized", &err);
295
+ if (err != NULL) {
296
+ error_propagate(errp, err);
297
+ return;
298
+ }
299
+ qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
300
+ qdev_get_gpio_in(armv7m, ADC_IRQ));
301
+
302
+ dev = DEVICE(&(s->adc[i]));
303
+ object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
304
+ if (err != NULL) {
305
+ error_propagate(errp, err);
306
+ return;
307
+ }
308
+ busdev = SYS_BUS_DEVICE(dev);
309
+ sysbus_mmio_map(busdev, 0, ADC_ADDR);
310
+ sysbus_connect_irq(busdev, 0,
311
+ qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
312
+
313
+ /* SPI devices */
314
+ for (i = 0; i < STM_NUM_SPIS; i++) {
315
+ dev = DEVICE(&(s->spi[i]));
316
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
317
+ if (err != NULL) {
318
+ error_propagate(errp, err);
319
+ return;
320
+ }
321
+ busdev = SYS_BUS_DEVICE(dev);
322
+ sysbus_mmio_map(busdev, 0, spi_addr[i]);
323
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i]));
324
+ }
325
+
326
+ /* EXTI device */
327
+ dev = DEVICE(&s->exti);
328
+ object_property_set_bool(OBJECT(&s->exti), true, "realized", &err);
329
+ if (err != NULL) {
330
+ error_propagate(errp, err);
331
+ return;
332
+ }
333
+ busdev = SYS_BUS_DEVICE(dev);
334
+ sysbus_mmio_map(busdev, 0, EXTI_ADDR);
335
+ for (i = 0; i < 16; i++) {
336
+ sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]));
337
+ }
338
+ for (i = 0; i < 16; i++) {
339
+ qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev, i));
340
+ }
341
+
342
+ create_unimplemented_device("timer[7]", 0x40001400, 0x400);
343
+ create_unimplemented_device("timer[12]", 0x40001800, 0x400);
344
+ create_unimplemented_device("timer[6]", 0x40001000, 0x400);
345
+ create_unimplemented_device("timer[13]", 0x40001C00, 0x400);
346
+ create_unimplemented_device("timer[14]", 0x40002000, 0x400);
347
+ create_unimplemented_device("RTC and BKP", 0x40002800, 0x400);
348
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
349
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
350
+ create_unimplemented_device("I2S2ext", 0x40003000, 0x400);
351
+ create_unimplemented_device("I2S3ext", 0x40004000, 0x400);
352
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
353
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
354
+ create_unimplemented_device("I2C3", 0x40005C00, 0x400);
355
+ create_unimplemented_device("CAN1", 0x40006400, 0x400);
356
+ create_unimplemented_device("CAN2", 0x40006800, 0x400);
357
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
358
+ create_unimplemented_device("DAC", 0x40007400, 0x400);
359
+ create_unimplemented_device("timer[1]", 0x40010000, 0x400);
360
+ create_unimplemented_device("timer[8]", 0x40010400, 0x400);
361
+ create_unimplemented_device("SDIO", 0x40012C00, 0x400);
362
+ create_unimplemented_device("timer[9]", 0x40014000, 0x400);
363
+ create_unimplemented_device("timer[10]", 0x40014400, 0x400);
364
+ create_unimplemented_device("timer[11]", 0x40014800, 0x400);
365
+ create_unimplemented_device("GPIOA", 0x40020000, 0x400);
366
+ create_unimplemented_device("GPIOB", 0x40020400, 0x400);
367
+ create_unimplemented_device("GPIOC", 0x40020800, 0x400);
368
+ create_unimplemented_device("GPIOD", 0x40020C00, 0x400);
369
+ create_unimplemented_device("GPIOE", 0x40021000, 0x400);
370
+ create_unimplemented_device("GPIOF", 0x40021400, 0x400);
371
+ create_unimplemented_device("GPIOG", 0x40021800, 0x400);
372
+ create_unimplemented_device("GPIOH", 0x40021C00, 0x400);
373
+ create_unimplemented_device("GPIOI", 0x40022000, 0x400);
374
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
375
+ create_unimplemented_device("RCC", 0x40023800, 0x400);
376
+ create_unimplemented_device("Flash Int", 0x40023C00, 0x400);
377
+ create_unimplemented_device("BKPSRAM", 0x40024000, 0x400);
378
+ create_unimplemented_device("DMA1", 0x40026000, 0x400);
379
+ create_unimplemented_device("DMA2", 0x40026400, 0x400);
380
+ create_unimplemented_device("Ethernet", 0x40028000, 0x1400);
381
+ create_unimplemented_device("USB OTG HS", 0x40040000, 0x30000);
382
+ create_unimplemented_device("USB OTG FS", 0x50000000, 0x31000);
383
+ create_unimplemented_device("DCMI", 0x50050000, 0x400);
384
+ create_unimplemented_device("RNG", 0x50060800, 0x400);
385
+}
386
+
387
+static Property stm32f405_soc_properties[] = {
388
+ DEFINE_PROP_STRING("cpu-type", STM32F405State, cpu_type),
389
+ DEFINE_PROP_END_OF_LIST(),
390
+};
391
+
392
+static void stm32f405_soc_class_init(ObjectClass *klass, void *data)
393
+{
394
+ DeviceClass *dc = DEVICE_CLASS(klass);
395
+
396
+ dc->realize = stm32f405_soc_realize;
397
+ dc->props = stm32f405_soc_properties;
398
+ /* No vmstate or reset required: device has no internal state */
399
+}
400
+
401
+static const TypeInfo stm32f405_soc_info = {
402
+ .name = TYPE_STM32F405_SOC,
403
+ .parent = TYPE_SYS_BUS_DEVICE,
404
+ .instance_size = sizeof(STM32F405State),
405
+ .instance_init = stm32f405_soc_initfn,
406
+ .class_init = stm32f405_soc_class_init,
407
+};
408
+
409
+static void stm32f405_soc_types(void)
410
+{
411
+ type_register_static(&stm32f405_soc_info);
412
+}
413
+
414
+type_init(stm32f405_soc_types)
415
diff --git a/MAINTAINERS b/MAINTAINERS
416
index XXXXXXX..XXXXXXX 100644
417
--- a/MAINTAINERS
418
+++ b/MAINTAINERS
419
@@ -XXX,XX +XXX,XX @@ F: hw/adc/*
420
F: hw/ssi/stm32f2xx_spi.c
421
F: include/hw/*/stm32*.h
422
423
+STM32F405
424
+M: Alistair Francis <alistair@alistair23.me>
425
+M: Peter Maydell <peter.maydell@linaro.org>
426
+S: Maintained
427
+F: hw/arm/stm32f405_soc.c
428
+F: hw/misc/stm32f4xx_syscfg.c
429
+F: hw/misc/stm32f4xx_exti.c
430
+
431
Netduino 2
432
M: Alistair Francis <alistair@alistair23.me>
433
M: Peter Maydell <peter.maydell@linaro.org>
434
--
181
--
435
2.20.1
182
2.20.1
436
183
437
184
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
2
2
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
3
The QTests perform five tests on the Xilinx ZynqMP CAN controller:
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Tests the CAN controller in loopback, sleep and snoop mode.
5
Message-id: dad8d8d47f7625913e35e27a1c00f603a6b08f9a.1576658572.git.alistair@alistair23.me
5
Tests filtering of incoming CAN messages.
6
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
9
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
10
Message-id: 1605728926-352690-4-git-send-email-fnu.vikram@xilinx.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/arm/Makefile.objs | 1 +
13
tests/qtest/xlnx-can-test.c | 360 ++++++++++++++++++++++++++++++++++++
9
hw/arm/netduinoplus2.c | 52 ++++++++++++++++++++++++++++++++++++++++++
14
tests/qtest/meson.build | 1 +
10
MAINTAINERS | 6 +++++
15
2 files changed, 361 insertions(+)
11
3 files changed, 59 insertions(+)
16
create mode 100644 tests/qtest/xlnx-can-test.c
12
create mode 100644 hw/arm/netduinoplus2.c
17
13
18
diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
14
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/Makefile.objs
17
+++ b/hw/arm/Makefile.objs
18
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MAINSTONE) += mainstone.o
19
obj-$(CONFIG_MICROBIT) += microbit.o
20
obj-$(CONFIG_MUSICPAL) += musicpal.o
21
obj-$(CONFIG_NETDUINO2) += netduino2.o
22
+obj-$(CONFIG_NETDUINOPLUS2) += netduinoplus2.o
23
obj-$(CONFIG_NSERIES) += nseries.o
24
obj-$(CONFIG_SX1) += omap_sx1.o
25
obj-$(CONFIG_CHEETAH) += palm.o
26
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
27
new file mode 100644
19
new file mode 100644
28
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
29
--- /dev/null
21
--- /dev/null
30
+++ b/hw/arm/netduinoplus2.c
22
+++ b/tests/qtest/xlnx-can-test.c
31
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
32
+/*
24
+/*
33
+ * Netduino Plus 2 Machine Model
25
+ * QTests for the Xilinx ZynqMP CAN controller.
34
+ *
26
+ *
35
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
27
+ * Copyright (c) 2020 Xilinx Inc.
28
+ *
29
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
36
+ *
30
+ *
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
33
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
...
...
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
47
+ * THE SOFTWARE.
54
+ */
48
+ */
55
+
49
+
56
+#include "qemu/osdep.h"
50
+#include "qemu/osdep.h"
57
+#include "qapi/error.h"
51
+#include "libqos/libqtest.h"
58
+#include "hw/boards.h"
52
+
59
+#include "hw/qdev-properties.h"
53
+/* Base address. */
60
+#include "qemu/error-report.h"
54
+#define CAN0_BASE_ADDR 0xFF060000
61
+#include "hw/arm/stm32f405_soc.h"
55
+#define CAN1_BASE_ADDR 0xFF070000
62
+#include "hw/arm/boot.h"
56
+
63
+
57
+/* Register addresses. */
64
+static void netduinoplus2_init(MachineState *machine)
58
+#define R_SRR_OFFSET 0x00
65
+{
59
+#define R_MSR_OFFSET 0x04
66
+ DeviceState *dev;
60
+#define R_SR_OFFSET 0x18
67
+
61
+#define R_ISR_OFFSET 0x1C
68
+ dev = qdev_create(NULL, TYPE_STM32F405_SOC);
62
+#define R_ICR_OFFSET 0x24
69
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
63
+#define R_TXID_OFFSET 0x30
70
+ object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
64
+#define R_TXDLC_OFFSET 0x34
71
+
65
+#define R_TXDATA1_OFFSET 0x38
72
+ armv7m_load_kernel(ARM_CPU(first_cpu),
66
+#define R_TXDATA2_OFFSET 0x3C
73
+ machine->kernel_filename,
67
+#define R_RXID_OFFSET 0x50
74
+ FLASH_SIZE);
68
+#define R_RXDLC_OFFSET 0x54
75
+}
69
+#define R_RXDATA1_OFFSET 0x58
76
+
70
+#define R_RXDATA2_OFFSET 0x5C
77
+static void netduinoplus2_machine_init(MachineClass *mc)
71
+#define R_AFR 0x60
78
+{
72
+#define R_AFMR1 0x64
79
+ mc->desc = "Netduino Plus 2 Machine";
73
+#define R_AFIR1 0x68
80
+ mc->init = netduinoplus2_init;
74
+#define R_AFMR2 0x6C
81
+}
75
+#define R_AFIR2 0x70
82
+
76
+#define R_AFMR3 0x74
83
+DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)
77
+#define R_AFIR3 0x78
84
diff --git a/MAINTAINERS b/MAINTAINERS
78
+#define R_AFMR4 0x7C
79
+#define R_AFIR4 0x80
80
+
81
+/* CAN modes. */
82
+#define CONFIG_MODE 0x00
83
+#define NORMAL_MODE 0x00
84
+#define LOOPBACK_MODE 0x02
85
+#define SNOOP_MODE 0x04
86
+#define SLEEP_MODE 0x01
87
+#define ENABLE_CAN (1 << 1)
88
+#define STATUS_NORMAL_MODE (1 << 3)
89
+#define STATUS_LOOPBACK_MODE (1 << 1)
90
+#define STATUS_SNOOP_MODE (1 << 12)
91
+#define STATUS_SLEEP_MODE (1 << 2)
92
+#define ISR_TXOK (1 << 1)
93
+#define ISR_RXOK (1 << 4)
94
+
95
+static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
96
+ uint8_t can_timestamp)
97
+{
98
+ uint16_t size = 0;
99
+ uint8_t len = 4;
100
+
101
+ while (size < len) {
102
+ if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET) {
103
+ g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp);
104
+ } else {
105
+ g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
106
+ }
107
+
108
+ size++;
109
+ }
110
+}
111
+
112
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
113
+{
114
+ uint32_t int_status;
115
+
116
+ /* Read the interrupt on CAN rx. */
117
+ int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
118
+
119
+ g_assert_cmpint(int_status, ==, ISR_RXOK);
120
+
121
+ /* Read the RX register data for CAN. */
122
+ buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET);
123
+ buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET);
124
+ buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET);
125
+ buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET);
126
+
127
+ /* Clear the RX interrupt. */
128
+ qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
129
+}
130
+
131
+static void send_data(QTestState *qts, uint64_t can_base_addr,
132
+ const uint32_t *buf_tx)
133
+{
134
+ uint32_t int_status;
135
+
136
+ /* Write the TX register data for CAN. */
137
+ qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
138
+ qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
139
+ qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]);
140
+ qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]);
141
+
142
+ /* Read the interrupt on CAN for tx. */
143
+ int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK;
144
+
145
+ g_assert_cmpint(int_status, ==, ISR_TXOK);
146
+
147
+ /* Clear the interrupt for tx. */
148
+ qtest_writel(qts, CAN0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK);
149
+}
150
+
151
+/*
152
+ * This test will be transferring data from CAN0 and CAN1 through canbus. CAN0
153
+ * initiate the data transfer to can-bus, CAN1 receives the data. Test compares
154
+ * the data sent from CAN0 with received on CAN1.
155
+ */
156
+static void test_can_bus(void)
157
+{
158
+ const uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
159
+ uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
160
+ uint32_t status = 0;
161
+ uint8_t can_timestamp = 1;
162
+
163
+ QTestState *qts = qtest_init("-machine xlnx-zcu102"
164
+ " -object can-bus,id=canbus0"
165
+ " -machine xlnx-zcu102.canbus0=canbus0"
166
+ " -machine xlnx-zcu102.canbus1=canbus0"
167
+ );
168
+
169
+ /* Configure the CAN0 and CAN1. */
170
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
171
+ qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
172
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
173
+ qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
174
+
175
+ /* Check here if CAN0 and CAN1 are in normal mode. */
176
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
177
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
178
+
179
+ status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
180
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
181
+
182
+ send_data(qts, CAN0_BASE_ADDR, buf_tx);
183
+
184
+ read_data(qts, CAN1_BASE_ADDR, buf_rx);
185
+ match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
186
+
187
+ qtest_quit(qts);
188
+}
189
+
190
+/*
191
+ * This test is performing loopback mode on CAN0 and CAN1. Data sent from TX of
192
+ * each CAN0 and CAN1 are compared with RX register data for respective CAN.
193
+ */
194
+static void test_can_loopback(void)
195
+{
196
+ uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
197
+ uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
198
+ uint32_t status = 0;
199
+
200
+ QTestState *qts = qtest_init("-machine xlnx-zcu102"
201
+ " -object can-bus,id=canbus0"
202
+ " -machine xlnx-zcu102.canbus0=canbus0"
203
+ " -machine xlnx-zcu102.canbus1=canbus0"
204
+ );
205
+
206
+ /* Configure the CAN0 in loopback mode. */
207
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
208
+ qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
209
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
210
+
211
+ /* Check here if CAN0 is set in loopback mode. */
212
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
213
+
214
+ g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
215
+
216
+ send_data(qts, CAN0_BASE_ADDR, buf_tx);
217
+ read_data(qts, CAN0_BASE_ADDR, buf_rx);
218
+ match_rx_tx_data(buf_tx, buf_rx, 0);
219
+
220
+ /* Configure the CAN1 in loopback mode. */
221
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
222
+ qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
223
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
224
+
225
+ /* Check here if CAN1 is set in loopback mode. */
226
+ status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
227
+
228
+ g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
229
+
230
+ send_data(qts, CAN1_BASE_ADDR, buf_tx);
231
+ read_data(qts, CAN1_BASE_ADDR, buf_rx);
232
+ match_rx_tx_data(buf_tx, buf_rx, 0);
233
+
234
+ qtest_quit(qts);
235
+}
236
+
237
+/*
238
+ * Enable filters for CAN1. This will filter incoming messages with ID. In this
239
+ * test message will pass through filter 2.
240
+ */
241
+static void test_can_filter(void)
242
+{
243
+ uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
244
+ uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
245
+ uint32_t status = 0;
246
+ uint8_t can_timestamp = 1;
247
+
248
+ QTestState *qts = qtest_init("-machine xlnx-zcu102"
249
+ " -object can-bus,id=canbus0"
250
+ " -machine xlnx-zcu102.canbus0=canbus0"
251
+ " -machine xlnx-zcu102.canbus1=canbus0"
252
+ );
253
+
254
+ /* Configure the CAN0 and CAN1. */
255
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
256
+ qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
257
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
258
+ qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
259
+
260
+ /* Check here if CAN0 and CAN1 are in normal mode. */
261
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
262
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
263
+
264
+ status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
265
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
266
+
267
+ /* Set filter for CAN1 for incoming messages. */
268
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0x0);
269
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR1, 0xF7);
270
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR1, 0x121F);
271
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR2, 0x5431);
272
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR2, 0x14);
273
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR3, 0x1234);
274
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR3, 0x5431);
275
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR4, 0xFFF);
276
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR4, 0x1234);
277
+
278
+ qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0xF);
279
+
280
+ send_data(qts, CAN0_BASE_ADDR, buf_tx);
281
+
282
+ read_data(qts, CAN1_BASE_ADDR, buf_rx);
283
+ match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
284
+
285
+ qtest_quit(qts);
286
+}
287
+
288
+/* Testing sleep mode on CAN0 while CAN1 is in normal mode. */
289
+static void test_can_sleepmode(void)
290
+{
291
+ uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
292
+ uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
293
+ uint32_t status = 0;
294
+ uint8_t can_timestamp = 1;
295
+
296
+ QTestState *qts = qtest_init("-machine xlnx-zcu102"
297
+ " -object can-bus,id=canbus0"
298
+ " -machine xlnx-zcu102.canbus0=canbus0"
299
+ " -machine xlnx-zcu102.canbus1=canbus0"
300
+ );
301
+
302
+ /* Configure the CAN0. */
303
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
304
+ qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SLEEP_MODE);
305
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
306
+
307
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
308
+ qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
309
+
310
+ /* Check here if CAN0 is in SLEEP mode and CAN1 in normal mode. */
311
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
312
+ g_assert_cmpint(status, ==, STATUS_SLEEP_MODE);
313
+
314
+ status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
315
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
316
+
317
+ send_data(qts, CAN1_BASE_ADDR, buf_tx);
318
+
319
+ /*
320
+ * Once CAN1 sends data on can-bus. CAN0 should exit sleep mode.
321
+ * Check the CAN0 status now. It should exit the sleep mode and receive the
322
+ * incoming data.
323
+ */
324
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
325
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
326
+
327
+ read_data(qts, CAN0_BASE_ADDR, buf_rx);
328
+
329
+ match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
330
+
331
+ qtest_quit(qts);
332
+}
333
+
334
+/* Testing Snoop mode on CAN0 while CAN1 is in normal mode. */
335
+static void test_can_snoopmode(void)
336
+{
337
+ uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
338
+ uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
339
+ uint32_t status = 0;
340
+ uint8_t can_timestamp = 1;
341
+
342
+ QTestState *qts = qtest_init("-machine xlnx-zcu102"
343
+ " -object can-bus,id=canbus0"
344
+ " -machine xlnx-zcu102.canbus0=canbus0"
345
+ " -machine xlnx-zcu102.canbus1=canbus0"
346
+ );
347
+
348
+ /* Configure the CAN0. */
349
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
350
+ qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SNOOP_MODE);
351
+ qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
352
+
353
+ qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
354
+ qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
355
+
356
+ /* Check here if CAN0 is in SNOOP mode and CAN1 in normal mode. */
357
+ status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
358
+ g_assert_cmpint(status, ==, STATUS_SNOOP_MODE);
359
+
360
+ status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
361
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
362
+
363
+ send_data(qts, CAN1_BASE_ADDR, buf_tx);
364
+
365
+ read_data(qts, CAN0_BASE_ADDR, buf_rx);
366
+
367
+ match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
368
+
369
+ qtest_quit(qts);
370
+}
371
+
372
+int main(int argc, char **argv)
373
+{
374
+ g_test_init(&argc, &argv, NULL);
375
+
376
+ qtest_add_func("/net/can/can_bus", test_can_bus);
377
+ qtest_add_func("/net/can/can_loopback", test_can_loopback);
378
+ qtest_add_func("/net/can/can_filter", test_can_filter);
379
+ qtest_add_func("/net/can/can_test_snoopmode", test_can_snoopmode);
380
+ qtest_add_func("/net/can/can_test_sleepmode", test_can_sleepmode);
381
+
382
+ return g_test_run();
383
+}
384
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
85
index XXXXXXX..XXXXXXX 100644
385
index XXXXXXX..XXXXXXX 100644
86
--- a/MAINTAINERS
386
--- a/tests/qtest/meson.build
87
+++ b/MAINTAINERS
387
+++ b/tests/qtest/meson.build
88
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
388
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
89
S: Maintained
389
['arm-cpu-features',
90
F: hw/arm/netduino2.c
390
'numa-test',
91
391
'boot-serial-test',
92
+Netduino Plus 2
392
+ 'xlnx-can-test',
93
+M: Alistair Francis <alistair@alistair23.me>
393
'migration-test']
94
+M: Peter Maydell <peter.maydell@linaro.org>
394
95
+S: Maintained
395
qtests_s390x = \
96
+F: hw/arm/netduinoplus2.c
97
+
98
SmartFusion2
99
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
100
M: Peter Maydell <peter.maydell@linaro.org>
101
--
396
--
102
2.20.1
397
2.20.1
103
398
104
399
diff view generated by jsdifflib
New patch
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
1
2
3
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
4
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
6
Message-id: 1605728926-352690-5-git-send-email-fnu.vikram@xilinx.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
MAINTAINERS | 8 ++++++++
10
1 file changed, 8 insertions(+)
11
12
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
14
--- a/MAINTAINERS
15
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ F: hw/net/opencores_eth.c
17
18
Devices
19
-------
20
+Xilinx CAN
21
+M: Vikram Garhwal <fnu.vikram@xilinx.com>
22
+M: Francisco Iglesias <francisco.iglesias@xilinx.com>
23
+S: Maintained
24
+F: hw/net/can/xlnx-*
25
+F: include/hw/net/xlnx-*
26
+F: tests/qtest/xlnx-can-test*
27
+
28
EDU
29
M: Jiri Slaby <jslaby@suse.cz>
30
S: Maintained
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
The wfi instruction can be configured to be trapped by a higher exception
3
Trusted Firmware now supports A72 on sbsa-ref by default [1] so enable
4
level, such as the EL2 hypervisor. When the instruction is trapped, the
4
it for QEMU as well. A53 was already enabled there.
5
program counter should contain the address of the wfi instruction that
6
caused the exception. The program counter is adjusted for this in the wfi op
7
helper function.
8
5
9
However, this correction is done to env->pc, which only applies to AArch64
6
1. https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/7117
10
mode. For AArch32, the program counter is stored in env->regs[15]. This
11
adds an if-else statement to modify the correct program counter location
12
based on the the current CPU mode.
13
7
14
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
8
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20201120141705.246690-1-marcin.juszkiewicz@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
target/arm/op_helper.c | 7 ++++++-
14
hw/arm/sbsa-ref.c | 23 ++++++++++++++++++++---
19
1 file changed, 6 insertions(+), 1 deletion(-)
15
1 file changed, 20 insertions(+), 3 deletions(-)
20
16
21
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
17
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/op_helper.c
19
--- a/hw/arm/sbsa-ref.c
24
+++ b/target/arm/op_helper.c
20
+++ b/hw/arm/sbsa-ref.c
25
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
21
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
22
[SBSA_GWDT] = 16,
23
};
24
25
+static const char * const valid_cpus[] = {
26
+ ARM_CPU_TYPE_NAME("cortex-a53"),
27
+ ARM_CPU_TYPE_NAME("cortex-a57"),
28
+ ARM_CPU_TYPE_NAME("cortex-a72"),
29
+};
30
+
31
+static bool cpu_type_valid(const char *cpu)
32
+{
33
+ int i;
34
+
35
+ for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
36
+ if (strcmp(cpu, valid_cpus[i]) == 0) {
37
+ return true;
38
+ }
39
+ }
40
+ return false;
41
+}
42
+
43
static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx)
44
{
45
uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
46
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
47
const CPUArchIdList *possible_cpus;
48
int n, sbsa_max_cpus;
49
50
- if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
51
- error_report("sbsa-ref: CPU type other than the built-in "
52
- "cortex-a57 not supported");
53
+ if (!cpu_type_valid(machine->cpu_type)) {
54
+ error_report("mach-virt: CPU type %s not supported", machine->cpu_type);
55
exit(1);
26
}
56
}
27
57
28
if (target_el) {
29
- env->pc -= insn_len;
30
+ if (env->aarch64) {
31
+ env->pc -= insn_len;
32
+ } else {
33
+ env->regs[15] -= insn_len;
34
+ }
35
+
36
raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
37
target_el);
38
}
39
--
58
--
40
2.20.1
59
2.20.1
41
60
42
61
diff view generated by jsdifflib
1
From: Masahiro Yamada <masahiroy@kernel.org>
1
From: Havard Skinnemoen <hskinnemoen@google.com>
2
2
3
According to the specification "Semihosting for AArch32 and Aarch64",
3
Dump the collected random data after a randomness test failure.
4
the SYS_OPEN operation should return:
5
4
6
- A nonzero handle if the call is successful
5
Note that this relies on the test having called
7
- -1 if the call is not successful
6
g_test_set_nonfatal_assertions() so we don't abort immediately on the
7
assertion failure.
8
8
9
So, it should never return 0.
9
Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
10
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Prior to commit 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting
11
[PMM: minor commit message tweak]
12
code hand out its own file descriptors"), the guest fd matched to the
13
host fd. It returned a nonzero handle on success since the fd 0 is
14
already used for stdin.
15
16
Now that the guest fd is the index of guestfd_array, it starts from 0.
17
18
I noticed this issue particularly because Trusted Firmware-A built with
19
PLAT=qemu is no longer working. Its io_semihosting driver only handles
20
a positive return value as a valid filehandle.
21
22
Basically, there are two ways to fix this:
23
24
- Use (guestfd - 1) as the index of guestfs_arrary. We need to insert
25
increment/decrement to convert the guestfd and the array index back
26
and forth.
27
28
- Keep using guestfd as the index of guestfs_array. The first entry
29
of guestfs_array is left unused.
30
31
I thought the latter is simpler. We end up with wasting a small piece
32
of memory for the unused first entry of guestfd_array, but this is
33
probably not a big deal.
34
35
Fixes: 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting code hand out its own file descriptors")
36
Cc: qemu-stable@nongnu.org
37
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20200109041228.10131-1-masahiroy@kernel.org
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
---
13
---
42
target/arm/arm-semi.c | 5 +++--
14
tests/qtest/npcm7xx_rng-test.c | 12 ++++++++++++
43
1 file changed, 3 insertions(+), 2 deletions(-)
15
1 file changed, 12 insertions(+)
44
16
45
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
17
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
46
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/arm-semi.c
19
--- a/tests/qtest/npcm7xx_rng-test.c
48
+++ b/target/arm/arm-semi.c
20
+++ b/tests/qtest/npcm7xx_rng-test.c
49
@@ -XXX,XX +XXX,XX @@ static int alloc_guestfd(void)
21
@@ -XXX,XX +XXX,XX @@
50
guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
22
23
#include "libqtest-single.h"
24
#include "qemu/bitops.h"
25
+#include "qemu-common.h"
26
27
#define RNG_BASE_ADDR 0xf000b000
28
29
@@ -XXX,XX +XXX,XX @@
30
/* Number of bits to collect for randomness tests. */
31
#define TEST_INPUT_BITS (128)
32
33
+static void dump_buf_if_failed(const uint8_t *buf, size_t size)
34
+{
35
+ if (g_test_failed()) {
36
+ qemu_hexdump(stderr, "", buf, size);
37
+ }
38
+}
39
+
40
static void rng_writeb(unsigned int offset, uint8_t value)
41
{
42
writeb(RNG_BASE_ADDR + offset, value);
43
@@ -XXX,XX +XXX,XX @@ static void test_continuous_monobit(void)
51
}
44
}
52
45
53
- for (i = 0; i < guestfd_array->len; i++) {
46
g_assert_cmpfloat(calc_monobit_p(buf, sizeof(buf)), >, 0.01);
54
+ /* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
47
+ dump_buf_if_failed(buf, sizeof(buf));
55
+ for (i = 1; i < guestfd_array->len; i++) {
48
}
56
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
49
57
50
/*
58
if (gf->type == GuestFDUnused) {
51
@@ -XXX,XX +XXX,XX @@ static void test_continuous_runs(void)
59
@@ -XXX,XX +XXX,XX @@ static GuestFD *do_get_guestfd(int guestfd)
60
return NULL;
61
}
52
}
62
53
63
- if (guestfd < 0 || guestfd >= guestfd_array->len) {
54
g_assert_cmpfloat(calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE), >, 0.01);
64
+ if (guestfd <= 0 || guestfd >= guestfd_array->len) {
55
+ dump_buf_if_failed(buf.c, sizeof(buf));
65
return NULL;
56
}
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ static void test_first_byte_monobit(void)
66
}
60
}
67
61
62
g_assert_cmpfloat(calc_monobit_p(buf, sizeof(buf)), >, 0.01);
63
+ dump_buf_if_failed(buf, sizeof(buf));
64
}
65
66
/*
67
@@ -XXX,XX +XXX,XX @@ static void test_first_byte_runs(void)
68
}
69
70
g_assert_cmpfloat(calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE), >, 0.01);
71
+ dump_buf_if_failed(buf.c, sizeof(buf));
72
}
73
74
int main(int argc, char **argv)
68
--
75
--
69
2.20.1
76
2.20.1
70
77
71
78
diff view generated by jsdifflib
New patch
1
From: Alex Chen <alex.chen@huawei.com>
1
2
3
We should use printf format specifier "%u" instead of "%d" for
4
argument of type "unsigned int".
5
6
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
8
Message-id: 20201126111109.112238-2-alex.chen@huawei.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/imx25_ccm.c | 12 ++++++------
13
1 file changed, 6 insertions(+), 6 deletions(-)
14
15
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/imx25_ccm.c
18
+++ b/hw/misc/imx25_ccm.c
19
@@ -XXX,XX +XXX,XX @@ static const char *imx25_ccm_reg_name(uint32_t reg)
20
case IMX25_CCM_LPIMR1_REG:
21
return "lpimr1";
22
default:
23
- sprintf(unknown, "[%d ?]", reg);
24
+ sprintf(unknown, "[%u ?]", reg);
25
return unknown;
26
}
27
}
28
@@ -XXX,XX +XXX,XX @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
29
freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_MPCTL_REG], CKIH_FREQ);
30
}
31
32
- DPRINTF("freq = %d\n", freq);
33
+ DPRINTF("freq = %u\n", freq);
34
35
return freq;
36
}
37
@@ -XXX,XX +XXX,XX @@ static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
38
39
freq = freq / (1 + EXTRACT(s->reg[IMX25_CCM_CCTL_REG], ARM_CLK_DIV));
40
41
- DPRINTF("freq = %d\n", freq);
42
+ DPRINTF("freq = %u\n", freq);
43
44
return freq;
45
}
46
@@ -XXX,XX +XXX,XX @@ static uint32_t imx25_ccm_get_ahb_clk(IMXCCMState *dev)
47
freq = imx25_ccm_get_mcu_clk(dev)
48
/ (1 + EXTRACT(s->reg[IMX25_CCM_CCTL_REG], AHB_CLK_DIV));
49
50
- DPRINTF("freq = %d\n", freq);
51
+ DPRINTF("freq = %u\n", freq);
52
53
return freq;
54
}
55
@@ -XXX,XX +XXX,XX @@ static uint32_t imx25_ccm_get_ipg_clk(IMXCCMState *dev)
56
57
freq = imx25_ccm_get_ahb_clk(dev) / 2;
58
59
- DPRINTF("freq = %d\n", freq);
60
+ DPRINTF("freq = %u\n", freq);
61
62
return freq;
63
}
64
@@ -XXX,XX +XXX,XX @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
65
break;
66
}
67
68
- DPRINTF("Clock = %d) = %d\n", clock, freq);
69
+ DPRINTF("Clock = %d) = %u\n", clock, freq);
70
71
return freq;
72
}
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Chen <alex.chen@huawei.com>
2
2
3
The kernel image and DeviceTree blob are built by the Armbian
3
We should use printf format specifier "%u" instead of "%d" for
4
project (based on Debian):
4
argument of type "unsigned int".
5
https://docs.armbian.com/Developer-Guide_Build-Preparation/
6
5
7
The cpio image used comes from the linux-build-test project:
6
Reported-by: Euler Robot <euler.robot@huawei.com>
8
https://github.com/groeck/linux-build-test
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
9
8
Message-id: 20201126111109.112238-3-alex.chen@huawei.com
10
If ARM is a target being built, "make check-acceptance" will
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
automatically include this test by the use of the "arch:arm" tags.
12
13
Alternatively, this test can be run using:
14
15
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
16
console: Uncompressing Linux... done, booting the kernel.
17
console: Booting Linux on physical CPU 0x0
18
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
19
[...]
20
console: ahci-sunxi 1c18000.sata: Linked as a consumer to regulator.4
21
console: ahci-sunxi 1c18000.sata: controller can't do 64bit DMA, forcing 32bit
22
console: ahci-sunxi 1c18000.sata: AHCI 0001.0000 32 slots 1 ports 1.5 Gbps 0x1 impl platform mode
23
console: ahci-sunxi 1c18000.sata: flags: ncq only
24
console: scsi host0: ahci-sunxi
25
console: ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 27
26
console: of_cfs_init
27
console: of_cfs_init: OK
28
console: vcc3v0: disabling
29
console: vcc5v0: disabling
30
console: usb1-vbus: disabling
31
console: usb2-vbus: disabling
32
console: ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
33
console: ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
34
console: ata1.00: 40960 sectors, multi 16: LBA48 NCQ (depth 32)
35
console: ata1.00: applying bridge limits
36
console: ata1.00: configured for UDMA/100
37
console: scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
38
console: sd 0:0:0:0: Attached scsi generic sg0 type 0
39
console: sd 0:0:0:0: [sda] 40960 512-byte logical blocks: (21.0 MB/20.0 MiB)
40
console: sd 0:0:0:0: [sda] Write Protect is off
41
console: sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
42
console: sd 0:0:0:0: [sda] Attached SCSI disk
43
console: EXT4-fs (sda): mounting ext2 file system using the ext4 subsystem
44
console: EXT4-fs (sda): mounted filesystem without journal. Opts: (null)
45
console: VFS: Mounted root (ext2 filesystem) readonly on device 8:0.
46
[...]
47
console: cat /proc/partitions
48
console: / # cat /proc/partitions
49
console: major minor #blocks name
50
console: 1 0 4096 ram0
51
console: 1 1 4096 ram1
52
console: 1 2 4096 ram2
53
console: 1 3 4096 ram3
54
console: 8 0 20480 sda
55
console: reboot
56
console: / # reboot
57
[...]
58
console: sd 0:0:0:0: [sda] Synchronizing SCSI cache
59
console: reboot: Restarting system
60
PASS (48.39 s)
61
62
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
63
Message-id: 20191230110953.25496-3-f4bug@amsat.org
64
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
65
---
11
---
66
tests/acceptance/boot_linux_console.py | 44 ++++++++++++++++++++++++++
12
hw/misc/imx31_ccm.c | 14 +++++++-------
67
1 file changed, 44 insertions(+)
13
hw/misc/imx_ccm.c | 4 ++--
14
2 files changed, 9 insertions(+), 9 deletions(-)
68
15
69
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
70
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
71
--- a/tests/acceptance/boot_linux_console.py
18
--- a/hw/misc/imx31_ccm.c
72
+++ b/tests/acceptance/boot_linux_console.py
19
+++ b/hw/misc/imx31_ccm.c
73
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
20
@@ -XXX,XX +XXX,XX @@ static const char *imx31_ccm_reg_name(uint32_t reg)
74
exec_command_and_wait_for_pattern(self, 'reboot',
21
case IMX31_CCM_PDR2_REG:
75
'reboot: Restarting system')
22
return "PDR2";
76
23
default:
77
+ def test_arm_cubieboard_sata(self):
24
- sprintf(unknown, "[%d ?]", reg);
78
+ """
25
+ sprintf(unknown, "[%u ?]", reg);
79
+ :avocado: tags=arch:arm
26
return unknown;
80
+ :avocado: tags=machine:cubieboard
27
}
81
+ """
28
}
82
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
29
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
83
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
30
freq = CKIH_FREQ;
84
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
31
}
85
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
32
86
+ kernel_path = self.extract_from_deb(deb_path,
33
- DPRINTF("freq = %d\n", freq);
87
+ '/boot/vmlinuz-4.20.7-sunxi')
34
+ DPRINTF("freq = %u\n", freq);
88
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
35
89
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
36
return freq;
90
+ rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
37
}
91
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
38
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
92
+ 'arm/rootfs-armv5.ext2.gz')
39
freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG],
93
+ rootfs_hash = '093e89d2b4d982234bf528bc9fb2f2f17a9d1f93'
40
imx31_ccm_get_pll_ref_clk(dev));
94
+ rootfs_path_gz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
41
95
+ rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
42
- DPRINTF("freq = %d\n", freq);
96
+ archive.gzip_uncompress(rootfs_path_gz, rootfs_path)
43
+ DPRINTF("freq = %u\n", freq);
97
+
44
98
+ self.vm.set_console()
45
return freq;
99
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
46
}
100
+ 'console=ttyS0,115200 '
47
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
101
+ 'usbcore.nousb '
48
freq = imx31_ccm_get_mpll_clk(dev);
102
+ 'root=/dev/sda ro '
49
}
103
+ 'panic=-1 noreboot')
50
104
+ self.vm.add_args('-kernel', kernel_path,
51
- DPRINTF("freq = %d\n", freq);
105
+ '-dtb', dtb_path,
52
+ DPRINTF("freq = %u\n", freq);
106
+ '-drive', 'if=none,format=raw,id=disk0,file='
53
107
+ + rootfs_path,
54
return freq;
108
+ '-device', 'ide-hd,bus=ide.0,drive=disk0',
55
}
109
+ '-append', kernel_command_line,
56
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
110
+ '-no-reboot')
57
freq = imx31_ccm_get_mcu_main_clk(dev)
111
+ self.vm.launch()
58
/ (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MAX));
112
+ self.wait_for_console_pattern('Boot successful.')
59
113
+
60
- DPRINTF("freq = %d\n", freq);
114
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
61
+ DPRINTF("freq = %u\n", freq);
115
+ 'Allwinner sun4i/sun5i')
62
116
+ exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
63
return freq;
117
+ 'sda')
64
}
118
+ exec_command_and_wait_for_pattern(self, 'reboot',
65
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
119
+ 'reboot: Restarting system')
66
freq = imx31_ccm_get_hclk_clk(dev)
120
+
67
/ (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], IPG));
121
def test_s390x_s390_ccw_virtio(self):
68
122
"""
69
- DPRINTF("freq = %d\n", freq);
123
:avocado: tags=arch:s390x
70
+ DPRINTF("freq = %u\n", freq);
71
72
return freq;
73
}
74
@@ -XXX,XX +XXX,XX @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
75
break;
76
}
77
78
- DPRINTF("Clock = %d) = %d\n", clock, freq);
79
+ DPRINTF("Clock = %d) = %u\n", clock, freq);
80
81
return freq;
82
}
83
diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/misc/imx_ccm.c
86
+++ b/hw/misc/imx_ccm.c
87
@@ -XXX,XX +XXX,XX @@ uint32_t imx_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
88
freq = klass->get_clock_frequency(dev, clock);
89
}
90
91
- DPRINTF("(clock = %d) = %d\n", clock, freq);
92
+ DPRINTF("(clock = %d) = %u\n", clock, freq);
93
94
return freq;
95
}
96
@@ -XXX,XX +XXX,XX @@ uint32_t imx_ccm_calc_pll(uint32_t pllreg, uint32_t base_freq)
97
freq = ((2 * (base_freq >> 10) * (mfi * mfd + mfn)) /
98
(mfd * pd)) << 10;
99
100
- DPRINTF("(pllreg = 0x%08x, base_freq = %d) = %d\n", pllreg, base_freq,
101
+ DPRINTF("(pllreg = 0x%08x, base_freq = %u) = %d\n", pllreg, base_freq,
102
freq);
103
104
return freq;
124
--
105
--
125
2.20.1
106
2.20.1
126
107
127
108
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Alex Chen <alex.chen@huawei.com>
2
2
3
This test boots a Linux kernel on a CubieBoard and verify
3
We should use printf format specifier "%u" instead of "%d" for
4
the serial output is working.
4
argument of type "unsigned int".
5
5
6
The kernel image and DeviceTree blob are built by the Armbian
6
Reported-by: Euler Robot <euler.robot@huawei.com>
7
project (based on Debian):
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
8
https://docs.armbian.com/Developer-Guide_Build-Preparation/
8
Message-id: 20201126111109.112238-4-alex.chen@huawei.com
9
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
The cpio image used comes from the linux-build-test project:
11
https://github.com/groeck/linux-build-test
12
13
If ARM is a target being built, "make check-acceptance" will
14
automatically include this test by the use of the "arch:arm" tags.
15
16
Alternatively, this test can be run using:
17
18
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
19
console: Uncompressing Linux... done, booting the kernel.
20
console: Booting Linux on physical CPU 0x0
21
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
22
console: CPU: ARMv7 Processor [410fc080] revision 0 (ARMv7), cr=50c5387d
23
console: CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
24
console: OF: fdt: Machine model: Cubietech Cubieboard
25
[...]
26
console: Boot successful.
27
console: cat /proc/cpuinfo
28
console: / # cat /proc/cpuinfo
29
console: processor : 0
30
console: model name : ARMv7 Processor rev 0 (v7l)
31
console: BogoMIPS : 832.51
32
[...]
33
console: Hardware : Allwinner sun4i/sun5i Families
34
console: Revision : 0000
35
console: Serial : 0000000000000000
36
console: cat /proc/iomem
37
console: / # cat /proc/iomem
38
console: 01c00000-01c0002f : system-control@1c00000
39
console: 01c02000-01c02fff : dma-controller@1c02000
40
console: 01c05000-01c05fff : spi@1c05000
41
console: 01c0b080-01c0b093 : mdio@1c0b080
42
console: 01c0c000-01c0cfff : lcd-controller@1c0c000
43
console: 01c0d000-01c0dfff : lcd-controller@1c0d000
44
console: 01c0f000-01c0ffff : mmc@1c0f000
45
[...]
46
PASS (54.35 s)
47
48
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
49
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
50
Tested-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
51
Message-id: 20191230110953.25496-2-f4bug@amsat.org
52
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
53
---
11
---
54
tests/acceptance/boot_linux_console.py | 41 ++++++++++++++++++++++++++
12
hw/misc/imx6_ccm.c | 20 ++++++++++----------
55
1 file changed, 41 insertions(+)
13
hw/misc/imx6_src.c | 2 +-
14
2 files changed, 11 insertions(+), 11 deletions(-)
56
15
57
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
58
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/acceptance/boot_linux_console.py
18
--- a/hw/misc/imx6_ccm.c
60
+++ b/tests/acceptance/boot_linux_console.py
19
+++ b/hw/misc/imx6_ccm.c
61
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
20
@@ -XXX,XX +XXX,XX @@ static const char *imx6_ccm_reg_name(uint32_t reg)
62
self.wait_for_console_pattern('Boot successful.')
21
case CCM_CMEOR:
63
# TODO user command, for now the uart is stuck
22
return "CMEOR";
64
23
default:
65
+ def test_arm_cubieboard_initrd(self):
24
- sprintf(unknown, "%d ?", reg);
66
+ """
25
+ sprintf(unknown, "%u ?", reg);
67
+ :avocado: tags=arch:arm
26
return unknown;
68
+ :avocado: tags=machine:cubieboard
27
}
69
+ """
28
}
70
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
29
@@ -XXX,XX +XXX,XX @@ static const char *imx6_analog_reg_name(uint32_t reg)
71
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
30
case USB_ANALOG_DIGPROG:
72
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
31
return "USB_ANALOG_DIGPROG";
73
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
32
default:
74
+ kernel_path = self.extract_from_deb(deb_path,
33
- sprintf(unknown, "%d ?", reg);
75
+ '/boot/vmlinuz-4.20.7-sunxi')
34
+ sprintf(unknown, "%u ?", reg);
76
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
35
return unknown;
77
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
36
}
78
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
37
}
79
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
38
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_analog_get_pll2_clk(IMX6CCMState *dev)
80
+ 'arm/rootfs-armv5.cpio.gz')
39
freq *= 20;
81
+ initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b'
40
}
82
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
41
83
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
42
- DPRINTF("freq = %d\n", (uint32_t)freq);
84
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
43
+ DPRINTF("freq = %u\n", (uint32_t)freq);
85
+
44
86
+ self.vm.set_console()
45
return freq;
87
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
46
}
88
+ 'console=ttyS0,115200 '
47
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev)
89
+ 'usbcore.nousb '
48
freq = imx6_analog_get_pll2_clk(dev) * 18
90
+ 'panic=-1 noreboot')
49
/ EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD0_FRAC);
91
+ self.vm.add_args('-kernel', kernel_path,
50
92
+ '-dtb', dtb_path,
51
- DPRINTF("freq = %d\n", (uint32_t)freq);
93
+ '-initrd', initrd_path,
52
+ DPRINTF("freq = %u\n", (uint32_t)freq);
94
+ '-append', kernel_command_line,
53
95
+ '-no-reboot')
54
return freq;
96
+ self.vm.launch()
55
}
97
+ self.wait_for_console_pattern('Boot successful.')
56
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_analog_get_pll2_pfd2_clk(IMX6CCMState *dev)
98
+
57
freq = imx6_analog_get_pll2_clk(dev) * 18
99
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
58
/ EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD2_FRAC);
100
+ 'Allwinner sun4i/sun5i')
59
101
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
60
- DPRINTF("freq = %d\n", (uint32_t)freq);
102
+ 'system-control@1c00000')
61
+ DPRINTF("freq = %u\n", (uint32_t)freq);
103
+ exec_command_and_wait_for_pattern(self, 'reboot',
62
104
+ 'reboot: Restarting system')
63
return freq;
105
+
64
}
106
def test_s390x_s390_ccw_virtio(self):
65
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_analog_get_periph_clk(IMX6CCMState *dev)
107
"""
66
break;
108
:avocado: tags=arch:s390x
67
}
68
69
- DPRINTF("freq = %d\n", (uint32_t)freq);
70
+ DPRINTF("freq = %u\n", (uint32_t)freq);
71
72
return freq;
73
}
74
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_ccm_get_ahb_clk(IMX6CCMState *dev)
75
freq = imx6_analog_get_periph_clk(dev)
76
/ (1 + EXTRACT(dev->ccm[CCM_CBCDR], AHB_PODF));
77
78
- DPRINTF("freq = %d\n", (uint32_t)freq);
79
+ DPRINTF("freq = %u\n", (uint32_t)freq);
80
81
return freq;
82
}
83
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_ccm_get_ipg_clk(IMX6CCMState *dev)
84
freq = imx6_ccm_get_ahb_clk(dev)
85
/ (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));
86
87
- DPRINTF("freq = %d\n", (uint32_t)freq);
88
+ DPRINTF("freq = %u\n", (uint32_t)freq);
89
90
return freq;
91
}
92
@@ -XXX,XX +XXX,XX @@ static uint64_t imx6_ccm_get_per_clk(IMX6CCMState *dev)
93
freq = imx6_ccm_get_ipg_clk(dev)
94
/ (1 + EXTRACT(dev->ccm[CCM_CSCMR1], PERCLK_PODF));
95
96
- DPRINTF("freq = %d\n", (uint32_t)freq);
97
+ DPRINTF("freq = %u\n", (uint32_t)freq);
98
99
return freq;
100
}
101
@@ -XXX,XX +XXX,XX @@ static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
102
break;
103
}
104
105
- DPRINTF("Clock = %d) = %d\n", clock, freq);
106
+ DPRINTF("Clock = %d) = %u\n", clock, freq);
107
108
return freq;
109
}
110
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/hw/misc/imx6_src.c
113
+++ b/hw/misc/imx6_src.c
114
@@ -XXX,XX +XXX,XX @@ static const char *imx6_src_reg_name(uint32_t reg)
115
case SRC_GPR10:
116
return "SRC_GPR10";
117
default:
118
- sprintf(unknown, "%d ?", reg);
119
+ sprintf(unknown, "%u ?", reg);
120
return unknown;
121
}
122
}
109
--
123
--
110
2.20.1
124
2.20.1
111
125
112
126
diff view generated by jsdifflib
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
1
From: Alex Chen <alex.chen@huawei.com>
2
2
3
The IL bit is set for 32-bit instructions, thus passing false
3
We should use printf format specifier "%u" instead of "%d" for
4
with the is_16bit parameter to syn_data_abort_with_iss() makes
4
argument of type "unsigned int".
5
a syn mask that always has the IL bit set.
6
5
7
Pass is_16bit as true to make the initial syn mask have IL=0,
6
Reported-by: Euler Robot <euler.robot@huawei.com>
8
so that the final IL value comes from or'ing template_syn.
7
Signed-off-by: Alex Chen <alex.chen@huawei.com>
9
8
Message-id: 20201126111109.112238-5-alex.chen@huawei.com
10
Cc: qemu-stable@nongnu.org
11
Fixes: aaa1f954d4ca ("target-arm: A64: Create Instruction Syndromes for Data Aborts")
12
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200117004618.2742-2-richard.henderson@linaro.org
15
[rth: Extracted this as a self-contained bug fix from a larger patch]
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
target/arm/tlb_helper.c | 2 +-
12
hw/misc/imx6ul_ccm.c | 4 ++--
21
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
22
14
23
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
15
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/tlb_helper.c
17
--- a/hw/misc/imx6ul_ccm.c
26
+++ b/target/arm/tlb_helper.c
18
+++ b/hw/misc/imx6ul_ccm.c
27
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
19
@@ -XXX,XX +XXX,XX @@ static const char *imx6ul_ccm_reg_name(uint32_t reg)
28
syn = syn_data_abort_with_iss(same_el,
20
case CCM_CMEOR:
29
0, 0, 0, 0, 0,
21
return "CMEOR";
30
ea, 0, s1ptw, is_write, fsc,
22
default:
31
- false);
23
- sprintf(unknown, "%d ?", reg);
32
+ true);
24
+ sprintf(unknown, "%u ?", reg);
33
/* Merge the runtime syndrome with the template syndrome. */
25
return unknown;
34
syn |= template_syn;
35
}
26
}
27
}
28
@@ -XXX,XX +XXX,XX @@ static const char *imx6ul_analog_reg_name(uint32_t reg)
29
case USB_ANALOG_DIGPROG:
30
return "USB_ANALOG_DIGPROG";
31
default:
32
- sprintf(unknown, "%d ?", reg);
33
+ sprintf(unknown, "%u ?", reg);
34
return unknown;
35
}
36
}
36
--
37
--
37
2.20.1
38
2.20.1
38
39
39
40
diff view generated by jsdifflib
New patch
1
For M-profile CPUs, the range from 0xe0000000 to 0xe00fffff is the
2
Private Peripheral Bus range, which includes all of the memory mapped
3
devices and registers that are part of the CPU itself, including the
4
NVIC, systick timer, and debug and trace components like the Data
5
Watchpoint and Trace unit (DWT). Within this large region, the range
6
0xe000e000 to 0xe000efff is the System Control Space (NVIC, system
7
registers, systick) and 0xe002e000 to 0exe002efff is its Non-secure
8
alias.
1
9
10
The architecture is clear that within the SCS unimplemented registers
11
should be RES0 for privileged accesses and generate BusFault for
12
unprivileged accesses, and we currently implement this.
13
14
It is less clear about how to handle accesses to unimplemented
15
regions of the wider PPB. Unprivileged accesses should definitely
16
cause BusFaults (R_DQQS), but the behaviour of privileged accesses is
17
not given as a general rule. However, the register definitions of
18
individual registers for components like the DWT all state that they
19
are RES0 if the relevant component is not implemented, so the
20
simplest way to provide that is to provide RAZ/WI for the whole range
21
for privileged accesses. (The v7M Arm ARM does say that reserved
22
registers should be UNK/SBZP.)
23
24
Expand the container MemoryRegion that the NVIC exposes so that
25
it covers the whole PPB space. This means:
26
* moving the address that the ARMV7M device maps it to down by
27
0xe000 bytes
28
* moving the off and the offsets within the container of all the
29
subregions forward by 0xe000 bytes
30
* adding a new default MemoryRegion that covers the whole container
31
at a lower priority than anything else and which provides the
32
RAZWI/BusFault behaviour
33
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20201119215617.29887-2-peter.maydell@linaro.org
37
---
38
include/hw/intc/armv7m_nvic.h | 1 +
39
hw/arm/armv7m.c | 2 +-
40
hw/intc/armv7m_nvic.c | 78 ++++++++++++++++++++++++++++++-----
41
3 files changed, 69 insertions(+), 12 deletions(-)
42
43
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/hw/intc/armv7m_nvic.h
46
+++ b/include/hw/intc/armv7m_nvic.h
47
@@ -XXX,XX +XXX,XX @@ struct NVICState {
48
MemoryRegion systickmem;
49
MemoryRegion systick_ns_mem;
50
MemoryRegion container;
51
+ MemoryRegion defaultmem;
52
53
uint32_t num_irq;
54
qemu_irq excpout;
55
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/armv7m.c
58
+++ b/hw/arm/armv7m.c
59
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
60
sysbus_connect_irq(sbd, 0,
61
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
62
63
- memory_region_add_subregion(&s->container, 0xe000e000,
64
+ memory_region_add_subregion(&s->container, 0xe0000000,
65
sysbus_mmio_get_region(sbd, 0));
66
67
for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
68
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/intc/armv7m_nvic.c
71
+++ b/hw/intc/armv7m_nvic.c
72
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvic_systick_ops = {
73
.endianness = DEVICE_NATIVE_ENDIAN,
74
};
75
76
+/*
77
+ * Unassigned portions of the PPB space are RAZ/WI for privileged
78
+ * accesses, and fault for non-privileged accesses.
79
+ */
80
+static MemTxResult ppb_default_read(void *opaque, hwaddr addr,
81
+ uint64_t *data, unsigned size,
82
+ MemTxAttrs attrs)
83
+{
84
+ qemu_log_mask(LOG_UNIMP, "Read of unassigned area of PPB: offset 0x%x\n",
85
+ (uint32_t)addr);
86
+ if (attrs.user) {
87
+ return MEMTX_ERROR;
88
+ }
89
+ *data = 0;
90
+ return MEMTX_OK;
91
+}
92
+
93
+static MemTxResult ppb_default_write(void *opaque, hwaddr addr,
94
+ uint64_t value, unsigned size,
95
+ MemTxAttrs attrs)
96
+{
97
+ qemu_log_mask(LOG_UNIMP, "Write of unassigned area of PPB: offset 0x%x\n",
98
+ (uint32_t)addr);
99
+ if (attrs.user) {
100
+ return MEMTX_ERROR;
101
+ }
102
+ return MEMTX_OK;
103
+}
104
+
105
+static const MemoryRegionOps ppb_default_ops = {
106
+ .read_with_attrs = ppb_default_read,
107
+ .write_with_attrs = ppb_default_write,
108
+ .endianness = DEVICE_NATIVE_ENDIAN,
109
+ .valid.min_access_size = 1,
110
+ .valid.max_access_size = 8,
111
+};
112
+
113
static int nvic_post_load(void *opaque, int version_id)
114
{
115
NVICState *s = opaque;
116
@@ -XXX,XX +XXX,XX @@ static void nvic_systick_trigger(void *opaque, int n, int level)
117
static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
118
{
119
NVICState *s = NVIC(dev);
120
- int regionlen;
121
122
/* The armv7m container object will have set our CPU pointer */
123
if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
124
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
125
M_REG_S));
126
}
127
128
- /* The NVIC and System Control Space (SCS) starts at 0xe000e000
129
+ /*
130
+ * This device provides a single sysbus memory region which
131
+ * represents the whole of the "System PPB" space. This is the
132
+ * range from 0xe0000000 to 0xe00fffff and includes the NVIC,
133
+ * the System Control Space (system registers), the systick timer,
134
+ * and for CPUs with the Security extension an NS banked version
135
+ * of all of these.
136
+ *
137
+ * The default behaviour for unimplemented registers/ranges
138
+ * (for instance the Data Watchpoint and Trace unit at 0xe0001000)
139
+ * is to RAZ/WI for privileged access and BusFault for non-privileged
140
+ * access.
141
+ *
142
+ * The NVIC and System Control Space (SCS) starts at 0xe000e000
143
* and looks like this:
144
* 0x004 - ICTR
145
* 0x010 - 0xff - systick
146
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
147
* generally code determining which banked register to use should
148
* use attrs.secure; code determining actual behaviour of the system
149
* should use env->v7m.secure.
150
+ *
151
+ * The container covers the whole PPB space. Within it the priority
152
+ * of overlapping regions is:
153
+ * - default region (for RAZ/WI and BusFault) : -1
154
+ * - system register regions : 0
155
+ * - systick : 1
156
+ * This is because the systick device is a small block of registers
157
+ * in the middle of the other system control registers.
158
*/
159
- regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
160
- memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
161
- /* The system register region goes at the bottom of the priority
162
- * stack as it covers the whole page.
163
- */
164
+ memory_region_init(&s->container, OBJECT(s), "nvic", 0x100000);
165
+ memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
166
+ "nvic-default", 0x100000);
167
+ memory_region_add_subregion_overlap(&s->container, 0, &s->defaultmem, -1);
168
memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
169
"nvic_sysregs", 0x1000);
170
- memory_region_add_subregion(&s->container, 0, &s->sysregmem);
171
+ memory_region_add_subregion(&s->container, 0xe000, &s->sysregmem);
172
173
memory_region_init_io(&s->systickmem, OBJECT(s),
174
&nvic_systick_ops, s,
175
"nvic_systick", 0xe0);
176
177
- memory_region_add_subregion_overlap(&s->container, 0x10,
178
+ memory_region_add_subregion_overlap(&s->container, 0xe010,
179
&s->systickmem, 1);
180
181
if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
182
memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
183
&nvic_sysreg_ns_ops, &s->sysregmem,
184
"nvic_sysregs_ns", 0x1000);
185
- memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
186
+ memory_region_add_subregion(&s->container, 0x2e000, &s->sysreg_ns_mem);
187
memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
188
&nvic_sysreg_ns_ops, &s->systickmem,
189
"nvic_systick_ns", 0xe0);
190
- memory_region_add_subregion_overlap(&s->container, 0x20010,
191
+ memory_region_add_subregion_overlap(&s->container, 0x2e010,
192
&s->systick_ns_mem, 1);
193
}
194
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
New patch
1
In v8.1M the PXN architecture extension adds a new PXN bit to the
2
MPU_RLAR registers, which forbids execution of code in the region
3
from a privileged mode.
1
4
5
This is another feature which is just in the generic "in v8.1M" set
6
and has no ID register field indicating its presence.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20201119215617.29887-3-peter.maydell@linaro.org
11
---
12
target/arm/helper.c | 7 ++++++-
13
1 file changed, 6 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
20
} else {
21
uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
22
uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
23
+ bool pxn = false;
24
+
25
+ if (arm_feature(env, ARM_FEATURE_V8_1M)) {
26
+ pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
27
+ }
28
29
if (m_is_system_region(env, address)) {
30
/* System space is always execute never */
31
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
32
}
33
34
*prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
35
- if (*prot && !xn) {
36
+ if (*prot && !xn && !(pxn && !is_user)) {
37
*prot |= PAGE_EXEC;
38
}
39
/* We don't need to look the attribute up in the MAIR0/MAIR1
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
New patch
1
In arm_cpu_realizefn() we check whether the board code disabled EL3
2
via the has_el3 CPU object property, which we create if the CPU
3
starts with the ARM_FEATURE_EL3 feature bit. If it is disabled, then
4
we turn off ARM_FEATURE_EL3 and also zero out the relevant fields in
5
the ID_PFR1 and ID_AA64PFR0 registers.
1
6
7
This codepath was incorrectly being taken for M-profile CPUs, which
8
do not have an EL3 and don't set ARM_FEATURE_EL3, but which may have
9
the M-profile Security extension and so should have non-zero values
10
in the ID_PFR1.Security field.
11
12
Restrict the handling of the feature flag to A/R-profile cores.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20201119215617.29887-4-peter.maydell@linaro.org
17
---
18
target/arm/cpu.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.c
24
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
26
}
27
}
28
29
- if (!cpu->has_el3) {
30
+ if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
31
/* If the has_el3 CPU property is disabled then we need to disable the
32
* feature.
33
*/
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
New patch
1
1
Implement the v8.1M VSCCLRM insn, which zeros floating point
2
registers if there is an active floating point context.
3
This requires support in write_neon_element32() for the MO_32
4
element size, so add it.
5
6
Because we want to use arm_gen_condlabel(), we need to move
7
the definition of that function up in translate.c so it is
8
before the #include of translate-vfp.c.inc.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20201119215617.29887-5-peter.maydell@linaro.org
13
---
14
target/arm/cpu.h | 9 ++++
15
target/arm/m-nocp.decode | 8 +++-
16
target/arm/translate.c | 21 +++++----
17
target/arm/translate-vfp.c.inc | 84 ++++++++++++++++++++++++++++++++++
18
4 files changed, 111 insertions(+), 11 deletions(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
25
return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
26
}
27
28
+static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
29
+{
30
+ /*
31
+ * Return true if M-profile state handling insns
32
+ * (VSCCLRM, CLRM, FPCTX access insns) are implemented
33
+ */
34
+ return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
35
+}
36
+
37
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
38
{
39
/* Sadly this is encoded differently for A-profile and M-profile */
40
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/m-nocp.decode
43
+++ b/target/arm/m-nocp.decode
44
@@ -XXX,XX +XXX,XX @@
45
# If the coprocessor is not present or disabled then we will generate
46
# the NOCP exception; otherwise we let the insn through to the main decode.
47
48
+%vd_dp 22:1 12:4
49
+%vd_sp 12:4 22:1
50
+
51
&nocp cp
52
53
{
54
# Special cases which do not take an early NOCP: VLLDM and VLSTM
55
VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
56
- # TODO: VSCCLRM (new in v8.1M) is similar:
57
- #VSCCLRM 1110 1100 1-01 1111 ---- 1011 ---- ---0
58
+ # VSCCLRM (new in v8.1M) is similar:
59
+ VSCCLRM 1110 1100 1.01 1111 .... 1011 imm:7 0 vd=%vd_dp size=3
60
+ VSCCLRM 1110 1100 1.01 1111 .... 1010 imm:8 vd=%vd_sp size=2
61
62
NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
63
NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
69
a64_translate_init();
70
}
71
72
+/* Generate a label used for skipping this instruction */
73
+static void arm_gen_condlabel(DisasContext *s)
74
+{
75
+ if (!s->condjmp) {
76
+ s->condlabel = gen_new_label();
77
+ s->condjmp = 1;
78
+ }
79
+}
80
+
81
/* Flags for the disas_set_da_iss info argument:
82
* lower bits hold the Rt register number, higher bits are flags.
83
*/
84
@@ -XXX,XX +XXX,XX @@ static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
85
long off = neon_element_offset(reg, ele, memop);
86
87
switch (memop) {
88
+ case MO_32:
89
+ tcg_gen_st32_i64(src, cpu_env, off);
90
+ break;
91
case MO_64:
92
tcg_gen_st_i64(src, cpu_env, off);
93
break;
94
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
95
s->base.is_jmp = DISAS_UPDATE_EXIT;
96
}
97
98
-/* Generate a label used for skipping this instruction */
99
-static void arm_gen_condlabel(DisasContext *s)
100
-{
101
- if (!s->condjmp) {
102
- s->condlabel = gen_new_label();
103
- s->condjmp = 1;
104
- }
105
-}
106
-
107
/* Skip this instruction if the ARM condition is false */
108
static void arm_skip_unless(DisasContext *s, uint32_t cond)
109
{
110
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/translate-vfp.c.inc
113
+++ b/target/arm/translate-vfp.c.inc
114
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
115
return true;
116
}
117
118
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
119
+{
120
+ int btmreg, topreg;
121
+ TCGv_i64 zero;
122
+ TCGv_i32 aspen, sfpa;
123
+
124
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
125
+ /* Before v8.1M, fall through in decode to NOCP check */
126
+ return false;
127
+ }
128
+
129
+ /* Explicitly UNDEF because this takes precedence over NOCP */
130
+ if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
131
+ unallocated_encoding(s);
132
+ return true;
133
+ }
134
+
135
+ if (!dc_isar_feature(aa32_vfp_simd, s)) {
136
+ /* NOP if we have neither FP nor MVE */
137
+ return true;
138
+ }
139
+
140
+ /*
141
+ * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
142
+ * active floating point context so we must NOP (without doing
143
+ * any lazy state preservation or the NOCP check).
144
+ */
145
+ aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
146
+ sfpa = load_cpu_field(v7m.control[M_REG_S]);
147
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
148
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
149
+ tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
150
+ tcg_gen_or_i32(sfpa, sfpa, aspen);
151
+ arm_gen_condlabel(s);
152
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
153
+
154
+ if (s->fp_excp_el != 0) {
155
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
156
+ syn_uncategorized(), s->fp_excp_el);
157
+ return true;
158
+ }
159
+
160
+ topreg = a->vd + a->imm - 1;
161
+ btmreg = a->vd;
162
+
163
+ /* Convert to Sreg numbers if the insn specified in Dregs */
164
+ if (a->size == 3) {
165
+ topreg = topreg * 2 + 1;
166
+ btmreg *= 2;
167
+ }
168
+
169
+ if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
170
+ /* UNPREDICTABLE: we choose to undef */
171
+ unallocated_encoding(s);
172
+ return true;
173
+ }
174
+
175
+ /* Silently ignore requests to clear D16-D31 if they don't exist */
176
+ if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
177
+ topreg = 31;
178
+ }
179
+
180
+ if (!vfp_access_check(s)) {
181
+ return true;
182
+ }
183
+
184
+ /* Zero the Sregs from btmreg to topreg inclusive. */
185
+ zero = tcg_const_i64(0);
186
+ if (btmreg & 1) {
187
+ write_neon_element64(zero, btmreg >> 1, 1, MO_32);
188
+ btmreg++;
189
+ }
190
+ for (; btmreg + 1 <= topreg; btmreg += 2) {
191
+ write_neon_element64(zero, btmreg >> 1, 0, MO_64);
192
+ }
193
+ if (btmreg == topreg) {
194
+ write_neon_element64(zero, btmreg >> 1, 0, MO_32);
195
+ btmreg++;
196
+ }
197
+ assert(btmreg == topreg + 1);
198
+ /* TODO: when MVE is implemented, zero VPR here */
199
+ return true;
200
+}
201
+
202
static bool trans_NOCP(DisasContext *s, arg_nocp *a)
203
{
204
/*
205
--
206
2.20.1
207
208
diff view generated by jsdifflib
New patch
1
In v8.1M the new CLRM instruction allows zeroing an arbitrary set of
2
the general-purpose registers and APSR. Implement this.
1
3
4
The encoding is a subset of the LDMIA T2 encoding, using what would
5
be Rn=0b1111 (which UNDEFs for LDMIA).
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201119215617.29887-6-peter.maydell@linaro.org
10
---
11
target/arm/t32.decode | 6 +++++-
12
target/arm/translate.c | 38 ++++++++++++++++++++++++++++++++++++++
13
2 files changed, 43 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/t32.decode
18
+++ b/target/arm/t32.decode
19
@@ -XXX,XX +XXX,XX @@ UXTAB 1111 1010 0101 .... 1111 .... 10.. .... @rrr_rot
20
21
STM_t32 1110 1000 10.0 .... ................ @ldstm i=1 b=0
22
STM_t32 1110 1001 00.0 .... ................ @ldstm i=0 b=1
23
-LDM_t32 1110 1000 10.1 .... ................ @ldstm i=1 b=0
24
+{
25
+ # Rn=15 UNDEFs for LDM; M-profile CLRM uses that encoding
26
+ CLRM 1110 1000 1001 1111 list:16
27
+ LDM_t32 1110 1000 10.1 .... ................ @ldstm i=1 b=0
28
+}
29
LDM_t32 1110 1001 00.1 .... ................ @ldstm i=0 b=1
30
31
&rfe !extern rn w pu
32
diff --git a/target/arm/translate.c b/target/arm/translate.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.c
35
+++ b/target/arm/translate.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
37
return do_ldm(s, a, 1);
38
}
39
40
+static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
41
+{
42
+ int i;
43
+ TCGv_i32 zero;
44
+
45
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
46
+ return false;
47
+ }
48
+
49
+ if (extract32(a->list, 13, 1)) {
50
+ return false;
51
+ }
52
+
53
+ if (!a->list) {
54
+ /* UNPREDICTABLE; we choose to UNDEF */
55
+ return false;
56
+ }
57
+
58
+ zero = tcg_const_i32(0);
59
+ for (i = 0; i < 15; i++) {
60
+ if (extract32(a->list, i, 1)) {
61
+ /* Clear R[i] */
62
+ tcg_gen_mov_i32(cpu_R[i], zero);
63
+ }
64
+ }
65
+ if (extract32(a->list, 15, 1)) {
66
+ /*
67
+ * Clear APSR (by calling the MSR helper with the same argument
68
+ * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
69
+ */
70
+ TCGv_i32 maskreg = tcg_const_i32(0xc << 8);
71
+ gen_helper_v7m_msr(cpu_env, maskreg, zero);
72
+ tcg_temp_free_i32(maskreg);
73
+ }
74
+ tcg_temp_free_i32(zero);
75
+ return true;
76
+}
77
+
78
/*
79
* Branch, branch with link
80
*/
81
--
82
2.20.1
83
84
diff view generated by jsdifflib
New patch
1
For M-profile before v8.1M, the only valid register for VMSR/VMRS is
2
the FPSCR. We have a comment that states this, but the actual logic
3
to forbid accesses for any other register value is missing, so we
4
would end up with A-profile style behaviour. Add the missing check.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201119215617.29887-7-peter.maydell@linaro.org
9
---
10
target/arm/translate-vfp.c.inc | 5 ++++-
11
1 file changed, 4 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
18
* Accesses to R15 are UNPREDICTABLE; we choose to undef.
19
* (FPSCR -> r15 is a special case which writes to the PSR flags.)
20
*/
21
- if (a->rt == 15 && (!a->l || a->reg != ARM_VFP_FPSCR)) {
22
+ if (a->reg != ARM_VFP_FPSCR) {
23
+ return false;
24
+ }
25
+ if (a->rt == 15 && !a->l) {
26
return false;
27
}
28
}
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
New patch
1
1
Currently M-profile borrows the A-profile code for VMSR and VMRS
2
(access to the FP system registers), because all it needs to support
3
is the FPSCR. In v8.1M things become significantly more complicated
4
in two ways:
5
6
* there are several new FP system registers; some have side effects
7
on read, and one (FPCXT_NS) needs to avoid the usual
8
vfp_access_check() and the "only if FPU implemented" check
9
10
* all sysregs are now accessible both by VMRS/VMSR (which
11
reads/writes a general purpose register) and also by VLDR/VSTR
12
(which reads/writes them directly to memory)
13
14
Refactor the structure of how we handle VMSR/VMRS to cope with this:
15
16
* keep the M-profile code entirely separate from the A-profile code
17
18
* abstract out the "read or write the general purpose register" part
19
of the code into a loadfn or storefn function pointer, so we can
20
reuse it for VLDR/VSTR.
21
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20201119215617.29887-8-peter.maydell@linaro.org
25
---
26
target/arm/cpu.h | 3 +
27
target/arm/translate-vfp.c.inc | 182 ++++++++++++++++++++++++++++++---
28
2 files changed, 171 insertions(+), 14 deletions(-)
29
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ enum arm_cpu_mode {
35
#define ARM_VFP_FPINST 9
36
#define ARM_VFP_FPINST2 10
37
38
+/* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
39
+#define QEMU_VFP_FPSCR_NZCV 0xffff
40
+
41
/* iwMMXt coprocessor control registers. */
42
#define ARM_IWMMXT_wCID 0
43
#define ARM_IWMMXT_wCon 1
44
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/translate-vfp.c.inc
47
+++ b/target/arm/translate-vfp.c.inc
48
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
49
return true;
50
}
51
52
+/*
53
+ * M-profile provides two different sets of instructions that can
54
+ * access floating point system registers: VMSR/VMRS (which move
55
+ * to/from a general purpose register) and VLDR/VSTR sysreg (which
56
+ * move directly to/from memory). In some cases there are also side
57
+ * effects which must happen after any write to memory (which could
58
+ * cause an exception). So we implement the common logic for the
59
+ * sysreg access in gen_M_fp_sysreg_write() and gen_M_fp_sysreg_read(),
60
+ * which take pointers to callback functions which will perform the
61
+ * actual "read/write general purpose register" and "read/write
62
+ * memory" operations.
63
+ */
64
+
65
+/*
66
+ * Emit code to store the sysreg to its final destination; frees the
67
+ * TCG temp 'value' it is passed.
68
+ */
69
+typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 value);
70
+/*
71
+ * Emit code to load the value to be copied to the sysreg; returns
72
+ * a new TCG temporary
73
+ */
74
+typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque);
75
+
76
+/* Common decode/access checks for fp sysreg read/write */
77
+typedef enum FPSysRegCheckResult {
78
+ FPSysRegCheckFailed, /* caller should return false */
79
+ FPSysRegCheckDone, /* caller should return true */
80
+ FPSysRegCheckContinue, /* caller should continue generating code */
81
+} FPSysRegCheckResult;
82
+
83
+static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
84
+{
85
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
86
+ return FPSysRegCheckFailed;
87
+ }
88
+
89
+ switch (regno) {
90
+ case ARM_VFP_FPSCR:
91
+ case QEMU_VFP_FPSCR_NZCV:
92
+ break;
93
+ default:
94
+ return FPSysRegCheckFailed;
95
+ }
96
+
97
+ if (!vfp_access_check(s)) {
98
+ return FPSysRegCheckDone;
99
+ }
100
+
101
+ return FPSysRegCheckContinue;
102
+}
103
+
104
+static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
105
+
106
+ fp_sysreg_loadfn *loadfn,
107
+ void *opaque)
108
+{
109
+ /* Do a write to an M-profile floating point system register */
110
+ TCGv_i32 tmp;
111
+
112
+ switch (fp_sysreg_checks(s, regno)) {
113
+ case FPSysRegCheckFailed:
114
+ return false;
115
+ case FPSysRegCheckDone:
116
+ return true;
117
+ case FPSysRegCheckContinue:
118
+ break;
119
+ }
120
+
121
+ switch (regno) {
122
+ case ARM_VFP_FPSCR:
123
+ tmp = loadfn(s, opaque);
124
+ gen_helper_vfp_set_fpscr(cpu_env, tmp);
125
+ tcg_temp_free_i32(tmp);
126
+ gen_lookup_tb(s);
127
+ break;
128
+ default:
129
+ g_assert_not_reached();
130
+ }
131
+ return true;
132
+}
133
+
134
+static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
135
+ fp_sysreg_storefn *storefn,
136
+ void *opaque)
137
+{
138
+ /* Do a read from an M-profile floating point system register */
139
+ TCGv_i32 tmp;
140
+
141
+ switch (fp_sysreg_checks(s, regno)) {
142
+ case FPSysRegCheckFailed:
143
+ return false;
144
+ case FPSysRegCheckDone:
145
+ return true;
146
+ case FPSysRegCheckContinue:
147
+ break;
148
+ }
149
+
150
+ switch (regno) {
151
+ case ARM_VFP_FPSCR:
152
+ tmp = tcg_temp_new_i32();
153
+ gen_helper_vfp_get_fpscr(tmp, cpu_env);
154
+ storefn(s, opaque, tmp);
155
+ break;
156
+ case QEMU_VFP_FPSCR_NZCV:
157
+ /*
158
+ * Read just NZCV; this is a special case to avoid the
159
+ * helper call for the "VMRS to CPSR.NZCV" insn.
160
+ */
161
+ tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
162
+ tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
163
+ storefn(s, opaque, tmp);
164
+ break;
165
+ default:
166
+ g_assert_not_reached();
167
+ }
168
+ return true;
169
+}
170
+
171
+static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value)
172
+{
173
+ arg_VMSR_VMRS *a = opaque;
174
+
175
+ if (a->rt == 15) {
176
+ /* Set the 4 flag bits in the CPSR */
177
+ gen_set_nzcv(value);
178
+ tcg_temp_free_i32(value);
179
+ } else {
180
+ store_reg(s, a->rt, value);
181
+ }
182
+}
183
+
184
+static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque)
185
+{
186
+ arg_VMSR_VMRS *a = opaque;
187
+
188
+ return load_reg(s, a->rt);
189
+}
190
+
191
+static bool gen_M_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
192
+{
193
+ /*
194
+ * Accesses to R15 are UNPREDICTABLE; we choose to undef.
195
+ * FPSCR -> r15 is a special case which writes to the PSR flags;
196
+ * set a->reg to a special value to tell gen_M_fp_sysreg_read()
197
+ * we only care about the top 4 bits of FPSCR there.
198
+ */
199
+ if (a->rt == 15) {
200
+ if (a->l && a->reg == ARM_VFP_FPSCR) {
201
+ a->reg = QEMU_VFP_FPSCR_NZCV;
202
+ } else {
203
+ return false;
204
+ }
205
+ }
206
+
207
+ if (a->l) {
208
+ /* VMRS, move FP system register to gp register */
209
+ return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_gpr, a);
210
+ } else {
211
+ /* VMSR, move gp register to FP system register */
212
+ return gen_M_fp_sysreg_write(s, a->reg, gpr_to_fp_sysreg, a);
213
+ }
214
+}
215
+
216
static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
217
{
218
TCGv_i32 tmp;
219
bool ignore_vfp_enabled = false;
220
221
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
222
- return false;
223
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
224
+ return gen_M_VMSR_VMRS(s, a);
225
}
226
227
- if (arm_dc_feature(s, ARM_FEATURE_M)) {
228
- /*
229
- * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
230
- * Accesses to R15 are UNPREDICTABLE; we choose to undef.
231
- * (FPSCR -> r15 is a special case which writes to the PSR flags.)
232
- */
233
- if (a->reg != ARM_VFP_FPSCR) {
234
- return false;
235
- }
236
- if (a->rt == 15 && !a->l) {
237
- return false;
238
- }
239
+ if (!dc_isar_feature(aa32_fpsp_v2, s)) {
240
+ return false;
241
}
242
243
switch (a->reg) {
244
--
245
2.20.1
246
247
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The constant-expander functions like negate, plus_2, etc, are
2
generally useful; move them up in translate.c so we can use them in
3
the VFP/Neon decoders as well as in the A32/T32/T16 decoders.
2
4
3
During the conversion to decodetree, the setting of
4
ISSIs16Bit got lost. This causes the guest os to
5
incorrectly adjust trapping memory operations.
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 46beb58efbb8a2a32 ("target/arm: Convert T16, load (literal)")
9
Reported-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200117004618.2742-3-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201119215617.29887-9-peter.maydell@linaro.org
14
---
8
---
15
target/arm/translate.c | 3 +++
9
target/arm/translate.c | 46 +++++++++++++++++++++++-------------------
16
1 file changed, 3 insertions(+)
10
1 file changed, 25 insertions(+), 21 deletions(-)
17
11
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
14
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
15
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
16
@@ -XXX,XX +XXX,XX @@ static void arm_gen_condlabel(DisasContext *s)
23
/* ISS not valid if writeback */
24
if (p && !w) {
25
ret = rd;
26
+ if (s->base.pc_next - s->pc_curr == 2) {
27
+ ret |= ISSIs16Bit;
28
+ }
29
} else {
30
ret = ISSInvalid;
31
}
17
}
18
}
19
20
+/*
21
+ * Constant expanders for the decoders.
22
+ */
23
+
24
+static int negate(DisasContext *s, int x)
25
+{
26
+ return -x;
27
+}
28
+
29
+static int plus_2(DisasContext *s, int x)
30
+{
31
+ return x + 2;
32
+}
33
+
34
+static int times_2(DisasContext *s, int x)
35
+{
36
+ return x * 2;
37
+}
38
+
39
+static int times_4(DisasContext *s, int x)
40
+{
41
+ return x * 4;
42
+}
43
+
44
/* Flags for the disas_set_da_iss info argument:
45
* lower bits hold the Rt register number, higher bits are flags.
46
*/
47
@@ -XXX,XX +XXX,XX @@ static void arm_skip_unless(DisasContext *s, uint32_t cond)
48
49
50
/*
51
- * Constant expanders for the decoders.
52
+ * Constant expanders used by T16/T32 decode
53
*/
54
55
-static int negate(DisasContext *s, int x)
56
-{
57
- return -x;
58
-}
59
-
60
-static int plus_2(DisasContext *s, int x)
61
-{
62
- return x + 2;
63
-}
64
-
65
-static int times_2(DisasContext *s, int x)
66
-{
67
- return x * 2;
68
-}
69
-
70
-static int times_4(DisasContext *s, int x)
71
-{
72
- return x * 4;
73
-}
74
-
75
/* Return only the rotation part of T32ExpandImm. */
76
static int t32_expandimm_rot(DisasContext *s, int x)
77
{
32
--
78
--
33
2.20.1
79
2.20.1
34
80
35
81
diff view generated by jsdifflib
1
From: Alistair Francis <alistair@alistair23.me>
1
Implement the new-in-v8.1M VLDR/VSTR variants which directly
2
read or write FP system registers to memory.
2
3
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: ef941d59fd8658589d34ed432e1d6dfdcf7fb1d0.1576658572.git.alistair@alistair23.me
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201119215617.29887-10-peter.maydell@linaro.org
8
---
7
---
9
hw/misc/Makefile.objs | 1 +
8
target/arm/vfp.decode | 14 ++++++
10
include/hw/misc/stm32f4xx_exti.h | 60 ++++++++++
9
target/arm/translate-vfp.c.inc | 91 ++++++++++++++++++++++++++++++++++
11
hw/misc/stm32f4xx_exti.c | 188 +++++++++++++++++++++++++++++++
10
2 files changed, 105 insertions(+)
12
hw/arm/Kconfig | 1 +
13
hw/misc/Kconfig | 3 +
14
hw/misc/trace-events | 5 +
15
6 files changed, 258 insertions(+)
16
create mode 100644 include/hw/misc/stm32f4xx_exti.h
17
create mode 100644 hw/misc/stm32f4xx_exti.c
18
11
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
12
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
14
--- a/target/arm/vfp.decode
22
+++ b/hw/misc/Makefile.objs
15
+++ b/target/arm/vfp.decode
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
16
@@ -XXX,XX +XXX,XX @@ VLDR_VSTR_hp ---- 1101 u:1 .0 l:1 rn:4 .... 1001 imm:8 vd=%vd_sp
24
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
17
VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 vd=%vd_sp
25
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
18
VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 vd=%vd_dp
26
common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
19
27
+common-obj-$(CONFIG_STM32F4XX_EXTI) += stm32f4xx_exti.o
20
+# M-profile VLDR/VSTR to sysreg
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
21
+%vldr_sysreg 22:1 13:3
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
22
+%imm7_0x4 0:7 !function=times_4
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
31
diff --git a/include/hw/misc/stm32f4xx_exti.h b/include/hw/misc/stm32f4xx_exti.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/misc/stm32f4xx_exti.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * STM32F4XX EXTI
39
+ *
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
41
+ *
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ * copies of the Software, and to permit persons to whom the Software is
47
+ * furnished to do so, subject to the following conditions:
48
+ *
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
60
+
23
+
61
+#ifndef HW_STM_EXTI_H
24
+&vldr_sysreg rn reg imm a w p
62
+#define HW_STM_EXTI_H
25
+@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \
26
+ reg=%vldr_sysreg imm=%imm7_0x4 &vldr_sysreg
63
+
27
+
64
+#include "hw/sysbus.h"
28
+# P=0 W=0 is SEE "Related encodings", so split into two patterns
65
+#include "hw/hw.h"
29
+VLDR_sysreg ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg p=1
30
+VLDR_sysreg ---- 110 0 . . 1 1 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
31
+VSTR_sysreg ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg p=1
32
+VSTR_sysreg ---- 110 0 . . 1 0 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
66
+
33
+
67
+#define EXTI_IMR 0x00
34
# We split the load/store multiple up into two patterns to avoid
68
+#define EXTI_EMR 0x04
35
# overlap with other insns in the "Advanced SIMD load/store and 64-bit move"
69
+#define EXTI_RTSR 0x08
36
# grouping:
70
+#define EXTI_FTSR 0x0C
37
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
71
+#define EXTI_SWIER 0x10
38
index XXXXXXX..XXXXXXX 100644
72
+#define EXTI_PR 0x14
39
--- a/target/arm/translate-vfp.c.inc
40
+++ b/target/arm/translate-vfp.c.inc
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
42
return true;
43
}
44
45
+static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 value)
46
+{
47
+ arg_vldr_sysreg *a = opaque;
48
+ uint32_t offset = a->imm;
49
+ TCGv_i32 addr;
73
+
50
+
74
+#define TYPE_STM32F4XX_EXTI "stm32f4xx-exti"
51
+ if (!a->a) {
75
+#define STM32F4XX_EXTI(obj) \
52
+ offset = - offset;
76
+ OBJECT_CHECK(STM32F4xxExtiState, (obj), TYPE_STM32F4XX_EXTI)
77
+
78
+#define NUM_GPIO_EVENT_IN_LINES 16
79
+#define NUM_INTERRUPT_OUT_LINES 16
80
+
81
+typedef struct {
82
+ SysBusDevice parent_obj;
83
+
84
+ MemoryRegion mmio;
85
+
86
+ uint32_t exti_imr;
87
+ uint32_t exti_emr;
88
+ uint32_t exti_rtsr;
89
+ uint32_t exti_ftsr;
90
+ uint32_t exti_swier;
91
+ uint32_t exti_pr;
92
+
93
+ qemu_irq irq[NUM_INTERRUPT_OUT_LINES];
94
+} STM32F4xxExtiState;
95
+
96
+#endif
97
diff --git a/hw/misc/stm32f4xx_exti.c b/hw/misc/stm32f4xx_exti.c
98
new file mode 100644
99
index XXXXXXX..XXXXXXX
100
--- /dev/null
101
+++ b/hw/misc/stm32f4xx_exti.c
102
@@ -XXX,XX +XXX,XX @@
103
+/*
104
+ * STM32F4XX EXTI
105
+ *
106
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
107
+ *
108
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
109
+ * of this software and associated documentation files (the "Software"), to deal
110
+ * in the Software without restriction, including without limitation the rights
111
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112
+ * copies of the Software, and to permit persons to whom the Software is
113
+ * furnished to do so, subject to the following conditions:
114
+ *
115
+ * The above copyright notice and this permission notice shall be included in
116
+ * all copies or substantial portions of the Software.
117
+ *
118
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
119
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
120
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
121
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
122
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
123
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
124
+ * THE SOFTWARE.
125
+ */
126
+
127
+#include "qemu/osdep.h"
128
+#include "qemu/log.h"
129
+#include "trace.h"
130
+#include "hw/irq.h"
131
+#include "migration/vmstate.h"
132
+#include "hw/misc/stm32f4xx_exti.h"
133
+
134
+static void stm32f4xx_exti_reset(DeviceState *dev)
135
+{
136
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(dev);
137
+
138
+ s->exti_imr = 0x00000000;
139
+ s->exti_emr = 0x00000000;
140
+ s->exti_rtsr = 0x00000000;
141
+ s->exti_ftsr = 0x00000000;
142
+ s->exti_swier = 0x00000000;
143
+ s->exti_pr = 0x00000000;
144
+}
145
+
146
+static void stm32f4xx_exti_set_irq(void *opaque, int irq, int level)
147
+{
148
+ STM32F4xxExtiState *s = opaque;
149
+
150
+ trace_stm32f4xx_exti_set_irq(irq, level);
151
+
152
+ if (((1 << irq) & s->exti_rtsr) && level) {
153
+ /* Rising Edge */
154
+ s->exti_pr |= 1 << irq;
155
+ }
53
+ }
156
+
54
+
157
+ if (((1 << irq) & s->exti_ftsr) && !level) {
55
+ addr = load_reg(s, a->rn);
158
+ /* Falling Edge */
56
+ if (a->p) {
159
+ s->exti_pr |= 1 << irq;
57
+ tcg_gen_addi_i32(addr, addr, offset);
160
+ }
58
+ }
161
+
59
+
162
+ if (!((1 << irq) & s->exti_imr)) {
60
+ if (s->v8m_stackcheck && a->rn == 13 && a->w) {
163
+ /* Interrupt is masked */
61
+ gen_helper_v8m_stackcheck(cpu_env, addr);
164
+ return;
165
+ }
62
+ }
166
+ qemu_irq_pulse(s->irq[irq]);
167
+}
168
+
63
+
169
+static uint64_t stm32f4xx_exti_read(void *opaque, hwaddr addr,
64
+ gen_aa32_st_i32(s, value, addr, get_mem_index(s),
170
+ unsigned int size)
65
+ MO_UL | MO_ALIGN | s->be_data);
171
+{
66
+ tcg_temp_free_i32(value);
172
+ STM32F4xxExtiState *s = opaque;
173
+
67
+
174
+ trace_stm32f4xx_exti_read(addr);
68
+ if (a->w) {
175
+
69
+ /* writeback */
176
+ switch (addr) {
70
+ if (!a->p) {
177
+ case EXTI_IMR:
71
+ tcg_gen_addi_i32(addr, addr, offset);
178
+ return s->exti_imr;
72
+ }
179
+ case EXTI_EMR:
73
+ store_reg(s, a->rn, addr);
180
+ return s->exti_emr;
74
+ } else {
181
+ case EXTI_RTSR:
75
+ tcg_temp_free_i32(addr);
182
+ return s->exti_rtsr;
183
+ case EXTI_FTSR:
184
+ return s->exti_ftsr;
185
+ case EXTI_SWIER:
186
+ return s->exti_swier;
187
+ case EXTI_PR:
188
+ return s->exti_pr;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "STM32F4XX_exti_read: Bad offset %x\n", (int)addr);
192
+ return 0;
193
+ }
194
+ return 0;
195
+}
196
+
197
+static void stm32f4xx_exti_write(void *opaque, hwaddr addr,
198
+ uint64_t val64, unsigned int size)
199
+{
200
+ STM32F4xxExtiState *s = opaque;
201
+ uint32_t value = (uint32_t) val64;
202
+
203
+ trace_stm32f4xx_exti_write(addr, value);
204
+
205
+ switch (addr) {
206
+ case EXTI_IMR:
207
+ s->exti_imr = value;
208
+ return;
209
+ case EXTI_EMR:
210
+ s->exti_emr = value;
211
+ return;
212
+ case EXTI_RTSR:
213
+ s->exti_rtsr = value;
214
+ return;
215
+ case EXTI_FTSR:
216
+ s->exti_ftsr = value;
217
+ return;
218
+ case EXTI_SWIER:
219
+ s->exti_swier = value;
220
+ return;
221
+ case EXTI_PR:
222
+ /* This bit is cleared by writing a 1 to it */
223
+ s->exti_pr &= ~value;
224
+ return;
225
+ default:
226
+ qemu_log_mask(LOG_GUEST_ERROR,
227
+ "STM32F4XX_exti_write: Bad offset %x\n", (int)addr);
228
+ }
76
+ }
229
+}
77
+}
230
+
78
+
231
+static const MemoryRegionOps stm32f4xx_exti_ops = {
79
+static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque)
232
+ .read = stm32f4xx_exti_read,
80
+{
233
+ .write = stm32f4xx_exti_write,
81
+ arg_vldr_sysreg *a = opaque;
234
+ .endianness = DEVICE_NATIVE_ENDIAN,
82
+ uint32_t offset = a->imm;
235
+};
83
+ TCGv_i32 addr;
84
+ TCGv_i32 value = tcg_temp_new_i32();
236
+
85
+
237
+static void stm32f4xx_exti_init(Object *obj)
86
+ if (!a->a) {
238
+{
87
+ offset = - offset;
239
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(obj);
240
+ int i;
241
+
242
+ for (i = 0; i < NUM_INTERRUPT_OUT_LINES; i++) {
243
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
244
+ }
88
+ }
245
+
89
+
246
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_exti_ops, s,
90
+ addr = load_reg(s, a->rn);
247
+ TYPE_STM32F4XX_EXTI, 0x400);
91
+ if (a->p) {
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
92
+ tcg_gen_addi_i32(addr, addr, offset);
93
+ }
249
+
94
+
250
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_exti_set_irq,
95
+ if (s->v8m_stackcheck && a->rn == 13 && a->w) {
251
+ NUM_GPIO_EVENT_IN_LINES);
96
+ gen_helper_v8m_stackcheck(cpu_env, addr);
97
+ }
98
+
99
+ gen_aa32_ld_i32(s, value, addr, get_mem_index(s),
100
+ MO_UL | MO_ALIGN | s->be_data);
101
+
102
+ if (a->w) {
103
+ /* writeback */
104
+ if (!a->p) {
105
+ tcg_gen_addi_i32(addr, addr, offset);
106
+ }
107
+ store_reg(s, a->rn, addr);
108
+ } else {
109
+ tcg_temp_free_i32(addr);
110
+ }
111
+ return value;
252
+}
112
+}
253
+
113
+
254
+static const VMStateDescription vmstate_stm32f4xx_exti = {
114
+static bool trans_VLDR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
255
+ .name = TYPE_STM32F4XX_EXTI,
115
+{
256
+ .version_id = 1,
116
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
257
+ .minimum_version_id = 1,
117
+ return false;
258
+ .fields = (VMStateField[]) {
259
+ VMSTATE_UINT32(exti_imr, STM32F4xxExtiState),
260
+ VMSTATE_UINT32(exti_emr, STM32F4xxExtiState),
261
+ VMSTATE_UINT32(exti_rtsr, STM32F4xxExtiState),
262
+ VMSTATE_UINT32(exti_ftsr, STM32F4xxExtiState),
263
+ VMSTATE_UINT32(exti_swier, STM32F4xxExtiState),
264
+ VMSTATE_UINT32(exti_pr, STM32F4xxExtiState),
265
+ VMSTATE_END_OF_LIST()
266
+ }
118
+ }
267
+};
119
+ if (a->rn == 15) {
268
+
120
+ return false;
269
+static void stm32f4xx_exti_class_init(ObjectClass *klass, void *data)
121
+ }
270
+{
122
+ return gen_M_fp_sysreg_write(s, a->reg, memory_to_fp_sysreg, a);
271
+ DeviceClass *dc = DEVICE_CLASS(klass);
272
+
273
+ dc->reset = stm32f4xx_exti_reset;
274
+ dc->vmsd = &vmstate_stm32f4xx_exti;
275
+}
123
+}
276
+
124
+
277
+static const TypeInfo stm32f4xx_exti_info = {
125
+static bool trans_VSTR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
278
+ .name = TYPE_STM32F4XX_EXTI,
279
+ .parent = TYPE_SYS_BUS_DEVICE,
280
+ .instance_size = sizeof(STM32F4xxExtiState),
281
+ .instance_init = stm32f4xx_exti_init,
282
+ .class_init = stm32f4xx_exti_class_init,
283
+};
284
+
285
+static void stm32f4xx_exti_register_types(void)
286
+{
126
+{
287
+ type_register_static(&stm32f4xx_exti_info);
127
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
128
+ return false;
129
+ }
130
+ if (a->rn == 15) {
131
+ return false;
132
+ }
133
+ return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_memory, a);
288
+}
134
+}
289
+
135
+
290
+type_init(stm32f4xx_exti_register_types)
136
static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
291
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
137
{
292
index XXXXXXX..XXXXXXX 100644
138
TCGv_i32 tmp;
293
--- a/hw/arm/Kconfig
294
+++ b/hw/arm/Kconfig
295
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
296
bool
297
select ARM_V7M
298
select STM32F4XX_SYSCFG
299
+ select STM32F4XX_EXTI
300
301
config XLNX_ZYNQMP_ARM
302
bool
303
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
304
index XXXXXXX..XXXXXXX 100644
305
--- a/hw/misc/Kconfig
306
+++ b/hw/misc/Kconfig
307
@@ -XXX,XX +XXX,XX @@ config STM32F2XX_SYSCFG
308
config STM32F4XX_SYSCFG
309
bool
310
311
+config STM32F4XX_EXTI
312
+ bool
313
+
314
config MIPS_ITU
315
bool
316
317
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
318
index XXXXXXX..XXXXXXX 100644
319
--- a/hw/misc/trace-events
320
+++ b/hw/misc/trace-events
321
@@ -XXX,XX +XXX,XX @@ stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
322
stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
323
stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
324
325
+# stm32f4xx_exti
326
+stm32f4xx_exti_set_irq(int irq, int leve) "Set EXTI: %d to %d"
327
+stm32f4xx_exti_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
328
+stm32f4xx_exti_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
329
+
330
# tz-mpc.c
331
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
332
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
333
--
139
--
334
2.20.1
140
2.20.1
335
141
336
142
diff view generated by jsdifflib
New patch
1
v8.1M defines a new FP system register FPSCR_nzcvqc; this behaves
2
like the existing FPSCR, except that it reads and writes only bits
3
[31:27] of the FPSCR (the N, Z, C, V and QC flag bits). (Unlike the
4
FPSCR, the special case for Rt=15 of writing the CPSR.NZCV is not
5
permitted.)
1
6
7
Implement the register. Since we don't yet implement MVE, we handle
8
the QC bit as RES0, with todo comments for where we will need to add
9
support later.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20201119215617.29887-11-peter.maydell@linaro.org
14
---
15
target/arm/cpu.h | 13 +++++++++++++
16
target/arm/translate-vfp.c.inc | 27 +++++++++++++++++++++++++++
17
2 files changed, 40 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
24
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
25
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
26
#define FPCR_QC (1 << 27) /* Cumulative saturation bit */
27
+#define FPCR_V (1 << 28) /* FP overflow flag */
28
+#define FPCR_C (1 << 29) /* FP carry flag */
29
+#define FPCR_Z (1 << 30) /* FP zero flag */
30
+#define FPCR_N (1 << 31) /* FP negative flag */
31
+
32
+#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
33
+#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
34
35
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
36
{
37
@@ -XXX,XX +XXX,XX @@ enum arm_cpu_mode {
38
#define ARM_VFP_FPEXC 8
39
#define ARM_VFP_FPINST 9
40
#define ARM_VFP_FPINST2 10
41
+/* These ones are M-profile only */
42
+#define ARM_VFP_FPSCR_NZCVQC 2
43
+#define ARM_VFP_VPR 12
44
+#define ARM_VFP_P0 13
45
+#define ARM_VFP_FPCXT_NS 14
46
+#define ARM_VFP_FPCXT_S 15
47
48
/* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
49
#define QEMU_VFP_FPSCR_NZCV 0xffff
50
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-vfp.c.inc
53
+++ b/target/arm/translate-vfp.c.inc
54
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
55
case ARM_VFP_FPSCR:
56
case QEMU_VFP_FPSCR_NZCV:
57
break;
58
+ case ARM_VFP_FPSCR_NZCVQC:
59
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
60
+ return false;
61
+ }
62
+ break;
63
default:
64
return FPSysRegCheckFailed;
65
}
66
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
67
tcg_temp_free_i32(tmp);
68
gen_lookup_tb(s);
69
break;
70
+ case ARM_VFP_FPSCR_NZCVQC:
71
+ {
72
+ TCGv_i32 fpscr;
73
+ tmp = loadfn(s, opaque);
74
+ /*
75
+ * TODO: when we implement MVE, write the QC bit.
76
+ * For non-MVE, QC is RES0.
77
+ */
78
+ tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
79
+ fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
80
+ tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK);
81
+ tcg_gen_or_i32(fpscr, fpscr, tmp);
82
+ store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
83
+ tcg_temp_free_i32(tmp);
84
+ break;
85
+ }
86
default:
87
g_assert_not_reached();
88
}
89
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
90
gen_helper_vfp_get_fpscr(tmp, cpu_env);
91
storefn(s, opaque, tmp);
92
break;
93
+ case ARM_VFP_FPSCR_NZCVQC:
94
+ /*
95
+ * TODO: MVE has a QC bit, which we probably won't store
96
+ * in the xregs[] field. For non-MVE, where QC is RES0,
97
+ * we can just fall through to the FPSCR_NZCV case.
98
+ */
99
case QEMU_VFP_FPSCR_NZCV:
100
/*
101
* Read just NZCV; this is a special case to avoid the
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
New patch
1
We defined a constant name for the mask of NZCV bits in the FPCR/FPSCR
2
in the previous commit; use it in a couple of places in existing code,
3
where we're masking out everything except NZCV for the "load to Rt=15
4
sets CPSR.NZCV" special case.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201119215617.29887-12-peter.maydell@linaro.org
9
---
10
target/arm/translate-vfp.c.inc | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
18
* helper call for the "VMRS to CPSR.NZCV" insn.
19
*/
20
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
21
- tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
22
+ tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
23
storefn(s, opaque, tmp);
24
break;
25
default:
26
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
27
case ARM_VFP_FPSCR:
28
if (a->rt == 15) {
29
tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
30
- tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
31
+ tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
32
} else {
33
tmp = tcg_temp_new_i32();
34
gen_helper_vfp_get_fpscr(tmp, cpu_env);
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
New patch
1
Factor out the code which handles M-profile lazy FP state preservation
2
from full_vfp_access_check(); accesses to the FPCXT_NS register are
3
a special case which need to do just this part (corresponding in the
4
pseudocode to the PreserveFPState() function), and not the full
5
set of actions matching the pseudocode ExecuteFPCheck() which
6
normal FP instructions need to do.
1
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20201119215617.29887-13-peter.maydell@linaro.org
12
---
13
target/arm/translate-vfp.c.inc | 45 ++++++++++++++++++++--------------
14
1 file changed, 27 insertions(+), 18 deletions(-)
15
16
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.c.inc
19
+++ b/target/arm/translate-vfp.c.inc
20
@@ -XXX,XX +XXX,XX @@ static inline long vfp_f16_offset(unsigned reg, bool top)
21
return offs;
22
}
23
24
+/*
25
+ * Generate code for M-profile lazy FP state preservation if needed;
26
+ * this corresponds to the pseudocode PreserveFPState() function.
27
+ */
28
+static void gen_preserve_fp_state(DisasContext *s)
29
+{
30
+ if (s->v7m_lspact) {
31
+ /*
32
+ * Lazy state saving affects external memory and also the NVIC,
33
+ * so we must mark it as an IO operation for icount (and cause
34
+ * this to be the last insn in the TB).
35
+ */
36
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
37
+ s->base.is_jmp = DISAS_UPDATE_EXIT;
38
+ gen_io_start();
39
+ }
40
+ gen_helper_v7m_preserve_fp_state(cpu_env);
41
+ /*
42
+ * If the preserve_fp_state helper doesn't throw an exception
43
+ * then it will clear LSPACT; we don't need to repeat this for
44
+ * any further FP insns in this TB.
45
+ */
46
+ s->v7m_lspact = false;
47
+ }
48
+}
49
+
50
/*
51
* Check that VFP access is enabled. If it is, do the necessary
52
* M-profile lazy-FP handling and then return true.
53
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
54
/* Handle M-profile lazy FP state mechanics */
55
56
/* Trigger lazy-state preservation if necessary */
57
- if (s->v7m_lspact) {
58
- /*
59
- * Lazy state saving affects external memory and also the NVIC,
60
- * so we must mark it as an IO operation for icount (and cause
61
- * this to be the last insn in the TB).
62
- */
63
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
64
- s->base.is_jmp = DISAS_UPDATE_EXIT;
65
- gen_io_start();
66
- }
67
- gen_helper_v7m_preserve_fp_state(cpu_env);
68
- /*
69
- * If the preserve_fp_state helper doesn't throw an exception
70
- * then it will clear LSPACT; we don't need to repeat this for
71
- * any further FP insns in this TB.
72
- */
73
- s->v7m_lspact = false;
74
- }
75
+ gen_preserve_fp_state(s);
76
77
/* Update ownership of FP context: set FPCCR.S to match current state */
78
if (s->v8m_fpccr_s_wrong) {
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
New patch
1
Implement the new-in-v8.1M FPCXT_S floating point system register.
2
This is for saving and restoring the secure floating point context,
3
and it reads and writes bits [27:0] from the FPSCR and the
4
CONTROL.SFPA bit in bit [31].
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201119215617.29887-14-peter.maydell@linaro.org
9
---
10
target/arm/translate-vfp.c.inc | 58 ++++++++++++++++++++++++++++++++++
11
1 file changed, 58 insertions(+)
12
13
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
18
return false;
19
}
20
break;
21
+ case ARM_VFP_FPCXT_S:
22
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
23
+ return false;
24
+ }
25
+ if (!s->v8m_secure) {
26
+ return false;
27
+ }
28
+ break;
29
default:
30
return FPSysRegCheckFailed;
31
}
32
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
33
tcg_temp_free_i32(tmp);
34
break;
35
}
36
+ case ARM_VFP_FPCXT_S:
37
+ {
38
+ TCGv_i32 sfpa, control, fpscr;
39
+ /* Set FPSCR[27:0] and CONTROL.SFPA from value */
40
+ tmp = loadfn(s, opaque);
41
+ sfpa = tcg_temp_new_i32();
42
+ tcg_gen_shri_i32(sfpa, tmp, 31);
43
+ control = load_cpu_field(v7m.control[M_REG_S]);
44
+ tcg_gen_deposit_i32(control, control, sfpa,
45
+ R_V7M_CONTROL_SFPA_SHIFT, 1);
46
+ store_cpu_field(control, v7m.control[M_REG_S]);
47
+ fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
48
+ tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
49
+ tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
50
+ tcg_gen_or_i32(fpscr, fpscr, tmp);
51
+ store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
52
+ tcg_temp_free_i32(tmp);
53
+ tcg_temp_free_i32(sfpa);
54
+ break;
55
+ }
56
default:
57
g_assert_not_reached();
58
}
59
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
60
tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
61
storefn(s, opaque, tmp);
62
break;
63
+ case ARM_VFP_FPCXT_S:
64
+ {
65
+ TCGv_i32 control, sfpa, fpscr;
66
+ /* Bits [27:0] from FPSCR, bit [31] from CONTROL.SFPA */
67
+ tmp = tcg_temp_new_i32();
68
+ sfpa = tcg_temp_new_i32();
69
+ gen_helper_vfp_get_fpscr(tmp, cpu_env);
70
+ tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
71
+ control = load_cpu_field(v7m.control[M_REG_S]);
72
+ tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
73
+ tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
74
+ tcg_gen_or_i32(tmp, tmp, sfpa);
75
+ tcg_temp_free_i32(sfpa);
76
+ /*
77
+ * Store result before updating FPSCR etc, in case
78
+ * it is a memory write which causes an exception.
79
+ */
80
+ storefn(s, opaque, tmp);
81
+ /*
82
+ * Now we must reset FPSCR from FPDSCR_NS, and clear
83
+ * CONTROL.SFPA; so we'll end the TB here.
84
+ */
85
+ tcg_gen_andi_i32(control, control, ~R_V7M_CONTROL_SFPA_MASK);
86
+ store_cpu_field(control, v7m.control[M_REG_S]);
87
+ fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
88
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
89
+ tcg_temp_free_i32(fpscr);
90
+ gen_lookup_tb(s);
91
+ break;
92
+ }
93
default:
94
g_assert_not_reached();
95
}
96
--
97
2.20.1
98
99
diff view generated by jsdifflib
New patch
1
The FPDSCR register has a similar layout to the FPSCR. In v8.1M it
2
gains new fields FZ16 (if half-precision floating point is supported)
3
and LTPSIZE (always reads as 4). Update the reset value and the code
4
that handles writes to this register accordingly.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201119215617.29887-16-peter.maydell@linaro.org
9
---
10
target/arm/cpu.h | 5 +++++
11
hw/intc/armv7m_nvic.c | 9 ++++++++-
12
target/arm/cpu.c | 3 +++
13
3 files changed, 16 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
20
#define FPCR_IXE (1 << 12) /* Inexact exception trap enable */
21
#define FPCR_IDE (1 << 15) /* Input Denormal exception trap enable */
22
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
23
+#define FPCR_RMODE_MASK (3 << 22) /* Rounding mode */
24
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
25
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
26
+#define FPCR_AHP (1 << 26) /* Alternative half-precision */
27
#define FPCR_QC (1 << 27) /* Cumulative saturation bit */
28
#define FPCR_V (1 << 28) /* FP overflow flag */
29
#define FPCR_C (1 << 29) /* FP carry flag */
30
#define FPCR_Z (1 << 30) /* FP zero flag */
31
#define FPCR_N (1 << 31) /* FP negative flag */
32
33
+#define FPCR_LTPSIZE_SHIFT 16 /* LTPSIZE, M-profile only */
34
+#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
35
+
36
#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
37
#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
38
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
44
break;
45
case 0xf3c: /* FPDSCR */
46
if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
47
- value &= 0x07c00000;
48
+ uint32_t mask = FPCR_AHP | FPCR_DN | FPCR_FZ | FPCR_RMODE_MASK;
49
+ if (cpu_isar_feature(any_fp16, cpu)) {
50
+ mask |= FPCR_FZ16;
51
+ }
52
+ value &= mask;
53
+ if (cpu_isar_feature(aa32_lob, cpu)) {
54
+ value |= 4 << FPCR_LTPSIZE_SHIFT;
55
+ }
56
cpu->env.v7m.fpdscr[attrs.secure] = value;
57
}
58
break;
59
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/cpu.c
62
+++ b/target/arm/cpu.c
63
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
64
* always reset to 4.
65
*/
66
env->v7m.ltpsize = 4;
67
+ /* The LTPSIZE field in FPDSCR is constant and reads as 4. */
68
+ env->v7m.fpdscr[M_REG_NS] = 4 << FPCR_LTPSIZE_SHIFT;
69
+ env->v7m.fpdscr[M_REG_S] = 4 << FPCR_LTPSIZE_SHIFT;
70
}
71
72
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
New patch
1
In v8.0M, on exception entry the registers R0-R3, R12, APSR and EPSR
2
are zeroed for an exception taken to Non-secure state; for an
3
exception taken to Secure state they become UNKNOWN, and we chose to
4
leave them at their previous values.
1
5
6
In v8.1M the behaviour is specified more tightly and these registers
7
are always zeroed regardless of the security state that the exception
8
targets (see rule R_KPZV). Implement this.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20201119215617.29887-17-peter.maydell@linaro.org
13
---
14
target/arm/m_helper.c | 16 ++++++++++++----
15
1 file changed, 12 insertions(+), 4 deletions(-)
16
17
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/m_helper.c
20
+++ b/target/arm/m_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
22
* Clear registers if necessary to prevent non-secure exception
23
* code being able to see register values from secure code.
24
* Where register values become architecturally UNKNOWN we leave
25
- * them with their previous values.
26
+ * them with their previous values. v8.1M is tighter than v8.0M
27
+ * here and always zeroes the caller-saved registers regardless
28
+ * of the security state the exception is targeting.
29
*/
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
31
- if (!targets_secure) {
32
+ if (!targets_secure || arm_feature(env, ARM_FEATURE_V8_1M)) {
33
/*
34
* Always clear the caller-saved registers (they have been
35
* pushed to the stack earlier in v7m_push_stack()).
36
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
37
* v7m_push_callee_stack()).
38
*/
39
int i;
40
+ /*
41
+ * r4..r11 are callee-saves, zero only if background
42
+ * state was Secure (EXCRET.S == 1) and exception
43
+ * targets Non-secure state
44
+ */
45
+ bool zero_callee_saves = !targets_secure &&
46
+ (lr & R_V7M_EXCRET_S_MASK);
47
48
for (i = 0; i < 13; i++) {
49
- /* r4..r11 are callee-saves, zero only if EXCRET.S == 1 */
50
- if (i < 4 || i > 11 || (lr & R_V7M_EXCRET_S_MASK)) {
51
+ if (i < 4 || i > 11 || zero_callee_saves) {
52
env->regs[i] = 0;
53
}
54
}
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
New patch
1
In v8.1M, vector table fetch failures don't set HFSR.FORCED (see rule
2
R_LLRP). (In previous versions of the architecture this was either
3
required or IMPDEF.)
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201119215617.29887-18-peter.maydell@linaro.org
8
---
9
target/arm/m_helper.c | 6 +++++-
10
1 file changed, 5 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/m_helper.c
15
+++ b/target/arm/m_helper.c
16
@@ -XXX,XX +XXX,XX @@ load_fail:
17
* The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
18
* secure); otherwise it targets the same security state as the
19
* underlying exception.
20
+ * In v8.1M HardFaults from vector table fetch fails don't set FORCED.
21
*/
22
if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
23
exc_secure = true;
24
}
25
- env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
26
+ env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK;
27
+ if (!arm_feature(env, ARM_FEATURE_V8_1M)) {
28
+ env->v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
29
+ }
30
armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
31
return false;
32
}
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
New patch
1
In v8.1M a REVIDR register is defined, which is at address 0xe00ecfc
2
and is a read-only IMPDEF register providing implementation specific
3
minor revision information, like the v8A REVIDR_EL1. Implement this.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201119215617.29887-19-peter.maydell@linaro.org
8
---
9
hw/intc/armv7m_nvic.c | 5 +++++
10
1 file changed, 5 insertions(+)
11
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
+++ b/hw/intc/armv7m_nvic.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
}
18
return val;
19
}
20
+ case 0xcfc:
21
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8_1M)) {
22
+ goto bad_offset;
23
+ }
24
+ return cpu->revidr;
25
case 0xd00: /* CPUID Base. */
26
return cpu->midr;
27
case 0xd04: /* Interrupt Control State (ICSR) */
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
New patch
1
In v8.1M a new exception return check is added which may cause a NOCP
2
UsageFault (see rule R_XLTP): before we clear s0..s15 and the FPSCR
3
we must check whether access to CP10 from the Security state of the
4
returning exception is disabled; if it is then we must take a fault.
1
5
6
(Note that for our implementation CPPWR is always RAZ/WI and so can
7
never cause CP10 accesses to fail.)
8
9
The other v8.1M change to this register-clearing code is that if MVE
10
is implemented VPR must also be cleared, so add a TODO comment to
11
that effect.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20201119215617.29887-20-peter.maydell@linaro.org
16
---
17
target/arm/m_helper.c | 22 +++++++++++++++++++++-
18
1 file changed, 21 insertions(+), 1 deletion(-)
19
20
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/m_helper.c
23
+++ b/target/arm/m_helper.c
24
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
25
v7m_exception_taken(cpu, excret, true, false);
26
return;
27
} else {
28
- /* Clear s0..s15 and FPSCR */
29
+ if (arm_feature(env, ARM_FEATURE_V8_1M)) {
30
+ /* v8.1M adds this NOCP check */
31
+ bool nsacr_pass = exc_secure ||
32
+ extract32(env->v7m.nsacr, 10, 1);
33
+ bool cpacr_pass = v7m_cpacr_pass(env, exc_secure, true);
34
+ if (!nsacr_pass) {
35
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
36
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
37
+ qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
38
+ "stackframe: NSACR prevents clearing FPU registers\n");
39
+ v7m_exception_taken(cpu, excret, true, false);
40
+ } else if (!cpacr_pass) {
41
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
42
+ exc_secure);
43
+ env->v7m.cfsr[exc_secure] |= R_V7M_CFSR_NOCP_MASK;
44
+ qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
45
+ "stackframe: CPACR prevents clearing FPU registers\n");
46
+ v7m_exception_taken(cpu, excret, true, false);
47
+ }
48
+ }
49
+ /* Clear s0..s15 and FPSCR; TODO also VPR when MVE is implemented */
50
int i;
51
52
for (i = 0; i < 16; i += 2) {
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
New patch
1
v8.1M adds new encodings of VLLDM and VLSTM (where bit 7 is set).
2
The only difference is that:
3
* the old T1 encodings UNDEF if the implementation implements 32
4
Dregs (this is currently architecturally impossible for M-profile)
5
* the new T2 encodings have the implementation-defined option to
6
read from memory (discarding the data) or write UNKNOWN values to
7
memory for the stack slots that would be D16-D31
1
8
9
We choose not to make those accesses, so for us the two
10
instructions behave identically assuming they don't UNDEF.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20201119215617.29887-21-peter.maydell@linaro.org
15
---
16
target/arm/m-nocp.decode | 2 +-
17
target/arm/translate-vfp.c.inc | 25 +++++++++++++++++++++++++
18
2 files changed, 26 insertions(+), 1 deletion(-)
19
20
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/m-nocp.decode
23
+++ b/target/arm/m-nocp.decode
24
@@ -XXX,XX +XXX,XX @@
25
26
{
27
# Special cases which do not take an early NOCP: VLLDM and VLSTM
28
- VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 0000 0000
29
+ VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 op:1 000 0000
30
# VSCCLRM (new in v8.1M) is similar:
31
VSCCLRM 1110 1100 1.01 1111 .... 1011 imm:7 0 vd=%vd_dp size=3
32
VSCCLRM 1110 1100 1.01 1111 .... 1010 imm:8 vd=%vd_sp size=2
33
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-vfp.c.inc
36
+++ b/target/arm/translate-vfp.c.inc
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
38
!arm_dc_feature(s, ARM_FEATURE_V8)) {
39
return false;
40
}
41
+
42
+ if (a->op) {
43
+ /*
44
+ * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
45
+ * to take the IMPDEF option to make memory accesses to the stack
46
+ * slots that correspond to the D16-D31 registers (discarding
47
+ * read data and writing UNKNOWN values), so for us the T2
48
+ * encoding behaves identically to the T1 encoding.
49
+ */
50
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
51
+ return false;
52
+ }
53
+ } else {
54
+ /*
55
+ * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
56
+ * This is currently architecturally impossible, but we add the
57
+ * check to stay in line with the pseudocode. Note that we must
58
+ * emit code for the UNDEF so it takes precedence over the NOCP.
59
+ */
60
+ if (dc_isar_feature(aa32_simd_r32, s)) {
61
+ unallocated_encoding(s);
62
+ return true;
63
+ }
64
+ }
65
+
66
/*
67
* If not secure, UNDEF. We must emit code for this
68
* rather than returning false so that this takes
69
--
70
2.20.1
71
72
diff view generated by jsdifflib
New patch
1
v8.1M introduces a new TRD flag in the CCR register, which enables
2
checking for stack frame integrity signatures on SG instructions.
3
This bit is not banked, and is always RAZ/WI to Non-secure code.
4
Adjust the code for handling CCR reads and writes to handle this.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201119215617.29887-23-peter.maydell@linaro.org
9
---
10
target/arm/cpu.h | 2 ++
11
hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++--------
12
2 files changed, 20 insertions(+), 8 deletions(-)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CCR, STKOFHFNMIGN, 10, 1)
19
FIELD(V7M_CCR, DC, 16, 1)
20
FIELD(V7M_CCR, IC, 17, 1)
21
FIELD(V7M_CCR, BP, 18, 1)
22
+FIELD(V7M_CCR, LOB, 19, 1)
23
+FIELD(V7M_CCR, TRD, 20, 1)
24
25
/* V7M SCR bits */
26
FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
27
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/armv7m_nvic.c
30
+++ b/hw/intc/armv7m_nvic.c
31
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
32
}
33
return cpu->env.v7m.scr[attrs.secure];
34
case 0xd14: /* Configuration Control. */
35
- /* The BFHFNMIGN bit is the only non-banked bit; we
36
- * keep it in the non-secure copy of the register.
37
+ /*
38
+ * Non-banked bits: BFHFNMIGN (stored in the NS copy of the register)
39
+ * and TRD (stored in the S copy of the register)
40
*/
41
val = cpu->env.v7m.ccr[attrs.secure];
42
val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
43
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
44
cpu->env.v7m.scr[attrs.secure] = value;
45
break;
46
case 0xd14: /* Configuration Control. */
47
+ {
48
+ uint32_t mask;
49
+
50
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
51
goto bad_offset;
52
}
53
54
/* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
55
- value &= (R_V7M_CCR_STKALIGN_MASK |
56
- R_V7M_CCR_BFHFNMIGN_MASK |
57
- R_V7M_CCR_DIV_0_TRP_MASK |
58
- R_V7M_CCR_UNALIGN_TRP_MASK |
59
- R_V7M_CCR_USERSETMPEND_MASK |
60
- R_V7M_CCR_NONBASETHRDENA_MASK);
61
+ mask = R_V7M_CCR_STKALIGN_MASK |
62
+ R_V7M_CCR_BFHFNMIGN_MASK |
63
+ R_V7M_CCR_DIV_0_TRP_MASK |
64
+ R_V7M_CCR_UNALIGN_TRP_MASK |
65
+ R_V7M_CCR_USERSETMPEND_MASK |
66
+ R_V7M_CCR_NONBASETHRDENA_MASK;
67
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8_1M) && attrs.secure) {
68
+ /* TRD is always RAZ/WI from NS */
69
+ mask |= R_V7M_CCR_TRD_MASK;
70
+ }
71
+ value &= mask;
72
73
if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
74
/* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
75
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
76
77
cpu->env.v7m.ccr[attrs.secure] = value;
78
break;
79
+ }
80
case 0xd24: /* System Handler Control and State (SHCSR) */
81
if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
82
goto bad_offset;
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
New patch
1
v8.1M introduces a new TRD flag in the CCR register, which enables
2
checking for stack frame integrity signatures on SG instructions.
3
Add the code in the SG insn implementation for the new behaviour.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201119215617.29887-24-peter.maydell@linaro.org
8
---
9
target/arm/m_helper.c | 86 +++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 86 insertions(+)
11
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/m_helper.c
15
+++ b/target/arm/m_helper.c
16
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
17
return true;
18
}
19
20
+static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
21
+ uint32_t addr, uint32_t *spdata)
22
+{
23
+ /*
24
+ * Read a word of data from the stack for the SG instruction,
25
+ * writing the value into *spdata. If the load succeeds, return
26
+ * true; otherwise pend an appropriate exception and return false.
27
+ * (We can't use data load helpers here that throw an exception
28
+ * because of the context we're called in, which is halfway through
29
+ * arm_v7m_cpu_do_interrupt().)
30
+ */
31
+ CPUState *cs = CPU(cpu);
32
+ CPUARMState *env = &cpu->env;
33
+ MemTxAttrs attrs = {};
34
+ MemTxResult txres;
35
+ target_ulong page_size;
36
+ hwaddr physaddr;
37
+ int prot;
38
+ ARMMMUFaultInfo fi = {};
39
+ ARMCacheAttrs cacheattrs = {};
40
+ uint32_t value;
41
+
42
+ if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
43
+ &attrs, &prot, &page_size, &fi, &cacheattrs)) {
44
+ /* MPU/SAU lookup failed */
45
+ if (fi.type == ARMFault_QEMU_SFault) {
46
+ qemu_log_mask(CPU_LOG_INT,
47
+ "...SecureFault during stack word read\n");
48
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
49
+ env->v7m.sfar = addr;
50
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
51
+ } else {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...MemManageFault during stack word read\n");
54
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_DACCVIOL_MASK |
55
+ R_V7M_CFSR_MMARVALID_MASK;
56
+ env->v7m.mmfar[M_REG_S] = addr;
57
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, false);
58
+ }
59
+ return false;
60
+ }
61
+ value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
62
+ attrs, &txres);
63
+ if (txres != MEMTX_OK) {
64
+ /* BusFault trying to read the data */
65
+ qemu_log_mask(CPU_LOG_INT,
66
+ "...BusFault during stack word read\n");
67
+ env->v7m.cfsr[M_REG_NS] |=
68
+ (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
69
+ env->v7m.bfar = addr;
70
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
71
+ return false;
72
+ }
73
+
74
+ *spdata = value;
75
+ return true;
76
+}
77
+
78
static bool v7m_handle_execute_nsc(ARMCPU *cpu)
79
{
80
/*
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
82
*/
83
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
84
", executing it\n", env->regs[15]);
85
+
86
+ if (cpu_isar_feature(aa32_m_sec_state, cpu) &&
87
+ !arm_v7m_is_handler_mode(env)) {
88
+ /*
89
+ * v8.1M exception stack frame integrity check. Note that we
90
+ * must perform the memory access even if CCR_S.TRD is zero
91
+ * and we aren't going to check what the data loaded is.
92
+ */
93
+ uint32_t spdata, sp;
94
+
95
+ /*
96
+ * We know we are currently NS, so the S stack pointers must be
97
+ * in other_ss_{psp,msp}, not in regs[13]/other_sp.
98
+ */
99
+ sp = v7m_using_psp(env) ? env->v7m.other_ss_psp : env->v7m.other_ss_msp;
100
+ if (!v7m_read_sg_stack_word(cpu, mmu_idx, sp, &spdata)) {
101
+ /* Stack access failed and an exception has been pended */
102
+ return false;
103
+ }
104
+
105
+ if (env->v7m.ccr[M_REG_S] & R_V7M_CCR_TRD_MASK) {
106
+ if (((spdata & ~1) == 0xfefa125a) ||
107
+ !(env->v7m.control[M_REG_S] & 1)) {
108
+ goto gen_invep;
109
+ }
110
+ }
111
+ }
112
+
113
env->regs[14] &= ~1;
114
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
115
switch_v7m_security_state(env, true);
116
--
117
2.20.1
118
119
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
In commit 077d7449100d824a4 we added code to handle the v8M
2
requirement that returns from NMI or HardFault forcibly deactivate
3
those exceptions regardless of what interrupt the guest is trying to
4
deactivate. Unfortunately this broke the handling of the "illegal
5
exception return because the returning exception number is not
6
active" check for those cases. In the pseudocode this test is done
7
on the exception the guest asks to return from, but because our
8
implementation was doing this in armv7m_nvic_complete_irq() after the
9
new "deactivate NMI/HardFault regardless" code we ended up doing the
10
test on the VecInfo for that exception instead, which usually meant
11
failing to raise the illegal exception return fault.
2
12
3
We won't reuse the CPU IRQ/FIQ variables. Simplify by calling
13
In the case for "configurable exception targeting the opposite
4
qdev_get_gpio_in() in place.
14
security state" we detected the illegal-return case but went ahead
15
and deactivated the VecInfo anyway, which is wrong because that is
16
the VecInfo for the other security state.
5
17
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Rearrange the code so that we first identify the illegal return
7
Message-id: 20191230110953.25496-6-f4bug@amsat.org
19
cases, then see if we really need to deactivate NMI or HardFault
20
instead, and finally do the deactivation.
21
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20201119215617.29887-25-peter.maydell@linaro.org
10
---
25
---
11
hw/arm/allwinner-a10.c | 9 ++++-----
26
hw/intc/armv7m_nvic.c | 59 +++++++++++++++++++++++--------------------
12
1 file changed, 4 insertions(+), 5 deletions(-)
27
1 file changed, 32 insertions(+), 27 deletions(-)
13
28
14
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
29
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/allwinner-a10.c
31
--- a/hw/intc/armv7m_nvic.c
17
+++ b/hw/arm/allwinner-a10.c
32
+++ b/hw/intc/armv7m_nvic.c
18
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
33
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
19
{
34
{
20
AwA10State *s = AW_A10(dev);
35
NVICState *s = (NVICState *)opaque;
21
SysBusDevice *sysbusdev;
36
VecInfo *vec = NULL;
22
- qemu_irq fiq, irq;
37
- int ret;
23
Error *err = NULL;
38
+ int ret = 0;
24
39
25
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
40
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
26
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
41
27
error_propagate(errp, err);
42
+ trace_nvic_complete_irq(irq, secure);
28
return;
43
+
44
+ if (secure && exc_is_banked(irq)) {
45
+ vec = &s->sec_vectors[irq];
46
+ } else {
47
+ vec = &s->vectors[irq];
48
+ }
49
+
50
+ /*
51
+ * Identify illegal exception return cases. We can't immediately
52
+ * return at this point because we still need to deactivate
53
+ * (either this exception or NMI/HardFault) first.
54
+ */
55
+ if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
56
+ /*
57
+ * Return from a configurable exception targeting the opposite
58
+ * security state from the one we're trying to complete it for.
59
+ * Clear vec because it's not really the VecInfo for this
60
+ * (irq, secstate) so we mustn't deactivate it.
61
+ */
62
+ ret = -1;
63
+ vec = NULL;
64
+ } else if (!vec->active) {
65
+ /* Return from an inactive interrupt */
66
+ ret = -1;
67
+ } else {
68
+ /* Legal return, we will return the RETTOBASE bit value to the caller */
69
+ ret = nvic_rettobase(s);
70
+ }
71
+
72
/*
73
* For negative priorities, v8M will forcibly deactivate the appropriate
74
* NMI or HardFault regardless of what interrupt we're being asked to
75
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
29
}
76
}
30
- irq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ);
77
31
- fiq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ);
78
if (!vec) {
32
79
- if (secure && exc_is_banked(irq)) {
33
object_property_set_bool(OBJECT(&s->intc), true, "realized", &err);
80
- vec = &s->sec_vectors[irq];
34
if (err != NULL) {
81
- } else {
35
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
82
- vec = &s->vectors[irq];
83
- }
84
- }
85
-
86
- trace_nvic_complete_irq(irq, secure);
87
-
88
- if (!vec->active) {
89
- /* Tell the caller this was an illegal exception return */
90
- return -1;
91
- }
92
-
93
- /*
94
- * If this is a configurable exception and it is currently
95
- * targeting the opposite security state from the one we're trying
96
- * to complete it for, this counts as an illegal exception return.
97
- * We still need to deactivate whatever vector the logic above has
98
- * selected, though, as it might not be the same as the one for the
99
- * requested exception number.
100
- */
101
- if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
102
- ret = -1;
103
- } else {
104
- ret = nvic_rettobase(s);
105
+ return ret;
36
}
106
}
37
sysbusdev = SYS_BUS_DEVICE(&s->intc);
107
38
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
108
vec->active = 0;
39
- sysbus_connect_irq(sysbusdev, 0, irq);
40
- sysbus_connect_irq(sysbusdev, 1, fiq);
41
+ sysbus_connect_irq(sysbusdev, 0,
42
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
43
+ sysbus_connect_irq(sysbusdev, 1,
44
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
45
qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
46
47
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
48
--
109
--
49
2.20.1
110
2.20.1
50
111
51
112
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
For v8.1M the architecture mandates that CPUs must provide at
2
least the "minimal RAS implementation" from the Reliability,
3
Availability and Serviceability extension. This consists of:
4
* an ESB instruction which is a NOP
5
-- since it is in the HINT space we need only add a comment
6
* an RFSR register which will RAZ/WI
7
* a RAZ/WI AIRCR.IESB bit
8
-- the code which handles writes to AIRCR does not allow setting
9
of RES0 bits, so we already treat this as RAZ/WI; add a comment
10
noting that this is deliberate
11
* minimal implementation of the RAS register block at 0xe0005000
12
-- this will be in a subsequent commit
13
* setting the ID_PFR0.RAS field to 0b0010
14
-- we will do this when we add the Cortex-M55 CPU model
2
15
3
These definitions are specific to the A10 SoC and don't need
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to be exported to the different Allwinner peripherals.
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20201119215617.29887-26-peter.maydell@linaro.org
19
---
20
target/arm/cpu.h | 14 ++++++++++++++
21
target/arm/t32.decode | 4 ++++
22
hw/intc/armv7m_nvic.c | 13 +++++++++++++
23
3 files changed, 31 insertions(+)
5
24
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
Message-id: 20191230110953.25496-4-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/allwinner-a10.h | 6 ------
12
hw/arm/allwinner-a10.c | 6 ++++++
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-a10.h
27
--- a/target/arm/cpu.h
18
+++ b/include/hw/arm/allwinner-a10.h
28
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ FIELD(ID_MMFR4, LSM, 20, 4)
20
#include "target/arm/cpu.h"
30
FIELD(ID_MMFR4, CCIDX, 24, 4)
21
31
FIELD(ID_MMFR4, EVT, 28, 4)
22
32
23
-#define AW_A10_PIC_REG_BASE 0x01c20400
33
+FIELD(ID_PFR0, STATE0, 0, 4)
24
-#define AW_A10_PIT_REG_BASE 0x01c20c00
34
+FIELD(ID_PFR0, STATE1, 4, 4)
25
-#define AW_A10_UART0_REG_BASE 0x01c28000
35
+FIELD(ID_PFR0, STATE2, 8, 4)
26
-#define AW_A10_EMAC_BASE 0x01c0b000
36
+FIELD(ID_PFR0, STATE3, 12, 4)
27
-#define AW_A10_SATA_BASE 0x01c18000
37
+FIELD(ID_PFR0, CSV2, 16, 4)
28
-
38
+FIELD(ID_PFR0, AMU, 20, 4)
29
#define AW_A10_SDRAM_BASE 0x40000000
39
+FIELD(ID_PFR0, DIT, 24, 4)
30
40
+FIELD(ID_PFR0, RAS, 28, 4)
31
#define TYPE_AW_A10 "allwinner-a10"
41
+
32
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
42
FIELD(ID_PFR1, PROGMOD, 0, 4)
43
FIELD(ID_PFR1, SECURITY, 4, 4)
44
FIELD(ID_PFR1, MPROGMOD, 8, 4)
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
46
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
47
}
48
49
+static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
50
+{
51
+ return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
52
+}
53
+
54
static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
55
{
56
return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
57
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
33
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/allwinner-a10.c
59
--- a/target/arm/t32.decode
35
+++ b/hw/arm/allwinner-a10.c
60
+++ b/target/arm/t32.decode
36
@@ -XXX,XX +XXX,XX @@
61
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
37
#include "hw/misc/unimp.h"
62
# SEV 1111 0011 1010 1111 1000 0000 0000 0100
38
#include "sysemu/sysemu.h"
63
# SEVL 1111 0011 1010 1111 1000 0000 0000 0101
39
64
40
+#define AW_A10_PIC_REG_BASE 0x01c20400
65
+ # For M-profile minimal-RAS ESB can be a NOP, which is the
41
+#define AW_A10_PIT_REG_BASE 0x01c20c00
66
+ # default behaviour since it is in the hint space.
42
+#define AW_A10_UART0_REG_BASE 0x01c28000
67
+ # ESB 1111 0011 1010 1111 1000 0000 0001 0000
43
+#define AW_A10_EMAC_BASE 0x01c0b000
44
+#define AW_A10_SATA_BASE 0x01c18000
45
+
68
+
46
static void aw_a10_init(Object *obj)
69
# The canonical nop ends in 0000 0000, but the whole rest
47
{
70
# of the space is "reserved hint, behaves as nop".
48
AwA10State *s = AW_A10(obj);
71
NOP 1111 0011 1010 1111 1000 0000 ---- ----
72
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/intc/armv7m_nvic.c
75
+++ b/hw/intc/armv7m_nvic.c
76
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
77
return 0;
78
}
79
return cpu->env.v7m.sfar;
80
+ case 0xf04: /* RFSR */
81
+ if (!cpu_isar_feature(aa32_ras, cpu)) {
82
+ goto bad_offset;
83
+ }
84
+ /* We provide minimal-RAS only: RFSR is RAZ/WI */
85
+ return 0;
86
case 0xf34: /* FPCCR */
87
if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
88
return 0;
89
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
90
R_V7M_AIRCR_PRIGROUP_SHIFT,
91
R_V7M_AIRCR_PRIGROUP_LENGTH);
92
}
93
+ /* AIRCR.IESB is RAZ/WI because we implement only minimal RAS */
94
if (attrs.secure) {
95
/* These bits are only writable by secure */
96
cpu->env.v7m.aircr = value &
97
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
98
}
99
break;
100
}
101
+ case 0xf04: /* RFSR */
102
+ if (!cpu_isar_feature(aa32_ras, cpu)) {
103
+ goto bad_offset;
104
+ }
105
+ /* We provide minimal-RAS only: RFSR is RAZ/WI */
106
+ break;
107
case 0xf34: /* FPCCR */
108
if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
109
/* Not all bits here are banked. */
49
--
110
--
50
2.20.1
111
2.20.1
51
112
52
113
diff view generated by jsdifflib
1
From: Martin Kaiser <martin@kaiser.cx>
1
The RAS feature has a block of memory-mapped registers at offset
2
0x5000 within the PPB. For a "minimal RAS" implementation we provide
3
no error records and so the only registers that exist in the block
4
are ERRIIDR and ERRDEVID.
2
5
3
Add an emulation for the RNGC random number generator and the compatible
6
The "RAZ/WI for privileged, BusFault for nonprivileged" behaviour
4
RNGB variant. These peripherals are included (at least) in imx25 and
7
of the "nvic-default" region is actually valid for minimal-RAS,
5
imx35 chipsets.
8
so the main benefit of providing an explicit implementation of
9
the register block is more accurate LOG_UNIMP messages, and a
10
framework for where we could add a real RAS implementation later
11
if necessary.
6
12
7
The emulation supports the initial self test, reseeding the prng and
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
reading random numbers.
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20201119215617.29887-27-peter.maydell@linaro.org
16
---
17
include/hw/intc/armv7m_nvic.h | 1 +
18
hw/intc/armv7m_nvic.c | 56 +++++++++++++++++++++++++++++++++++
19
2 files changed, 57 insertions(+)
9
20
10
Signed-off-by: Martin Kaiser <martin@kaiser.cx>
21
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/misc/Makefile.objs | 1 +
15
include/hw/arm/fsl-imx25.h | 5 +
16
include/hw/misc/imx_rngc.h | 35 +++++
17
hw/arm/fsl-imx25.c | 11 ++
18
hw/misc/imx_rngc.c | 278 +++++++++++++++++++++++++++++++++++++
19
5 files changed, 330 insertions(+)
20
create mode 100644 include/hw/misc/imx_rngc.h
21
create mode 100644 hw/misc/imx_rngc.c
22
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/Makefile.objs
23
--- a/include/hw/intc/armv7m_nvic.h
26
+++ b/hw/misc/Makefile.objs
24
+++ b/include/hw/intc/armv7m_nvic.h
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_IMX) += imx7_ccm.o
25
@@ -XXX,XX +XXX,XX @@ struct NVICState {
28
common-obj-$(CONFIG_IMX) += imx2_wdt.o
26
MemoryRegion sysreg_ns_mem;
29
common-obj-$(CONFIG_IMX) += imx7_snvs.o
27
MemoryRegion systickmem;
30
common-obj-$(CONFIG_IMX) += imx7_gpr.o
28
MemoryRegion systick_ns_mem;
31
+common-obj-$(CONFIG_IMX) += imx_rngc.o
29
+ MemoryRegion ras_mem;
32
common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
30
MemoryRegion container;
33
common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
31
MemoryRegion defaultmem;
34
common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
32
35
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
33
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
36
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/arm/fsl-imx25.h
35
--- a/hw/intc/armv7m_nvic.c
38
+++ b/include/hw/arm/fsl-imx25.h
36
+++ b/hw/intc/armv7m_nvic.c
39
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvic_systick_ops = {
40
#include "hw/timer/imx_gpt.h"
38
.endianness = DEVICE_NATIVE_ENDIAN,
41
#include "hw/timer/imx_epit.h"
39
};
42
#include "hw/net/imx_fec.h"
40
43
+#include "hw/misc/imx_rngc.h"
44
#include "hw/i2c/imx_i2c.h"
45
#include "hw/gpio/imx_gpio.h"
46
#include "exec/memory.h"
47
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
48
IMXGPTState gpt[FSL_IMX25_NUM_GPTS];
49
IMXEPITState epit[FSL_IMX25_NUM_EPITS];
50
IMXFECState fec;
51
+ IMXRNGCState rngc;
52
IMXI2CState i2c[FSL_IMX25_NUM_I2CS];
53
IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS];
54
MemoryRegion rom[2];
55
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
56
#define FSL_IMX25_GPIO4_SIZE 0x4000
57
#define FSL_IMX25_GPIO3_ADDR 0x53FA4000
58
#define FSL_IMX25_GPIO3_SIZE 0x4000
59
+#define FSL_IMX25_RNGC_ADDR 0x53FB0000
60
+#define FSL_IMX25_RNGC_SIZE 0x4000
61
#define FSL_IMX25_GPIO1_ADDR 0x53FCC000
62
#define FSL_IMX25_GPIO1_SIZE 0x4000
63
#define FSL_IMX25_GPIO2_ADDR 0x53FD0000
64
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
65
#define FSL_IMX25_EPIT1_IRQ 28
66
#define FSL_IMX25_EPIT2_IRQ 27
67
#define FSL_IMX25_FEC_IRQ 57
68
+#define FSL_IMX25_RNGC_IRQ 22
69
#define FSL_IMX25_I2C1_IRQ 3
70
#define FSL_IMX25_I2C2_IRQ 4
71
#define FSL_IMX25_I2C3_IRQ 10
72
diff --git a/include/hw/misc/imx_rngc.h b/include/hw/misc/imx_rngc.h
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/include/hw/misc/imx_rngc.h
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * Freescale i.MX RNGC emulation
80
+ *
81
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
82
+ *
83
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
84
+ * See the COPYING file in the top-level directory.
85
+ */
86
+
41
+
87
+#ifndef IMX_RNGC_H
42
+static MemTxResult ras_read(void *opaque, hwaddr addr,
88
+#define IMX_RNGC_H
43
+ uint64_t *data, unsigned size,
44
+ MemTxAttrs attrs)
45
+{
46
+ if (attrs.user) {
47
+ return MEMTX_ERROR;
48
+ }
89
+
49
+
90
+#include "hw/sysbus.h"
50
+ switch (addr) {
91
+
51
+ case 0xe10: /* ERRIIDR */
92
+#define TYPE_IMX_RNGC "imx.rngc"
52
+ /* architect field = Arm; product/variant/revision 0 */
93
+#define IMX_RNGC(obj) OBJECT_CHECK(IMXRNGCState, (obj), TYPE_IMX_RNGC)
53
+ *data = 0x43b;
94
+
95
+typedef struct IMXRNGCState {
96
+ /*< private >*/
97
+ SysBusDevice parent_obj;
98
+
99
+ /*< public >*/
100
+ MemoryRegion iomem;
101
+
102
+ uint8_t op_self_test;
103
+ uint8_t op_seed;
104
+ uint8_t mask;
105
+ bool auto_seed;
106
+
107
+ QEMUBH *self_test_bh;
108
+ QEMUBH *seed_bh;
109
+ qemu_irq irq;
110
+} IMXRNGCState;
111
+
112
+#endif /* IMX_RNGC_H */
113
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/arm/fsl-imx25.c
116
+++ b/hw/arm/fsl-imx25.c
117
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
118
119
sysbus_init_child_obj(obj, "fec", &s->fec, sizeof(s->fec), TYPE_IMX_FEC);
120
121
+ sysbus_init_child_obj(obj, "rngc", &s->rngc, sizeof(s->rngc),
122
+ TYPE_IMX_RNGC);
123
+
124
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
125
sysbus_init_child_obj(obj, "i2c[*]", &s->i2c[i], sizeof(s->i2c[i]),
126
TYPE_IMX_I2C);
127
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
128
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
129
qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
130
131
+ object_property_set_bool(OBJECT(&s->rngc), true, "realized", &err);
132
+ if (err) {
133
+ error_propagate(errp, err);
134
+ return;
135
+ }
136
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->rngc), 0, FSL_IMX25_RNGC_ADDR);
137
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rngc), 0,
138
+ qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_RNGC_IRQ));
139
140
/* Initialize all I2C */
141
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
142
diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
146
+++ b/hw/misc/imx_rngc.c
147
@@ -XXX,XX +XXX,XX @@
148
+/*
149
+ * Freescale i.MX RNGC emulation
150
+ *
151
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
152
+ *
153
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
154
+ * See the COPYING file in the top-level directory.
155
+ *
156
+ * This driver provides the minimum functionality to initialize and seed
157
+ * an rngc and to read random numbers. The rngb that is found in imx25
158
+ * chipsets is also supported.
159
+ */
160
+
161
+#include "qemu/osdep.h"
162
+#include "qemu/main-loop.h"
163
+#include "qemu/module.h"
164
+#include "qemu/log.h"
165
+#include "qemu/guest-random.h"
166
+#include "hw/irq.h"
167
+#include "hw/misc/imx_rngc.h"
168
+#include "migration/vmstate.h"
169
+
170
+#define RNGC_NAME "i.MX RNGC"
171
+
172
+#define RNGC_VER_ID 0x00
173
+#define RNGC_COMMAND 0x04
174
+#define RNGC_CONTROL 0x08
175
+#define RNGC_STATUS 0x0C
176
+#define RNGC_FIFO 0x14
177
+
178
+/* These version info are reported by the rngb in an imx258 chip. */
179
+#define RNG_TYPE_RNGB 0x1
180
+#define V_MAJ 0x2
181
+#define V_MIN 0x40
182
+
183
+#define RNGC_CMD_BIT_SW_RST 0x40
184
+#define RNGC_CMD_BIT_CLR_ERR 0x20
185
+#define RNGC_CMD_BIT_CLR_INT 0x10
186
+#define RNGC_CMD_BIT_SEED 0x02
187
+#define RNGC_CMD_BIT_SELF_TEST 0x01
188
+
189
+#define RNGC_CTRL_BIT_MASK_ERR 0x40
190
+#define RNGC_CTRL_BIT_MASK_DONE 0x20
191
+#define RNGC_CTRL_BIT_AUTO_SEED 0x10
192
+
193
+/* the current status for self-test and seed operations */
194
+#define OP_IDLE 0
195
+#define OP_RUN 1
196
+#define OP_DONE 2
197
+
198
+static uint64_t imx_rngc_read(void *opaque, hwaddr offset, unsigned size)
199
+{
200
+ IMXRNGCState *s = IMX_RNGC(opaque);
201
+ uint64_t val = 0;
202
+
203
+ switch (offset) {
204
+ case RNGC_VER_ID:
205
+ val |= RNG_TYPE_RNGB << 28 | V_MAJ << 8 | V_MIN;
206
+ break;
54
+ break;
207
+
55
+ case 0xfc8: /* ERRDEVID */
208
+ case RNGC_COMMAND:
56
+ /* Minimal RAS: we implement 0 error record indexes */
209
+ if (s->op_seed == OP_RUN) {
57
+ *data = 0;
210
+ val |= RNGC_CMD_BIT_SEED;
211
+ }
212
+ if (s->op_self_test == OP_RUN) {
213
+ val |= RNGC_CMD_BIT_SELF_TEST;
214
+ }
215
+ break;
58
+ break;
216
+
59
+ default:
217
+ case RNGC_CONTROL:
60
+ qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
218
+ /*
61
+ (uint32_t)addr);
219
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
62
+ *data = 0;
220
+ * They read as 0.
221
+ */
222
+ val |= s->mask;
223
+ if (s->auto_seed) {
224
+ val |= RNGC_CTRL_BIT_AUTO_SEED;
225
+ }
226
+ /*
227
+ * We don't have an internal fifo like the real hardware.
228
+ * There's no need for strategy to handle fifo underflows.
229
+ * We return the FIFO_UFLOW_RESPONSE bits as 0.
230
+ */
231
+ break;
232
+
233
+ case RNGC_STATUS:
234
+ /*
235
+ * We never report any statistics test or self-test errors or any
236
+ * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
237
+ */
238
+
239
+ /*
240
+ * We don't have an internal fifo, see above. Therefore, we
241
+ * report back the default fifo size (5 32-bit words) and
242
+ * indicate that our fifo is always full.
243
+ */
244
+ val |= 5 << 12 | 5 << 8;
245
+
246
+ /* We always have a new seed available. */
247
+ val |= 1 << 6;
248
+
249
+ if (s->op_seed == OP_DONE) {
250
+ val |= 1 << 5;
251
+ }
252
+ if (s->op_self_test == OP_DONE) {
253
+ val |= 1 << 4;
254
+ }
255
+ if (s->op_seed == OP_RUN || s->op_self_test == OP_RUN) {
256
+ /*
257
+ * We're busy if self-test is running or if we're
258
+ * seeding the prng.
259
+ */
260
+ val |= 1 << 1;
261
+ } else {
262
+ /*
263
+ * We're ready to provide secure random numbers whenever
264
+ * we're not busy.
265
+ */
266
+ val |= 1;
267
+ }
268
+ break;
269
+
270
+ case RNGC_FIFO:
271
+ qemu_guest_getrandom_nofail(&val, sizeof(val));
272
+ break;
63
+ break;
273
+ }
64
+ }
274
+
65
+ return MEMTX_OK;
275
+ return val;
276
+}
66
+}
277
+
67
+
278
+static void imx_rngc_do_reset(IMXRNGCState *s)
68
+static MemTxResult ras_write(void *opaque, hwaddr addr,
69
+ uint64_t value, unsigned size,
70
+ MemTxAttrs attrs)
279
+{
71
+{
280
+ s->op_self_test = OP_IDLE;
72
+ if (attrs.user) {
281
+ s->op_seed = OP_IDLE;
73
+ return MEMTX_ERROR;
282
+ s->mask = 0;
74
+ }
283
+ s->auto_seed = false;
75
+
76
+ switch (addr) {
77
+ default:
78
+ qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
79
+ (uint32_t)addr);
80
+ break;
81
+ }
82
+ return MEMTX_OK;
284
+}
83
+}
285
+
84
+
286
+static void imx_rngc_write(void *opaque, hwaddr offset, uint64_t value,
85
+static const MemoryRegionOps ras_ops = {
287
+ unsigned size)
86
+ .read_with_attrs = ras_read,
288
+{
87
+ .write_with_attrs = ras_write,
289
+ IMXRNGCState *s = IMX_RNGC(opaque);
290
+
291
+ switch (offset) {
292
+ case RNGC_COMMAND:
293
+ if (value & RNGC_CMD_BIT_SW_RST) {
294
+ imx_rngc_do_reset(s);
295
+ }
296
+
297
+ /*
298
+ * For now, both CLR_ERR and CLR_INT clear the interrupt. We
299
+ * don't report any errors yet.
300
+ */
301
+ if (value & (RNGC_CMD_BIT_CLR_ERR | RNGC_CMD_BIT_CLR_INT)) {
302
+ qemu_irq_lower(s->irq);
303
+ }
304
+
305
+ if (value & RNGC_CMD_BIT_SEED) {
306
+ s->op_seed = OP_RUN;
307
+ qemu_bh_schedule(s->seed_bh);
308
+ }
309
+
310
+ if (value & RNGC_CMD_BIT_SELF_TEST) {
311
+ s->op_self_test = OP_RUN;
312
+ qemu_bh_schedule(s->self_test_bh);
313
+ }
314
+ break;
315
+
316
+ case RNGC_CONTROL:
317
+ /*
318
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
319
+ * We ignore them if they're set by the caller.
320
+ */
321
+
322
+ if (value & RNGC_CTRL_BIT_MASK_ERR) {
323
+ s->mask |= RNGC_CTRL_BIT_MASK_ERR;
324
+ } else {
325
+ s->mask &= ~RNGC_CTRL_BIT_MASK_ERR;
326
+ }
327
+
328
+ if (value & RNGC_CTRL_BIT_MASK_DONE) {
329
+ s->mask |= RNGC_CTRL_BIT_MASK_DONE;
330
+ } else {
331
+ s->mask &= ~RNGC_CTRL_BIT_MASK_DONE;
332
+ }
333
+
334
+ if (value & RNGC_CTRL_BIT_AUTO_SEED) {
335
+ s->auto_seed = true;
336
+ } else {
337
+ s->auto_seed = false;
338
+ }
339
+ break;
340
+ }
341
+}
342
+
343
+static const MemoryRegionOps imx_rngc_ops = {
344
+ .read = imx_rngc_read,
345
+ .write = imx_rngc_write,
346
+ .endianness = DEVICE_NATIVE_ENDIAN,
88
+ .endianness = DEVICE_NATIVE_ENDIAN,
347
+};
89
+};
348
+
90
+
349
+static void imx_rngc_self_test(void *opaque)
91
/*
350
+{
92
* Unassigned portions of the PPB space are RAZ/WI for privileged
351
+ IMXRNGCState *s = IMX_RNGC(opaque);
93
* accesses, and fault for non-privileged accesses.
94
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
95
&s->systick_ns_mem, 1);
96
}
97
98
+ if (cpu_isar_feature(aa32_ras, s->cpu)) {
99
+ memory_region_init_io(&s->ras_mem, OBJECT(s),
100
+ &ras_ops, s, "nvic_ras", 0x1000);
101
+ memory_region_add_subregion(&s->container, 0x5000, &s->ras_mem);
102
+ }
352
+
103
+
353
+ s->op_self_test = OP_DONE;
104
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
354
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
105
}
355
+ qemu_irq_raise(s->irq);
106
356
+ }
357
+}
358
+
359
+static void imx_rngc_seed(void *opaque)
360
+{
361
+ IMXRNGCState *s = IMX_RNGC(opaque);
362
+
363
+ s->op_seed = OP_DONE;
364
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
365
+ qemu_irq_raise(s->irq);
366
+ }
367
+}
368
+
369
+static void imx_rngc_realize(DeviceState *dev, Error **errp)
370
+{
371
+ IMXRNGCState *s = IMX_RNGC(dev);
372
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
373
+
374
+ memory_region_init_io(&s->iomem, OBJECT(s), &imx_rngc_ops, s,
375
+ TYPE_IMX_RNGC, 0x1000);
376
+ sysbus_init_mmio(sbd, &s->iomem);
377
+
378
+ sysbus_init_irq(sbd, &s->irq);
379
+ s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s);
380
+ s->seed_bh = qemu_bh_new(imx_rngc_seed, s);
381
+}
382
+
383
+static void imx_rngc_reset(DeviceState *dev)
384
+{
385
+ IMXRNGCState *s = IMX_RNGC(dev);
386
+
387
+ imx_rngc_do_reset(s);
388
+}
389
+
390
+static const VMStateDescription vmstate_imx_rngc = {
391
+ .name = RNGC_NAME,
392
+ .version_id = 1,
393
+ .minimum_version_id = 1,
394
+ .fields = (VMStateField[]) {
395
+ VMSTATE_UINT8(op_self_test, IMXRNGCState),
396
+ VMSTATE_UINT8(op_seed, IMXRNGCState),
397
+ VMSTATE_UINT8(mask, IMXRNGCState),
398
+ VMSTATE_BOOL(auto_seed, IMXRNGCState),
399
+ VMSTATE_END_OF_LIST()
400
+ }
401
+};
402
+
403
+static void imx_rngc_class_init(ObjectClass *klass, void *data)
404
+{
405
+ DeviceClass *dc = DEVICE_CLASS(klass);
406
+
407
+ dc->realize = imx_rngc_realize;
408
+ dc->reset = imx_rngc_reset;
409
+ dc->desc = RNGC_NAME,
410
+ dc->vmsd = &vmstate_imx_rngc;
411
+}
412
+
413
+static const TypeInfo imx_rngc_info = {
414
+ .name = TYPE_IMX_RNGC,
415
+ .parent = TYPE_SYS_BUS_DEVICE,
416
+ .instance_size = sizeof(IMXRNGCState),
417
+ .class_init = imx_rngc_class_init,
418
+};
419
+
420
+static void imx_rngc_register_types(void)
421
+{
422
+ type_register_static(&imx_rngc_info);
423
+}
424
+
425
+type_init(imx_rngc_register_types)
426
--
107
--
427
2.20.1
108
2.20.1
428
109
429
110
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Correct a typo in the name we give the NVIC object.
2
2
3
By calling qdev_pass_gpios() we don't need to hold a copy of the
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
IRQs from the INTC into the SoC state.
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Instead of filling an array of qemu_irq and passing it around, we
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
can now directly call qdev_get_gpio_in() on the SoC.
6
Message-id: 20201119215617.29887-28-peter.maydell@linaro.org
7
---
8
hw/arm/armv7m.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
7
10
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
9
Message-id: 20191230110953.25496-5-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/allwinner-a10.h | 1 -
14
hw/arm/allwinner-a10.c | 24 +++++++++++-------------
15
2 files changed, 11 insertions(+), 14 deletions(-)
16
17
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/allwinner-a10.h
13
--- a/hw/arm/armv7m.c
20
+++ b/include/hw/arm/allwinner-a10.h
14
+++ b/hw/arm/armv7m.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
15
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
22
/*< public >*/
16
23
17
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
24
ARMCPU cpu;
18
25
- qemu_irq irq[AW_A10_PIC_INT_NR];
19
- object_initialize_child(obj, "nvnic", &s->nvic, TYPE_NVIC);
26
AwA10PITState timer;
20
+ object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
27
AwA10PICState intc;
21
object_property_add_alias(obj, "num-irq",
28
AwEmacState emac;
22
OBJECT(&s->nvic), "num-irq");
29
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/allwinner-a10.c
32
+++ b/hw/arm/allwinner-a10.c
33
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
34
{
35
AwA10State *s = AW_A10(dev);
36
SysBusDevice *sysbusdev;
37
- uint8_t i;
38
qemu_irq fiq, irq;
39
Error *err = NULL;
40
41
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
42
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
43
sysbus_connect_irq(sysbusdev, 0, irq);
44
sysbus_connect_irq(sysbusdev, 1, fiq);
45
- for (i = 0; i < AW_A10_PIC_INT_NR; i++) {
46
- s->irq[i] = qdev_get_gpio_in(DEVICE(&s->intc), i);
47
- }
48
+ qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
49
50
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
51
if (err != NULL) {
52
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
53
}
54
sysbusdev = SYS_BUS_DEVICE(&s->timer);
55
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIT_REG_BASE);
56
- sysbus_connect_irq(sysbusdev, 0, s->irq[22]);
57
- sysbus_connect_irq(sysbusdev, 1, s->irq[23]);
58
- sysbus_connect_irq(sysbusdev, 2, s->irq[24]);
59
- sysbus_connect_irq(sysbusdev, 3, s->irq[25]);
60
- sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
61
- sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
62
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 22));
63
+ sysbus_connect_irq(sysbusdev, 1, qdev_get_gpio_in(dev, 23));
64
+ sysbus_connect_irq(sysbusdev, 2, qdev_get_gpio_in(dev, 24));
65
+ sysbus_connect_irq(sysbusdev, 3, qdev_get_gpio_in(dev, 25));
66
+ sysbus_connect_irq(sysbusdev, 4, qdev_get_gpio_in(dev, 67));
67
+ sysbus_connect_irq(sysbusdev, 5, qdev_get_gpio_in(dev, 68));
68
69
memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
70
&error_fatal);
71
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
72
}
73
sysbusdev = SYS_BUS_DEVICE(&s->emac);
74
sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
75
- sysbus_connect_irq(sysbusdev, 0, s->irq[55]);
76
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 55));
77
78
object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
79
if (err) {
80
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
81
return;
82
}
83
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, AW_A10_SATA_BASE);
84
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, s->irq[56]);
85
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, qdev_get_gpio_in(dev, 56));
86
87
/* FIXME use a qdev chardev prop instead of serial_hd() */
88
- serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
89
+ serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
90
+ qdev_get_gpio_in(dev, 1),
91
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
92
}
93
23
94
--
24
--
95
2.20.1
25
2.20.1
96
26
97
27
diff view generated by jsdifflib