1
First arm pullreq for the 2.12 cycle, with all the
1
As promised, more Arm patches. The big thing in here is the
2
things that queued up during the release phase.
2
MPS2-AN521 board model.
3
2.11 isn't quite released yet, but might as well put
4
the pullreq on the mailing list :-)
5
3
6
thanks
4
thanks
7
-- PMM
5
-- PMM
8
6
9
The following changes since commit 0a0dc59d27527b78a195c2d838d28b7b49e5a639:
7
The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:
10
8
11
Update version for v2.11.0 release (2017-12-13 14:31:09 +0000)
9
Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)
12
10
13
are available in the git repository at:
11
are available in the Git repository at:
14
12
15
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171213
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190201
16
14
17
for you to fetch changes up to d3c348b6e3af3598bfcb755d59f8f4de80a2228a:
15
for you to fetch changes up to 7743b70ffe7a8ce168adce2cf50ad156b1fefb8c:
18
16
19
xilinx_spips: Use memset instead of a for loop to zero registers (2017-12-13 17:59:26 +0000)
17
tests/microbit-test: Add tests for nRF51 NVMC (2019-02-01 15:32:17 +0000)
20
18
21
----------------------------------------------------------------
19
----------------------------------------------------------------
22
target-arm queue:
20
target-arm queue:
23
* xilinx_spips: set reset values correctly
21
* New machine mps2-an521 -- this is a model of the AN521 FPGA image for the MPS2 devboard
24
* MAINTAINERS: fix an email address
22
* Fix various places where we failed to UNDEF invalid A64 instructions
25
* hw/display/tc6393xb: limit irq handler index to TC6393XB_GPIOS
23
* Don't UNDEF a valid FCMLA on 32-bit inputs
26
* nvic: Make systick banked for v8M
24
* Fix some bugs in the newly-added PAuth implementation
27
* refactor get_phys_addr() so we can return the right format PAR
25
* microbit: Implement NVMC non-volatile memory controller
28
for ATS operations
29
* implement v8M TT instruction
30
* fix some minor v8M bugs
31
* Implement reset for GICv3 ITS
32
* xlnx-zcu102: Add support for the ZynqMP QSPI
33
26
34
----------------------------------------------------------------
27
----------------------------------------------------------------
35
Alistair Francis (3):
28
Aaron Lindsay OS (2):
36
xilinx_spips: Update the QSPI Mod ID reset value
29
target/arm: Send interrupts on PMU counter overflow
37
xilinx_spips: Set all of the reset values
30
target/arm: Add a timer to predict PMU counter overflow
38
xilinx_spips: Use memset instead of a for loop to zero registers
39
31
40
Edgar E. Iglesias (1):
32
Julia Suvorova (1):
41
target/arm: Extend PAR format determination
33
arm: Clarify the logic of set_pc()
42
34
43
Eric Auger (4):
35
Peter Maydell (33):
44
hw/intc/arm_gicv3_its: Don't call post_load on reset
36
armv7m: Don't assume the NVIC's CPU is CPU 0
45
hw/intc/arm_gicv3_its: Implement a minimalist reset
37
armv7m: Make cpu object a child of the armv7m container
46
linux-headers: update to 4.15-rc1
38
armv7m: Pass through start-powered-off CPU property
47
hw/intc/arm_gicv3_its: Implement full reset
39
hw/arm/iotkit: Rename IoTKit to ARMSSE
40
hw/arm/iotkit: Refactor into abstract base class and subclass
41
hw/arm/iotkit: Rename 'iotkit' local variables and functions
42
hw/arm/iotkit: Rename files to hw/arm/armsse.[ch]
43
hw/misc/iotkit-secctl: Support 4 internal MPCs
44
hw/arm/armsse: Make number of SRAM banks parameterised
45
hw/arm/armsse: Make SRAM bank size configurable
46
hw/arm/armsse: Support dual-CPU configuration
47
hw/arm/armsse: Give each CPU its own view of memory
48
hw/arm/armsse: Put each CPU in its own cluster object
49
iotkit-sysinfo: Make SYS_VERSION and SYS_CONFIG configurable
50
hw/arm/armsse: Add unimplemented-device stubs for MHUs
51
hw/arm/armsse: Add unimplemented-device stubs for PPUs
52
hw/arm/armsse: Add unimplemented-device stub for cache control registers
53
hw/arm/armsse: Add unimplemented-device stub for CPU local control registers
54
hw/misc/armsse-cpuid: Implement SSE-200 CPU_IDENTITY register block
55
hw/arm/armsse: Add CPU_IDENTITY block to SSE-200
56
hw/arm/armsse: Add SSE-200 model
57
hw/arm/mps2-tz: Add IRQ infrastructure to support SSE-200
58
hw/arm/mps2-tz: Add mps2-an521 model
59
target/arm/translate-a64: Don't underdecode system instructions
60
target/arm/translate-a64: Don't underdecode PRFM
61
target/arm/translate-a64: Don't underdecode SIMD ld/st multiple
62
target/arm/translate-a64: Don't underdecode SIMD ld/st single
63
target/arm/translate-a64: Don't underdecode add/sub extended register
64
target/arm/translate-a64: Don't underdecode FP insns
65
target/arm/translate-a64: Don't underdecode SDOT and UDOT
66
exec.c: Don't reallocate IOMMUNotifiers that are in use
67
target/arm/translate-a64: Fix FCMLA decoding error
68
target/arm/translate-a64: Fix mishandling of size in FCMLA decode
48
69
49
Francisco Iglesias (13):
70
Remi Denis-Courmont (2):
50
m25p80: Add support for continuous read out of RDSR and READ_FSR
71
target/arm: fix AArch64 virtual address space size
51
m25p80: Add support for SST READ ID 0x90/0xAB commands
72
target/arm: fix decoding of B{,L}RA{A,B}
52
m25p80: Add support for BRRD/BRWR and BULK_ERASE (0x60)
53
m25p80: Add support for n25q512a11 and n25q512a13
54
xilinx_spips: Move FlashCMD, XilinxQSPIPS and XilinxSPIPSClass
55
xilinx_spips: Update striping to be big-endian bit order
56
xilinx_spips: Add support for RX discard and RX drain
57
xilinx_spips: Make tx/rx_data_bytes more generic and reusable
58
xilinx_spips: Add support for zero pumping
59
xilinx_spips: Add support for 4 byte addresses in the LQSPI
60
xilinx_spips: Don't set TX FIFO UNDERFLOW at cmd done
61
xilinx_spips: Add support for the ZynqMP Generic QSPI
62
xlnx-zcu102: Add support for the ZynqMP QSPI
63
73
64
Peter Maydell (20):
74
Richard Henderson (5):
65
target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads
75
target/arm: Enable API, APK bits in SCR, HCR
66
target/arm: Allow explicit writes to CONTROL.SPSEL in Handler mode
76
target/arm: Always enable pac keys for user-only
67
target/arm: Add missing M profile case to regime_is_user()
77
aarch64-linux-user: Update HWCAP bits from linux 5.0-rc1
68
target/arm: Split M profile MNegPri mmu index into user and priv
78
aarch64-linux-user: Enable HWCAP bits for PAuth
69
target/arm: Create new arm_v7m_mmu_idx_for_secstate_and_priv()
79
linux-user: Initialize aarch64 pac keys
70
target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8()
71
target/arm: Implement TT instruction
72
target/arm: Provide fault type enum and FSR conversion functions
73
target/arm: Remove fsr argument from arm_ld*_ptw()
74
target/arm: Convert get_phys_addr_v5() to not return FSC values
75
target/arm: Convert get_phys_addr_v6() to not return FSC values
76
target/arm: Convert get_phys_addr_lpae() to not return FSC values
77
target/arm: Convert get_phys_addr_pmsav5() to not return FSC values
78
target/arm: Convert get_phys_addr_pmsav7() to not return FSC values
79
target/arm: Convert get_phys_addr_pmsav8() to not return FSC values
80
target/arm: Use ARMMMUFaultInfo in deliver_fault()
81
target/arm: Ignore fsr from get_phys_addr() in do_ats_write()
82
target/arm: Remove fsr argument from get_phys_addr() and arm_tlb_fill()
83
nvic: Make nvic_sysreg_ns_ops work with any MemoryRegion
84
nvic: Make systick banked
85
80
86
Prasad J Pandit (1):
81
Steffen Görtz (3):
87
hw/display/tc6393xb: limit irq handler index to TC6393XB_GPIOS
82
hw/nvram/nrf51_nvm: Add nRF51 non-volatile memories
83
arm: Instantiate NRF51 special NVM's and NVMC
84
tests/microbit-test: Add tests for nRF51 NVMC
88
85
89
Zhaoshenglong (1):
86
kumar sourav (1):
90
MAINTAINERS: replace the unavailable email address
87
hw/arm/nrf51_soc: set object owner in memory_region_init_ram
91
88
92
include/hw/arm/xlnx-zynqmp.h | 5 +
89
hw/arm/Makefile.objs | 2 +-
93
include/hw/intc/armv7m_nvic.h | 4 +-
90
hw/misc/Makefile.objs | 1 +
94
include/hw/ssi/xilinx_spips.h | 74 +-
91
hw/nvram/Makefile.objs | 1 +
95
include/standard-headers/asm-s390/virtio-ccw.h | 1 +
92
include/hw/arm/{iotkit.h => armsse.h} | 113 ++-
96
include/standard-headers/asm-x86/hyperv.h | 394 +--------
93
include/hw/arm/armv7m.h | 1 +
97
include/standard-headers/linux/input-event-codes.h | 2 +
94
include/hw/arm/nrf51_soc.h | 2 +
98
include/standard-headers/linux/input.h | 1 +
95
include/hw/misc/armsse-cpuid.h | 41 ++
99
include/standard-headers/linux/pci_regs.h | 45 +-
96
include/hw/misc/iotkit-secctl.h | 6 +-
100
linux-headers/asm-arm/kvm.h | 8 +
97
include/hw/misc/iotkit-sysinfo.h | 6 +
101
linux-headers/asm-arm/kvm_para.h | 1 +
98
include/hw/nvram/nrf51_nvm.h | 64 ++
102
linux-headers/asm-arm/unistd.h | 2 +
99
include/qom/cpu.h | 16 +-
103
linux-headers/asm-arm64/kvm.h | 8 +
100
linux-user/aarch64/target_syscall.h | 2 +
104
linux-headers/asm-arm64/unistd.h | 1 +
101
target/arm/cpu.h | 12 +-
105
linux-headers/asm-powerpc/epapr_hcalls.h | 1 +
102
exec.c | 10 +-
106
linux-headers/asm-powerpc/kvm.h | 1 +
103
hw/arm/armsse.c | 1241 +++++++++++++++++++++++++++++++++
107
linux-headers/asm-powerpc/kvm_para.h | 1 +
104
hw/arm/armv7m.c | 23 +-
108
linux-headers/asm-powerpc/unistd.h | 1 +
105
hw/arm/boot.c | 4 -
109
linux-headers/asm-s390/kvm.h | 1 +
106
hw/arm/iotkit.c | 759 --------------------
110
linux-headers/asm-s390/kvm_para.h | 1 +
107
hw/arm/mps2-tz.c | 121 +++-
111
linux-headers/asm-s390/unistd.h | 4 +-
108
hw/arm/nrf51_soc.c | 44 +-
112
linux-headers/asm-x86/kvm.h | 1 +
109
hw/intc/armv7m_nvic.c | 3 +-
113
linux-headers/asm-x86/kvm_para.h | 2 +-
110
hw/misc/armsse-cpuid.c | 134 ++++
114
linux-headers/asm-x86/unistd.h | 1 +
111
hw/misc/iotkit-secctl.c | 5 +-
115
linux-headers/linux/kvm.h | 2 +
112
hw/misc/iotkit-sysinfo.c | 15 +-
116
linux-headers/linux/kvm_para.h | 1 +
113
hw/nvram/nrf51_nvm.c | 388 +++++++++++
117
linux-headers/linux/psci.h | 1 +
114
linux-user/aarch64/cpu_loop.c | 31 +-
118
linux-headers/linux/userfaultfd.h | 1 +
115
linux-user/elfload.c | 10 +
119
linux-headers/linux/vfio.h | 1 +
116
target/arm/arm-powerctl.c | 3 -
120
linux-headers/linux/vfio_ccw.h | 1 +
117
target/arm/cpu.c | 41 +-
121
linux-headers/linux/vhost.h | 1 +
118
target/arm/cpu64.c | 75 --
122
target/arm/cpu.h | 73 +-
119
target/arm/helper.c | 139 +++-
123
target/arm/helper.h | 2 +
120
target/arm/translate-a64.c | 59 +-
124
target/arm/internals.h | 193 ++++-
121
tests/microbit-test.c | 108 +++
125
hw/arm/xlnx-zcu102.c | 23 +
122
MAINTAINERS | 6 +-
126
hw/arm/xlnx-zynqmp.c | 26 +
123
default-configs/arm-softmmu.mak | 3 +-
127
hw/block/m25p80.c | 80 +-
124
hw/misc/trace-events | 4 +
128
hw/display/tc6393xb.c | 1 +
125
36 files changed, 2552 insertions(+), 941 deletions(-)
129
hw/intc/arm_gicv3_its_common.c | 2 -
126
rename include/hw/arm/{iotkit.h => armsse.h} (53%)
130
hw/intc/arm_gicv3_its_kvm.c | 53 +-
127
create mode 100644 include/hw/misc/armsse-cpuid.h
131
hw/intc/armv7m_nvic.c | 100 ++-
128
create mode 100644 include/hw/nvram/nrf51_nvm.h
132
hw/ssi/xilinx_spips.c | 928 +++++++++++++++++----
129
create mode 100644 hw/arm/armsse.c
133
target/arm/helper.c | 489 +++++++----
130
delete mode 100644 hw/arm/iotkit.c
134
target/arm/op_helper.c | 82 +-
131
create mode 100644 hw/misc/armsse-cpuid.c
135
target/arm/translate.c | 37 +-
132
create mode 100644 hw/nvram/nrf51_nvm.c
136
MAINTAINERS | 2 +-
137
default-configs/arm-softmmu.mak | 2 +-
138
46 files changed, 1833 insertions(+), 828 deletions(-)
139
133
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: kumar sourav <sourav.jb1988@gmail.com>
2
2
3
Update the reset value to match the latest ZynqMP register spec.
3
set object owner in memory_region_init_ram() instead
4
of NULL.
4
5
5
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
6
Signed-off-by: kumar sourav <sourav.jb1988@gmail.com>
6
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-id: c03e51d041db7f055596084891aeb1e856e32b9f.1513104804.git.alistair.francis@xilinx.com
9
Message-id: 20190125155630.17430-1-sourav.jb1988@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/ssi/xilinx_spips.c | 1 +
12
hw/arm/nrf51_soc.c | 3 ++-
12
1 file changed, 1 insertion(+)
13
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
14
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
15
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/xilinx_spips.c
17
--- a/hw/arm/nrf51_soc.c
17
+++ b/hw/ssi/xilinx_spips.c
18
+++ b/hw/arm/nrf51_soc.c
18
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
19
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
19
s->regs[R_GQSPI_RX_THRESH] = 1;
20
}
20
s->regs[R_GQSPI_GFIFO_THRESH] = 1;
21
memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
21
s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
22
22
+ s->regs[R_MOD_ID] = 0x01090101;
23
- memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
23
s->man_start_com_g = false;
24
+ memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
24
s->gqspi_irqline = 0;
25
+ &err);
25
xlnx_zynqmp_qspips_update_ixr(s);
26
if (err) {
27
error_propagate(errp, err);
28
return;
26
--
29
--
27
2.7.4
30
2.20.1
28
31
29
32
diff view generated by jsdifflib
1
Generalize nvic_sysreg_ns_ops so that we can pass it an
1
Currently the ARMv7M NVIC object's realize method assumes that the
2
arbitrary MemoryRegion which it will use as the underlying
2
CPU the NVIC is attached to is CPU 0, because it thinks there can
3
register implementation to apply the NS-alias behaviour
3
only ever be one CPU in the system. To allow a dual-Cortex-M33
4
to. We'll want this so we can do the same with systick.
4
setup we need to remove this assumption; instead the armv7m
5
wrapper object tells the NVIC its CPU, in the same way that it
6
already tells the CPU what the NVIC is.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 1512154296-5652-2-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190121185118.18550-2-peter.maydell@linaro.org
9
---
12
---
10
hw/intc/armv7m_nvic.c | 10 +++++++---
13
hw/arm/armv7m.c | 6 ++++--
11
1 file changed, 7 insertions(+), 3 deletions(-)
14
hw/intc/armv7m_nvic.c | 3 +--
15
2 files changed, 5 insertions(+), 4 deletions(-)
12
16
17
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/armv7m.c
20
+++ b/hw/arm/armv7m.c
21
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
22
}
23
}
24
25
- /* Tell the CPU where the NVIC is; it will fail realize if it doesn't
26
- * have one.
27
+ /*
28
+ * Tell the CPU where the NVIC is; it will fail realize if it doesn't
29
+ * have one. Similarly, tell the NVIC where its CPU is.
30
*/
31
s->cpu->env.nvic = &s->nvic;
32
+ s->nvic.cpu = s->cpu;
33
34
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
35
if (err != NULL) {
13
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
14
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/armv7m_nvic.c
38
--- a/hw/intc/armv7m_nvic.c
16
+++ b/hw/intc/armv7m_nvic.c
39
+++ b/hw/intc/armv7m_nvic.c
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
18
uint64_t value, unsigned size,
19
MemTxAttrs attrs)
20
{
21
+ MemoryRegion *mr = opaque;
22
+
23
if (attrs.secure) {
24
/* S accesses to the alias act like NS accesses to the real region */
25
attrs.secure = 0;
26
- return nvic_sysreg_write(opaque, addr, value, size, attrs);
27
+ return memory_region_dispatch_write(mr, addr, value, size, attrs);
28
} else {
29
/* NS attrs are RAZ/WI for privileged, and BusFault for user */
30
if (attrs.user) {
31
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
32
uint64_t *data, unsigned size,
33
MemTxAttrs attrs)
34
{
35
+ MemoryRegion *mr = opaque;
36
+
37
if (attrs.secure) {
38
/* S accesses to the alias act like NS accesses to the real region */
39
attrs.secure = 0;
40
- return nvic_sysreg_read(opaque, addr, data, size, attrs);
41
+ return memory_region_dispatch_read(mr, addr, data, size, attrs);
42
} else {
43
/* NS attrs are RAZ/WI for privileged, and BusFault for user */
44
if (attrs.user) {
45
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
46
41
Error *err = NULL;
47
if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
42
int regionlen;
48
memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
43
49
- &nvic_sysreg_ns_ops, s,
44
- s->cpu = ARM_CPU(qemu_get_cpu(0));
50
+ &nvic_sysreg_ns_ops, &s->sysregmem,
45
-
51
"nvic_sysregs_ns", 0x1000);
46
+ /* The armv7m container object will have set our CPU pointer */
52
memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
47
if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
53
}
48
error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
49
return;
54
--
50
--
55
2.7.4
51
2.20.1
56
52
57
53
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
Rather than just creating the CPUs with object_new, make them child
2
objects of the armv7m container. This will allow the cluster code to
3
find the CPUs if an armv7m object is made a child of a cluster object.
4
object_new_with_props() will do the parenting for us.
2
5
3
Use memset() instead of a for loop to zero all of the registers.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190121185118.18550-3-peter.maydell@linaro.org
10
---
11
hw/arm/armv7m.c | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
4
13
5
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
14
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
6
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: c076e907f355923864cb1afde31b938ffb677778.1513104804.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/ssi/xilinx_spips.c | 11 +++--------
12
1 file changed, 3 insertions(+), 8 deletions(-)
13
14
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/xilinx_spips.c
16
--- a/hw/arm/armv7m.c
17
+++ b/hw/ssi/xilinx_spips.c
17
+++ b/hw/arm/armv7m.c
18
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
18
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
19
{
19
20
XilinxSPIPS *s = XILINX_SPIPS(d);
20
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
21
21
22
- int i;
22
- s->cpu = ARM_CPU(object_new(s->cpu_type));
23
- for (i = 0; i < XLNX_SPIPS_R_MAX; i++) {
23
+ s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
24
- s->regs[i] = 0;
24
+ &err, NULL));
25
- }
25
+ if (err != NULL) {
26
+ memset(s->regs, 0, sizeof(s->regs));
26
+ error_propagate(errp, err);
27
27
+ return;
28
fifo8_reset(&s->rx_fifo);
28
+ }
29
fifo8_reset(&s->rx_fifo);
29
30
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
30
object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
31
static void xlnx_zynqmp_qspips_reset(DeviceState *d)
31
&error_abort);
32
{
33
XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(d);
34
- int i;
35
36
xilinx_spips_reset(d);
37
38
- for (i = 0; i < XLNX_ZYNQMP_SPIPS_R_MAX; i++) {
39
- s->regs[i] = 0;
40
- }
41
+ memset(s->regs, 0, sizeof(s->regs));
42
+
43
fifo8_reset(&s->rx_fifo_g);
44
fifo8_reset(&s->rx_fifo_g);
45
fifo32_reset(&s->fifo_g);
46
--
32
--
47
2.7.4
33
2.20.1
48
34
49
35
diff view generated by jsdifflib
1
For the v8M security extension, there should be two systick
1
Expose "start-powered-off" as a property of the ARMv7M container,
2
devices, which use separate banked systick exceptions. The
2
which we just pass through to the CPU object in the same way that we
3
register interface is banked in the same way as for other
3
do for "init-svtor" and "idau". (We want this for the SSE-200, which
4
banked registers, including the existence of an NS alias
4
powers up only the first CPU at reset and leaves the second powered
5
region for secure code to access the nonsecure timer.
5
down.)
6
7
As with the other CPU properties here, we can't just use alias
8
properties, because the CPU QOM object is not created until armv7m
9
realize time.
6
10
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1512154296-5652-3-git-send-email-peter.maydell@linaro.org
13
Message-id: 20190121185118.18550-4-peter.maydell@linaro.org
10
---
14
---
11
include/hw/intc/armv7m_nvic.h | 4 +-
15
include/hw/arm/armv7m.h | 1 +
12
hw/intc/armv7m_nvic.c | 90 ++++++++++++++++++++++++++++++++++++-------
16
hw/arm/armv7m.c | 10 ++++++++++
13
2 files changed, 80 insertions(+), 14 deletions(-)
17
2 files changed, 11 insertions(+)
14
18
15
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
19
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/armv7m_nvic.h
21
--- a/include/hw/arm/armv7m.h
18
+++ b/include/hw/intc/armv7m_nvic.h
22
+++ b/include/hw/arm/armv7m.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
20
24
Object *idau;
21
MemoryRegion sysregmem;
25
uint32_t init_svtor;
22
MemoryRegion sysreg_ns_mem;
26
bool enable_bitband;
23
+ MemoryRegion systickmem;
27
+ bool start_powered_off;
24
+ MemoryRegion systick_ns_mem;
28
} ARMv7MState;
25
MemoryRegion container;
26
27
uint32_t num_irq;
28
qemu_irq excpout;
29
qemu_irq sysresetreq;
30
31
- SysTickState systick;
32
+ SysTickState systick[M_REG_NUM_BANKS];
33
} NVICState;
34
29
35
#endif
30
#endif
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
31
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
37
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/armv7m_nvic.c
33
--- a/hw/arm/armv7m.c
39
+++ b/hw/intc/armv7m_nvic.c
34
+++ b/hw/arm/armv7m.c
40
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvic_sysreg_ns_ops = {
35
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
41
.endianness = DEVICE_NATIVE_ENDIAN,
36
return;
42
};
37
}
43
44
+static MemTxResult nvic_systick_write(void *opaque, hwaddr addr,
45
+ uint64_t value, unsigned size,
46
+ MemTxAttrs attrs)
47
+{
48
+ NVICState *s = opaque;
49
+ MemoryRegion *mr;
50
+
51
+ /* Direct the access to the correct systick */
52
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
53
+ return memory_region_dispatch_write(mr, addr, value, size, attrs);
54
+}
55
+
56
+static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
57
+ uint64_t *data, unsigned size,
58
+ MemTxAttrs attrs)
59
+{
60
+ NVICState *s = opaque;
61
+ MemoryRegion *mr;
62
+
63
+ /* Direct the access to the correct systick */
64
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
65
+ return memory_region_dispatch_read(mr, addr, data, size, attrs);
66
+}
67
+
68
+static const MemoryRegionOps nvic_systick_ops = {
69
+ .read_with_attrs = nvic_systick_read,
70
+ .write_with_attrs = nvic_systick_write,
71
+ .endianness = DEVICE_NATIVE_ENDIAN,
72
+};
73
+
74
static int nvic_post_load(void *opaque, int version_id)
75
{
76
NVICState *s = opaque;
77
@@ -XXX,XX +XXX,XX @@ static void nvic_systick_trigger(void *opaque, int n, int level)
78
/* SysTick just asked us to pend its exception.
79
* (This is different from an external interrupt line's
80
* behaviour.)
81
- * TODO: when we implement the banked systicks we must make
82
- * this pend the correct banked exception.
83
+ * n == 0 : NonSecure systick
84
+ * n == 1 : Secure systick
85
*/
86
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, false);
87
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n);
88
}
38
}
89
}
39
+ if (object_property_find(OBJECT(s->cpu), "start-powered-off", NULL)) {
90
40
+ object_property_set_bool(OBJECT(s->cpu), s->start_powered_off,
91
static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
41
+ "start-powered-off", &err);
92
{
93
NVICState *s = NVIC(dev);
94
- SysBusDevice *systick_sbd;
95
Error *err = NULL;
96
int regionlen;
97
98
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
99
/* include space for internal exception vectors */
100
s->num_irq += NVIC_FIRST_IRQ;
101
102
- object_property_set_bool(OBJECT(&s->systick), true, "realized", &err);
103
+ object_property_set_bool(OBJECT(&s->systick[M_REG_NS]), true,
104
+ "realized", &err);
105
if (err != NULL) {
106
error_propagate(errp, err);
107
return;
108
}
109
- systick_sbd = SYS_BUS_DEVICE(&s->systick);
110
- sysbus_connect_irq(systick_sbd, 0,
111
- qdev_get_gpio_in_named(dev, "systick-trigger", 0));
112
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
113
+ qdev_get_gpio_in_named(dev, "systick-trigger",
114
+ M_REG_NS));
115
+
116
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
117
+ /* We couldn't init the secure systick device in instance_init
118
+ * as we didn't know then if the CPU had the security extensions;
119
+ * so we have to do it here.
120
+ */
121
+ object_initialize(&s->systick[M_REG_S], sizeof(s->systick[M_REG_S]),
122
+ TYPE_SYSTICK);
123
+ qdev_set_parent_bus(DEVICE(&s->systick[M_REG_S]), sysbus_get_default());
124
+
125
+ object_property_set_bool(OBJECT(&s->systick[M_REG_S]), true,
126
+ "realized", &err);
127
+ if (err != NULL) {
42
+ if (err != NULL) {
128
+ error_propagate(errp, err);
43
+ error_propagate(errp, err);
129
+ return;
44
+ return;
130
+ }
45
+ }
131
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
132
+ qdev_get_gpio_in_named(dev, "systick-trigger",
133
+ M_REG_S));
134
+ }
46
+ }
135
47
136
/* The NVIC and System Control Space (SCS) starts at 0xe000e000
48
/*
137
* and looks like this:
49
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
138
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
50
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
139
memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
51
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
140
"nvic_sysregs", 0x1000);
52
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
141
memory_region_add_subregion(&s->container, 0, &s->sysregmem);
53
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
142
+
54
+ DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
143
+ memory_region_init_io(&s->systickmem, OBJECT(s),
55
+ false),
144
+ &nvic_systick_ops, s,
56
DEFINE_PROP_END_OF_LIST(),
145
+ "nvic_systick", 0xe0);
57
};
146
+
58
147
memory_region_add_subregion_overlap(&s->container, 0x10,
148
- sysbus_mmio_get_region(systick_sbd, 0),
149
- 1);
150
+ &s->systickmem, 1);
151
152
if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
153
memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
154
&nvic_sysreg_ns_ops, &s->sysregmem,
155
"nvic_sysregs_ns", 0x1000);
156
memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
157
+ memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
158
+ &nvic_sysreg_ns_ops, &s->systickmem,
159
+ "nvic_systick_ns", 0xe0);
160
+ memory_region_add_subregion_overlap(&s->container, 0x20010,
161
+ &s->systick_ns_mem, 1);
162
}
163
164
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
165
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_instance_init(Object *obj)
166
NVICState *nvic = NVIC(obj);
167
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
168
169
- object_initialize(&nvic->systick, sizeof(nvic->systick), TYPE_SYSTICK);
170
- qdev_set_parent_bus(DEVICE(&nvic->systick), sysbus_get_default());
171
+ object_initialize(&nvic->systick[M_REG_NS],
172
+ sizeof(nvic->systick[M_REG_NS]), TYPE_SYSTICK);
173
+ qdev_set_parent_bus(DEVICE(&nvic->systick[M_REG_NS]), sysbus_get_default());
174
+ /* We can't initialize the secure systick here, as we don't know
175
+ * yet if we need it.
176
+ */
177
178
sysbus_init_irq(sbd, &nvic->excpout);
179
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
180
- qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", 1);
181
+ qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
182
+ M_REG_NUM_BANKS);
183
}
184
185
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
186
--
59
--
187
2.7.4
60
2.20.1
188
61
189
62
diff view generated by jsdifflib
New patch
1
1
The Arm IoTKit was effectively the forerunner of a series of
2
subsystems for embedded SoCs, named the SSE-050, SSE-100 and SSE-200:
3
https://developer.arm.com/products/system-design/subsystems
4
These are generally quite similar, though later iterations have
5
extra devices that earlier ones do not.
6
7
We want to add a model of the SSE-200, which means refactoring the
8
IoTKit code into an abstract base class and subclasses (using the
9
same design that the bcm283x SoC and Aspeed SoC family
10
implementations do). As a first step, rename the IoTKit struct and
11
QOM macros to ARMSSE, which is what we're going to name the base
12
class. We temporarily retain TYPE_IOTKIT to avoid changing the
13
code that instantiates a TYPE_IOTKIT device here and then changing
14
it back again when it is re-introduced as a subclass.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190121185118.18550-5-peter.maydell@linaro.org
20
---
21
include/hw/arm/iotkit.h | 22 ++++++++++-----
22
hw/arm/iotkit.c | 59 +++++++++++++++++++++--------------------
23
hw/arm/mps2-tz.c | 2 +-
24
3 files changed, 47 insertions(+), 36 deletions(-)
25
26
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/iotkit.h
29
+++ b/include/hw/arm/iotkit.h
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM IoT Kit
33
+ * ARM SSE (Subsystems for Embedded): IoTKit
34
*
35
* Copyright (c) 2018 Linaro Limited
36
* Written by Peter Maydell
37
@@ -XXX,XX +XXX,XX @@
38
* (at your option) any later version.
39
*/
40
41
-/* This is a model of the Arm IoT Kit which is documented in
42
+/*
43
+ * This is a model of the Arm "Subsystems for Embedded" family of
44
+ * hardware, which include the IoT Kit and the SSE-050, SSE-100 and
45
+ * SSE-200. Currently we model only the Arm IoT Kit which is documented in
46
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
47
* It contains:
48
* a Cortex-M33
49
@@ -XXX,XX +XXX,XX @@
50
#include "hw/or-irq.h"
51
#include "hw/core/split-irq.h"
52
53
-#define TYPE_IOTKIT "iotkit"
54
-#define IOTKIT(obj) OBJECT_CHECK(IoTKit, (obj), TYPE_IOTKIT)
55
+#define TYPE_ARMSSE "iotkit"
56
+#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
57
+
58
+/*
59
+ * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
60
+ * latter's underlying name is left as "iotkit"); in a later
61
+ * commit it will become a subclass of TYPE_ARMSSE.
62
+ */
63
+#define TYPE_IOTKIT TYPE_ARMSSE
64
65
/* We have an IRQ splitter and an OR gate input for each external PPC
66
* and the 2 internal PPCs
67
@@ -XXX,XX +XXX,XX @@
68
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
69
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
70
71
-typedef struct IoTKit {
72
+typedef struct ARMSSE {
73
/*< private >*/
74
SysBusDevice parent_obj;
75
76
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
77
MemoryRegion *board_memory;
78
uint32_t exp_numirq;
79
uint32_t mainclk_frq;
80
-} IoTKit;
81
+} ARMSSE;
82
83
#endif
84
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/iotkit.c
87
+++ b/hw/arm/iotkit.c
88
@@ -XXX,XX +XXX,XX @@
89
/*
90
- * Arm IoT Kit
91
+ * Arm SSE (Subsystems for Embedded): IoTKit
92
*
93
* Copyright (c) 2018 Linaro Limited
94
* Written by Peter Maydell
95
@@ -XXX,XX +XXX,XX @@
96
/* Create an alias region of @size bytes starting at @base
97
* which mirrors the memory starting at @orig.
98
*/
99
-static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name,
100
+static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
101
hwaddr base, hwaddr size, hwaddr orig)
102
{
103
memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
104
@@ -XXX,XX +XXX,XX @@ static void irq_status_forwarder(void *opaque, int n, int level)
105
106
static void nsccfg_handler(void *opaque, int n, int level)
107
{
108
- IoTKit *s = IOTKIT(opaque);
109
+ ARMSSE *s = ARMSSE(opaque);
110
111
s->nsccfg = level;
112
}
113
114
-static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
115
+static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
116
{
117
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
118
- * system using the IoTKit has a collection of control lines which
119
+ * system using the ARMSSE has a collection of control lines which
120
* are provided by the security controller and which we want to
121
- * expose as control lines on the IoTKit device itself, so the
122
- * code using the IoTKit can wire them up to the PPCs.
123
+ * expose as control lines on the ARMSSE device itself, so the
124
+ * code using the ARMSSE can wire them up to the PPCs.
125
*/
126
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
127
DeviceState *iotkitdev = DEVICE(s);
128
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
129
g_free(name);
130
}
131
132
-static void iotkit_forward_sec_resp_cfg(IoTKit *s)
133
+static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
134
{
135
/* Forward the 3rd output from the splitter device as a
136
* named GPIO output of the iotkit object.
137
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_sec_resp_cfg(IoTKit *s)
138
139
static void iotkit_init(Object *obj)
140
{
141
- IoTKit *s = IOTKIT(obj);
142
+ ARMSSE *s = ARMSSE(obj);
143
int i;
144
145
memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
146
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
147
148
static void iotkit_exp_irq(void *opaque, int n, int level)
149
{
150
- IoTKit *s = IOTKIT(opaque);
151
+ ARMSSE *s = ARMSSE(opaque);
152
153
qemu_set_irq(s->exp_irqs[n], level);
154
}
155
156
static void iotkit_mpcexp_status(void *opaque, int n, int level)
157
{
158
- IoTKit *s = IOTKIT(opaque);
159
+ ARMSSE *s = ARMSSE(opaque);
160
qemu_set_irq(s->mpcexp_status_in[n], level);
161
}
162
163
static void iotkit_realize(DeviceState *dev, Error **errp)
164
{
165
- IoTKit *s = IOTKIT(dev);
166
+ ARMSSE *s = ARMSSE(dev);
167
int i;
168
MemoryRegion *mr;
169
Error *err = NULL;
170
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
171
* devices exist in both address spaces but with hard-wired security
172
* permissions that will cause the CPU to fault for non-secure accesses.
173
*
174
- * The IoTKit has an IDAU (Implementation Defined Access Unit),
175
+ * The ARMSSE has an IDAU (Implementation Defined Access Unit),
176
* which specifies hard-wired security permissions for different
177
- * areas of the physical address space. For the IoTKit IDAU, the
178
+ * areas of the physical address space. For the ARMSSE IDAU, the
179
* top 4 bits of the physical address are the IDAU region ID, and
180
* if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
181
* region, otherwise it is an S region.
182
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
183
* 0x20000000..0x2007ffff 32KB FPGA block RAM
184
* 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
185
* 0x40000000..0x4000ffff base peripheral region 1
186
- * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit)
187
+ * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
188
* 0x40020000..0x4002ffff system control element peripherals
189
* 0x40080000..0x400fffff base peripheral region 2
190
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
191
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
192
qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
193
194
/* The sec_resp_cfg output from the security controller must be split into
195
- * multiple lines, one for each of the PPCs within the IoTKit and one
196
- * that will be an output from the IoTKit to the system.
197
+ * multiple lines, one for each of the PPCs within the ARMSSE and one
198
+ * that will be an output from the ARMSSE to the system.
199
*/
200
object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
201
"num-lines", &err);
202
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
203
204
/* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
205
206
- /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */
207
+ /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
208
/* Devices behind APB PPC1:
209
* 0x4002f000: S32K timer
210
*/
211
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
212
qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
213
sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
214
215
- /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
216
+ /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
217
218
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
219
object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
220
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
221
* Expose our container region to the board model; this corresponds
222
* to the AHB Slave Expansion ports which allow bus master devices
223
* (eg DMA controllers) in the board model to make transactions into
224
- * devices in the IoTKit.
225
+ * devices in the ARMSSE.
226
*/
227
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
228
229
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
230
static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
231
int *iregion, bool *exempt, bool *ns, bool *nsc)
232
{
233
- /* For IoTKit systems the IDAU responses are simple logical functions
234
+ /*
235
+ * For ARMSSE systems the IDAU responses are simple logical functions
236
* of the address bits. The NSC attribute is guest-adjustable via the
237
* NSCCFG register in the security controller.
238
*/
239
- IoTKit *s = IOTKIT(ii);
240
+ ARMSSE *s = ARMSSE(ii);
241
int region = extract32(address, 28, 4);
242
243
*ns = !(region & 1);
244
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_vmstate = {
245
.version_id = 1,
246
.minimum_version_id = 1,
247
.fields = (VMStateField[]) {
248
- VMSTATE_UINT32(nsccfg, IoTKit),
249
+ VMSTATE_UINT32(nsccfg, ARMSSE),
250
VMSTATE_END_OF_LIST()
251
}
252
};
253
254
static Property iotkit_properties[] = {
255
- DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION,
256
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
257
MemoryRegion *),
258
- DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64),
259
- DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0),
260
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
261
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
262
DEFINE_PROP_END_OF_LIST()
263
};
264
265
static void iotkit_reset(DeviceState *dev)
266
{
267
- IoTKit *s = IOTKIT(dev);
268
+ ARMSSE *s = ARMSSE(dev);
269
270
s->nsccfg = 0;
271
}
272
@@ -XXX,XX +XXX,XX @@ static void iotkit_class_init(ObjectClass *klass, void *data)
273
}
274
275
static const TypeInfo iotkit_info = {
276
- .name = TYPE_IOTKIT,
277
+ .name = TYPE_ARMSSE,
278
.parent = TYPE_SYS_BUS_DEVICE,
279
- .instance_size = sizeof(IoTKit),
280
+ .instance_size = sizeof(ARMSSE),
281
.instance_init = iotkit_init,
282
.class_init = iotkit_class_init,
283
.interfaces = (InterfaceInfo[]) {
284
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/arm/mps2-tz.c
287
+++ b/hw/arm/mps2-tz.c
288
@@ -XXX,XX +XXX,XX @@ typedef struct {
289
typedef struct {
290
MachineState parent;
291
292
- IoTKit iotkit;
293
+ ARMSSE iotkit;
294
MemoryRegion psram;
295
MemoryRegion ssram[3];
296
MemoryRegion ssram1_m;
297
--
298
2.20.1
299
300
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
The Arm SSE-200 Subsystem for Embedded is a revised and
2
extended version of the older IoTKit SoC. Prepare for
3
adding a model of it by refactoring the IoTKit code into
4
an abstract base class which contains the functionality,
5
driven by a class data block specific to each subclass.
6
(This is the same approach used by the existing bcm283x
7
SoC family implementation.)
2
8
3
Add support for continuous read out of the RDSR and READ_FSR status
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
registers until the chip select is deasserted. This feature is supported
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
by amongst others 1 or more flashtypes manufactured by Numonyx (Micron),
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Windbond, SST, Gigadevice, Eon and Macronix.
12
Message-id: 20190121185118.18550-6-peter.maydell@linaro.org
13
---
14
include/hw/arm/iotkit.h | 22 +++++++++++++++++-----
15
hw/arm/iotkit.c | 34 +++++++++++++++++++++++++++++-----
16
2 files changed, 46 insertions(+), 10 deletions(-)
7
17
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
18
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
9
Acked-by: Marcin Krzemiński<mar.krzeminski@gmail.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Message-id: 20171126231634.9531-2-frasse.iglesias@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/block/m25p80.c | 39 ++++++++++++++++++++++++++++++++++++++-
16
1 file changed, 38 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/m25p80.c
20
--- a/include/hw/arm/iotkit.h
21
+++ b/hw/block/m25p80.c
21
+++ b/include/hw/arm/iotkit.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Flash {
22
@@ -XXX,XX +XXX,XX @@
23
uint8_t data[M25P80_INTERNAL_DATA_BUFFER_SZ];
23
#include "hw/or-irq.h"
24
uint32_t len;
24
#include "hw/core/split-irq.h"
25
uint32_t pos;
25
26
+ bool data_read_loop;
26
-#define TYPE_ARMSSE "iotkit"
27
uint8_t needed_bytes;
27
+#define TYPE_ARMSSE "arm-sse"
28
uint8_t cmd_in_progress;
28
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
29
uint32_t cur_addr;
29
30
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
30
/*
31
}
31
- * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
32
s->pos = 0;
32
- * latter's underlying name is left as "iotkit"); in a later
33
s->len = 1;
33
- * commit it will become a subclass of TYPE_ARMSSE.
34
+ s->data_read_loop = true;
34
+ * These type names are for specific IoTKit subsystems; other than
35
s->state = STATE_READING_DATA;
35
+ * instantiating them, code using these devices should always handle
36
break;
36
+ * them via the ARMSSE base class, so they have no IOTKIT() etc macros.
37
37
*/
38
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
38
-#define TYPE_IOTKIT TYPE_ARMSSE
39
}
39
+#define TYPE_IOTKIT "iotkit"
40
s->pos = 0;
40
41
s->len = 1;
41
/* We have an IRQ splitter and an OR gate input for each external PPC
42
+ s->data_read_loop = true;
42
* and the 2 internal PPCs
43
s->state = STATE_READING_DATA;
43
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
44
break;
44
uint32_t mainclk_frq;
45
45
} ARMSSE;
46
@@ -XXX,XX +XXX,XX @@ static int m25p80_cs(SSISlave *ss, bool select)
46
47
s->pos = 0;
47
+typedef struct ARMSSEInfo ARMSSEInfo;
48
s->state = STATE_IDLE;
49
flash_sync_dirty(s, -1);
50
+ s->data_read_loop = false;
51
}
52
53
DB_PRINT_L(0, "%sselect\n", select ? "de" : "");
54
@@ -XXX,XX +XXX,XX @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
55
s->pos++;
56
if (s->pos == s->len) {
57
s->pos = 0;
58
- s->state = STATE_IDLE;
59
+ if (!s->data_read_loop) {
60
+ s->state = STATE_IDLE;
61
+ }
62
}
63
break;
64
65
@@ -XXX,XX +XXX,XX @@ static Property m25p80_properties[] = {
66
DEFINE_PROP_END_OF_LIST(),
67
};
68
69
+static int m25p80_pre_load(void *opaque)
70
+{
71
+ Flash *s = (Flash *)opaque;
72
+
48
+
73
+ s->data_read_loop = false;
49
+typedef struct ARMSSEClass {
74
+ return 0;
50
+ DeviceClass parent_class;
75
+}
51
+ const ARMSSEInfo *info;
52
+} ARMSSEClass;
76
+
53
+
77
+static bool m25p80_data_read_loop_needed(void *opaque)
54
+#define ARMSSE_CLASS(klass) \
78
+{
55
+ OBJECT_CLASS_CHECK(ARMSSEClass, (klass), TYPE_ARMSSE)
79
+ Flash *s = (Flash *)opaque;
56
+#define ARMSSE_GET_CLASS(obj) \
57
+ OBJECT_GET_CLASS(ARMSSEClass, (obj), TYPE_ARMSSE)
80
+
58
+
81
+ return s->data_read_loop;
59
#endif
82
+}
60
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
83
+
61
index XXXXXXX..XXXXXXX 100644
84
+static const VMStateDescription vmstate_m25p80_data_read_loop = {
62
--- a/hw/arm/iotkit.c
85
+ .name = "m25p80/data_read_loop",
63
+++ b/hw/arm/iotkit.c
86
+ .version_id = 1,
64
@@ -XXX,XX +XXX,XX @@
87
+ .minimum_version_id = 1,
65
#include "hw/arm/iotkit.h"
88
+ .needed = m25p80_data_read_loop_needed,
66
#include "hw/arm/arm.h"
89
+ .fields = (VMStateField[]) {
67
90
+ VMSTATE_BOOL(data_read_loop, Flash),
68
+struct ARMSSEInfo {
91
+ VMSTATE_END_OF_LIST()
69
+ const char *name;
92
+ }
93
+};
70
+};
94
+
71
+
95
static const VMStateDescription vmstate_m25p80 = {
72
+static const ARMSSEInfo armsse_variants[] = {
96
.name = "m25p80",
73
+ {
97
.version_id = 0,
74
+ .name = TYPE_IOTKIT,
98
.minimum_version_id = 0,
99
.pre_save = m25p80_pre_save,
100
+ .pre_load = m25p80_pre_load,
101
.fields = (VMStateField[]) {
102
VMSTATE_UINT8(state, Flash),
103
VMSTATE_UINT8_ARRAY(data, Flash, M25P80_INTERNAL_DATA_BUFFER_SZ),
104
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m25p80 = {
105
VMSTATE_UINT8(spansion_cr3nv, Flash),
106
VMSTATE_UINT8(spansion_cr4nv, Flash),
107
VMSTATE_END_OF_LIST()
108
+ },
75
+ },
109
+ .subsections = (const VMStateDescription * []) {
76
+};
110
+ &vmstate_m25p80_data_read_loop,
77
+
111
+ NULL
78
/* Clock frequency in HZ of the 32KHz "slow clock" */
79
#define S32KCLK (32 * 1000)
80
81
@@ -XXX,XX +XXX,XX @@ static void iotkit_class_init(ObjectClass *klass, void *data)
82
{
83
DeviceClass *dc = DEVICE_CLASS(klass);
84
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
85
+ ARMSSEClass *asc = ARMSSE_CLASS(klass);
86
87
dc->realize = iotkit_realize;
88
dc->vmsd = &iotkit_vmstate;
89
dc->props = iotkit_properties;
90
dc->reset = iotkit_reset;
91
iic->check = iotkit_idau_check;
92
+ asc->info = data;
93
}
94
95
-static const TypeInfo iotkit_info = {
96
+static const TypeInfo armsse_info = {
97
.name = TYPE_ARMSSE,
98
.parent = TYPE_SYS_BUS_DEVICE,
99
.instance_size = sizeof(ARMSSE),
100
.instance_init = iotkit_init,
101
- .class_init = iotkit_class_init,
102
+ .abstract = true,
103
.interfaces = (InterfaceInfo[]) {
104
{ TYPE_IDAU_INTERFACE },
105
{ }
112
}
106
}
113
};
107
};
114
108
109
-static void iotkit_register_types(void)
110
+static void armsse_register_types(void)
111
{
112
- type_register_static(&iotkit_info);
113
+ int i;
114
+
115
+ type_register_static(&armsse_info);
116
+
117
+ for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
118
+ TypeInfo ti = {
119
+ .name = armsse_variants[i].name,
120
+ .parent = TYPE_ARMSSE,
121
+ .class_init = iotkit_class_init,
122
+ .class_data = (void *)&armsse_variants[i],
123
+ };
124
+ type_register(&ti);
125
+ }
126
}
127
128
-type_init(iotkit_register_types);
129
+type_init(armsse_register_types);
115
--
130
--
116
2.7.4
131
2.20.1
117
132
118
133
diff view generated by jsdifflib
New patch
1
1
Rename various internal uses of 'iotkit' in hw/arm/iotkit.c to
2
'armsse', for consistency. The remaining occurences are:
3
* related to the devices TYPE_IOTKIT_SYSCTL, TYPE_IOTKIT_SYSINFO,
4
etc, which this refactor is not touching
5
* references that apply specifically to the IoTKit (like
6
the lack of a private CPU region)
7
* the vmstate, which keeps its old "iotkit" name for
8
migration compatibility reasons
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-7-peter.maydell@linaro.org
14
---
15
hw/arm/iotkit.c | 68 ++++++++++++++++++++++++-------------------------
16
1 file changed, 34 insertions(+), 34 deletions(-)
17
18
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/iotkit.c
21
+++ b/hw/arm/iotkit.c
22
@@ -XXX,XX +XXX,XX @@ static void nsccfg_handler(void *opaque, int n, int level)
23
s->nsccfg = level;
24
}
25
26
-static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
27
+static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
28
{
29
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
30
* system using the ARMSSE has a collection of control lines which
31
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
32
* code using the ARMSSE can wire them up to the PPCs.
33
*/
34
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
35
- DeviceState *iotkitdev = DEVICE(s);
36
+ DeviceState *armssedev = DEVICE(s);
37
DeviceState *dev_secctl = DEVICE(&s->secctl);
38
DeviceState *dev_splitter = DEVICE(splitter);
39
char *name;
40
41
name = g_strdup_printf("%s_nonsec", ppcname);
42
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
43
+ qdev_pass_gpios(dev_secctl, armssedev, name);
44
g_free(name);
45
name = g_strdup_printf("%s_ap", ppcname);
46
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
47
+ qdev_pass_gpios(dev_secctl, armssedev, name);
48
g_free(name);
49
name = g_strdup_printf("%s_irq_enable", ppcname);
50
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
51
+ qdev_pass_gpios(dev_secctl, armssedev, name);
52
g_free(name);
53
name = g_strdup_printf("%s_irq_clear", ppcname);
54
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
55
+ qdev_pass_gpios(dev_secctl, armssedev, name);
56
g_free(name);
57
58
/* irq_status is a little more tricky, because we need to
59
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
60
qdev_connect_gpio_out(dev_splitter, 1,
61
qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
62
s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
63
- qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder,
64
+ qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
65
s->irq_status_in[ppcnum], name, 1);
66
g_free(name);
67
}
68
69
-static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
70
+static void armsse_forward_sec_resp_cfg(ARMSSE *s)
71
{
72
/* Forward the 3rd output from the splitter device as a
73
- * named GPIO output of the iotkit object.
74
+ * named GPIO output of the armsse object.
75
*/
76
DeviceState *dev = DEVICE(s);
77
DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
78
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
79
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
80
}
81
82
-static void iotkit_init(Object *obj)
83
+static void armsse_init(Object *obj)
84
{
85
ARMSSE *s = ARMSSE(obj);
86
int i;
87
88
- memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
89
+ memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
90
91
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
92
TYPE_ARMV7M);
93
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
94
sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
95
sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
96
sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
97
- sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
98
+ sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
99
sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
100
- sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
101
+ sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
102
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
103
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
104
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
105
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
106
}
107
}
108
109
-static void iotkit_exp_irq(void *opaque, int n, int level)
110
+static void armsse_exp_irq(void *opaque, int n, int level)
111
{
112
ARMSSE *s = ARMSSE(opaque);
113
114
qemu_set_irq(s->exp_irqs[n], level);
115
}
116
117
-static void iotkit_mpcexp_status(void *opaque, int n, int level)
118
+static void armsse_mpcexp_status(void *opaque, int n, int level)
119
{
120
ARMSSE *s = ARMSSE(opaque);
121
qemu_set_irq(s->mpcexp_status_in[n], level);
122
}
123
124
-static void iotkit_realize(DeviceState *dev, Error **errp)
125
+static void armsse_realize(DeviceState *dev, Error **errp)
126
{
127
ARMSSE *s = ARMSSE(dev);
128
int i;
129
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
130
for (i = 0; i < s->exp_numirq; i++) {
131
s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
132
}
133
- qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq);
134
+ qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
135
136
/* Set up the big aliases first */
137
make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
138
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
139
qdev_get_gpio_in(dev_splitter, 0));
140
141
/* This RAM lives behind the Memory Protection Controller */
142
- memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
143
+ memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
144
if (err) {
145
error_propagate(errp, err);
146
return;
147
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
148
for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
149
char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
150
151
- iotkit_forward_ppc(s, ppcname, i);
152
+ armsse_forward_ppc(s, ppcname, i);
153
g_free(ppcname);
154
}
155
156
for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
157
char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
158
159
- iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
160
+ armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
161
g_free(ppcname);
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
165
/* Create GPIO inputs which will pass the line state for our
166
* mpcexp_irq inputs to the correct splitter devices.
167
*/
168
- qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
169
+ qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
170
IOTS_NUM_EXP_MPC);
171
172
- iotkit_forward_sec_resp_cfg(s);
173
+ armsse_forward_sec_resp_cfg(s);
174
175
/* Forward the MSC related signals */
176
qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
177
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
178
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
179
}
180
181
-static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
182
+static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
183
int *iregion, bool *exempt, bool *ns, bool *nsc)
184
{
185
/*
186
@@ -XXX,XX +XXX,XX @@ static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
187
*iregion = region;
188
}
189
190
-static const VMStateDescription iotkit_vmstate = {
191
+static const VMStateDescription armsse_vmstate = {
192
.name = "iotkit",
193
.version_id = 1,
194
.minimum_version_id = 1,
195
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_vmstate = {
196
}
197
};
198
199
-static Property iotkit_properties[] = {
200
+static Property armsse_properties[] = {
201
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
202
MemoryRegion *),
203
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
204
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
205
DEFINE_PROP_END_OF_LIST()
206
};
207
208
-static void iotkit_reset(DeviceState *dev)
209
+static void armsse_reset(DeviceState *dev)
210
{
211
ARMSSE *s = ARMSSE(dev);
212
213
s->nsccfg = 0;
214
}
215
216
-static void iotkit_class_init(ObjectClass *klass, void *data)
217
+static void armsse_class_init(ObjectClass *klass, void *data)
218
{
219
DeviceClass *dc = DEVICE_CLASS(klass);
220
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
221
ARMSSEClass *asc = ARMSSE_CLASS(klass);
222
223
- dc->realize = iotkit_realize;
224
- dc->vmsd = &iotkit_vmstate;
225
- dc->props = iotkit_properties;
226
- dc->reset = iotkit_reset;
227
- iic->check = iotkit_idau_check;
228
+ dc->realize = armsse_realize;
229
+ dc->vmsd = &armsse_vmstate;
230
+ dc->props = armsse_properties;
231
+ dc->reset = armsse_reset;
232
+ iic->check = armsse_idau_check;
233
asc->info = data;
234
}
235
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo armsse_info = {
237
.name = TYPE_ARMSSE,
238
.parent = TYPE_SYS_BUS_DEVICE,
239
.instance_size = sizeof(ARMSSE),
240
- .instance_init = iotkit_init,
241
+ .instance_init = armsse_init,
242
.abstract = true,
243
.interfaces = (InterfaceInfo[]) {
244
{ TYPE_IDAU_INTERFACE },
245
@@ -XXX,XX +XXX,XX @@ static void armsse_register_types(void)
246
TypeInfo ti = {
247
.name = armsse_variants[i].name,
248
.parent = TYPE_ARMSSE,
249
- .class_init = iotkit_class_init,
250
+ .class_init = armsse_class_init,
251
.class_data = (void *)&armsse_variants[i],
252
};
253
type_register(&ti);
254
--
255
2.20.1
256
257
diff view generated by jsdifflib
1
From: Zhaoshenglong <zhaoshenglong@huawei.com>
1
Rename the files that used to be iotkit.[ch] to
2
armsse.[ch] to reflect the fact they new cover
3
multiple Arm subsystems for embedded.
2
4
3
Since I'm not working as an assignee in Linaro, replace the Linaro email
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
address with my personal one.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-8-peter.maydell@linaro.org
9
---
10
hw/arm/Makefile.objs | 2 +-
11
include/hw/arm/{iotkit.h => armsse.h} | 4 ++--
12
hw/arm/{iotkit.c => armsse.c} | 2 +-
13
hw/arm/mps2-tz.c | 2 +-
14
MAINTAINERS | 4 ++--
15
default-configs/arm-softmmu.mak | 2 +-
16
6 files changed, 8 insertions(+), 8 deletions(-)
17
rename include/hw/arm/{iotkit.h => armsse.h} (99%)
18
rename hw/arm/{iotkit.c => armsse.c} (99%)
5
19
6
Signed-off-by: Zhaoshenglong <zhaoshenglong@huawei.com>
20
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
7
Message-id: 1513058845-9768-1-git-send-email-zhaoshenglong@huawei.com
21
index XXXXXXX..XXXXXXX 100644
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
--- a/hw/arm/Makefile.objs
9
---
23
+++ b/hw/arm/Makefile.objs
10
MAINTAINERS | 2 +-
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
11
1 file changed, 1 insertion(+), 1 deletion(-)
25
obj-$(CONFIG_MPS2) += mps2.o
12
26
obj-$(CONFIG_MPS2) += mps2-tz.o
27
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
28
-obj-$(CONFIG_IOTKIT) += iotkit.o
29
+obj-$(CONFIG_ARMSSE) += armsse.o
30
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
31
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
32
obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
33
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/armsse.h
34
similarity index 99%
35
rename from include/hw/arm/iotkit.h
36
rename to include/hw/arm/armsse.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/arm/iotkit.h
39
+++ b/include/hw/arm/armsse.h
40
@@ -XXX,XX +XXX,XX @@
41
* + named GPIO outputs mscexp_ns[0..15]
42
*/
43
44
-#ifndef IOTKIT_H
45
-#define IOTKIT_H
46
+#ifndef ARMSSE_H
47
+#define ARMSSE_H
48
49
#include "hw/sysbus.h"
50
#include "hw/arm/armv7m.h"
51
diff --git a/hw/arm/iotkit.c b/hw/arm/armsse.c
52
similarity index 99%
53
rename from hw/arm/iotkit.c
54
rename to hw/arm/armsse.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/iotkit.c
57
+++ b/hw/arm/armsse.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "trace.h"
60
#include "hw/sysbus.h"
61
#include "hw/registerfields.h"
62
-#include "hw/arm/iotkit.h"
63
+#include "hw/arm/armsse.h"
64
#include "hw/arm/arm.h"
65
66
struct ARMSSEInfo {
67
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/mps2-tz.c
70
+++ b/hw/arm/mps2-tz.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "hw/misc/mps2-fpgaio.h"
73
#include "hw/misc/tz-mpc.h"
74
#include "hw/misc/tz-msc.h"
75
-#include "hw/arm/iotkit.h"
76
+#include "hw/arm/armsse.h"
77
#include "hw/dma/pl080.h"
78
#include "hw/ssi/pl022.h"
79
#include "hw/devices.h"
13
diff --git a/MAINTAINERS b/MAINTAINERS
80
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
15
--- a/MAINTAINERS
82
--- a/MAINTAINERS
16
+++ b/MAINTAINERS
83
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ F: include/hw/*/xlnx*.h
84
@@ -XXX,XX +XXX,XX @@ F: hw/arm/mps2.c
18
85
F: hw/arm/mps2-tz.c
19
ARM ACPI Subsystem
86
F: hw/misc/mps2-*.c
20
M: Shannon Zhao <zhaoshenglong@huawei.com>
87
F: include/hw/misc/mps2-*.h
21
-M: Shannon Zhao <shannon.zhao@linaro.org>
88
-F: hw/arm/iotkit.c
22
+M: Shannon Zhao <shannon.zhaosl@gmail.com>
89
-F: include/hw/arm/iotkit.h
23
L: qemu-arm@nongnu.org
90
+F: hw/arm/armsse.c
24
S: Maintained
91
+F: include/hw/arm/armsse.h
25
F: hw/arm/virt-acpi-build.c
92
F: hw/misc/iotkit-secctl.c
93
F: include/hw/misc/iotkit-secctl.h
94
F: hw/misc/iotkit-sysctl.c
95
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
96
index XXXXXXX..XXXXXXX 100644
97
--- a/default-configs/arm-softmmu.mak
98
+++ b/default-configs/arm-softmmu.mak
99
@@ -XXX,XX +XXX,XX @@ CONFIG_MPS2_SCC=y
100
CONFIG_TZ_MPC=y
101
CONFIG_TZ_MSC=y
102
CONFIG_TZ_PPC=y
103
-CONFIG_IOTKIT=y
104
+CONFIG_ARMSSE=y
105
CONFIG_IOTKIT_SECCTL=y
106
CONFIG_IOTKIT_SYSCTL=y
107
CONFIG_IOTKIT_SYSINFO=y
26
--
108
--
27
2.7.4
109
2.20.1
28
110
29
111
diff view generated by jsdifflib
1
Make get_phys_addr_v5() return a fault type in the ARMMMUFaultInfo
1
The SSE-200 has 4 banks of SRAM, each with its own internal
2
structure, which we convert to the FSC at the callsite.
2
Memory Protection Controller. The interrupt status for these
3
extra MPCs appears in the same security controller SECMPCINTSTATUS
4
register as the MPC for the IoTKit's single SRAM bank. Enhance the
5
iotkit-secctl device to allow 4 MPCs. (If the particular IoTKit/SSE
6
variant in use does not have all 4 MPCs then the unused inputs will
7
simply result in the SECMPCINTSTATUS bits being zero as required.)
8
9
The hardcoded constant "1"s in armsse.c indicate the actual number
10
of SRAM MPCs the IoTKit has, and will be replaced in the following
11
commit.
3
12
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20190121185118.18550-9-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-4-git-send-email-peter.maydell@linaro.org
9
---
16
---
10
target/arm/helper.c | 33 ++++++++++++++++++---------------
17
include/hw/misc/iotkit-secctl.h | 6 +++---
11
1 file changed, 18 insertions(+), 15 deletions(-)
18
hw/arm/armsse.c | 6 +++---
19
hw/misc/iotkit-secctl.c | 5 +++--
20
3 files changed, 9 insertions(+), 8 deletions(-)
12
21
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
24
--- a/include/hw/misc/iotkit-secctl.h
16
+++ b/target/arm/helper.c
25
+++ b/include/hw/misc/iotkit-secctl.h
17
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
26
@@ -XXX,XX +XXX,XX @@
18
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
27
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
28
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
20
hwaddr *phys_ptr, int *prot,
29
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
21
- target_ulong *page_size, uint32_t *fsr,
30
- * Controlling the MPC in the IoTKit:
22
+ target_ulong *page_size,
31
- * + named GPIO input mpc_status
23
ARMMMUFaultInfo *fi)
32
+ * Controlling the (up to) 4 MPCs in the IoTKit/SSE:
33
+ * + named GPIO inputs mpc_status[0..3]
34
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
35
* might provide:
36
* + named GPIO inputs mpcexp_status[0..15]
37
@@ -XXX,XX +XXX,XX @@
38
#define IOTS_NUM_APB_EXP_PPC 4
39
#define IOTS_NUM_AHB_EXP_PPC 4
40
#define IOTS_NUM_EXP_MPC 16
41
-#define IOTS_NUM_MPC 1
42
+#define IOTS_NUM_MPC 4
43
#define IOTS_NUM_EXP_MSC 16
44
45
typedef struct IoTKitSecCtl IoTKitSecCtl;
46
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/armsse.c
49
+++ b/hw/arm/armsse.c
50
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
51
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
52
&error_abort, NULL);
53
54
- for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
55
+ for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
56
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
57
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
58
59
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
60
61
/* We must OR together lines from the MPC splitters to go to the NVIC */
62
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
63
- IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
64
+ IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
65
if (err) {
66
error_propagate(errp, err);
67
return;
68
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
69
}
70
71
/* Wire up the splitters for the MPC IRQs */
72
- for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
73
+ for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
74
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
75
DeviceState *dev_splitter = DEVICE(splitter);
76
77
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/misc/iotkit-secctl.c
80
+++ b/hw/misc/iotkit-secctl.c
81
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
24
{
82
{
25
CPUState *cs = CPU(arm_env_get_cpu(env));
83
IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
26
- int code;
84
27
+ int level = 1;
85
- s->mpcintstatus = deposit32(s->mpcintstatus, 0, 1, !!level);
28
uint32_t table;
86
+ s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
29
uint32_t desc;
30
int type;
31
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
32
/* Lookup l1 descriptor. */
33
if (!get_level1_table_address(env, mmu_idx, &table, address)) {
34
/* Section translation fault if page walk is disabled by PD0 or PD1 */
35
- code = 5;
36
+ fi->type = ARMFault_Translation;
37
goto do_fault;
38
}
39
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
41
domain_prot = (dacr >> (domain * 2)) & 3;
42
if (type == 0) {
43
/* Section translation fault. */
44
- code = 5;
45
+ fi->type = ARMFault_Translation;
46
goto do_fault;
47
}
48
+ if (type != 2) {
49
+ level = 2;
50
+ }
51
if (domain_prot == 0 || domain_prot == 2) {
52
- if (type == 2)
53
- code = 9; /* Section domain fault. */
54
- else
55
- code = 11; /* Page domain fault. */
56
+ fi->type = ARMFault_Domain;
57
goto do_fault;
58
}
59
if (type == 2) {
60
/* 1Mb section. */
61
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
62
ap = (desc >> 10) & 3;
63
- code = 13;
64
*page_size = 1024 * 1024;
65
} else {
66
/* Lookup l2 entry. */
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
68
mmu_idx, fi);
69
switch (desc & 3) {
70
case 0: /* Page translation fault. */
71
- code = 7;
72
+ fi->type = ARMFault_Translation;
73
goto do_fault;
74
case 1: /* 64k page. */
75
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
76
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
77
/* UNPREDICTABLE in ARMv5; we choose to take a
78
* page translation fault.
79
*/
80
- code = 7;
81
+ fi->type = ARMFault_Translation;
82
goto do_fault;
83
}
84
} else {
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
86
/* Never happens, but compiler isn't smart enough to tell. */
87
abort();
88
}
89
- code = 15;
90
}
91
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
92
*prot |= *prot ? PAGE_EXEC : 0;
93
if (!(*prot & (1 << access_type))) {
94
/* Access permission fault. */
95
+ fi->type = ARMFault_Permission;
96
goto do_fault;
97
}
98
*phys_ptr = phys_addr;
99
return false;
100
do_fault:
101
- *fsr = code | (domain << 4);
102
+ fi->domain = domain;
103
+ fi->level = level;
104
return true;
105
}
87
}
106
88
107
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
89
static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
108
return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
90
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
109
attrs, prot, page_size, fsr, fi);
91
qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
110
} else {
92
qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
111
- return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr,
93
112
- prot, page_size, fsr, fi);
94
- qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1);
113
+ bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
95
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
114
+ phys_ptr, prot, page_size, fi);
96
+ IOTS_NUM_MPC);
115
+
97
qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
116
+ *fsr = arm_fi_to_sfsc(fi);
98
"mpcexp_status", IOTS_NUM_EXP_MPC);
117
+ return ret;
118
}
119
}
120
99
121
--
100
--
122
2.7.4
101
2.20.1
123
102
124
103
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
The SSE-200 has four banks of SRAM, each with its own
2
Memory Protection Controller, where the IoTKit has only one.
3
Make the number of SRAM banks a field in ARMSSEInfo.
2
4
3
Following the ZynqMP register spec let's ensure that all reset values
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
are set.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-10-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 9 +++--
10
hw/arm/armsse.c | 78 ++++++++++++++++++++++++++---------------
11
2 files changed, 56 insertions(+), 31 deletions(-)
5
12
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: 19836f3e0a298b13343c5a59c87425355e7fd8bd.1513104804.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/ssi/xilinx_spips.h | 2 +-
12
hw/ssi/xilinx_spips.c | 35 ++++++++++++++++++++++++++++++-----
13
2 files changed, 31 insertions(+), 6 deletions(-)
14
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
15
--- a/include/hw/arm/armsse.h
18
+++ b/include/hw/ssi/xilinx_spips.h
16
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
20
typedef struct XilinxSPIPS XilinxSPIPS;
18
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
21
19
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
22
#define XLNX_SPIPS_R_MAX (0x100 / 4)
20
23
-#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
21
+#define MAX_SRAM_BANKS 4
24
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4)
22
+#if MAX_SRAM_BANKS > IOTS_NUM_MPC
25
23
+#error Too many SRAM banks
26
/* Bite off 4k chunks at a time */
24
+#endif
27
#define LQSPI_CACHE_SIZE 1024
25
+
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
26
typedef struct ARMSSE {
27
/*< private >*/
28
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
30
IoTKitSecCtl secctl;
31
TZPPC apb_ppc0;
32
TZPPC apb_ppc1;
33
- TZMPC mpc;
34
+ TZMPC mpc[IOTS_NUM_MPC];
35
CMSDKAPBTIMER timer0;
36
CMSDKAPBTIMER timer1;
37
CMSDKAPBTIMER s32ktimer;
38
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
39
MemoryRegion alias1;
40
MemoryRegion alias2;
41
MemoryRegion alias3;
42
- MemoryRegion sram0;
43
+ MemoryRegion sram[MAX_SRAM_BANKS];
44
45
qemu_irq *exp_irqs;
46
qemu_irq ppc0_irq;
47
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
29
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/ssi/xilinx_spips.c
49
--- a/hw/arm/armsse.c
31
+++ b/hw/ssi/xilinx_spips.c
50
+++ b/hw/arm/armsse.c
32
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
33
52
34
/* interrupt mechanism */
53
struct ARMSSEInfo {
35
#define R_INTR_STATUS (0x04 / 4)
54
const char *name;
36
+#define R_INTR_STATUS_RESET (0x104)
55
+ int sram_banks;
37
#define R_INTR_EN (0x08 / 4)
56
};
38
#define R_INTR_DIS (0x0C / 4)
57
39
#define R_INTR_MASK (0x10 / 4)
58
static const ARMSSEInfo armsse_variants[] = {
40
@@ -XXX,XX +XXX,XX @@
59
{
41
#define R_SLAVE_IDLE_COUNT (0x24 / 4)
60
.name = TYPE_IOTKIT,
42
#define R_TX_THRES (0x28 / 4)
61
+ .sram_banks = 1,
43
#define R_RX_THRES (0x2C / 4)
62
},
44
+#define R_GPIO (0x30 / 4)
63
};
45
+#define R_LPBK_DLY_ADJ (0x38 / 4)
64
46
+#define R_LPBK_DLY_ADJ_RESET (0x33)
65
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
47
#define R_TXD1 (0x80 / 4)
66
static void armsse_init(Object *obj)
48
#define R_TXD2 (0x84 / 4)
67
{
49
#define R_TXD3 (0x88 / 4)
68
ARMSSE *s = ARMSSE(obj);
50
@@ -XXX,XX +XXX,XX @@
69
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
51
#define R_GQSPI_IER (0x108 / 4)
70
+ const ARMSSEInfo *info = asc->info;
52
#define R_GQSPI_IDR (0x10c / 4)
71
int i;
53
#define R_GQSPI_IMR (0x110 / 4)
72
54
+#define R_GQSPI_IMR_RESET (0xfbe)
73
+ assert(info->sram_banks <= MAX_SRAM_BANKS);
55
#define R_GQSPI_TX_THRESH (0x128 / 4)
56
#define R_GQSPI_RX_THRESH (0x12c / 4)
57
+#define R_GQSPI_GPIO (0x130 / 4)
58
+#define R_GQSPI_LPBK_DLY_ADJ (0x138 / 4)
59
+#define R_GQSPI_LPBK_DLY_ADJ_RESET (0x33)
60
#define R_GQSPI_CNFG (0x100 / 4)
61
FIELD(GQSPI_CNFG, MODE_EN, 30, 2)
62
FIELD(GQSPI_CNFG, GEN_FIFO_START_MODE, 29, 1)
63
@@ -XXX,XX +XXX,XX @@
64
FIELD(GQSPI_GF_SNAPSHOT, EXPONENT, 9, 1)
65
FIELD(GQSPI_GF_SNAPSHOT, DATA_XFER, 8, 1)
66
FIELD(GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA, 0, 8)
67
-#define R_GQSPI_MOD_ID (0x168 / 4)
68
-#define R_GQSPI_MOD_ID_VALUE 0x010A0000
69
+#define R_GQSPI_MOD_ID (0x1fc / 4)
70
+#define R_GQSPI_MOD_ID_RESET (0x10a0000)
71
+
74
+
72
+#define R_QSPIDMA_DST_CTRL (0x80c / 4)
75
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
73
+#define R_QSPIDMA_DST_CTRL_RESET (0x803ffa00)
76
74
+#define R_QSPIDMA_DST_I_MASK (0x820 / 4)
77
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
75
+#define R_QSPIDMA_DST_I_MASK_RESET (0xfe)
78
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
76
+#define R_QSPIDMA_DST_CTRL2 (0x824 / 4)
79
TYPE_TZ_PPC);
77
+#define R_QSPIDMA_DST_CTRL2_RESET (0x081bfff8)
80
sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
81
TYPE_TZ_PPC);
82
- sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
83
+ for (i = 0; i < info->sram_banks; i++) {
84
+ char *name = g_strdup_printf("mpc%d", i);
85
+ sysbus_init_child_obj(obj, name, &s->mpc[i],
86
+ sizeof(s->mpc[i]), TYPE_TZ_MPC);
87
+ g_free(name);
88
+ }
89
object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
90
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
91
&error_abort, NULL);
92
93
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
94
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
95
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
96
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
97
98
@@ -XXX,XX +XXX,XX @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
99
static void armsse_realize(DeviceState *dev, Error **errp)
100
{
101
ARMSSE *s = ARMSSE(dev);
102
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
103
+ const ARMSSEInfo *info = asc->info;
104
int i;
105
MemoryRegion *mr;
106
Error *err = NULL;
107
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
108
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
109
qdev_get_gpio_in(dev_splitter, 0));
110
111
- /* This RAM lives behind the Memory Protection Controller */
112
- memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
113
- if (err) {
114
- error_propagate(errp, err);
115
- return;
116
+ /* Each SRAM bank lives behind its own Memory Protection Controller */
117
+ for (i = 0; i < info->sram_banks; i++) {
118
+ char *ramname = g_strdup_printf("armsse.sram%d", i);
119
+ SysBusDevice *sbd_mpc;
78
+
120
+
79
/* size of TXRX FIFOs */
121
+ memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
80
#define RXFF_A (128)
122
+ g_free(ramname);
81
#define TXFF_A (128)
123
+ if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
124
+ error_propagate(errp, err);
83
fifo8_reset(&s->rx_fifo_g);
125
+ return;
84
fifo8_reset(&s->rx_fifo_g);
126
+ }
85
fifo32_reset(&s->fifo_g);
127
+ object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
86
+ s->regs[R_INTR_STATUS] = R_INTR_STATUS_RESET;
128
+ "downstream", &err);
87
+ s->regs[R_GPIO] = 1;
129
+ if (err) {
88
+ s->regs[R_LPBK_DLY_ADJ] = R_LPBK_DLY_ADJ_RESET;
130
+ error_propagate(errp, err);
89
+ s->regs[R_GQSPI_GFIFO_THRESH] = 0x10;
131
+ return;
90
+ s->regs[R_MOD_ID] = 0x01090101;
132
+ }
91
+ s->regs[R_GQSPI_IMR] = R_GQSPI_IMR_RESET;
133
+ object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
92
s->regs[R_GQSPI_TX_THRESH] = 1;
134
+ if (err) {
93
s->regs[R_GQSPI_RX_THRESH] = 1;
135
+ error_propagate(errp, err);
94
- s->regs[R_GQSPI_GFIFO_THRESH] = 1;
136
+ return;
95
- s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
137
+ }
96
- s->regs[R_MOD_ID] = 0x01090101;
138
+ /* Map the upstream end of the MPC into the right place... */
97
+ s->regs[R_GQSPI_GPIO] = 1;
139
+ sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
98
+ s->regs[R_GQSPI_LPBK_DLY_ADJ] = R_GQSPI_LPBK_DLY_ADJ_RESET;
140
+ memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
99
+ s->regs[R_GQSPI_MOD_ID] = R_GQSPI_MOD_ID_RESET;
141
+ sysbus_mmio_get_region(sbd_mpc, 1));
100
+ s->regs[R_QSPIDMA_DST_CTRL] = R_QSPIDMA_DST_CTRL_RESET;
142
+ /* ...and its register interface */
101
+ s->regs[R_QSPIDMA_DST_I_MASK] = R_QSPIDMA_DST_I_MASK_RESET;
143
+ memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
102
+ s->regs[R_QSPIDMA_DST_CTRL2] = R_QSPIDMA_DST_CTRL2_RESET;
144
+ sysbus_mmio_get_region(sbd_mpc, 0));
103
s->man_start_com_g = false;
145
}
104
s->gqspi_irqline = 0;
146
- object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
105
xlnx_zynqmp_qspips_update_ixr(s);
147
- "downstream", &err);
148
- if (err) {
149
- error_propagate(errp, err);
150
- return;
151
- }
152
- object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
153
- if (err) {
154
- error_propagate(errp, err);
155
- return;
156
- }
157
- /* Map the upstream end of the MPC into the right place... */
158
- memory_region_add_subregion(&s->container, 0x20000000,
159
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
160
- 1));
161
- /* ...and its register interface */
162
- memory_region_add_subregion(&s->container, 0x50083000,
163
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
164
- 0));
165
166
/* We must OR together lines from the MPC splitters to go to the NVIC */
167
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
168
- IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
169
+ IOTS_NUM_EXP_MPC + info->sram_banks,
170
+ "num-lines", &err);
171
if (err) {
172
error_propagate(errp, err);
173
return;
174
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
175
}
176
177
/* Wire up the splitters for the MPC IRQs */
178
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
179
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
180
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
181
DeviceState *dev_splitter = DEVICE(splitter);
182
183
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
184
"mpcexp_status", i));
185
} else {
186
/* Splitter input is from our own MPC */
187
- qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
188
+ qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
189
+ "irq", 0,
190
qdev_get_gpio_in(dev_splitter, 0));
191
qdev_connect_gpio_out(dev_splitter, 0,
192
qdev_get_gpio_in_named(dev_secctl,
106
--
193
--
107
2.7.4
194
2.20.1
108
195
109
196
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
For the IoTKit the SRAM bank size is always 32K (15 bits); for the
2
SSE-200 this is a configurable parameter, which defaults to 32K but
3
can be changed when it is built into a particular SoC. For instance
4
the Musca-B1 board sets it to 128K (17 bits).
2
5
3
At the moment the ITS is not properly reset and this causes
6
Make the bank size a QOM property. We follow the SSE-200 hardware in
4
various bugs on save/restore. We implement a minimalist reset
7
naming the parameter SRAM_ADDR_WIDTH, which specifies the number of
5
through individual register writes but for kernel versions
8
address bits of a single SRAM bank.
6
before v4.15 this fails voiding the vITS cache. We cannot
7
claim we have a comprehensive reset (hence the error message)
8
but that's better than nothing.
9
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1511883692-11511-3-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190121185118.18550-11-peter.maydell@linaro.org
14
---
13
---
15
hw/intc/arm_gicv3_its_kvm.c | 42 ++++++++++++++++++++++++++++++++++++++++++
14
include/hw/arm/armsse.h | 1 +
16
1 file changed, 42 insertions(+)
15
hw/arm/armsse.c | 18 ++++++++++++++++--
16
2 files changed, 17 insertions(+), 2 deletions(-)
17
17
18
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
18
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gicv3_its_kvm.c
20
--- a/include/hw/arm/armsse.h
21
+++ b/hw/intc/arm_gicv3_its_kvm.c
21
+++ b/include/hw/arm/armsse.h
22
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
23
23
MemoryRegion *board_memory;
24
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
24
uint32_t exp_numirq;
25
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
25
uint32_t mainclk_frq;
26
+#define KVM_ARM_ITS_CLASS(klass) \
26
+ uint32_t sram_addr_width;
27
+ OBJECT_CLASS_CHECK(KVMARMITSClass, (klass), TYPE_KVM_ARM_ITS)
27
} ARMSSE;
28
+#define KVM_ARM_ITS_GET_CLASS(obj) \
28
29
+ OBJECT_GET_CLASS(KVMARMITSClass, (obj), TYPE_KVM_ARM_ITS)
29
typedef struct ARMSSEInfo ARMSSEInfo;
30
+
30
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
+typedef struct KVMARMITSClass {
31
index XXXXXXX..XXXXXXX 100644
32
+ GICv3ITSCommonClass parent_class;
32
--- a/hw/arm/armsse.c
33
+ void (*parent_reset)(DeviceState *dev);
33
+++ b/hw/arm/armsse.c
34
+} KVMARMITSClass;
34
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
35
+
35
DeviceState *dev_apb_ppc1;
36
36
DeviceState *dev_secctl;
37
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
37
DeviceState *dev_splitter;
38
{
38
+ uint32_t addr_width_max;
39
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
39
40
GITS_CTLR, &s->ctlr, true, &error_abort);
40
if (!s->board_memory) {
41
}
41
error_setg(errp, "memory property was not set");
42
42
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
43
+static void kvm_arm_its_reset(DeviceState *dev)
43
return;
44
+{
44
}
45
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
45
46
+ KVMARMITSClass *c = KVM_ARM_ITS_GET_CLASS(s);
46
+ /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
47
+ int i;
47
+ assert(is_power_of_2(info->sram_banks));
48
+
48
+ addr_width_max = 24 - ctz32(info->sram_banks);
49
+ c->parent_reset(dev);
49
+ if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
50
+
50
+ error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
51
+ error_report("ITS KVM: full reset is not supported by QEMU");
51
+ addr_width_max);
52
+
53
+ if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
54
+ GITS_CTLR)) {
55
+ return;
52
+ return;
56
+ }
53
+ }
57
+
54
+
58
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
55
/* Handling of which devices should be available only to secure
59
+ GITS_CTLR, &s->ctlr, true, &error_abort);
56
* code is usually done differently for M profile than for A profile.
60
+
57
* Instead of putting some devices only into the secure address space,
61
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
58
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
+ GITS_CBASER, &s->cbaser, true, &error_abort);
59
for (i = 0; i < info->sram_banks; i++) {
63
+
60
char *ramname = g_strdup_printf("armsse.sram%d", i);
64
+ for (i = 0; i < 8; i++) {
61
SysBusDevice *sbd_mpc;
65
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
62
+ uint32_t sram_bank_size = 1 << s->sram_addr_width;
66
+ GITS_BASER + i * 8, &s->baser[i], true,
63
67
+ &error_abort);
64
- memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
68
+ }
65
+ memory_region_init_ram(&s->sram[i], NULL, ramname,
69
+}
66
+ sram_bank_size, &err);
70
+
67
g_free(ramname);
71
static Property kvm_arm_its_props[] = {
68
if (err) {
72
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
69
error_propagate(errp, err);
73
GICv3State *),
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
74
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
71
}
75
{
72
/* Map the upstream end of the MPC into the right place... */
76
DeviceClass *dc = DEVICE_CLASS(klass);
73
sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
77
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
74
- memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
78
+ KVMARMITSClass *ic = KVM_ARM_ITS_CLASS(klass);
75
+ memory_region_add_subregion(&s->container,
79
76
+ 0x20000000 + i * sram_bank_size,
80
dc->realize = kvm_arm_its_realize;
77
sysbus_mmio_get_region(sbd_mpc, 1));
81
dc->props = kvm_arm_its_props;
78
/* ...and its register interface */
82
+ ic->parent_reset = dc->reset;
79
memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
83
icc->send_msi = kvm_its_send_msi;
80
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
84
icc->pre_save = kvm_arm_its_pre_save;
81
MemoryRegion *),
85
icc->post_load = kvm_arm_its_post_load;
82
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
86
+ dc->reset = kvm_arm_its_reset;
83
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
87
}
84
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
88
85
DEFINE_PROP_END_OF_LIST()
89
static const TypeInfo kvm_arm_its_info = {
90
@@ -XXX,XX +XXX,XX @@ static const TypeInfo kvm_arm_its_info = {
91
.parent = TYPE_ARM_GICV3_ITS_COMMON,
92
.instance_size = sizeof(GICv3ITSState),
93
.class_init = kvm_arm_its_class_init,
94
+ .class_size = sizeof(KVMARMITSClass),
95
};
86
};
96
87
97
static void kvm_arm_its_register_types(void)
98
--
88
--
99
2.7.4
89
2.20.1
100
90
101
91
diff view generated by jsdifflib
1
The TT instruction is going to need to look up the MMU index
1
The SSE-200 has two Cortex-M33 CPUs. These see the same view
2
for a specified security and privilege state. Refactor the
2
of memory, with the exception of the "private CPU region" which
3
existing arm_v7m_mmu_idx_for_secstate() into a version that
3
has per-CPU devices. Internal device interrupts for SSE-200
4
lets you specify the privilege state and one that uses the
4
devices are mostly wired up to both CPUs, with the exception of
5
current state of the CPU.
5
a few per-CPU devices. External GPIO inputs on the SSE-200
6
device are provided for the second CPU's interrupts above 32,
7
as is already the case for the first CPU.
8
9
Refactor the code to support creation of multiple CPUs.
10
For the moment we leave all CPUs with the same view of
11
memory: this will not work in the multiple-CPU case, but
12
we will fix this in the following commit.
6
13
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1512153879-5291-6-git-send-email-peter.maydell@linaro.org
16
Message-id: 20190121185118.18550-12-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
17
---
12
target/arm/cpu.h | 21 ++++++++++++++++-----
18
include/hw/arm/armsse.h | 21 +++-
13
1 file changed, 16 insertions(+), 5 deletions(-)
19
hw/arm/armsse.c | 206 ++++++++++++++++++++++++++++++++--------
20
2 files changed, 180 insertions(+), 47 deletions(-)
14
21
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
24
--- a/include/hw/arm/armsse.h
18
+++ b/target/arm/cpu.h
25
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
26
@@ -XXX,XX +XXX,XX @@
20
}
27
* + QOM property "memory" is a MemoryRegion containing the devices provided
28
* by the board model.
29
* + QOM property "MAINCLK" is the frequency of the main system clock
30
- * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts
31
- * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which
32
- * are wired to the NVIC lines 32 .. n+32
33
+ * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
34
+ * (In hardware, the SSE-200 permits the number of expansion interrupts
35
+ * for the two CPUs to be configured separately, but we restrict it to
36
+ * being the same for both, to avoid having to have separate Property
37
+ * lists for different variants. This restriction can be relaxed later
38
+ * if necessary.)
39
+ * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
40
+ * which are wired to its NVIC lines 32 .. n+32
41
+ * + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
42
+ * CPU 1, which are wired to its NVIC lines 32 .. n+32
43
* + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows
44
* bus master devices in the board model to make transactions into
45
* all the devices and memory areas in the IoTKit
46
@@ -XXX,XX +XXX,XX @@
47
#error Too many SRAM banks
48
#endif
49
50
+#define SSE_MAX_CPUS 2
51
+
52
typedef struct ARMSSE {
53
/*< private >*/
54
SysBusDevice parent_obj;
55
56
/*< public >*/
57
- ARMv7MState armv7m;
58
+ ARMv7MState armv7m[SSE_MAX_CPUS];
59
IoTKitSecCtl secctl;
60
TZPPC apb_ppc0;
61
TZPPC apb_ppc1;
62
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
63
qemu_or_irq mpc_irq_orgate;
64
qemu_or_irq nmi_orgate;
65
66
+ SplitIRQ cpu_irq_splitter[32];
67
+
68
CMSDKAPBDualTimer dualtimer;
69
70
CMSDKAPBWatchdog s32kwatchdog;
71
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
72
MemoryRegion alias3;
73
MemoryRegion sram[MAX_SRAM_BANKS];
74
75
- qemu_irq *exp_irqs;
76
+ qemu_irq *exp_irqs[SSE_MAX_CPUS];
77
qemu_irq ppc0_irq;
78
qemu_irq ppc1_irq;
79
qemu_irq sec_resp_cfg;
80
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/armsse.c
83
+++ b/hw/arm/armsse.c
84
@@ -XXX,XX +XXX,XX @@
85
struct ARMSSEInfo {
86
const char *name;
87
int sram_banks;
88
+ int num_cpus;
89
};
90
91
static const ARMSSEInfo armsse_variants[] = {
92
{
93
.name = TYPE_IOTKIT,
94
.sram_banks = 1,
95
+ .num_cpus = 1,
96
},
97
};
98
99
/* Clock frequency in HZ of the 32KHz "slow clock" */
100
#define S32KCLK (32 * 1000)
101
102
+/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
103
+static bool irq_is_common[32] = {
104
+ [0 ... 5] = true,
105
+ /* 6, 7: per-CPU MHU interrupts */
106
+ [8 ... 12] = true,
107
+ /* 13: per-CPU icache interrupt */
108
+ /* 14: reserved */
109
+ [15 ... 20] = true,
110
+ /* 21: reserved */
111
+ [22 ... 26] = true,
112
+ /* 27: reserved */
113
+ /* 28, 29: per-CPU CTI interrupts */
114
+ /* 30, 31: reserved */
115
+};
116
+
117
/* Create an alias region of @size bytes starting at @base
118
* which mirrors the memory starting at @orig.
119
*/
120
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
121
int i;
122
123
assert(info->sram_banks <= MAX_SRAM_BANKS);
124
+ assert(info->num_cpus <= SSE_MAX_CPUS);
125
126
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
127
128
- sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
129
- TYPE_ARMV7M);
130
- qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type",
131
- ARM_CPU_TYPE_NAME("cortex-m33"));
132
+ for (i = 0; i < info->num_cpus; i++) {
133
+ char *name = g_strdup_printf("armv7m%d", i);
134
+ sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
135
+ TYPE_ARMV7M);
136
+ qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
137
+ ARM_CPU_TYPE_NAME("cortex-m33"));
138
+ g_free(name);
139
+ }
140
141
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
142
TYPE_IOTKIT_SECCTL);
143
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
144
TYPE_SPLIT_IRQ, &error_abort, NULL);
145
g_free(name);
146
}
147
+ if (info->num_cpus > 1) {
148
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
149
+ if (irq_is_common[i]) {
150
+ char *name = g_strdup_printf("cpu-irq-splitter%d", i);
151
+ SplitIRQ *splitter = &s->cpu_irq_splitter[i];
152
+
153
+ object_initialize_child(obj, name, splitter, sizeof(*splitter),
154
+ TYPE_SPLIT_IRQ, &error_abort, NULL);
155
+ g_free(name);
156
+ }
157
+ }
158
+ }
21
}
159
}
22
160
23
-/* Return the MMU index for a v7M CPU in the specified security state */
161
static void armsse_exp_irq(void *opaque, int n, int level)
24
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
25
- bool secstate)
26
+/* Return the MMU index for a v7M CPU in the specified security and
27
+ * privilege state
28
+ */
29
+static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
30
+ bool secstate,
31
+ bool priv)
32
{
162
{
33
- int el = arm_current_el(env);
163
- ARMSSE *s = ARMSSE(opaque);
34
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
164
+ qemu_irq *irqarray = opaque;
35
165
36
- if (el != 0) {
166
- qemu_set_irq(s->exp_irqs[n], level);
37
+ if (priv) {
167
+ qemu_set_irq(irqarray[n], level);
38
mmu_idx |= ARM_MMU_IDX_M_PRIV;
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
42
return mmu_idx;
43
}
168
}
44
169
45
+/* Return the MMU index for a v7M CPU in the specified security state */
170
static void armsse_mpcexp_status(void *opaque, int n, int level)
46
+static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
171
@@ -XXX,XX +XXX,XX @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
47
+ bool secstate)
172
qemu_set_irq(s->mpcexp_status_in[n], level);
173
}
174
175
+static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
48
+{
176
+{
49
+ bool priv = arm_current_el(env) != 0;
177
+ /*
50
+
178
+ * Return a qemu_irq which can be used to signal IRQ n to
51
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
179
+ * all CPUs in the SSE.
180
+ */
181
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
182
+ const ARMSSEInfo *info = asc->info;
183
+
184
+ assert(irq_is_common[irqno]);
185
+
186
+ if (info->num_cpus == 1) {
187
+ /* Only one CPU -- just connect directly to it */
188
+ return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
189
+ } else {
190
+ /* Connect to the splitter which feeds all CPUs */
191
+ return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
192
+ }
52
+}
193
+}
53
+
194
+
54
/* Determine the current mmu_idx to use for normal loads/stores */
195
static void armsse_realize(DeviceState *dev, Error **errp)
55
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
56
{
196
{
197
ARMSSE *s = ARMSSE(dev);
198
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
199
200
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
201
202
- qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32);
203
- /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
204
- * register in the IoT Kit System Control Register block, and the
205
- * initial value of that is in turn specifiable by the FPGA that
206
- * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
207
- * and simply set the CPU's init-svtor to the IoT Kit default value.
208
- */
209
- qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000);
210
- object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container),
211
- "memory", &err);
212
- if (err) {
213
- error_propagate(errp, err);
214
- return;
215
- }
216
- object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
217
- if (err) {
218
- error_propagate(errp, err);
219
- return;
220
- }
221
- object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
222
- if (err) {
223
- error_propagate(errp, err);
224
- return;
225
+ for (i = 0; i < info->num_cpus; i++) {
226
+ DeviceState *cpudev = DEVICE(&s->armv7m[i]);
227
+ Object *cpuobj = OBJECT(&s->armv7m[i]);
228
+ int j;
229
+ char *gpioname;
230
+
231
+ qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
232
+ /*
233
+ * In real hardware the initial Secure VTOR is set from the INITSVTOR0
234
+ * register in the IoT Kit System Control Register block, and the
235
+ * initial value of that is in turn specifiable by the FPGA that
236
+ * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
237
+ * and simply set the CPU's init-svtor to the IoT Kit default value.
238
+ * In SSE-200 the situation is similar, except that the default value
239
+ * is a reset-time signal input. Typically a board using the SSE-200
240
+ * will have a system control processor whose boot firmware initializes
241
+ * the INITSVTOR* registers before powering up the CPUs in any case,
242
+ * so the hardware's default value doesn't matter. QEMU doesn't emulate
243
+ * the control processor, so instead we behave in the way that the
244
+ * firmware does. All boards currently known about have firmware that
245
+ * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
246
+ * IoTKit default. We can make this more configurable if necessary.
247
+ */
248
+ qdev_prop_set_uint32(cpudev, "init-svtor", 0x10000000);
249
+ /*
250
+ * Start all CPUs except CPU0 powered down. In real hardware it is
251
+ * a configurable property of the SSE-200 which CPUs start powered up
252
+ * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
253
+ * the boards we care about start CPU0 and leave CPU1 powered off,
254
+ * we hard-code that for now. We can add QOM properties for this
255
+ * later if necessary.
256
+ */
257
+ if (i > 0) {
258
+ object_property_set_bool(cpuobj, true, "start-powered-off", &err);
259
+ if (err) {
260
+ error_propagate(errp, err);
261
+ return;
262
+ }
263
+ }
264
+ object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
265
+ if (err) {
266
+ error_propagate(errp, err);
267
+ return;
268
+ }
269
+ object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
270
+ if (err) {
271
+ error_propagate(errp, err);
272
+ return;
273
+ }
274
+ object_property_set_bool(cpuobj, true, "realized", &err);
275
+ if (err) {
276
+ error_propagate(errp, err);
277
+ return;
278
+ }
279
+
280
+ /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
281
+ s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
282
+ for (j = 0; j < s->exp_numirq; j++) {
283
+ s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
284
+ }
285
+ if (i == 0) {
286
+ gpioname = g_strdup("EXP_IRQ");
287
+ } else {
288
+ gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
289
+ }
290
+ qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
291
+ s->exp_irqs[i],
292
+ gpioname, s->exp_numirq);
293
+ g_free(gpioname);
294
}
295
296
- /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
297
- s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
298
- for (i = 0; i < s->exp_numirq; i++) {
299
- s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
300
+ /* Wire up the splitters that connect common IRQs to all CPUs */
301
+ if (info->num_cpus > 1) {
302
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
303
+ if (irq_is_common[i]) {
304
+ Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
305
+ DeviceState *devs = DEVICE(splitter);
306
+ int cpunum;
307
+
308
+ object_property_set_int(splitter, info->num_cpus,
309
+ "num-lines", &err);
310
+ if (err) {
311
+ error_propagate(errp, err);
312
+ return;
313
+ }
314
+ object_property_set_bool(splitter, true, "realized", &err);
315
+ if (err) {
316
+ error_propagate(errp, err);
317
+ return;
318
+ }
319
+ for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
320
+ DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
321
+
322
+ qdev_connect_gpio_out(devs, cpunum,
323
+ qdev_get_gpio_in(cpudev, i));
324
+ }
325
+ }
326
+ }
327
}
328
- qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
329
330
/* Set up the big aliases first */
331
make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
332
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
333
return;
334
}
335
qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
336
- qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
337
+ armsse_get_common_irq_in(s, 9));
338
339
/* Devices behind APB PPC0:
340
* 0x40000000: timer0
341
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
342
return;
343
}
344
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
345
- qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
346
+ armsse_get_common_irq_in(s, 3));
347
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
348
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
349
if (err) {
350
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
351
return;
352
}
353
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
354
- qdev_get_gpio_in(DEVICE(&s->armv7m), 4));
355
+ armsse_get_common_irq_in(s, 4));
356
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
357
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
358
if (err) {
359
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
360
return;
361
}
362
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
363
- qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
364
+ armsse_get_common_irq_in(s, 5));
365
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
366
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
367
if (err) {
368
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
369
return;
370
}
371
qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
372
- qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
373
+ armsse_get_common_irq_in(s, 10));
374
375
/* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
376
377
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
378
return;
379
}
380
sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
381
- qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
382
+ armsse_get_common_irq_in(s, 2));
383
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
384
object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
385
if (err) {
386
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
387
return;
388
}
389
sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
390
- qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
391
+ armsse_get_common_irq_in(s, 1));
392
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
393
394
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
395
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
396
qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
397
qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
398
qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
399
- qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
400
+ armsse_get_common_irq_in(s, 11));
401
402
/*
403
* Expose our container region to the board model; this corresponds
57
--
404
--
58
2.7.4
405
2.20.1
59
406
60
407
diff view generated by jsdifflib
1
Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo
1
Give each CPU its own container memory region. This is necessary
2
structure, which we convert to the FSC at the callsite.
2
for two reasons:
3
* some devices are instantiated one per CPU and the CPU sees only
4
its own device
5
* since a memory region can only be put into one container, we must
6
give each armv7m object a different MemoryRegion as its 'memory'
7
property, or a dual-CPU configuration will assert on realize when
8
the second armv7m object tries to put the MR into a container when
9
it is already in the first armv7m object's container
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Message-id: 20190121185118.18550-13-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-6-git-send-email-peter.maydell@linaro.org
9
---
14
---
10
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
15
include/hw/arm/armsse.h | 10 ++++++++++
11
1 file changed, 18 insertions(+), 23 deletions(-)
16
hw/arm/armsse.c | 22 ++++++++++++++++++++--
17
2 files changed, 30 insertions(+), 2 deletions(-)
12
18
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
21
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/helper.c
22
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
18
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
24
IoTKitSysCtl sysctl;
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
25
IoTKitSysCtl sysinfo;
20
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
26
21
- target_ulong *page_size_ptr, uint32_t *fsr,
27
+ /*
22
+ target_ulong *page_size_ptr,
28
+ * 'container' holds all devices seen by all CPUs.
23
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
29
+ * 'cpu_container[i]' is the view that CPU i has: this has the
24
30
+ * per-CPU devices of that CPU, plus as the background 'container'
25
/* Security attributes for an address, as returned by v8m_security_lookup. */
31
+ * (or an alias of it, since we can only use it directly once).
26
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
32
+ * container_alias[i] is the alias of 'container' used by CPU i+1;
27
hwaddr s2pa;
33
+ * CPU 0 can use 'container' directly.
28
int s2prot;
34
+ */
29
int ret;
35
MemoryRegion container;
30
- uint32_t fsr;
36
+ MemoryRegion container_alias[SSE_MAX_CPUS - 1];
31
37
+ MemoryRegion cpu_container[SSE_MAX_CPUS];
32
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
38
MemoryRegion alias1;
33
- &txattrs, &s2prot, &s2size, &fsr, fi, NULL);
39
MemoryRegion alias2;
34
+ &txattrs, &s2prot, &s2size, fi, NULL);
40
MemoryRegion alias3;
35
if (ret) {
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
36
fi->s2addr = addr;
42
index XXXXXXX..XXXXXXX 100644
37
fi->stage2 = true;
43
--- a/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@ do_fault:
44
+++ b/hw/arm/armsse.c
39
return true;
45
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
40
}
46
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
41
47
ARM_CPU_TYPE_NAME("cortex-m33"));
42
-/* Fault type for long-descriptor MMU fault reporting; this corresponds
48
g_free(name);
43
- * to bits [5..2] in the STATUS field in long-format DFSR/IFSR.
49
+ name = g_strdup_printf("arm-sse-cpu-container%d", i);
44
- */
50
+ memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
45
-typedef enum {
51
+ g_free(name);
46
- translation_fault = 1,
52
+ if (i > 0) {
47
- access_fault = 2,
53
+ name = g_strdup_printf("arm-sse-container-alias%d", i);
48
- permission_fault = 3,
54
+ memory_region_init_alias(&s->container_alias[i - 1], obj,
49
-} MMUFaultType;
55
+ name, &s->container, 0, UINT64_MAX);
50
-
56
+ g_free(name);
51
/*
57
+ }
52
* check_s2_mmu_setup
53
* @cpu: ARMCPU
54
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
55
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
56
MMUAccessType access_type, ARMMMUIdx mmu_idx,
57
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
58
- target_ulong *page_size_ptr, uint32_t *fsr,
59
+ target_ulong *page_size_ptr,
60
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
61
{
62
ARMCPU *cpu = arm_env_get_cpu(env);
63
CPUState *cs = CPU(cpu);
64
/* Read an LPAE long-descriptor translation table. */
65
- MMUFaultType fault_type = translation_fault;
66
+ ARMFaultType fault_type = ARMFault_Translation;
67
uint32_t level;
68
uint32_t epd = 0;
69
int32_t t0sz, t1sz;
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
71
ttbr_select = 1;
72
} else {
73
/* in the gap between the two regions, this is a Translation fault */
74
- fault_type = translation_fault;
75
+ fault_type = ARMFault_Translation;
76
goto do_fault;
77
}
58
}
78
59
79
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
60
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
80
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
81
inputsize, stride);
62
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
82
if (!ok) {
63
*/
83
- fault_type = translation_fault;
64
84
+ fault_type = ARMFault_Translation;
65
- memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
85
goto do_fault;
66
+ memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
67
68
for (i = 0; i < info->num_cpus; i++) {
69
DeviceState *cpudev = DEVICE(&s->armv7m[i]);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
return;
72
}
86
}
73
}
87
level = startlevel;
74
- object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
89
/* Here descaddr is the final physical address, and attributes
90
* are all in attrs.
91
*/
92
- fault_type = access_fault;
93
+ fault_type = ARMFault_AccessFlag;
94
if ((attrs & (1 << 8)) == 0) {
95
/* Access flag */
96
goto do_fault;
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
98
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
99
}
100
101
- fault_type = permission_fault;
102
+ fault_type = ARMFault_Permission;
103
if (!(*prot & (1 << access_type))) {
104
goto do_fault;
105
}
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
107
return false;
108
109
do_fault:
110
- /* Long-descriptor format IFSR/DFSR value */
111
- *fsr = (1 << 9) | (fault_type << 2) | level;
112
+ fi->type = fault_type;
113
+ fi->level = level;
114
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
115
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS);
116
return true;
117
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
118
/* S1 is done. Now do S2 translation. */
119
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
120
phys_ptr, attrs, &s2_prot,
121
- page_size, fsr, fi,
122
+ page_size, fi,
123
cacheattrs != NULL ? &cacheattrs2 : NULL);
124
+ *fsr = arm_fi_to_lfsc(fi);
125
fi->s2addr = ipa;
126
/* Combine the S1 and S2 perms. */
127
*prot &= s2_prot;
128
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
129
}
130
131
if (regime_using_lpae_format(env, mmu_idx)) {
132
- return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
133
- attrs, prot, page_size, fsr, fi, cacheattrs);
134
+ bool ret = get_phys_addr_lpae(env, address, access_type, mmu_idx,
135
+ phys_ptr, attrs, prot, page_size,
136
+ fi, cacheattrs);
137
+
75
+
138
+ *fsr = arm_fi_to_lfsc(fi);
76
+ if (i > 0) {
139
+ return ret;
77
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
140
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
78
+ &s->container_alias[i - 1], -1);
141
bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
79
+ } else {
142
phys_ptr, attrs, prot, page_size, fi);
80
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
81
+ &s->container, -1);
82
+ }
83
+ object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
84
+ "memory", &err);
85
if (err) {
86
error_propagate(errp, err);
87
return;
143
--
88
--
144
2.7.4
89
2.20.1
145
90
146
91
diff view generated by jsdifflib
1
Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo
1
Create a cluster object to hold each CPU in the SSE. They are
2
structure, which we convert to the FSC at the callsite.
2
logically distinct and may be configured differently (for instance
3
one may not have an FPU where the other does).
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20190121185118.18550-14-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-5-git-send-email-peter.maydell@linaro.org
9
---
8
---
10
target/arm/helper.c | 40 ++++++++++++++++++++++------------------
9
include/hw/arm/armsse.h | 2 ++
11
1 file changed, 22 insertions(+), 18 deletions(-)
10
hw/arm/armsse.c | 31 ++++++++++++++++++++++++++++---
11
2 files changed, 30 insertions(+), 3 deletions(-)
12
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
15
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/helper.c
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ do_fault:
17
@@ -XXX,XX +XXX,XX @@
18
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
18
#include "hw/misc/iotkit-sysinfo.h"
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
19
#include "hw/or-irq.h"
20
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
20
#include "hw/core/split-irq.h"
21
- target_ulong *page_size, uint32_t *fsr,
21
+#include "hw/cpu/cluster.h"
22
- ARMMMUFaultInfo *fi)
22
23
+ target_ulong *page_size, ARMMMUFaultInfo *fi)
23
#define TYPE_ARMSSE "arm-sse"
24
{
24
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
25
CPUState *cs = CPU(arm_env_get_cpu(env));
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
- int code;
26
27
+ int level = 1;
27
/*< public >*/
28
uint32_t table;
28
ARMv7MState armv7m[SSE_MAX_CPUS];
29
uint32_t desc;
29
+ CPUClusterState cluster[SSE_MAX_CPUS];
30
uint32_t xn;
30
IoTKitSecCtl secctl;
31
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
31
TZPPC apb_ppc0;
32
/* Lookup l1 descriptor. */
32
TZPPC apb_ppc1;
33
if (!get_level1_table_address(env, mmu_idx, &table, address)) {
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
/* Section translation fault if page walk is disabled by PD0 or PD1 */
34
index XXXXXXX..XXXXXXX 100644
35
- code = 5;
35
--- a/hw/arm/armsse.c
36
+ fi->type = ARMFault_Translation;
36
+++ b/hw/arm/armsse.c
37
goto do_fault;
37
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
38
}
38
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
39
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
39
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
40
for (i = 0; i < info->num_cpus; i++) {
41
/* Section translation fault, or attempt to use the encoding
41
- char *name = g_strdup_printf("armv7m%d", i);
42
* which is Reserved on implementations without PXN.
42
- sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
43
*/
43
- TYPE_ARMV7M);
44
- code = 5;
44
+ /*
45
+ fi->type = ARMFault_Translation;
45
+ * We put each CPU in its own cluster as they are logically
46
goto do_fault;
46
+ * distinct and may be configured differently.
47
}
47
+ */
48
if ((type == 1) || !(desc & (1 << 18))) {
48
+ char *name;
49
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
49
+
50
} else {
50
+ name = g_strdup_printf("cluster%d", i);
51
dacr = env->cp15.dacr_s;
51
+ object_initialize_child(obj, name, &s->cluster[i],
52
}
52
+ sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
53
+ if (type == 1) {
53
+ &error_abort, NULL);
54
+ level = 2;
54
+ qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
55
+ }
55
+ g_free(name);
56
domain_prot = (dacr >> (domain * 2)) & 3;
56
+
57
if (domain_prot == 0 || domain_prot == 2) {
57
+ name = g_strdup_printf("armv7m%d", i);
58
- if (type != 1) {
58
+ sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
59
- code = 9; /* Section domain fault. */
59
+ &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
60
- } else {
60
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
61
- code = 11; /* Page domain fault. */
61
ARM_CPU_TYPE_NAME("cortex-m33"));
62
- }
62
g_free(name);
63
+ /* Section or Page domain fault */
63
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
64
+ fi->type = ARMFault_Domain;
64
error_propagate(errp, err);
65
goto do_fault;
65
return;
66
}
67
if (type != 1) {
68
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
69
ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
70
xn = desc & (1 << 4);
71
pxn = desc & 1;
72
- code = 13;
73
ns = extract32(desc, 19, 1);
74
} else {
75
if (arm_feature(env, ARM_FEATURE_PXN)) {
76
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
77
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
78
switch (desc & 3) {
79
case 0: /* Page translation fault. */
80
- code = 7;
81
+ fi->type = ARMFault_Translation;
82
goto do_fault;
83
case 1: /* 64k page. */
84
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
86
/* Never happens, but compiler isn't smart enough to tell. */
87
abort();
88
}
66
}
89
- code = 15;
67
+ /*
90
}
68
+ * The cluster must be realized after the armv7m container, as
91
if (domain_prot == 3) {
69
+ * the container's CPU object is only created on realize, and the
92
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
70
+ * CPU must exist and have been parented into the cluster before
93
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
71
+ * the cluster is realized.
94
if (pxn && !regime_is_user(env, mmu_idx)) {
72
+ */
95
xn = 1;
73
+ object_property_set_bool(OBJECT(&s->cluster[i]),
96
}
74
+ true, "realized", &err);
97
- if (xn && access_type == MMU_INST_FETCH)
75
+ if (err) {
98
+ if (xn && access_type == MMU_INST_FETCH) {
76
+ error_propagate(errp, err);
99
+ fi->type = ARMFault_Permission;
77
+ return;
100
goto do_fault;
101
+ }
78
+ }
102
79
103
if (arm_feature(env, ARM_FEATURE_V6K) &&
80
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
104
(regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
81
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
105
/* The simplified model uses AP[0] as an access control bit. */
106
if ((ap & 1) == 0) {
107
/* Access flag fault. */
108
- code = (code == 15) ? 6 : 3;
109
+ fi->type = ARMFault_AccessFlag;
110
goto do_fault;
111
}
112
*prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
113
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
114
}
115
if (!(*prot & (1 << access_type))) {
116
/* Access permission fault. */
117
+ fi->type = ARMFault_Permission;
118
goto do_fault;
119
}
120
}
121
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
122
*phys_ptr = phys_addr;
123
return false;
124
do_fault:
125
- *fsr = code | (domain << 4);
126
+ fi->domain = domain;
127
+ fi->level = level;
128
return true;
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
132
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
133
attrs, prot, page_size, fsr, fi, cacheattrs);
134
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
135
- return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
136
- attrs, prot, page_size, fsr, fi);
137
+ bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
138
+ phys_ptr, attrs, prot, page_size, fi);
139
+
140
+ *fsr = arm_fi_to_sfsc(fi);
141
+ return ret;
142
} else {
143
bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
144
phys_ptr, prot, page_size, fi);
145
--
82
--
146
2.7.4
83
2.20.1
147
84
148
85
diff view generated by jsdifflib
1
Currently get_phys_addr() and its various subfunctions return
1
The SYS_VERSION and SYS_CONFIG register values differ between the
2
a hard-coded fault status register value for translation
2
IoTKit and SSE-200. Make them configurable via QOM properties rather
3
failures. This is awkward because FSR values these days may
3
than hard-coded, and set them appropriately in the ARMSSE code that
4
be either long-descriptor format or short-descriptor format.
4
instantiates the IOTKIT_SYSINFO device.
5
Worse, the right FSR type to use doesn't depend only on the
6
translation table being walked -- some cases, like fault
7
info reported to AArch32 EL2 for some kinds of ATS operation,
8
must be in long-descriptor format even if the translation
9
table being walked was short format. We can't get those cases
10
right with our current approach.
11
12
Provide fields in the ARMMMUFaultInfo struct which allow
13
get_phys_addr() to provide sufficient information for a caller to
14
construct an FSR value themselves, and utility functions which do
15
this for both long and short format FSR values, as a first step in
16
switching get_phys_addr() and its children to only returning the
17
failure cause in the ARMMMUFaultInfo struct.
18
5
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20190121185118.18550-15-peter.maydell@linaro.org
22
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
23
Message-id: 1512503192-2239-2-git-send-email-peter.maydell@linaro.org
24
---
9
---
25
target/arm/internals.h | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
10
include/hw/misc/iotkit-sysinfo.h | 6 ++++
26
1 file changed, 185 insertions(+)
11
hw/arm/armsse.c | 51 ++++++++++++++++++++++++++++++++
12
hw/misc/iotkit-sysinfo.c | 15 ++++++++--
13
3 files changed, 70 insertions(+), 2 deletions(-)
27
14
28
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/internals.h
17
--- a/include/hw/misc/iotkit-sysinfo.h
31
+++ b/target/arm/internals.h
18
+++ b/include/hw/misc/iotkit-sysinfo.h
32
@@ -XXX,XX +XXX,XX @@ static inline void arm_clear_exclusive(CPUARMState *env)
19
@@ -XXX,XX +XXX,XX @@
33
}
20
* Arm IoTKit and documented in
34
21
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
35
/**
22
* QEMU interface:
36
+ * ARMFaultType: type of an ARM MMU fault
23
+ * + QOM property "SYS_VERSION": value to use for SYS_VERSION register
37
+ * This corresponds to the v8A pseudocode's Fault enumeration,
24
+ * + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
38
+ * with extensions for QEMU internal conditions.
25
* + sysbus MMIO region 0: the system information register bank
39
+ */
26
*/
40
+typedef enum ARMFaultType {
27
41
+ ARMFault_None,
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysInfo {
42
+ ARMFault_AccessFlag,
29
43
+ ARMFault_Alignment,
30
/*< public >*/
44
+ ARMFault_Background,
31
MemoryRegion iomem;
45
+ ARMFault_Domain,
46
+ ARMFault_Permission,
47
+ ARMFault_Translation,
48
+ ARMFault_AddressSize,
49
+ ARMFault_SyncExternal,
50
+ ARMFault_SyncExternalOnWalk,
51
+ ARMFault_SyncParity,
52
+ ARMFault_SyncParityOnWalk,
53
+ ARMFault_AsyncParity,
54
+ ARMFault_AsyncExternal,
55
+ ARMFault_Debug,
56
+ ARMFault_TLBConflict,
57
+ ARMFault_Lockdown,
58
+ ARMFault_Exclusive,
59
+ ARMFault_ICacheMaint,
60
+ ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
61
+ ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
62
+} ARMFaultType;
63
+
32
+
64
+/**
33
+ /* Properties */
65
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
34
+ uint32_t sys_version;
66
+ * @type: Type of fault
35
+ uint32_t sys_config;
67
+ * @level: Table walk level (for translation, access flag and permission faults)
36
} IoTKitSysInfo;
68
+ * @domain: Domain of the fault address (for non-LPAE CPUs only)
37
69
* @s2addr: Address that caused a fault at stage 2
38
#endif
70
* @stage2: True if we faulted at stage 2
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
71
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
40
index XXXXXXX..XXXXXXX 100644
72
@@ -XXX,XX +XXX,XX @@ static inline void arm_clear_exclusive(CPUARMState *env)
41
--- a/hw/arm/armsse.c
73
*/
42
+++ b/hw/arm/armsse.c
74
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
43
@@ -XXX,XX +XXX,XX @@
75
struct ARMMMUFaultInfo {
44
#include "hw/arm/armsse.h"
76
+ ARMFaultType type;
45
#include "hw/arm/arm.h"
77
target_ulong s2addr;
46
78
+ int level;
47
+/* Format of the System Information block SYS_CONFIG register */
79
+ int domain;
48
+typedef enum SysConfigFormat {
80
bool stage2;
49
+ IoTKitFormat,
81
bool s1ptw;
50
+ SSE200Format,
82
bool ea;
51
+} SysConfigFormat;
52
+
53
struct ARMSSEInfo {
54
const char *name;
55
int sram_banks;
56
int num_cpus;
57
+ uint32_t sys_version;
58
+ SysConfigFormat sys_config_format;
83
};
59
};
84
60
85
+/**
61
static const ARMSSEInfo armsse_variants[] = {
86
+ * arm_fi_to_sfsc: Convert fault info struct to short-format FSC
62
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
87
+ * Compare pseudocode EncodeSDFSC(), though unlike that function
63
.name = TYPE_IOTKIT,
88
+ * we set up a whole FSR-format code including domain field and
64
.sram_banks = 1,
89
+ * putting the high bit of the FSC into bit 10.
65
.num_cpus = 1,
90
+ */
66
+ .sys_version = 0x41743,
91
+static inline uint32_t arm_fi_to_sfsc(ARMMMUFaultInfo *fi)
67
+ .sys_config_format = IoTKitFormat,
68
},
69
};
70
71
+static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
92
+{
72
+{
93
+ uint32_t fsc;
73
+ /* Return the SYS_CONFIG value for this SSE */
74
+ uint32_t sys_config;
94
+
75
+
95
+ switch (fi->type) {
76
+ switch (info->sys_config_format) {
96
+ case ARMFault_None:
77
+ case IoTKitFormat:
97
+ return 0;
78
+ sys_config = 0;
98
+ case ARMFault_AccessFlag:
79
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
99
+ fsc = fi->level == 1 ? 0x3 : 0x6;
80
+ sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
100
+ break;
81
+ break;
101
+ case ARMFault_Alignment:
82
+ case SSE200Format:
102
+ fsc = 0x1;
83
+ sys_config = 0;
103
+ break;
84
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
104
+ case ARMFault_Permission:
85
+ sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
105
+ fsc = fi->level == 1 ? 0xd : 0xf;
86
+ sys_config = deposit32(sys_config, 24, 4, 2);
106
+ break;
87
+ if (info->num_cpus > 1) {
107
+ case ARMFault_Domain:
88
+ sys_config = deposit32(sys_config, 10, 1, 1);
108
+ fsc = fi->level == 1 ? 0x9 : 0xb;
89
+ sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
109
+ break;
90
+ sys_config = deposit32(sys_config, 28, 4, 2);
110
+ case ARMFault_Translation:
91
+ }
111
+ fsc = fi->level == 1 ? 0x5 : 0x7;
112
+ break;
113
+ case ARMFault_SyncExternal:
114
+ fsc = 0x8 | (fi->ea << 12);
115
+ break;
116
+ case ARMFault_SyncExternalOnWalk:
117
+ fsc = fi->level == 1 ? 0xc : 0xe;
118
+ fsc |= (fi->ea << 12);
119
+ break;
120
+ case ARMFault_SyncParity:
121
+ fsc = 0x409;
122
+ break;
123
+ case ARMFault_SyncParityOnWalk:
124
+ fsc = fi->level == 1 ? 0x40c : 0x40e;
125
+ break;
126
+ case ARMFault_AsyncParity:
127
+ fsc = 0x408;
128
+ break;
129
+ case ARMFault_AsyncExternal:
130
+ fsc = 0x406 | (fi->ea << 12);
131
+ break;
132
+ case ARMFault_Debug:
133
+ fsc = 0x2;
134
+ break;
135
+ case ARMFault_TLBConflict:
136
+ fsc = 0x400;
137
+ break;
138
+ case ARMFault_Lockdown:
139
+ fsc = 0x404;
140
+ break;
141
+ case ARMFault_Exclusive:
142
+ fsc = 0x405;
143
+ break;
144
+ case ARMFault_ICacheMaint:
145
+ fsc = 0x4;
146
+ break;
147
+ case ARMFault_Background:
148
+ fsc = 0x0;
149
+ break;
150
+ case ARMFault_QEMU_NSCExec:
151
+ fsc = M_FAKE_FSR_NSC_EXEC;
152
+ break;
153
+ case ARMFault_QEMU_SFault:
154
+ fsc = M_FAKE_FSR_SFAULT;
155
+ break;
92
+ break;
156
+ default:
93
+ default:
157
+ /* Other faults can't occur in a context that requires a
158
+ * short-format status code.
159
+ */
160
+ g_assert_not_reached();
94
+ g_assert_not_reached();
161
+ }
95
+ }
162
+
96
+ return sys_config;
163
+ fsc |= (fi->domain << 4);
164
+ return fsc;
165
+}
97
+}
166
+
98
+
167
+/**
99
/* Clock frequency in HZ of the 32KHz "slow clock" */
168
+ * arm_fi_to_lfsc: Convert fault info struct to long-format FSC
100
#define S32KCLK (32 * 1000)
169
+ * Compare pseudocode EncodeLDFSC(), though unlike that function
101
170
+ * we fill in also the LPAE bit 9 of a DFSR format.
102
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
171
+ */
103
qdev_get_gpio_in_named(dev_apb_ppc1,
172
+static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
104
"cfg_sec_resp", 0));
173
+{
105
174
+ uint32_t fsc;
106
+ object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
107
+ "SYS_VERSION", &err);
108
+ if (err) {
109
+ error_propagate(errp, err);
110
+ return;
111
+ }
112
+ object_property_set_int(OBJECT(&s->sysinfo),
113
+ armsse_sys_config_value(s, info),
114
+ "SYS_CONFIG", &err);
115
+ if (err) {
116
+ error_propagate(errp, err);
117
+ return;
118
+ }
119
object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
120
if (err) {
121
error_propagate(errp, err);
122
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/misc/iotkit-sysinfo.c
125
+++ b/hw/misc/iotkit-sysinfo.c
126
@@ -XXX,XX +XXX,XX @@ static const int sysinfo_id[] = {
127
static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
128
unsigned size)
129
{
130
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
131
uint64_t r;
132
133
switch (offset) {
134
case A_SYS_VERSION:
135
- r = 0x41743;
136
+ r = s->sys_version;
137
break;
138
139
case A_SYS_CONFIG:
140
- r = 0x31;
141
+ r = s->sys_config;
142
break;
143
case A_PID4 ... A_CID3:
144
r = sysinfo_id[(offset - A_PID4) / 4];
145
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
146
.valid.max_access_size = 4,
147
};
148
149
+static Property iotkit_sysinfo_props[] = {
150
+ DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
151
+ DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
152
+ DEFINE_PROP_END_OF_LIST()
153
+};
175
+
154
+
176
+ switch (fi->type) {
155
static void iotkit_sysinfo_init(Object *obj)
177
+ case ARMFault_None:
156
{
178
+ return 0;
157
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
179
+ case ARMFault_AddressSize:
158
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_init(Object *obj)
180
+ fsc = fi->level & 3;
159
181
+ break;
160
static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
182
+ case ARMFault_AccessFlag:
161
{
183
+ fsc = (fi->level & 3) | (0x2 << 2);
162
+ DeviceClass *dc = DEVICE_CLASS(klass);
184
+ break;
185
+ case ARMFault_Permission:
186
+ fsc = (fi->level & 3) | (0x3 << 2);
187
+ break;
188
+ case ARMFault_Translation:
189
+ fsc = (fi->level & 3) | (0x1 << 2);
190
+ break;
191
+ case ARMFault_SyncExternal:
192
+ fsc = 0x10 | (fi->ea << 12);
193
+ break;
194
+ case ARMFault_SyncExternalOnWalk:
195
+ fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
196
+ break;
197
+ case ARMFault_SyncParity:
198
+ fsc = 0x18;
199
+ break;
200
+ case ARMFault_SyncParityOnWalk:
201
+ fsc = (fi->level & 3) | (0x7 << 2);
202
+ break;
203
+ case ARMFault_AsyncParity:
204
+ fsc = 0x19;
205
+ break;
206
+ case ARMFault_AsyncExternal:
207
+ fsc = 0x11 | (fi->ea << 12);
208
+ break;
209
+ case ARMFault_Alignment:
210
+ fsc = 0x21;
211
+ break;
212
+ case ARMFault_Debug:
213
+ fsc = 0x22;
214
+ break;
215
+ case ARMFault_TLBConflict:
216
+ fsc = 0x30;
217
+ break;
218
+ case ARMFault_Lockdown:
219
+ fsc = 0x34;
220
+ break;
221
+ case ARMFault_Exclusive:
222
+ fsc = 0x35;
223
+ break;
224
+ default:
225
+ /* Other faults can't occur in a context that requires a
226
+ * long-format status code.
227
+ */
228
+ g_assert_not_reached();
229
+ }
230
+
163
+
231
+ fsc |= 1 << 9;
164
/*
232
+ return fsc;
165
* This device has no guest-modifiable state and so it
233
+}
166
* does not need a reset function or VMState.
167
*/
234
+
168
+
235
/* Do a page table walk and add page to TLB if possible */
169
+ dc->props = iotkit_sysinfo_props;
236
bool arm_tlb_fill(CPUState *cpu, vaddr address,
170
}
237
MMUAccessType access_type, int mmu_idx,
171
172
static const TypeInfo iotkit_sysinfo_info = {
238
--
173
--
239
2.7.4
174
2.20.1
240
175
241
176
diff view generated by jsdifflib
1
When we added the ARMMMUIdx_MSUser MMU index we forgot to
1
The SSE-200 has two Message Handling Units (MHUs), which sit behind
2
add it to the case statement in regime_is_user(), so we
2
the APB PPC0. Wire up some unimplemented-device stubs for these,
3
weren't treating it as unprivileged when doing MPU lookups.
3
since we don't yet implement a real model of this device.
4
Correct the omission.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1512153879-5291-4-git-send-email-peter.maydell@linaro.org
7
Message-id: 20190121185118.18550-16-peter.maydell@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
---
8
---
11
target/arm/helper.c | 1 +
9
include/hw/arm/armsse.h | 3 +++
12
1 file changed, 1 insertion(+)
10
hw/arm/armsse.c | 41 +++++++++++++++++++++++++++++++++++++++++
11
2 files changed, 44 insertions(+)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/include/hw/arm/armsse.h
17
+++ b/target/arm/helper.c
16
+++ b/include/hw/arm/armsse.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
17
@@ -XXX,XX +XXX,XX @@
19
case ARMMMUIdx_S1SE0:
18
#include "hw/watchdog/cmsdk-apb-watchdog.h"
20
case ARMMMUIdx_S1NSE0:
19
#include "hw/misc/iotkit-sysctl.h"
21
case ARMMMUIdx_MUser:
20
#include "hw/misc/iotkit-sysinfo.h"
22
+ case ARMMMUIdx_MSUser:
21
+#include "hw/misc/unimp.h"
23
return true;
22
#include "hw/or-irq.h"
24
default:
23
#include "hw/core/split-irq.h"
25
return false;
24
#include "hw/cpu/cluster.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
IoTKitSysCtl sysctl;
27
IoTKitSysCtl sysinfo;
28
29
+ UnimplementedDeviceState mhu[2];
30
+
31
/*
32
* 'container' holds all devices seen by all CPUs.
33
* 'cpu_container[i]' is the view that CPU i has: this has the
34
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/armsse.c
37
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
39
int num_cpus;
40
uint32_t sys_version;
41
SysConfigFormat sys_config_format;
42
+ bool has_mhus;
43
};
44
45
static const ARMSSEInfo armsse_variants[] = {
46
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
47
.num_cpus = 1,
48
.sys_version = 0x41743,
49
.sys_config_format = IoTKitFormat,
50
+ .has_mhus = false,
51
},
52
};
53
54
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
55
sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
56
sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
57
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
58
+ if (info->has_mhus) {
59
+ sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
60
+ TYPE_UNIMPLEMENTED_DEVICE);
61
+ sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
62
+ TYPE_UNIMPLEMENTED_DEVICE);
63
+ }
64
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
65
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
66
&error_abort, NULL);
67
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
68
* 0x40000000: timer0
69
* 0x40001000: timer1
70
* 0x40002000: dual timer
71
+ * 0x40003000: MHU0 (SSE-200 only)
72
+ * 0x40004000: MHU1 (SSE-200 only)
73
* We must configure and realize each downstream device and connect
74
* it to the appropriate PPC port; then we can realize the PPC and
75
* map its upstream ends to the right place in the container.
76
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
77
return;
78
}
79
80
+ if (info->has_mhus) {
81
+ for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
82
+ char *name = g_strdup_printf("MHU%d", i);
83
+ char *port = g_strdup_printf("port[%d]", i + 3);
84
+
85
+ qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
86
+ qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
87
+ object_property_set_bool(OBJECT(&s->mhu[i]), true,
88
+ "realized", &err);
89
+ if (err) {
90
+ error_propagate(errp, err);
91
+ return;
92
+ }
93
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
94
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
95
+ port, &err);
96
+ if (err) {
97
+ error_propagate(errp, err);
98
+ return;
99
+ }
100
+ g_free(name);
101
+ g_free(port);
102
+ }
103
+ }
104
+
105
object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
106
if (err) {
107
error_propagate(errp, err);
108
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
109
memory_region_add_subregion(&s->container, 0x40001000, mr);
110
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
111
memory_region_add_subregion(&s->container, 0x40002000, mr);
112
+ if (info->has_mhus) {
113
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
114
+ memory_region_add_subregion(&s->container, 0x40003000, mr);
115
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
116
+ memory_region_add_subregion(&s->container, 0x40004000, mr);
117
+ }
118
for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
119
qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
120
qdev_get_gpio_in_named(dev_apb_ppc0,
26
--
121
--
27
2.7.4
122
2.20.1
28
123
29
124
diff view generated by jsdifflib
1
For the TT instruction we're going to need to do an MPU lookup that
1
Add unimplemented-device stubs for the various Power Policy Unit
2
also tells us which MPU region the access hit. This requires us
2
devices that the SSE-200 has.
3
to do the MPU lookup without first doing the SAU security access
4
check, so pull the MPU lookup parts of get_phys_addr_pmsav8()
5
out into their own function.
6
7
The TT instruction also needs to know the MPU region number which
8
the lookup hit, so provide this information to the caller of the
9
MPU lookup code, even though get_phys_addr_pmsav8() doesn't
10
need to know it.
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 1512153879-5291-7-git-send-email-peter.maydell@linaro.org
6
Message-id: 20190121185118.18550-17-peter.maydell@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
---
7
---
17
target/arm/helper.c | 130 +++++++++++++++++++++++++++++++---------------------
8
include/hw/arm/armsse.h | 11 ++++++++
18
1 file changed, 79 insertions(+), 51 deletions(-)
9
hw/arm/armsse.c | 58 +++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 69 insertions(+)
19
11
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
14
--- a/include/hw/arm/armsse.h
23
+++ b/target/arm/helper.c
15
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
16
@@ -XXX,XX +XXX,XX @@
17
18
#define SSE_MAX_CPUS 2
19
20
+/* These define what each PPU in the ppu[] index is for */
21
+#define CPU0CORE_PPU 0
22
+#define CPU1CORE_PPU 1
23
+#define DBG_PPU 2
24
+#define RAM0_PPU 3
25
+#define RAM1_PPU 4
26
+#define RAM2_PPU 5
27
+#define RAM3_PPU 6
28
+#define NUM_PPUS 7
29
+
30
typedef struct ARMSSE {
31
/*< private >*/
32
SysBusDevice parent_obj;
33
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
34
IoTKitSysCtl sysinfo;
35
36
UnimplementedDeviceState mhu[2];
37
+ UnimplementedDeviceState ppu[NUM_PPUS];
38
39
/*
40
* 'container' holds all devices seen by all CPUs.
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/armsse.c
44
+++ b/hw/arm/armsse.c
45
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
46
uint32_t sys_version;
47
SysConfigFormat sys_config_format;
48
bool has_mhus;
49
+ bool has_ppus;
50
};
51
52
static const ARMSSEInfo armsse_variants[] = {
53
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
54
.sys_version = 0x41743,
55
.sys_config_format = IoTKitFormat,
56
.has_mhus = false,
57
+ .has_ppus = false,
58
},
59
};
60
61
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
62
sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
63
TYPE_UNIMPLEMENTED_DEVICE);
64
}
65
+ if (info->has_ppus) {
66
+ for (i = 0; i < info->num_cpus; i++) {
67
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
68
+ int ppuidx = CPU0CORE_PPU + i;
69
+
70
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
71
+ sizeof(s->ppu[ppuidx]),
72
+ TYPE_UNIMPLEMENTED_DEVICE);
73
+ g_free(name);
74
+ }
75
+ sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
76
+ sizeof(s->ppu[DBG_PPU]),
77
+ TYPE_UNIMPLEMENTED_DEVICE);
78
+ for (i = 0; i < info->sram_banks; i++) {
79
+ char *name = g_strdup_printf("RAM%d_PPU", i);
80
+ int ppuidx = RAM0_PPU + i;
81
+
82
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
83
+ sizeof(s->ppu[ppuidx]),
84
+ TYPE_UNIMPLEMENTED_DEVICE);
85
+ g_free(name);
86
+ }
87
+ }
88
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
89
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
90
&error_abort, NULL);
91
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
25
}
92
}
26
}
93
}
27
94
28
-static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
95
+static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
29
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
96
+{
30
- hwaddr *phys_ptr, MemTxAttrs *txattrs,
97
+ /* Map a PPU unimplemented device stub */
31
- int *prot, uint32_t *fsr)
98
+ DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
32
+static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
99
+
33
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
100
+ qdev_prop_set_string(dev, "name", name);
34
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
101
+ qdev_prop_set_uint64(dev, "size", 0x1000);
35
+ int *prot, uint32_t *fsr, uint32_t *mregion)
102
+ qdev_init_nofail(dev);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
104
+}
105
+
106
static void armsse_realize(DeviceState *dev, Error **errp)
36
{
107
{
37
+ /* Perform a PMSAv8 MPU lookup (without also doing the SAU check
108
ARMSSE *s = ARMSSE(dev);
38
+ * that a full phys-to-virt translation does).
109
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
39
+ * mregion is (if not NULL) set to the region number which matched,
40
+ * or -1 if no region number is returned (MPU off, address did not
41
+ * hit a region, address hit in multiple regions).
42
+ */
43
ARMCPU *cpu = arm_env_get_cpu(env);
44
bool is_user = regime_is_user(env, mmu_idx);
45
uint32_t secure = regime_is_secure(env, mmu_idx);
46
int n;
47
int matchregion = -1;
48
bool hit = false;
49
- V8M_SAttributes sattrs = {};
50
51
*phys_ptr = address;
52
*prot = 0;
53
-
54
- if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
55
- v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
56
- if (access_type == MMU_INST_FETCH) {
57
- /* Instruction fetches always use the MMU bank and the
58
- * transaction attribute determined by the fetch address,
59
- * regardless of CPU state. This is painful for QEMU
60
- * to handle, because it would mean we need to encode
61
- * into the mmu_idx not just the (user, negpri) information
62
- * for the current security state but also that for the
63
- * other security state, which would balloon the number
64
- * of mmu_idx values needed alarmingly.
65
- * Fortunately we can avoid this because it's not actually
66
- * possible to arbitrarily execute code from memory with
67
- * the wrong security attribute: it will always generate
68
- * an exception of some kind or another, apart from the
69
- * special case of an NS CPU executing an SG instruction
70
- * in S&NSC memory. So we always just fail the translation
71
- * here and sort things out in the exception handler
72
- * (including possibly emulating an SG instruction).
73
- */
74
- if (sattrs.ns != !secure) {
75
- *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
76
- return true;
77
- }
78
- } else {
79
- /* For data accesses we always use the MMU bank indicated
80
- * by the current CPU state, but the security attributes
81
- * might downgrade a secure access to nonsecure.
82
- */
83
- if (sattrs.ns) {
84
- txattrs->secure = false;
85
- } else if (!secure) {
86
- /* NS access to S memory must fault.
87
- * Architecturally we should first check whether the
88
- * MPU information for this address indicates that we
89
- * are doing an unaligned access to Device memory, which
90
- * should generate a UsageFault instead. QEMU does not
91
- * currently check for that kind of unaligned access though.
92
- * If we added it we would need to do so as a special case
93
- * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
94
- */
95
- *fsr = M_FAKE_FSR_SFAULT;
96
- return true;
97
- }
98
- }
99
+ if (mregion) {
100
+ *mregion = -1;
101
}
110
}
102
111
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
103
/* Unlike the ARM ARM pseudocode, we don't need to check whether this
112
104
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
113
+ if (info->has_ppus) {
105
/* We don't need to look the attribute up in the MAIR0/MAIR1
114
+ /* CPUnCORE_PPU for each CPU */
106
* registers because that only tells us about cacheability.
115
+ for (i = 0; i < info->num_cpus; i++) {
107
*/
116
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
108
+ if (mregion) {
117
+
109
+ *mregion = matchregion;
118
+ map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
119
+ /*
120
+ * We don't support CPU debug so don't create the
121
+ * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
122
+ */
123
+ g_free(name);
110
+ }
124
+ }
111
}
125
+ map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
112
113
*fsr = 0x00d; /* Permission fault */
114
return !(*prot & (1 << access_type));
115
}
116
117
+
126
+
118
+static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
127
+ for (i = 0; i < info->sram_banks; i++) {
119
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
128
+ char *name = g_strdup_printf("RAM%d_PPU", i);
120
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
121
+ int *prot, uint32_t *fsr)
122
+{
123
+ uint32_t secure = regime_is_secure(env, mmu_idx);
124
+ V8M_SAttributes sattrs = {};
125
+
129
+
126
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
130
+ map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
127
+ v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
131
+ g_free(name);
128
+ if (access_type == MMU_INST_FETCH) {
129
+ /* Instruction fetches always use the MMU bank and the
130
+ * transaction attribute determined by the fetch address,
131
+ * regardless of CPU state. This is painful for QEMU
132
+ * to handle, because it would mean we need to encode
133
+ * into the mmu_idx not just the (user, negpri) information
134
+ * for the current security state but also that for the
135
+ * other security state, which would balloon the number
136
+ * of mmu_idx values needed alarmingly.
137
+ * Fortunately we can avoid this because it's not actually
138
+ * possible to arbitrarily execute code from memory with
139
+ * the wrong security attribute: it will always generate
140
+ * an exception of some kind or another, apart from the
141
+ * special case of an NS CPU executing an SG instruction
142
+ * in S&NSC memory. So we always just fail the translation
143
+ * here and sort things out in the exception handler
144
+ * (including possibly emulating an SG instruction).
145
+ */
146
+ if (sattrs.ns != !secure) {
147
+ *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
148
+ *phys_ptr = address;
149
+ *prot = 0;
150
+ return true;
151
+ }
152
+ } else {
153
+ /* For data accesses we always use the MMU bank indicated
154
+ * by the current CPU state, but the security attributes
155
+ * might downgrade a secure access to nonsecure.
156
+ */
157
+ if (sattrs.ns) {
158
+ txattrs->secure = false;
159
+ } else if (!secure) {
160
+ /* NS access to S memory must fault.
161
+ * Architecturally we should first check whether the
162
+ * MPU information for this address indicates that we
163
+ * are doing an unaligned access to Device memory, which
164
+ * should generate a UsageFault instead. QEMU does not
165
+ * currently check for that kind of unaligned access though.
166
+ * If we added it we would need to do so as a special case
167
+ * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
168
+ */
169
+ *fsr = M_FAKE_FSR_SFAULT;
170
+ *phys_ptr = address;
171
+ *prot = 0;
172
+ return true;
173
+ }
174
+ }
132
+ }
175
+ }
133
+ }
176
+
134
+
177
+ return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
135
/* This OR gate wires together outputs from the secure watchdogs to NMI */
178
+ txattrs, prot, fsr, NULL);
136
object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
179
+}
137
if (err) {
180
+
181
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
182
MMUAccessType access_type, ARMMMUIdx mmu_idx,
183
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
184
--
138
--
185
2.7.4
139
2.20.1
186
140
187
141
diff view generated by jsdifflib
1
In ARMv7M the CPU ignores explicit writes to CONTROL.SPSEL
1
The SSE-200 gives each CPU a register bank to use to control its
2
in Handler mode. In v8M the behaviour is slightly different:
2
L1 instruction cache. Put in an unimplemented-device stub for this.
3
writes to the bit are permitted but will have no effect.
4
5
We've already done the hard work to handle the value in
6
CONTROL.SPSEL being out of sync with what stack pointer is
7
actually in use, so all we need to do to fix this last loose
8
end is to update the condition we use to guard whether we
9
call write_v7m_control_spsel() on the register write.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 1512153879-5291-3-git-send-email-peter.maydell@linaro.org
6
Message-id: 20190121185118.18550-18-peter.maydell@linaro.org
14
---
7
---
15
target/arm/helper.c | 5 ++++-
8
include/hw/arm/armsse.h | 1 +
16
1 file changed, 4 insertions(+), 1 deletion(-)
9
hw/arm/armsse.c | 39 ++++++++++++++++++++++++++++++++++++++-
10
2 files changed, 39 insertions(+), 1 deletion(-)
17
11
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
14
--- a/include/hw/arm/armsse.h
21
+++ b/target/arm/helper.c
15
+++ b/include/hw/arm/armsse.h
22
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
23
* thread mode; other bits can be updated by any privileged code.
17
24
* write_v7m_control_spsel() deals with updating the SPSEL bit in
18
UnimplementedDeviceState mhu[2];
25
* env->v7m.control, so we only need update the others.
19
UnimplementedDeviceState ppu[NUM_PPUS];
26
+ * For v7M, we must just ignore explicit writes to SPSEL in handler
20
+ UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
27
+ * mode; for v8M the write is permitted but will have no effect.
21
28
*/
22
/*
29
- if (!arm_v7m_is_handler_mode(env)) {
23
* 'container' holds all devices seen by all CPUs.
30
+ if (arm_feature(env, ARM_FEATURE_V8) ||
24
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
+ !arm_v7m_is_handler_mode(env)) {
25
index XXXXXXX..XXXXXXX 100644
32
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
26
--- a/hw/arm/armsse.c
27
+++ b/hw/arm/armsse.c
28
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
29
SysConfigFormat sys_config_format;
30
bool has_mhus;
31
bool has_ppus;
32
+ bool has_cachectrl;
33
};
34
35
static const ARMSSEInfo armsse_variants[] = {
36
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
37
.sys_config_format = IoTKitFormat,
38
.has_mhus = false,
39
.has_ppus = false,
40
+ .has_cachectrl = false,
41
},
42
};
43
44
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
45
g_free(name);
33
}
46
}
34
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
47
}
48
+ if (info->has_cachectrl) {
49
+ for (i = 0; i < info->num_cpus; i++) {
50
+ char *name = g_strdup_printf("cachectrl%d", i);
51
+
52
+ sysbus_init_child_obj(obj, name, &s->cachectrl[i],
53
+ sizeof(s->cachectrl[i]),
54
+ TYPE_UNIMPLEMENTED_DEVICE);
55
+ g_free(name);
56
+ }
57
+ }
58
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
59
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
60
&error_abort, NULL);
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
63
armsse_get_common_irq_in(s, 10));
64
65
- /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
66
+ /*
67
+ * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
68
+ * private per-CPU region (all these devices are SSE-200 only):
69
+ * 0x50010000: L1 icache control registers
70
+ * 0x50011000: CPUSECCTRL (CPU local security control registers)
71
+ * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
72
+ */
73
+ if (info->has_cachectrl) {
74
+ for (i = 0; i < info->num_cpus; i++) {
75
+ char *name = g_strdup_printf("cachectrl%d", i);
76
+ MemoryRegion *mr;
77
+
78
+ qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
79
+ g_free(name);
80
+ qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
81
+ object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
82
+ "realized", &err);
83
+ if (err) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
89
+ memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
90
+ }
91
+ }
92
93
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
94
/* Devices behind APB PPC1:
35
--
95
--
36
2.7.4
96
2.20.1
37
97
38
98
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav7() return a fault type in the ARMMMUFaultInfo
1
The SSE-200 has a "CPU local security control" register bank; add an
2
structure, which we convert to the FSC at the callsite.
2
unimplemented-device stub for it. (The register bank has only one
3
interesting register, which allows the guest to lock down changes
4
to various CPU registers so they cannot be modified further. We
5
don't support that in our Cortex-M33 model anyway.)
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20190121185118.18550-19-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-8-git-send-email-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper.c | 11 +++++++----
11
include/hw/arm/armsse.h | 1 +
11
1 file changed, 7 insertions(+), 4 deletions(-)
12
hw/arm/armsse.c | 31 +++++++++++++++++++++++++++++++
13
2 files changed, 32 insertions(+)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/include/hw/arm/armsse.h
16
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
18
20
UnimplementedDeviceState mhu[2];
19
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
21
UnimplementedDeviceState ppu[NUM_PPUS];
20
MMUAccessType access_type, ARMMMUIdx mmu_idx,
22
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
21
- hwaddr *phys_ptr, int *prot, uint32_t *fsr)
23
+ UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
22
+ hwaddr *phys_ptr, int *prot,
24
23
+ ARMMMUFaultInfo *fi)
25
/*
24
{
26
* 'container' holds all devices seen by all CPUs.
25
ARMCPU *cpu = arm_env_get_cpu(env);
27
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
26
int n;
28
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
29
--- a/hw/arm/armsse.c
28
if (n == -1) { /* no hits */
30
+++ b/hw/arm/armsse.c
29
if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
31
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
30
/* background fault */
32
bool has_mhus;
31
- *fsr = 0;
33
bool has_ppus;
32
+ fi->type = ARMFault_Background;
34
bool has_cachectrl;
33
return true;
35
+ bool has_cpusecctrl;
34
}
36
};
35
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
37
36
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
38
static const ARMSSEInfo armsse_variants[] = {
39
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
40
.has_mhus = false,
41
.has_ppus = false,
42
.has_cachectrl = false,
43
+ .has_cpusecctrl = false,
44
},
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
48
g_free(name);
37
}
49
}
38
}
50
}
39
51
+ if (info->has_cpusecctrl) {
40
- *fsr = 0x00d; /* Permission fault */
52
+ for (i = 0; i < info->num_cpus; i++) {
41
+ fi->type = ARMFault_Permission;
53
+ char *name = g_strdup_printf("cpusecctrl%d", i);
42
+ fi->level = 1;
54
+
43
return !(*prot & (1 << access_type));
55
+ sysbus_init_child_obj(obj, name, &s->cpusecctrl[i],
44
}
56
+ sizeof(s->cpusecctrl[i]),
45
57
+ TYPE_UNIMPLEMENTED_DEVICE);
46
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
58
+ g_free(name);
47
} else if (arm_feature(env, ARM_FEATURE_V7)) {
59
+ }
48
/* PMSAv7 */
60
+ }
49
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
61
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
50
- phys_ptr, prot, fsr);
62
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
51
+ phys_ptr, prot, fi);
63
&error_abort, NULL);
52
+ *fsr = arm_fi_to_sfsc(fi);
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
53
} else {
65
memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
54
/* Pre-v7 MPU */
66
}
55
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
67
}
68
+ if (info->has_cpusecctrl) {
69
+ for (i = 0; i < info->num_cpus; i++) {
70
+ char *name = g_strdup_printf("CPUSECCTRL%d", i);
71
+ MemoryRegion *mr;
72
+
73
+ qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
74
+ g_free(name);
75
+ qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
76
+ object_property_set_bool(OBJECT(&s->cpusecctrl[i]), true,
77
+ "realized", &err);
78
+ if (err) {
79
+ error_propagate(errp, err);
80
+ return;
81
+ }
82
+
83
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
84
+ memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
85
+ }
86
+ }
87
88
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
89
/* Devices behind APB PPC1:
56
--
90
--
57
2.7.4
91
2.20.1
58
92
59
93
diff view generated by jsdifflib
New patch
1
1
The SSE-200 has a CPU_IDENTITY register block, which is a set of
2
read-only registers. As well as the usual PID/CID registers, there
3
is a single CPUID register which indicates whether the CPU is CPU 0
4
or CPU 1. Implement a model of this register block.
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-20-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/armsse-cpuid.h | 41 ++++++++++
12
hw/misc/armsse-cpuid.c | 134 ++++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
hw/misc/trace-events | 4 +
16
6 files changed, 183 insertions(+)
17
create mode 100644 include/hw/misc/armsse-cpuid.h
18
create mode 100644 hw/misc/armsse-cpuid.c
19
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/Makefile.objs
23
+++ b/hw/misc/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_TZ_PPC) += tz-ppc.o
25
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
26
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
27
obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
28
+obj-$(CONFIG_ARMSSE_CPUID) += armsse-cpuid.o
29
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
31
obj-$(CONFIG_AUX) += auxbus.o
32
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/armsse-cpuid.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * ARM SSE-200 CPU_IDENTITY register block
40
+ *
41
+ * Copyright (c) 2019 Linaro Limited
42
+ * Written by Peter Maydell
43
+ *
44
+ * This program is free software; you can redistribute it and/or modify
45
+ * it under the terms of the GNU General Public License version 2 or
46
+ * (at your option) any later version.
47
+ */
48
+
49
+/*
50
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
51
+ * Arm SSE-200 and documented in
52
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ *
54
+ * QEMU interface:
55
+ * + QOM property "CPUID": the value to use for the CPUID register
56
+ * + sysbus MMIO region 0: the system information register bank
57
+ */
58
+
59
+#ifndef HW_MISC_ARMSSE_CPUID_H
60
+#define HW_MISC_ARMSSE_CPUID_H
61
+
62
+#include "hw/sysbus.h"
63
+
64
+#define TYPE_ARMSSE_CPUID "armsse-cpuid"
65
+#define ARMSSE_CPUID(obj) OBJECT_CHECK(ARMSSECPUID, (obj), TYPE_ARMSSE_CPUID)
66
+
67
+typedef struct ARMSSECPUID {
68
+ /*< private >*/
69
+ SysBusDevice parent_obj;
70
+
71
+ /*< public >*/
72
+ MemoryRegion iomem;
73
+
74
+ /* Properties */
75
+ uint32_t cpuid;
76
+} ARMSSECPUID;
77
+
78
+#endif
79
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
80
new file mode 100644
81
index XXXXXXX..XXXXXXX
82
--- /dev/null
83
+++ b/hw/misc/armsse-cpuid.c
84
@@ -XXX,XX +XXX,XX @@
85
+/*
86
+ * ARM SSE-200 CPU_IDENTITY register block
87
+ *
88
+ * Copyright (c) 2019 Linaro Limited
89
+ * Written by Peter Maydell
90
+ *
91
+ * This program is free software; you can redistribute it and/or modify
92
+ * it under the terms of the GNU General Public License version 2 or
93
+ * (at your option) any later version.
94
+ */
95
+
96
+/*
97
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
98
+ * Arm SSE-200 and documented in
99
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
100
+ *
101
+ * It consists of one read-only CPUID register (set by QOM property), plus the
102
+ * usual ID registers.
103
+ */
104
+
105
+#include "qemu/osdep.h"
106
+#include "qemu/log.h"
107
+#include "trace.h"
108
+#include "qapi/error.h"
109
+#include "sysemu/sysemu.h"
110
+#include "hw/sysbus.h"
111
+#include "hw/registerfields.h"
112
+#include "hw/misc/armsse-cpuid.h"
113
+
114
+REG32(CPUID, 0x0)
115
+REG32(PID4, 0xfd0)
116
+REG32(PID5, 0xfd4)
117
+REG32(PID6, 0xfd8)
118
+REG32(PID7, 0xfdc)
119
+REG32(PID0, 0xfe0)
120
+REG32(PID1, 0xfe4)
121
+REG32(PID2, 0xfe8)
122
+REG32(PID3, 0xfec)
123
+REG32(CID0, 0xff0)
124
+REG32(CID1, 0xff4)
125
+REG32(CID2, 0xff8)
126
+REG32(CID3, 0xffc)
127
+
128
+/* PID/CID values */
129
+static const int sysinfo_id[] = {
130
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
131
+ 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
132
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
133
+};
134
+
135
+static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
136
+ unsigned size)
137
+{
138
+ ARMSSECPUID *s = ARMSSE_CPUID(opaque);
139
+ uint64_t r;
140
+
141
+ switch (offset) {
142
+ case A_CPUID:
143
+ r = s->cpuid;
144
+ break;
145
+ case A_PID4 ... A_CID3:
146
+ r = sysinfo_id[(offset - A_PID4) / 4];
147
+ break;
148
+ default:
149
+ qemu_log_mask(LOG_GUEST_ERROR,
150
+ "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
151
+ r = 0;
152
+ break;
153
+ }
154
+ trace_armsse_cpuid_read(offset, r, size);
155
+ return r;
156
+}
157
+
158
+static void armsse_cpuid_write(void *opaque, hwaddr offset,
159
+ uint64_t value, unsigned size)
160
+{
161
+ trace_armsse_cpuid_write(offset, value, size);
162
+
163
+ qemu_log_mask(LOG_GUEST_ERROR,
164
+ "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
165
+}
166
+
167
+static const MemoryRegionOps armsse_cpuid_ops = {
168
+ .read = armsse_cpuid_read,
169
+ .write = armsse_cpuid_write,
170
+ .endianness = DEVICE_LITTLE_ENDIAN,
171
+ /* byte/halfword accesses are just zero-padded on reads and writes */
172
+ .impl.min_access_size = 4,
173
+ .impl.max_access_size = 4,
174
+ .valid.min_access_size = 1,
175
+ .valid.max_access_size = 4,
176
+};
177
+
178
+static Property armsse_cpuid_props[] = {
179
+ DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
180
+ DEFINE_PROP_END_OF_LIST()
181
+};
182
+
183
+static void armsse_cpuid_init(Object *obj)
184
+{
185
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
186
+ ARMSSECPUID *s = ARMSSE_CPUID(obj);
187
+
188
+ memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
189
+ s, "armsse-cpuid", 0x1000);
190
+ sysbus_init_mmio(sbd, &s->iomem);
191
+}
192
+
193
+static void armsse_cpuid_class_init(ObjectClass *klass, void *data)
194
+{
195
+ DeviceClass *dc = DEVICE_CLASS(klass);
196
+
197
+ /*
198
+ * This device has no guest-modifiable state and so it
199
+ * does not need a reset function or VMState.
200
+ */
201
+
202
+ dc->props = armsse_cpuid_props;
203
+}
204
+
205
+static const TypeInfo armsse_cpuid_info = {
206
+ .name = TYPE_ARMSSE_CPUID,
207
+ .parent = TYPE_SYS_BUS_DEVICE,
208
+ .instance_size = sizeof(ARMSSECPUID),
209
+ .instance_init = armsse_cpuid_init,
210
+ .class_init = armsse_cpuid_class_init,
211
+};
212
+
213
+static void armsse_cpuid_register_types(void)
214
+{
215
+ type_register_static(&armsse_cpuid_info);
216
+}
217
+
218
+type_init(armsse_cpuid_register_types);
219
diff --git a/MAINTAINERS b/MAINTAINERS
220
index XXXXXXX..XXXXXXX 100644
221
--- a/MAINTAINERS
222
+++ b/MAINTAINERS
223
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysctl.c
224
F: include/hw/misc/iotkit-sysctl.h
225
F: hw/misc/iotkit-sysinfo.c
226
F: include/hw/misc/iotkit-sysinfo.h
227
+F: hw/misc/armsse-cpuid.c
228
+F: include/hw/misc/armsse-cpuid.h
229
230
Musicpal
231
M: Jan Kiszka <jan.kiszka@web.de>
232
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
233
index XXXXXXX..XXXXXXX 100644
234
--- a/default-configs/arm-softmmu.mak
235
+++ b/default-configs/arm-softmmu.mak
236
@@ -XXX,XX +XXX,XX @@ CONFIG_ARMSSE=y
237
CONFIG_IOTKIT_SECCTL=y
238
CONFIG_IOTKIT_SYSCTL=y
239
CONFIG_IOTKIT_SYSINFO=y
240
+CONFIG_ARMSSE_CPUID=y
241
242
CONFIG_VERSATILE=y
243
CONFIG_VERSATILE_PCI=y
244
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/misc/trace-events
247
+++ b/hw/misc/trace-events
248
@@ -XXX,XX +XXX,XX @@ iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysI
249
iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
250
iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
251
iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
252
+
253
+# hw/misc/armsse-cpuid.c
254
+armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
255
+armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav5() return a fault type in the ARMMMUFaultInfo
1
Instantiate a copy of the CPU_IDENTITY register block for each CPU
2
structure, which we convert to the FSC at the callsite.
2
in an SSE-200.
3
4
Note that PMSAv5 does not define any guest-visible fault status
5
register, so the different "fsr" values we were previously
6
returning are entirely arbitrary. So we can just switch to using
7
the most appropriae fi->type values without worrying that we
8
need to special-case FaultInfo->FSC conversion for PMSAv5.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Message-id: 20190121185118.18550-21-peter.maydell@linaro.org
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-7-git-send-email-peter.maydell@linaro.org
15
---
7
---
16
target/arm/helper.c | 20 +++++++++++++-------
8
include/hw/arm/armsse.h | 3 +++
17
1 file changed, 13 insertions(+), 7 deletions(-)
9
hw/arm/armsse.c | 28 ++++++++++++++++++++++++++++
10
2 files changed, 31 insertions(+)
18
11
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
14
--- a/include/hw/arm/armsse.h
22
+++ b/target/arm/helper.c
15
+++ b/include/hw/arm/armsse.h
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
16
@@ -XXX,XX +XXX,XX @@
24
17
#include "hw/watchdog/cmsdk-apb-watchdog.h"
25
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
18
#include "hw/misc/iotkit-sysctl.h"
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
19
#include "hw/misc/iotkit-sysinfo.h"
27
- hwaddr *phys_ptr, int *prot, uint32_t *fsr)
20
+#include "hw/misc/armsse-cpuid.h"
28
+ hwaddr *phys_ptr, int *prot,
21
#include "hw/misc/unimp.h"
29
+ ARMMMUFaultInfo *fi)
22
#include "hw/or-irq.h"
30
{
23
#include "hw/core/split-irq.h"
31
int n;
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
32
uint32_t mask;
25
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
26
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
27
28
+ ARMSSECPUID cpuid[SSE_MAX_CPUS];
29
+
30
/*
31
* 'container' holds all devices seen by all CPUs.
32
* 'cpu_container[i]' is the view that CPU i has: this has the
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
38
bool has_ppus;
39
bool has_cachectrl;
40
bool has_cpusecctrl;
41
+ bool has_cpuid;
42
};
43
44
static const ARMSSEInfo armsse_variants[] = {
45
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
46
.has_ppus = false,
47
.has_cachectrl = false,
48
.has_cpusecctrl = false,
49
+ .has_cpuid = false,
50
},
51
};
52
53
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
54
g_free(name);
34
}
55
}
35
}
56
}
36
if (n < 0) {
57
+ if (info->has_cpuid) {
37
- *fsr = 2;
58
+ for (i = 0; i < info->num_cpus; i++) {
38
+ fi->type = ARMFault_Background;
59
+ char *name = g_strdup_printf("cpuid%d", i);
39
return true;
60
+
61
+ sysbus_init_child_obj(obj, name, &s->cpuid[i],
62
+ sizeof(s->cpuid[i]),
63
+ TYPE_ARMSSE_CPUID);
64
+ g_free(name);
65
+ }
66
+ }
67
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
68
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
69
&error_abort, NULL);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
72
}
40
}
73
}
41
74
+ if (info->has_cpuid) {
42
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
75
+ for (i = 0; i < info->num_cpus; i++) {
43
mask = (mask >> (n * 4)) & 0xf;
76
+ MemoryRegion *mr;
44
switch (mask) {
77
+
45
case 0:
78
+ qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
46
- *fsr = 1;
79
+ object_property_set_bool(OBJECT(&s->cpuid[i]), true,
47
+ fi->type = ARMFault_Permission;
80
+ "realized", &err);
48
+ fi->level = 1;
81
+ if (err) {
49
return true;
82
+ error_propagate(errp, err);
50
case 1:
83
+ return;
51
if (is_user) {
84
+ }
52
- *fsr = 1;
85
+
53
+ fi->type = ARMFault_Permission;
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
54
+ fi->level = 1;
87
+ memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
55
return true;
88
+ }
56
}
89
+ }
57
*prot = PAGE_READ | PAGE_WRITE;
90
58
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
91
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
59
break;
92
/* Devices behind APB PPC1:
60
case 5:
61
if (is_user) {
62
- *fsr = 1;
63
+ fi->type = ARMFault_Permission;
64
+ fi->level = 1;
65
return true;
66
}
67
*prot = PAGE_READ;
68
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
69
break;
70
default:
71
/* Bad permission. */
72
- *fsr = 1;
73
+ fi->type = ARMFault_Permission;
74
+ fi->level = 1;
75
return true;
76
}
77
*prot |= PAGE_EXEC;
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
79
} else {
80
/* Pre-v7 MPU */
81
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
82
- phys_ptr, prot, fsr);
83
+ phys_ptr, prot, fi);
84
+ *fsr = arm_fi_to_sfsc(fi);
85
}
86
qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
87
" mmu_idx %u -> %s (prot %c%c%c)\n",
88
--
93
--
89
2.7.4
94
2.20.1
90
95
91
96
diff view generated by jsdifflib
1
For v8M it is possible for the CONTROL.SPSEL bit value and the
1
Add a model of the SSE-200, now we have put in all
2
current stack to be out of sync. This means we need to update
2
the code that lets us make it different from the IoTKit.
3
the checks used in reads and writes of the PSP and MSP special
4
registers to use v7m_using_psp() rather than directly checking
5
the SPSEL bit in the control register.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1512153879-5291-2-git-send-email-peter.maydell@linaro.org
6
Message-id: 20190121185118.18550-22-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
7
---
12
target/arm/helper.c | 10 ++++------
8
include/hw/arm/armsse.h | 19 ++++++++++++++++---
13
1 file changed, 4 insertions(+), 6 deletions(-)
9
hw/arm/armsse.c | 12 ++++++++++++
10
2 files changed, 28 insertions(+), 3 deletions(-)
14
11
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
14
--- a/include/hw/arm/armsse.h
18
+++ b/target/arm/helper.c
15
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
16
@@ -XXX,XX +XXX,XX @@
20
17
/*
21
switch (reg) {
18
- * ARM SSE (Subsystems for Embedded): IoTKit
22
case 8: /* MSP */
19
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
23
- return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
20
*
24
- env->v7m.other_sp : env->regs[13];
21
* Copyright (c) 2018 Linaro Limited
25
+ return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
22
* Written by Peter Maydell
26
case 9: /* PSP */
23
@@ -XXX,XX +XXX,XX @@
27
- return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
24
/*
28
- env->regs[13] : env->v7m.other_sp;
25
* This is a model of the Arm "Subsystems for Embedded" family of
29
+ return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
26
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
30
case 16: /* PRIMASK */
27
- * SSE-200. Currently we model only the Arm IoT Kit which is documented in
31
return env->v7m.primask[env->v7m.secure];
28
+ * SSE-200. Currently we model:
32
case 17: /* BASEPRI */
29
+ * - the Arm IoT Kit which is documented in
33
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
30
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
34
}
31
- * It contains:
35
break;
32
+ * - the SSE-200 which is documented in
36
case 8: /* MSP */
33
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
37
- if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
34
+ *
38
+ if (v7m_using_psp(env)) {
35
+ * The IoTKit contains:
39
env->v7m.other_sp = val;
36
* a Cortex-M33
40
} else {
37
* the IDAU
41
env->regs[13] = val;
38
* some timers and watchdogs
42
}
39
@@ -XXX,XX +XXX,XX @@
43
break;
40
* a security controller
44
case 9: /* PSP */
41
* a bus fabric which arranges that some parts of the address
45
- if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
42
* space are secure and non-secure aliases of each other
46
+ if (v7m_using_psp(env)) {
43
+ * The SSE-200 additionally contains:
47
env->regs[13] = val;
44
+ * a second Cortex-M33
48
} else {
45
+ * two Message Handling Units (MHUs)
49
env->v7m.other_sp = val;
46
+ * an optional CryptoCell (which we do not model)
47
+ * more SRAM banks with associated MPCs
48
+ * multiple Power Policy Units (PPUs)
49
+ * a control interface for an icache for each CPU
50
+ * per-CPU identity and control register blocks
51
*
52
* QEMU interface:
53
* + QOM property "memory" is a MemoryRegion containing the devices provided
54
@@ -XXX,XX +XXX,XX @@
55
* them via the ARMSSE base class, so they have no IOTKIT() etc macros.
56
*/
57
#define TYPE_IOTKIT "iotkit"
58
+#define TYPE_SSE200 "sse-200"
59
60
/* We have an IRQ splitter and an OR gate input for each external PPC
61
* and the 2 internal PPCs
62
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/armsse.c
65
+++ b/hw/arm/armsse.c
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
67
.has_cpusecctrl = false,
68
.has_cpuid = false,
69
},
70
+ {
71
+ .name = TYPE_SSE200,
72
+ .sram_banks = 4,
73
+ .num_cpus = 2,
74
+ .sys_version = 0x22041743,
75
+ .sys_config_format = SSE200Format,
76
+ .has_mhus = true,
77
+ .has_ppus = true,
78
+ .has_cachectrl = true,
79
+ .has_cpusecctrl = true,
80
+ .has_cpuid = true,
81
+ },
82
};
83
84
static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
50
--
85
--
51
2.7.4
86
2.20.1
52
87
53
88
diff view generated by jsdifflib
1
Implement the TT instruction which queries the security
1
In preparation for adding support for the AN521 MPS2 image, we need
2
state and access permissions of a memory location.
2
to handle wiring up the MPS2 device interrupt lines to both CPUs in
3
the SSE-200, rather than just the one that the IoTKit has.
4
5
Abstract out a "connect to the IoTKit interrupt line" function
6
and make it connect to a splitter which feeds both sets of inputs
7
for the SSE-200 case.
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1512153879-5291-8-git-send-email-peter.maydell@linaro.org
11
Message-id: 20190121185118.18550-23-peter.maydell@linaro.org
7
---
12
---
8
target/arm/helper.h | 2 +
13
hw/arm/mps2-tz.c | 79 ++++++++++++++++++++++++++++++++++++------------
9
target/arm/helper.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 59 insertions(+), 20 deletions(-)
10
target/arm/translate.c | 29 ++++++++++++-
11
3 files changed, 138 insertions(+), 1 deletion(-)
12
15
13
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.h
18
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/helper.h
19
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_mrs, i32, env, i32)
20
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_2(v7m_bxns, void, env, i32)
21
#include "net/net.h"
19
DEF_HELPER_2(v7m_blxns, void, env, i32)
22
#include "hw/core/split-irq.h"
20
23
21
+DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
24
+#define MPS2TZ_NUMIRQ 92
22
+
25
+
23
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
26
typedef enum MPS2TZFPGAType {
24
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
27
FPGA_AN505,
25
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
28
+ FPGA_AN521,
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
} MPS2TZFPGAType;
27
index XXXXXXX..XXXXXXX 100644
30
28
--- a/target/arm/helper.c
31
typedef struct {
29
+++ b/target/arm/helper.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
33
SplitIRQ sec_resp_splitter;
31
g_assert_not_reached();
34
qemu_or_irq uart_irq_orgate;
35
DeviceState *lan9118;
36
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
37
} MPS2TZMachineState;
38
39
#define TYPE_MPS2TZ_MACHINE "mps2tz"
40
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
41
memory_region_add_subregion(get_system_memory(), base, mr);
32
}
42
}
33
43
34
+uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
44
+static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
35
+{
45
+{
36
+ /* The TT instructions can be used by unprivileged code, but in
46
+ /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
37
+ * user-only emulation we don't have the MPU.
47
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
38
+ * Luckily since we know we are NonSecure unprivileged (and that in
48
+
39
+ * turn means that the A flag wasn't specified), all the bits in the
49
+ assert(irqno < MPS2TZ_NUMIRQ);
40
+ * register must be zero:
50
+
41
+ * IREGION: 0 because IRVALID is 0
51
+ switch (mmc->fpga_type) {
42
+ * IRVALID: 0 because NS
52
+ case FPGA_AN505:
43
+ * S: 0 because NS
53
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
44
+ * NSRW: 0 because NS
54
+ case FPGA_AN521:
45
+ * NSR: 0 because NS
55
+ return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
46
+ * RW: 0 because unpriv and A flag not set
56
+ default:
47
+ * R: 0 because unpriv and A flag not set
57
+ g_assert_not_reached();
48
+ * SRVALID: 0 because NS
58
+ }
49
+ * MRVALID: 0 because unpriv and A flag not set
50
+ * SREGION: 0 becaus SRVALID is 0
51
+ * MREGION: 0 because MRVALID is 0
52
+ */
53
+ return 0;
54
+}
59
+}
55
+
60
+
56
void switch_mode(CPUARMState *env, int mode)
61
/* Most of the devices in the AN505 FPGA image sit behind
62
* Peripheral Protection Controllers. These data structures
63
* define the layout of which devices sit behind which PPCs.
64
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
65
int txirqno = i * 2 + 1;
66
int combirqno = i + 10;
67
SysBusDevice *s;
68
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
70
71
sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
72
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
73
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
74
object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
75
s = SYS_BUS_DEVICE(uart);
76
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
77
- "EXP_IRQ", txirqno));
78
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
79
- "EXP_IRQ", rxirqno));
80
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
81
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
82
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
83
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
84
- sysbus_connect_irq(s, 4, qdev_get_gpio_in_named(iotkitdev,
85
- "EXP_IRQ", combirqno));
86
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
87
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
88
}
89
90
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
91
const char *name, hwaddr size)
57
{
92
{
58
ARMCPU *cpu = arm_env_get_cpu(env);
93
SysBusDevice *s;
59
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
94
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
60
}
95
NICInfo *nd = &nd_table[0];
96
97
/* In hardware this is a LAN9220; the LAN9118 is software compatible
98
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
99
qdev_init_nofail(mms->lan9118);
100
101
s = SYS_BUS_DEVICE(mms->lan9118);
102
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
103
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
104
return sysbus_mmio_get_region(s, 0);
61
}
105
}
62
106
63
+uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
107
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
64
+{
108
65
+ /* Implement the TT instruction. op is bits [7:6] of the insn. */
109
s = SYS_BUS_DEVICE(dma);
66
+ bool forceunpriv = op & 1;
110
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
67
+ bool alt = op & 2;
111
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
68
+ V8M_SAttributes sattrs = {};
112
- "EXP_IRQ", 58 + i * 3));
69
+ uint32_t tt_resp;
113
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
70
+ bool r, rw, nsr, nsrw, mrvalid;
114
- "EXP_IRQ", 56 + i * 3));
71
+ int prot;
115
- sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev,
72
+ MemTxAttrs attrs = {};
116
- "EXP_IRQ", 57 + i * 3));
73
+ hwaddr phys_addr;
117
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
74
+ uint32_t fsr;
118
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
75
+ ARMMMUIdx mmu_idx;
119
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
76
+ uint32_t mregion;
120
77
+ bool targetpriv;
121
g_free(mscname);
78
+ bool targetsec = env->v7m.secure;
122
return sysbus_mmio_get_region(s, 0);
123
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
124
*/
125
PL022State *spi = opaque;
126
int i = spi - &mms->spi[0];
127
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
128
SysBusDevice *s;
129
130
sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
131
TYPE_PL022);
132
object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
133
s = SYS_BUS_DEVICE(spi);
134
- sysbus_connect_irq(s, 0,
135
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i));
136
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
137
return sysbus_mmio_get_region(s, 0);
138
}
139
140
static void mps2tz_common_init(MachineState *machine)
141
{
142
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
143
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
144
MachineClass *mc = MACHINE_GET_CLASS(machine);
145
MemoryRegion *system_memory = get_system_memory();
146
DeviceState *iotkitdev;
147
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
148
iotkitdev = DEVICE(&mms->iotkit);
149
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
150
"memory", &error_abort);
151
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", 92);
152
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
153
qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
154
object_property_set_bool(OBJECT(&mms->iotkit), true, "realized",
155
&error_fatal);
156
157
+ /*
158
+ * The AN521 needs us to create splitters to feed the IRQ inputs
159
+ * for each CPU in the SSE-200 from each device in the board.
160
+ */
161
+ if (mmc->fpga_type == FPGA_AN521) {
162
+ for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
163
+ char *name = g_strdup_printf("mps2-irq-splitter%d", i);
164
+ SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
79
+
165
+
80
+ /* Work out what the security state and privilege level we're
166
+ object_initialize_child(OBJECT(machine), name,
81
+ * interested in is...
167
+ splitter, sizeof(*splitter),
82
+ */
168
+ TYPE_SPLIT_IRQ, &error_fatal, NULL);
83
+ if (alt) {
169
+ g_free(name);
84
+ targetsec = !targetsec;
170
+
171
+ object_property_set_int(OBJECT(splitter), 2, "num-lines",
172
+ &error_fatal);
173
+ object_property_set_bool(OBJECT(splitter), true, "realized",
174
+ &error_fatal);
175
+ qdev_connect_gpio_out(DEVICE(splitter), 0,
176
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
177
+ "EXP_IRQ", i));
178
+ qdev_connect_gpio_out(DEVICE(splitter), 1,
179
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
180
+ "EXP_CPU1_IRQ", i));
181
+ }
85
+ }
182
+ }
86
+
183
+
87
+ if (forceunpriv) {
184
/* The sec_resp_cfg output from the IoTKit must be split into multiple
88
+ targetpriv = false;
185
* lines, one for each of the PPCs we create here, plus one per MSC.
89
+ } else {
186
*/
90
+ targetpriv = arm_v7m_is_handler_mode(env) ||
187
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
91
+ !(env->v7m.control[targetsec] & R_V7M_CONTROL_NPRIV_MASK);
188
object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true,
92
+ }
189
"realized", &error_fatal);
93
+
190
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
94
+ /* ...and then figure out which MMU index this is */
191
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 15));
95
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targetsec, targetpriv);
192
+ get_sse_irq_in(mms, 15));
96
+
193
97
+ /* We know that the MPU and SAU don't care about the access type
194
/* Most of the devices in the FPGA are behind Peripheral Protection
98
+ * for our purposes beyond that we don't want to claim to be
195
* Controllers. The required order for initializing things is:
99
+ * an insn fetch, so we arbitrarily call this a read.
100
+ */
101
+
102
+ /* MPU region info only available for privileged or if
103
+ * inspecting the other MPU state.
104
+ */
105
+ if (arm_current_el(env) != 0 || alt) {
106
+ /* We can ignore the return value as prot is always set */
107
+ pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
108
+ &phys_addr, &attrs, &prot, &fsr, &mregion);
109
+ if (mregion == -1) {
110
+ mrvalid = false;
111
+ mregion = 0;
112
+ } else {
113
+ mrvalid = true;
114
+ }
115
+ r = prot & PAGE_READ;
116
+ rw = prot & PAGE_WRITE;
117
+ } else {
118
+ r = false;
119
+ rw = false;
120
+ mrvalid = false;
121
+ mregion = 0;
122
+ }
123
+
124
+ if (env->v7m.secure) {
125
+ v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
126
+ nsr = sattrs.ns && r;
127
+ nsrw = sattrs.ns && rw;
128
+ } else {
129
+ sattrs.ns = true;
130
+ nsr = false;
131
+ nsrw = false;
132
+ }
133
+
134
+ tt_resp = (sattrs.iregion << 24) |
135
+ (sattrs.irvalid << 23) |
136
+ ((!sattrs.ns) << 22) |
137
+ (nsrw << 21) |
138
+ (nsr << 20) |
139
+ (rw << 19) |
140
+ (r << 18) |
141
+ (sattrs.srvalid << 17) |
142
+ (mrvalid << 16) |
143
+ (sattrs.sregion << 8) |
144
+ mregion;
145
+
146
+ return tt_resp;
147
+}
148
+
149
#endif
150
151
void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
157
if (insn & (1 << 22)) {
158
/* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
159
* - load/store doubleword, load/store exclusive, ldacq/strel,
160
- * table branch.
161
+ * table branch, TT.
162
*/
163
if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
164
arm_dc_feature(s, ARM_FEATURE_V8)) {
165
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
166
} else if ((insn & (1 << 23)) == 0) {
167
/* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
168
* - load/store exclusive word
169
+ * - TT (v8M only)
170
*/
171
if (rs == 15) {
172
+ if (!(insn & (1 << 20)) &&
173
+ arm_dc_feature(s, ARM_FEATURE_M) &&
174
+ arm_dc_feature(s, ARM_FEATURE_V8)) {
175
+ /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
176
+ * - TT (v8M only)
177
+ */
178
+ bool alt = insn & (1 << 7);
179
+ TCGv_i32 addr, op, ttresp;
180
+
181
+ if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
182
+ /* we UNDEF for these UNPREDICTABLE cases */
183
+ goto illegal_op;
184
+ }
185
+
186
+ if (alt && !s->v8m_secure) {
187
+ goto illegal_op;
188
+ }
189
+
190
+ addr = load_reg(s, rn);
191
+ op = tcg_const_i32(extract32(insn, 6, 2));
192
+ ttresp = tcg_temp_new_i32();
193
+ gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
194
+ tcg_temp_free_i32(addr);
195
+ tcg_temp_free_i32(op);
196
+ store_reg(s, rd, ttresp);
197
+ }
198
goto illegal_op;
199
}
200
addr = tcg_temp_local_new_i32();
201
--
196
--
202
2.7.4
197
2.20.1
203
198
204
199
diff view generated by jsdifflib
1
Now that ARMMMUFaultInfo is guaranteed to have enough information
1
Add a model of the MPS2 FPGA image described in Application Note
2
to construct a fault status code, we can pass it in to the
2
AN521. This is identical to the AN505 image, except that it uses
3
deliver_fault() function and let it generate the correct type
3
the SSE-200 rather than the IoTKit and so has two Cortex-M33 CPUs.
4
of FSR for the destination, rather than relying on the value
5
provided by get_phys_addr().
6
7
I don't think there are any cases the old code was getting
8
wrong, but this is more obviously correct.
9
4
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20190121185118.18550-24-peter.maydell@linaro.org
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-10-git-send-email-peter.maydell@linaro.org
15
---
8
---
16
target/arm/op_helper.c | 79 ++++++++++++++------------------------------------
9
hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++++++--
17
1 file changed, 22 insertions(+), 57 deletions(-)
10
1 file changed, 36 insertions(+), 2 deletions(-)
18
11
19
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/op_helper.c
14
--- a/hw/arm/mps2-tz.c
22
+++ b/target/arm/op_helper.c
15
+++ b/hw/arm/mps2-tz.c
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
16
@@ -XXX,XX +XXX,XX @@
17
* as seen by the guest depend significantly on the FPGA image.
18
* This source file covers the following FPGA images, for TrustZone cores:
19
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
20
+ * "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
21
*
22
* Links to the TRM for the board itself and to the various Application
23
* Notes which document the FPGA images can be found here:
24
@@ -XXX,XX +XXX,XX @@
25
* http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
26
* Application Note AN505:
27
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
28
+ * Application Note AN521:
29
+ * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
30
*
31
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
32
* (ARM ECM0601256) for the details of some of the device layout:
33
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
34
+ * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
35
+ * most of the device layout:
36
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
37
+ *
38
*/
39
40
#include "qemu/osdep.h"
41
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
MachineClass parent;
43
MPS2TZFPGAType fpga_type;
44
uint32_t scc_id;
45
+ const char *armsse_type;
46
} MPS2TZMachineClass;
47
48
typedef struct {
49
@@ -XXX,XX +XXX,XX @@ typedef struct {
50
51
#define TYPE_MPS2TZ_MACHINE "mps2tz"
52
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
53
+#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
54
55
#define MPS2TZ_MACHINE(obj) \
56
OBJECT_CHECK(MPS2TZMachineState, obj, TYPE_MPS2TZ_MACHINE)
57
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
58
}
59
60
sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
61
- sizeof(mms->iotkit), TYPE_IOTKIT);
62
+ sizeof(mms->iotkit), mmc->armsse_type);
63
iotkitdev = DEVICE(&mms->iotkit);
64
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
65
"memory", &error_abort);
66
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
67
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
68
69
mc->init = mps2tz_common_init;
70
- mc->max_cpus = 1;
71
iic->check = mps2_tz_idau_check;
24
}
72
}
25
73
26
static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
74
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
27
- uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
75
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
28
+ int mmu_idx, ARMMMUFaultInfo *fi)
76
77
mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
78
+ mc->default_cpus = 1;
79
+ mc->min_cpus = mc->default_cpus;
80
+ mc->max_cpus = mc->default_cpus;
81
mmc->fpga_type = FPGA_AN505;
82
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
83
mmc->scc_id = 0x41045050;
84
+ mmc->armsse_type = TYPE_IOTKIT;
85
+}
86
+
87
+static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
88
+{
89
+ MachineClass *mc = MACHINE_CLASS(oc);
90
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
91
+
92
+ mc->desc = "ARM MPS2 with AN521 FPGA image for dual Cortex-M33";
93
+ mc->default_cpus = 2;
94
+ mc->min_cpus = mc->default_cpus;
95
+ mc->max_cpus = mc->default_cpus;
96
+ mmc->fpga_type = FPGA_AN521;
97
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
98
+ mmc->scc_id = 0x41045210;
99
+ mmc->armsse_type = TYPE_SSE200;
100
}
101
102
static const TypeInfo mps2tz_info = {
103
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an505_info = {
104
.class_init = mps2tz_an505_class_init,
105
};
106
107
+static const TypeInfo mps2tz_an521_info = {
108
+ .name = TYPE_MPS2TZ_AN521_MACHINE,
109
+ .parent = TYPE_MPS2TZ_MACHINE,
110
+ .class_init = mps2tz_an521_class_init,
111
+};
112
+
113
static void mps2tz_machine_init(void)
29
{
114
{
30
CPUARMState *env = &cpu->env;
115
type_register_static(&mps2tz_info);
31
int target_el;
116
type_register_static(&mps2tz_an505_info);
32
bool same_el;
117
+ type_register_static(&mps2tz_an521_info);
33
- uint32_t syn, exc;
34
+ uint32_t syn, exc, fsr, fsc;
35
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
36
37
target_el = exception_target_el(env);
38
if (fi->stage2) {
39
@@ -XXX,XX +XXX,XX @@ static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
40
}
41
same_el = (arm_current_el(env) == target_el);
42
43
- if (fsc == 0x3f) {
44
- /* Caller doesn't have a long-format fault status code. This
45
- * should only happen if this fault will never actually be reported
46
- * to an EL that uses a syndrome register. Check that here.
47
- * 0x3f is a (currently) reserved FSC code, in case the constructed
48
- * syndrome does leak into the guest somehow.
49
+ if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
50
+ arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
51
+ /* LPAE format fault status register : bottom 6 bits are
52
+ * status code in the same form as needed for syndrome
53
+ */
54
+ fsr = arm_fi_to_lfsc(fi);
55
+ fsc = extract32(fsr, 0, 6);
56
+ } else {
57
+ fsr = arm_fi_to_sfsc(fi);
58
+ /* Short format FSR : this fault will never actually be reported
59
+ * to an EL that uses a syndrome register. Use a (currently)
60
+ * reserved FSR code in case the constructed syndrome does leak
61
+ * into the guest somehow.
62
*/
63
- assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
64
+ fsc = 0x3f;
65
}
66
67
if (access_type == MMU_INST_FETCH) {
68
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
69
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
70
if (unlikely(ret)) {
71
ARMCPU *cpu = ARM_CPU(cs);
72
- uint32_t fsc;
73
74
if (retaddr) {
75
/* now we have a real cpu fault */
76
cpu_restore_state(cs, retaddr);
77
}
78
79
- if (fsr & (1 << 9)) {
80
- /* LPAE format fault status register : bottom 6 bits are
81
- * status code in the same form as needed for syndrome
82
- */
83
- fsc = extract32(fsr, 0, 6);
84
- } else {
85
- /* Short format FSR : this fault will never actually be reported
86
- * to an EL that uses a syndrome register. Use a (currently)
87
- * reserved FSR code in case the constructed syndrome does leak
88
- * into the guest somehow. deliver_fault will assert that
89
- * we don't target an EL using the syndrome.
90
- */
91
- fsc = 0x3f;
92
- }
93
-
94
- deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
95
+ deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
96
}
97
}
118
}
98
119
99
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
120
type_init(mps2tz_machine_init);
100
int mmu_idx, uintptr_t retaddr)
101
{
102
ARMCPU *cpu = ARM_CPU(cs);
103
- CPUARMState *env = &cpu->env;
104
- uint32_t fsr, fsc;
105
ARMMMUFaultInfo fi = {};
106
- ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
107
108
if (retaddr) {
109
/* now we have a real cpu fault */
110
cpu_restore_state(cs, retaddr);
111
}
112
113
- /* the DFSR for an alignment fault depends on whether we're using
114
- * the LPAE long descriptor format, or the short descriptor format
115
- */
116
- if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
117
- fsr = (1 << 9) | 0x21;
118
- } else {
119
- fsr = 0x1;
120
- }
121
- fsc = 0x21;
122
-
123
- deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
124
+ fi.type = ARMFault_Alignment;
125
+ deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
/* arm_cpu_do_transaction_failed: handle a memory system error response
129
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
130
MemTxResult response, uintptr_t retaddr)
131
{
132
ARMCPU *cpu = ARM_CPU(cs);
133
- CPUARMState *env = &cpu->env;
134
- uint32_t fsr, fsc;
135
ARMMMUFaultInfo fi = {};
136
- ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
137
138
if (retaddr) {
139
/* now we have a real cpu fault */
140
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
141
* Slave error (1); in QEMU we follow that.
142
*/
143
fi.ea = (response != MEMTX_DECODE_ERROR);
144
-
145
- /* The fault status register format depends on whether we're using
146
- * the LPAE long descriptor format, or the short descriptor format.
147
- */
148
- if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
149
- /* long descriptor form, STATUS 0b010000: synchronous ext abort */
150
- fsr = (fi.ea << 12) | (1 << 9) | 0x10;
151
- } else {
152
- /* short descriptor form, FSR 0b01000 : synchronous ext abort */
153
- fsr = (fi.ea << 12) | 0x8;
154
- }
155
- fsc = 0x10;
156
-
157
- deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
158
+ fi.type = ARMFault_SyncExternal;
159
+ deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
160
}
161
162
#endif /* !defined(CONFIG_USER_ONLY) */
163
--
121
--
164
2.7.4
122
2.20.1
165
123
166
124
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
The "system instructions" and "system register move" subcategories
2
of "branches, exception generating and system instructions" for A64
3
only apply if bits [23:22] are zero; other values are currently
4
unallocated. Correctly UNDEF these unallocated encodings.
2
5
3
Add support for 4 byte addresses in the LQSPI and correct LQSPI_CFG_SEP_BUS.
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20171126231634.9531-11-frasse.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-2-peter.maydell@linaro.org
11
---
10
---
12
hw/ssi/xilinx_spips.c | 6 +++++-
11
target/arm/translate-a64.c | 6 +++++-
13
1 file changed, 5 insertions(+), 1 deletion(-)
12
1 file changed, 5 insertions(+), 1 deletion(-)
14
13
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
16
--- a/target/arm/translate-a64.c
18
+++ b/hw/ssi/xilinx_spips.c
17
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
20
#define R_LQSPI_CFG_RESET 0x03A002EB
19
break;
21
#define LQSPI_CFG_LQ_MODE (1U << 31)
20
case 0x6a: /* Exception generation / System */
22
#define LQSPI_CFG_TWO_MEM (1 << 30)
21
if (insn & (1 << 24)) {
23
-#define LQSPI_CFG_SEP_BUS (1 << 30)
22
- disas_system(s, insn);
24
+#define LQSPI_CFG_SEP_BUS (1 << 29)
23
+ if (extract32(insn, 22, 2) == 0) {
25
#define LQSPI_CFG_U_PAGE (1 << 28)
24
+ disas_system(s, insn);
26
+#define LQSPI_CFG_ADDR4 (1 << 27)
25
+ } else {
27
#define LQSPI_CFG_MODE_EN (1 << 25)
26
+ unallocated_encoding(s);
28
#define LQSPI_CFG_MODE_WIDTH 8
27
+ }
29
#define LQSPI_CFG_MODE_SHIFT 16
28
} else {
30
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
29
disas_exc(s, insn);
31
fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE);
30
}
32
/* read address */
33
DB_PRINT_L(0, "pushing read address %06x\n", flash_addr);
34
+ if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_ADDR4) {
35
+ fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 24));
36
+ }
37
fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16));
38
fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8));
39
fifo8_push(&s->tx_fifo, (uint8_t)flash_addr);
40
--
31
--
41
2.7.4
32
2.20.1
42
33
43
34
diff view generated by jsdifflib
New patch
1
The PRFM prefetch insn in the load/store with imm9 encodings
2
requires idx field 0b00; we were underdecoding this by
3
only checking !is_unpriv (which is equivalent to idx != 2).
4
Correctly UNDEF the unallocated encodings where idx == 0b01
5
and 0b11 as well as 0b10.
1
6
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-3-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
20
} else {
21
if (size == 3 && opc == 2) {
22
/* PRFM - prefetch */
23
- if (is_unpriv) {
24
+ if (idx != 0) {
25
unallocated_encoding(s);
26
return;
27
}
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
In the AdvSIMD load/store multiple structures encodings,
2
the non-post-indexed case should have zeroes in [20:16]
3
(which is the Rm field for the post-indexed case).
4
Correctly UNDEF the currently unallocated encodings which
5
have non-zeroes in those bits.
2
6
3
Add support for the ZynqMP QSPI (consisting of the Generic QSPI and Legacy
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
QSPI) and connect Numonyx n25q512a11 flashes to it.
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-4-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 7 ++++++-
13
1 file changed, 6 insertions(+), 1 deletion(-)
5
14
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20171126231634.9531-14-frasse.iglesias@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/hw/arm/xlnx-zynqmp.h | 5 +++++
15
hw/arm/xlnx-zcu102.c | 23 +++++++++++++++++++++++
16
hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++++++++++++++
17
3 files changed, 54 insertions(+)
18
19
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/xlnx-zynqmp.h
17
--- a/target/arm/translate-a64.c
22
+++ b/include/hw/arm/xlnx-zynqmp.h
18
+++ b/target/arm/translate-a64.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
24
#define XLNX_ZYNQMP_NUM_SDHCI 2
20
{
25
#define XLNX_ZYNQMP_NUM_SPIS 2
21
int rt = extract32(insn, 0, 5);
26
22
int rn = extract32(insn, 5, 5);
27
+#define XLNX_ZYNQMP_NUM_QSPI_BUS 2
23
+ int rm = extract32(insn, 16, 5);
28
+#define XLNX_ZYNQMP_NUM_QSPI_BUS_CS 2
24
int size = extract32(insn, 10, 2);
29
+#define XLNX_ZYNQMP_NUM_QSPI_FLASH 4
25
int opcode = extract32(insn, 12, 4);
30
+
26
bool is_store = !extract32(insn, 22, 1);
31
#define XLNX_ZYNQMP_NUM_OCM_BANKS 4
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
32
#define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000
28
return;
33
#define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000
34
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxZynqMPState {
35
SysbusAHCIState sata;
36
SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
37
XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
38
+ XlnxZynqMPQSPIPS qspi;
39
XlnxDPState dp;
40
XlnxDPDMAState dpdma;
41
42
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/xlnx-zcu102.c
45
+++ b/hw/arm/xlnx-zcu102.c
46
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine)
47
sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi[i]), 1, cs_line);
48
}
29
}
49
30
50
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_FLASH; i++) {
31
+ if (!is_postidx && rm != 0) {
51
+ SSIBus *spi_bus;
32
+ unallocated_encoding(s);
52
+ DeviceState *flash_dev;
33
+ return;
53
+ qemu_irq cs_line;
54
+ DriveInfo *dinfo = drive_get_next(IF_MTD);
55
+ int bus = i / XLNX_ZYNQMP_NUM_QSPI_BUS_CS;
56
+ gchar *bus_name = g_strdup_printf("qspi%d", bus);
57
+
58
+ spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
59
+ g_free(bus_name);
60
+
61
+ flash_dev = ssi_create_slave_no_init(spi_bus, "n25q512a11");
62
+ if (dinfo) {
63
+ qdev_prop_set_drive(flash_dev, "drive", blk_by_legacy_dinfo(dinfo),
64
+ &error_fatal);
65
+ }
66
+ qdev_init_nofail(flash_dev);
67
+
68
+ cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
69
+
70
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.qspi), i + 1, cs_line);
71
+ }
34
+ }
72
+
35
+
73
/* TODO create and connect IDE devices for ide_drive_get() */
36
/* From the shared decode logic */
74
37
switch (opcode) {
75
xlnx_zcu102_binfo.ram_size = ram_size;
38
case 0x0:
76
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
39
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/arm/xlnx-zynqmp.c
79
+++ b/hw/arm/xlnx-zynqmp.c
80
@@ -XXX,XX +XXX,XX @@
81
#define SATA_ADDR 0xFD0C0000
82
#define SATA_NUM_PORTS 2
83
84
+#define QSPI_ADDR 0xff0f0000
85
+#define LQSPI_ADDR 0xc0000000
86
+#define QSPI_IRQ 15
87
+
88
#define DP_ADDR 0xfd4a0000
89
#define DP_IRQ 113
90
91
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
92
qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
93
}
40
}
94
41
95
+ object_initialize(&s->qspi, sizeof(s->qspi), TYPE_XLNX_ZYNQMP_QSPIPS);
42
if (is_postidx) {
96
+ qdev_set_parent_bus(DEVICE(&s->qspi), sysbus_get_default());
43
- int rm = extract32(insn, 16, 5);
97
+
44
if (rm == 31) {
98
object_initialize(&s->dp, sizeof(s->dp), TYPE_XLNX_DP);
45
tcg_gen_mov_i64(tcg_rn, tcg_addr);
99
qdev_set_parent_bus(DEVICE(&s->dp), sysbus_get_default());
46
} else {
100
101
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
102
g_free(bus_name);
103
}
104
105
+ object_property_set_bool(OBJECT(&s->qspi), true, "realized", &err);
106
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
107
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
108
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
109
+
110
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
111
+ gchar *bus_name;
112
+ gchar *target_bus;
113
+
114
+ /* Alias controller SPI bus to the SoC itself */
115
+ bus_name = g_strdup_printf("qspi%d", i);
116
+ target_bus = g_strdup_printf("spi%d", i);
117
+ object_property_add_alias(OBJECT(s), bus_name,
118
+ OBJECT(&s->qspi), target_bus,
119
+ &error_abort);
120
+ g_free(bus_name);
121
+ g_free(target_bus);
122
+ }
123
+
124
object_property_set_bool(OBJECT(&s->dp), true, "realized", &err);
125
if (err) {
126
error_propagate(errp, err);
127
--
47
--
128
2.7.4
48
2.20.1
129
49
130
50
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
In the AdvSIMD load/store single structure encodings, the
2
non-post-indexed case should have zeroes in [20:16] (which is the
3
Rm field for the post-indexed case). Bit 31 must also be zero
4
(a check we got right in ldst_multiple but not here). Correctly
5
UNDEF these unallocated encodings.
2
6
3
Update headers against v4.15-rc1.
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-5-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 11 ++++++++++-
13
1 file changed, 10 insertions(+), 1 deletion(-)
4
14
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
6
Message-id: 1511883692-11511-4-git-send-email-eric.auger@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/standard-headers/asm-s390/virtio-ccw.h | 1 +
10
include/standard-headers/asm-x86/hyperv.h | 394 +--------------------
11
include/standard-headers/linux/input-event-codes.h | 2 +
12
include/standard-headers/linux/input.h | 1 +
13
include/standard-headers/linux/pci_regs.h | 45 ++-
14
linux-headers/asm-arm/kvm.h | 8 +
15
linux-headers/asm-arm/kvm_para.h | 1 +
16
linux-headers/asm-arm/unistd.h | 2 +
17
linux-headers/asm-arm64/kvm.h | 8 +
18
linux-headers/asm-arm64/unistd.h | 1 +
19
linux-headers/asm-powerpc/epapr_hcalls.h | 1 +
20
linux-headers/asm-powerpc/kvm.h | 1 +
21
linux-headers/asm-powerpc/kvm_para.h | 1 +
22
linux-headers/asm-powerpc/unistd.h | 1 +
23
linux-headers/asm-s390/kvm.h | 1 +
24
linux-headers/asm-s390/kvm_para.h | 1 +
25
linux-headers/asm-s390/unistd.h | 4 +-
26
linux-headers/asm-x86/kvm.h | 1 +
27
linux-headers/asm-x86/kvm_para.h | 2 +-
28
linux-headers/asm-x86/unistd.h | 1 +
29
linux-headers/linux/kvm.h | 2 +
30
linux-headers/linux/kvm_para.h | 1 +
31
linux-headers/linux/psci.h | 1 +
32
linux-headers/linux/userfaultfd.h | 1 +
33
linux-headers/linux/vfio.h | 1 +
34
linux-headers/linux/vfio_ccw.h | 1 +
35
linux-headers/linux/vhost.h | 1 +
36
27 files changed, 74 insertions(+), 411 deletions(-)
37
38
diff --git a/include/standard-headers/asm-s390/virtio-ccw.h b/include/standard-headers/asm-s390/virtio-ccw.h
39
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
40
--- a/include/standard-headers/asm-s390/virtio-ccw.h
17
--- a/target/arm/translate-a64.c
41
+++ b/include/standard-headers/asm-s390/virtio-ccw.h
18
+++ b/target/arm/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
43
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
20
{
44
/*
21
int rt = extract32(insn, 0, 5);
45
* Definitions for virtio-ccw devices.
22
int rn = extract32(insn, 5, 5);
46
*
23
+ int rm = extract32(insn, 16, 5);
47
diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h
24
int size = extract32(insn, 10, 2);
48
index XXXXXXX..XXXXXXX 100644
25
int S = extract32(insn, 12, 1);
49
--- a/include/standard-headers/asm-x86/hyperv.h
26
int opc = extract32(insn, 13, 3);
50
+++ b/include/standard-headers/asm-x86/hyperv.h
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
51
@@ -1,393 +1 @@
28
int ebytes, xs;
52
-#ifndef _ASM_X86_HYPERV_H
29
TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
53
-#define _ASM_X86_HYPERV_H
30
54
-
31
+ if (extract32(insn, 31, 1)) {
55
-#include "standard-headers/linux/types.h"
32
+ unallocated_encoding(s);
56
-
33
+ return;
57
-/*
34
+ }
58
- * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
35
+ if (!is_postidx && rm != 0) {
59
- * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
36
+ unallocated_encoding(s);
60
- */
37
+ return;
61
-#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS    0x40000000
38
+ }
62
-#define HYPERV_CPUID_INTERFACE            0x40000001
63
-#define HYPERV_CPUID_VERSION            0x40000002
64
-#define HYPERV_CPUID_FEATURES            0x40000003
65
-#define HYPERV_CPUID_ENLIGHTMENT_INFO        0x40000004
66
-#define HYPERV_CPUID_IMPLEMENT_LIMITS        0x40000005
67
-
68
-#define HYPERV_HYPERVISOR_PRESENT_BIT        0x80000000
69
-#define HYPERV_CPUID_MIN            0x40000005
70
-#define HYPERV_CPUID_MAX            0x4000ffff
71
-
72
-/*
73
- * Feature identification. EAX indicates which features are available
74
- * to the partition based upon the current partition privileges.
75
- */
76
-
77
-/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
78
-#define HV_X64_MSR_VP_RUNTIME_AVAILABLE        (1 << 0)
79
-/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
80
-#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE    (1 << 1)
81
-/* Partition reference TSC MSR is available */
82
-#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
83
-
84
-/* A partition's reference time stamp counter (TSC) page */
85
-#define HV_X64_MSR_REFERENCE_TSC        0x40000021
86
-
87
-/*
88
- * There is a single feature flag that signifies if the partition has access
89
- * to MSRs with local APIC and TSC frequencies.
90
- */
91
-#define HV_X64_ACCESS_FREQUENCY_MSRS        (1 << 11)
92
-
93
-/*
94
- * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
95
- * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
96
- */
97
-#define HV_X64_MSR_SYNIC_AVAILABLE        (1 << 2)
98
-/*
99
- * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
100
- * HV_X64_MSR_STIMER3_COUNT) available
101
- */
102
-#define HV_X64_MSR_SYNTIMER_AVAILABLE        (1 << 3)
103
-/*
104
- * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
105
- * are available
106
- */
107
-#define HV_X64_MSR_APIC_ACCESS_AVAILABLE    (1 << 4)
108
-/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
109
-#define HV_X64_MSR_HYPERCALL_AVAILABLE        (1 << 5)
110
-/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
111
-#define HV_X64_MSR_VP_INDEX_AVAILABLE        (1 << 6)
112
-/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
113
-#define HV_X64_MSR_RESET_AVAILABLE        (1 << 7)
114
- /*
115
- * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
116
- * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
117
- * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
118
- */
119
-#define HV_X64_MSR_STAT_PAGES_AVAILABLE        (1 << 8)
120
-
121
-/* Frequency MSRs available */
122
-#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE    (1 << 8)
123
-
124
-/* Crash MSR available */
125
-#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
126
-
127
-/*
128
- * Feature identification: EBX indicates which flags were specified at
129
- * partition creation. The format is the same as the partition creation
130
- * flag structure defined in section Partition Creation Flags.
131
- */
132
-#define HV_X64_CREATE_PARTITIONS        (1 << 0)
133
-#define HV_X64_ACCESS_PARTITION_ID        (1 << 1)
134
-#define HV_X64_ACCESS_MEMORY_POOL        (1 << 2)
135
-#define HV_X64_ADJUST_MESSAGE_BUFFERS        (1 << 3)
136
-#define HV_X64_POST_MESSAGES            (1 << 4)
137
-#define HV_X64_SIGNAL_EVENTS            (1 << 5)
138
-#define HV_X64_CREATE_PORT            (1 << 6)
139
-#define HV_X64_CONNECT_PORT            (1 << 7)
140
-#define HV_X64_ACCESS_STATS            (1 << 8)
141
-#define HV_X64_DEBUGGING            (1 << 11)
142
-#define HV_X64_CPU_POWER_MANAGEMENT        (1 << 12)
143
-#define HV_X64_CONFIGURE_PROFILER        (1 << 13)
144
-
145
-/*
146
- * Feature identification. EDX indicates which miscellaneous features
147
- * are available to the partition.
148
- */
149
-/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
150
-#define HV_X64_MWAIT_AVAILABLE                (1 << 0)
151
-/* Guest debugging support is available */
152
-#define HV_X64_GUEST_DEBUGGING_AVAILABLE        (1 << 1)
153
-/* Performance Monitor support is available*/
154
-#define HV_X64_PERF_MONITOR_AVAILABLE            (1 << 2)
155
-/* Support for physical CPU dynamic partitioning events is available*/
156
-#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE    (1 << 3)
157
-/*
158
- * Support for passing hypercall input parameter block via XMM
159
- * registers is available
160
- */
161
-#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE        (1 << 4)
162
-/* Support for a virtual guest idle state is available */
163
-#define HV_X64_GUEST_IDLE_STATE_AVAILABLE        (1 << 5)
164
-/* Guest crash data handler available */
165
-#define HV_X64_GUEST_CRASH_MSR_AVAILABLE        (1 << 10)
166
-
167
-/*
168
- * Implementation recommendations. Indicates which behaviors the hypervisor
169
- * recommends the OS implement for optimal performance.
170
- */
171
- /*
172
- * Recommend using hypercall for address space switches rather
173
- * than MOV to CR3 instruction
174
- */
175
-#define HV_X64_AS_SWITCH_RECOMMENDED        (1 << 0)
176
-/* Recommend using hypercall for local TLB flushes rather
177
- * than INVLPG or MOV to CR3 instructions */
178
-#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED    (1 << 1)
179
-/*
180
- * Recommend using hypercall for remote TLB flushes rather
181
- * than inter-processor interrupts
182
- */
183
-#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED    (1 << 2)
184
-/*
185
- * Recommend using MSRs for accessing APIC registers
186
- * EOI, ICR and TPR rather than their memory-mapped counterparts
187
- */
188
-#define HV_X64_APIC_ACCESS_RECOMMENDED        (1 << 3)
189
-/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
190
-#define HV_X64_SYSTEM_RESET_RECOMMENDED        (1 << 4)
191
-/*
192
- * Recommend using relaxed timing for this partition. If used,
193
- * the VM should disable any watchdog timeouts that rely on the
194
- * timely delivery of external interrupts
195
- */
196
-#define HV_X64_RELAXED_TIMING_RECOMMENDED    (1 << 5)
197
-
198
-/*
199
- * Virtual APIC support
200
- */
201
-#define HV_X64_DEPRECATING_AEOI_RECOMMENDED    (1 << 9)
202
-
203
-/* Recommend using the newer ExProcessorMasks interface */
204
-#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED    (1 << 11)
205
-
206
-/*
207
- * Crash notification flag.
208
- */
209
-#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
210
-
211
-/* MSR used to identify the guest OS. */
212
-#define HV_X64_MSR_GUEST_OS_ID            0x40000000
213
-
214
-/* MSR used to setup pages used to communicate with the hypervisor. */
215
-#define HV_X64_MSR_HYPERCALL            0x40000001
216
-
217
-/* MSR used to provide vcpu index */
218
-#define HV_X64_MSR_VP_INDEX            0x40000002
219
-
220
-/* MSR used to reset the guest OS. */
221
-#define HV_X64_MSR_RESET            0x40000003
222
-
223
-/* MSR used to provide vcpu runtime in 100ns units */
224
-#define HV_X64_MSR_VP_RUNTIME            0x40000010
225
-
226
-/* MSR used to read the per-partition time reference counter */
227
-#define HV_X64_MSR_TIME_REF_COUNT        0x40000020
228
-
229
-/* MSR used to retrieve the TSC frequency */
230
-#define HV_X64_MSR_TSC_FREQUENCY        0x40000022
231
-
232
-/* MSR used to retrieve the local APIC timer frequency */
233
-#define HV_X64_MSR_APIC_FREQUENCY        0x40000023
234
-
235
-/* Define the virtual APIC registers */
236
-#define HV_X64_MSR_EOI                0x40000070
237
-#define HV_X64_MSR_ICR                0x40000071
238
-#define HV_X64_MSR_TPR                0x40000072
239
-#define HV_X64_MSR_APIC_ASSIST_PAGE        0x40000073
240
-
241
-/* Define synthetic interrupt controller model specific registers. */
242
-#define HV_X64_MSR_SCONTROL            0x40000080
243
-#define HV_X64_MSR_SVERSION            0x40000081
244
-#define HV_X64_MSR_SIEFP            0x40000082
245
-#define HV_X64_MSR_SIMP                0x40000083
246
-#define HV_X64_MSR_EOM                0x40000084
247
-#define HV_X64_MSR_SINT0            0x40000090
248
-#define HV_X64_MSR_SINT1            0x40000091
249
-#define HV_X64_MSR_SINT2            0x40000092
250
-#define HV_X64_MSR_SINT3            0x40000093
251
-#define HV_X64_MSR_SINT4            0x40000094
252
-#define HV_X64_MSR_SINT5            0x40000095
253
-#define HV_X64_MSR_SINT6            0x40000096
254
-#define HV_X64_MSR_SINT7            0x40000097
255
-#define HV_X64_MSR_SINT8            0x40000098
256
-#define HV_X64_MSR_SINT9            0x40000099
257
-#define HV_X64_MSR_SINT10            0x4000009A
258
-#define HV_X64_MSR_SINT11            0x4000009B
259
-#define HV_X64_MSR_SINT12            0x4000009C
260
-#define HV_X64_MSR_SINT13            0x4000009D
261
-#define HV_X64_MSR_SINT14            0x4000009E
262
-#define HV_X64_MSR_SINT15            0x4000009F
263
-
264
-/*
265
- * Synthetic Timer MSRs. Four timers per vcpu.
266
- */
267
-#define HV_X64_MSR_STIMER0_CONFIG        0x400000B0
268
-#define HV_X64_MSR_STIMER0_COUNT        0x400000B1
269
-#define HV_X64_MSR_STIMER1_CONFIG        0x400000B2
270
-#define HV_X64_MSR_STIMER1_COUNT        0x400000B3
271
-#define HV_X64_MSR_STIMER2_CONFIG        0x400000B4
272
-#define HV_X64_MSR_STIMER2_COUNT        0x400000B5
273
-#define HV_X64_MSR_STIMER3_CONFIG        0x400000B6
274
-#define HV_X64_MSR_STIMER3_COUNT        0x400000B7
275
-
276
-/* Hyper-V guest crash notification MSR's */
277
-#define HV_X64_MSR_CRASH_P0            0x40000100
278
-#define HV_X64_MSR_CRASH_P1            0x40000101
279
-#define HV_X64_MSR_CRASH_P2            0x40000102
280
-#define HV_X64_MSR_CRASH_P3            0x40000103
281
-#define HV_X64_MSR_CRASH_P4            0x40000104
282
-#define HV_X64_MSR_CRASH_CTL            0x40000105
283
-#define HV_X64_MSR_CRASH_CTL_NOTIFY        (1ULL << 63)
284
-#define HV_X64_MSR_CRASH_PARAMS        \
285
-        (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
286
-
287
-#define HV_X64_MSR_HYPERCALL_ENABLE        0x00000001
288
-#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT    12
289
-#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK    \
290
-        (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
291
-
292
-/* Declare the various hypercall operations. */
293
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE    0x0002
294
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST    0x0003
295
-#define HVCALL_NOTIFY_LONG_SPIN_WAIT        0x0008
296
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
297
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
298
-#define HVCALL_POST_MESSAGE            0x005c
299
-#define HVCALL_SIGNAL_EVENT            0x005d
300
-
301
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE        0x00000001
302
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT    12
303
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK    \
304
-        (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
305
-
306
-#define HV_X64_MSR_TSC_REFERENCE_ENABLE        0x00000001
307
-#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT    12
308
-
309
-#define HV_PROCESSOR_POWER_STATE_C0        0
310
-#define HV_PROCESSOR_POWER_STATE_C1        1
311
-#define HV_PROCESSOR_POWER_STATE_C2        2
312
-#define HV_PROCESSOR_POWER_STATE_C3        3
313
-
314
-#define HV_FLUSH_ALL_PROCESSORS            BIT(0)
315
-#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES    BIT(1)
316
-#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY    BIT(2)
317
-#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT    BIT(3)
318
-
319
-enum HV_GENERIC_SET_FORMAT {
320
-    HV_GENERIC_SET_SPARCE_4K,
321
-    HV_GENERIC_SET_ALL,
322
-};
323
-
324
-/* hypercall status code */
325
-#define HV_STATUS_SUCCESS            0
326
-#define HV_STATUS_INVALID_HYPERCALL_CODE    2
327
-#define HV_STATUS_INVALID_HYPERCALL_INPUT    3
328
-#define HV_STATUS_INVALID_ALIGNMENT        4
329
-#define HV_STATUS_INSUFFICIENT_MEMORY        11
330
-#define HV_STATUS_INVALID_CONNECTION_ID        18
331
-#define HV_STATUS_INSUFFICIENT_BUFFERS        19
332
-
333
-typedef struct _HV_REFERENCE_TSC_PAGE {
334
-    uint32_t tsc_sequence;
335
-    uint32_t res1;
336
-    uint64_t tsc_scale;
337
-    int64_t tsc_offset;
338
-} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
339
-
340
-/* Define the number of synthetic interrupt sources. */
341
-#define HV_SYNIC_SINT_COUNT        (16)
342
-/* Define the expected SynIC version. */
343
-#define HV_SYNIC_VERSION_1        (0x1)
344
-
345
-#define HV_SYNIC_CONTROL_ENABLE        (1ULL << 0)
346
-#define HV_SYNIC_SIMP_ENABLE        (1ULL << 0)
347
-#define HV_SYNIC_SIEFP_ENABLE        (1ULL << 0)
348
-#define HV_SYNIC_SINT_MASKED        (1ULL << 16)
349
-#define HV_SYNIC_SINT_AUTO_EOI        (1ULL << 17)
350
-#define HV_SYNIC_SINT_VECTOR_MASK    (0xFF)
351
-
352
-#define HV_SYNIC_STIMER_COUNT        (4)
353
-
354
-/* Define synthetic interrupt controller message constants. */
355
-#define HV_MESSAGE_SIZE            (256)
356
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT    (240)
357
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT    (30)
358
-
359
-/* Define hypervisor message types. */
360
-enum hv_message_type {
361
-    HVMSG_NONE            = 0x00000000,
362
-
363
-    /* Memory access messages. */
364
-    HVMSG_UNMAPPED_GPA        = 0x80000000,
365
-    HVMSG_GPA_INTERCEPT        = 0x80000001,
366
-
367
-    /* Timer notification messages. */
368
-    HVMSG_TIMER_EXPIRED            = 0x80000010,
369
-
370
-    /* Error messages. */
371
-    HVMSG_INVALID_VP_REGISTER_VALUE    = 0x80000020,
372
-    HVMSG_UNRECOVERABLE_EXCEPTION    = 0x80000021,
373
-    HVMSG_UNSUPPORTED_FEATURE        = 0x80000022,
374
-
375
-    /* Trace buffer complete messages. */
376
-    HVMSG_EVENTLOG_BUFFERCOMPLETE    = 0x80000040,
377
-
378
-    /* Platform-specific processor intercept messages. */
379
-    HVMSG_X64_IOPORT_INTERCEPT        = 0x80010000,
380
-    HVMSG_X64_MSR_INTERCEPT        = 0x80010001,
381
-    HVMSG_X64_CPUID_INTERCEPT        = 0x80010002,
382
-    HVMSG_X64_EXCEPTION_INTERCEPT    = 0x80010003,
383
-    HVMSG_X64_APIC_EOI            = 0x80010004,
384
-    HVMSG_X64_LEGACY_FP_ERROR        = 0x80010005
385
-};
386
-
387
-/* Define synthetic interrupt controller message flags. */
388
-union hv_message_flags {
389
-    uint8_t asu8;
390
-    struct {
391
-        uint8_t msg_pending:1;
392
-        uint8_t reserved:7;
393
-    };
394
-};
395
-
396
-/* Define port identifier type. */
397
-union hv_port_id {
398
-    uint32_t asu32;
399
-    struct {
400
-        uint32_t id:24;
401
-        uint32_t reserved:8;
402
-    } u;
403
-};
404
-
405
-/* Define synthetic interrupt controller message header. */
406
-struct hv_message_header {
407
-    uint32_t message_type;
408
-    uint8_t payload_size;
409
-    union hv_message_flags message_flags;
410
-    uint8_t reserved[2];
411
-    union {
412
-        uint64_t sender;
413
-        union hv_port_id port;
414
-    };
415
-};
416
-
417
-/* Define synthetic interrupt controller message format. */
418
-struct hv_message {
419
-    struct hv_message_header header;
420
-    union {
421
-        uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
422
-    } u;
423
-};
424
-
425
-/* Define the synthetic interrupt message page layout. */
426
-struct hv_message_page {
427
-    struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
428
-};
429
-
430
-/* Define timer message payload structure. */
431
-struct hv_timer_message_payload {
432
-    uint32_t timer_index;
433
-    uint32_t reserved;
434
-    uint64_t expiration_time;    /* When the timer expired */
435
-    uint64_t delivery_time;    /* When the message was delivered */
436
-};
437
-
438
-#define HV_STIMER_ENABLE        (1ULL << 0)
439
-#define HV_STIMER_PERIODIC        (1ULL << 1)
440
-#define HV_STIMER_LAZY            (1ULL << 2)
441
-#define HV_STIMER_AUTOENABLE        (1ULL << 3)
442
-#define HV_STIMER_SINT(config)        (uint8_t)(((config) >> 16) & 0x0F)
443
-
444
-#endif
445
+ /* this is a temporary placeholder until kvm_para.h stops including it */
446
diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
447
index XXXXXXX..XXXXXXX 100644
448
--- a/include/standard-headers/linux/input-event-codes.h
449
+++ b/include/standard-headers/linux/input-event-codes.h
450
@@ -XXX,XX +XXX,XX @@
451
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
452
/*
453
* Input event codes
454
*
455
@@ -XXX,XX +XXX,XX @@
456
#define BTN_TOOL_MOUSE        0x146
457
#define BTN_TOOL_LENS        0x147
458
#define BTN_TOOL_QUINTTAP    0x148    /* Five fingers on trackpad */
459
+#define BTN_STYLUS3        0x149
460
#define BTN_TOUCH        0x14a
461
#define BTN_STYLUS        0x14b
462
#define BTN_STYLUS2        0x14c
463
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
464
index XXXXXXX..XXXXXXX 100644
465
--- a/include/standard-headers/linux/input.h
466
+++ b/include/standard-headers/linux/input.h
467
@@ -XXX,XX +XXX,XX @@
468
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
469
/*
470
* Copyright (c) 1999-2002 Vojtech Pavlik
471
*
472
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
473
index XXXXXXX..XXXXXXX 100644
474
--- a/include/standard-headers/linux/pci_regs.h
475
+++ b/include/standard-headers/linux/pci_regs.h
476
@@ -XXX,XX +XXX,XX @@
477
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
478
/*
479
*    pci_regs.h
480
*
481
@@ -XXX,XX +XXX,XX @@
482
#define PCI_ERR_ROOT_FIRST_FATAL    0x00000010 /* First UNC is Fatal */
483
#define PCI_ERR_ROOT_NONFATAL_RCV    0x00000020 /* Non-Fatal Received */
484
#define PCI_ERR_ROOT_FATAL_RCV        0x00000040 /* Fatal Received */
485
+#define PCI_ERR_ROOT_AER_IRQ        0xf8000000 /* Advanced Error Interrupt Message Number */
486
#define PCI_ERR_ROOT_ERR_SRC    52    /* Error Source Identification */
487
488
/* Virtual Channel */
489
@@ -XXX,XX +XXX,XX @@
490
#define PCI_SATA_SIZEOF_LONG    16
491
492
/* Resizable BARs */
493
+#define PCI_REBAR_CAP        4    /* capability register */
494
+#define PCI_REBAR_CAP_SIZES        0x00FFFFF0 /* supported BAR sizes */
495
#define PCI_REBAR_CTRL        8    /* control register */
496
-#define PCI_REBAR_CTRL_NBAR_MASK    (7 << 5)    /* mask for # bars */
497
-#define PCI_REBAR_CTRL_NBAR_SHIFT    5    /* shift for # bars */
498
+#define PCI_REBAR_CTRL_BAR_IDX        0x00000007 /* BAR index */
499
+#define PCI_REBAR_CTRL_NBAR_MASK    0x000000E0 /* # of resizable BARs */
500
+#define PCI_REBAR_CTRL_NBAR_SHIFT    5      /* shift for # of BARs */
501
+#define PCI_REBAR_CTRL_BAR_SIZE    0x00001F00 /* BAR size */
502
503
/* Dynamic Power Allocation */
504
#define PCI_DPA_CAP        4    /* capability register */
505
@@ -XXX,XX +XXX,XX @@
506
507
/* Downstream Port Containment */
508
#define PCI_EXP_DPC_CAP            4    /* DPC Capability */
509
+#define PCI_EXP_DPC_IRQ            0x1f    /* DPC Interrupt Message Number */
510
#define PCI_EXP_DPC_CAP_RP_EXT        0x20    /* Root Port Extensions for DPC */
511
#define PCI_EXP_DPC_CAP_POISONED_TLP    0x40    /* Poisoned TLP Egress Blocking Supported */
512
#define PCI_EXP_DPC_CAP_SW_TRIGGER    0x80    /* Software Triggering Supported */
513
@@ -XXX,XX +XXX,XX @@
514
#define PCI_PTM_CTRL_ENABLE        0x00000001 /* PTM enable */
515
#define PCI_PTM_CTRL_ROOT        0x00000002 /* Root select */
516
517
-/* L1 PM Substates */
518
-#define PCI_L1SS_CAP         4    /* capability register */
519
-#define PCI_L1SS_CAP_PCIPM_L1_2     1    /* PCI PM L1.2 Support */
520
-#define PCI_L1SS_CAP_PCIPM_L1_1     2    /* PCI PM L1.1 Support */
521
-#define PCI_L1SS_CAP_ASPM_L1_2         4    /* ASPM L1.2 Support */
522
-#define PCI_L1SS_CAP_ASPM_L1_1         8    /* ASPM L1.1 Support */
523
-#define PCI_L1SS_CAP_L1_PM_SS        16    /* L1 PM Substates Support */
524
-#define PCI_L1SS_CTL1         8    /* Control Register 1 */
525
-#define PCI_L1SS_CTL1_PCIPM_L1_2    1    /* PCI PM L1.2 Enable */
526
-#define PCI_L1SS_CTL1_PCIPM_L1_1    2    /* PCI PM L1.1 Support */
527
-#define PCI_L1SS_CTL1_ASPM_L1_2    4    /* ASPM L1.2 Support */
528
-#define PCI_L1SS_CTL1_ASPM_L1_1    8    /* ASPM L1.1 Support */
529
-#define PCI_L1SS_CTL1_L1SS_MASK    0x0000000F
530
-#define PCI_L1SS_CTL2         0xC    /* Control Register 2 */
531
+/* ASPM L1 PM Substates */
532
+#define PCI_L1SS_CAP        0x04    /* Capabilities Register */
533
+#define PCI_L1SS_CAP_PCIPM_L1_2    0x00000001 /* PCI-PM L1.2 Supported */
534
+#define PCI_L1SS_CAP_PCIPM_L1_1    0x00000002 /* PCI-PM L1.1 Supported */
535
+#define PCI_L1SS_CAP_ASPM_L1_2        0x00000004 /* ASPM L1.2 Supported */
536
+#define PCI_L1SS_CAP_ASPM_L1_1        0x00000008 /* ASPM L1.1 Supported */
537
+#define PCI_L1SS_CAP_L1_PM_SS        0x00000010 /* L1 PM Substates Supported */
538
+#define PCI_L1SS_CAP_CM_RESTORE_TIME    0x0000ff00 /* Port Common_Mode_Restore_Time */
539
+#define PCI_L1SS_CAP_P_PWR_ON_SCALE    0x00030000 /* Port T_POWER_ON scale */
540
+#define PCI_L1SS_CAP_P_PWR_ON_VALUE    0x00f80000 /* Port T_POWER_ON value */
541
+#define PCI_L1SS_CTL1        0x08    /* Control 1 Register */
542
+#define PCI_L1SS_CTL1_PCIPM_L1_2    0x00000001 /* PCI-PM L1.2 Enable */
543
+#define PCI_L1SS_CTL1_PCIPM_L1_1    0x00000002 /* PCI-PM L1.1 Enable */
544
+#define PCI_L1SS_CTL1_ASPM_L1_2    0x00000004 /* ASPM L1.2 Enable */
545
+#define PCI_L1SS_CTL1_ASPM_L1_1    0x00000008 /* ASPM L1.1 Enable */
546
+#define PCI_L1SS_CTL1_L1SS_MASK    0x0000000f
547
+#define PCI_L1SS_CTL1_CM_RESTORE_TIME    0x0000ff00 /* Common_Mode_Restore_Time */
548
+#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE    0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */
549
+#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE    0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */
550
+#define PCI_L1SS_CTL2        0x0c    /* Control 2 Register */
551
552
#endif /* LINUX_PCI_REGS_H */
553
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
554
index XXXXXXX..XXXXXXX 100644
555
--- a/linux-headers/asm-arm/kvm.h
556
+++ b/linux-headers/asm-arm/kvm.h
557
@@ -XXX,XX +XXX,XX @@
558
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
559
/*
560
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
561
* Author: Christoffer Dall <c.dall@virtualopensystems.com>
562
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
563
    (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
564
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
565
566
+/* PL1 Physical Timer Registers */
567
+#define KVM_REG_ARM_PTIMER_CTL        ARM_CP15_REG32(0, 14, 2, 1)
568
+#define KVM_REG_ARM_PTIMER_CNT        ARM_CP15_REG64(0, 14)
569
+#define KVM_REG_ARM_PTIMER_CVAL        ARM_CP15_REG64(2, 14)
570
+
39
+
571
+/* Virtual Timer Registers */
40
switch (scale) {
572
#define KVM_REG_ARM_TIMER_CTL        ARM_CP15_REG32(0, 14, 3, 1)
41
case 3:
573
#define KVM_REG_ARM_TIMER_CNT        ARM_CP15_REG64(1, 14)
42
if (!is_load || S) {
574
#define KVM_REG_ARM_TIMER_CVAL        ARM_CP15_REG64(3, 14)
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
575
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
44
}
576
#define KVM_DEV_ARM_ITS_SAVE_TABLES        1
45
577
#define KVM_DEV_ARM_ITS_RESTORE_TABLES    2
46
if (is_postidx) {
578
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES    3
47
- int rm = extract32(insn, 16, 5);
579
+#define KVM_DEV_ARM_ITS_CTRL_RESET        4
48
if (rm == 31) {
580
49
tcg_gen_mov_i64(tcg_rn, tcg_addr);
581
/* KVM_IRQ_LINE irq field index values */
50
} else {
582
#define KVM_ARM_IRQ_TYPE_SHIFT        24
583
diff --git a/linux-headers/asm-arm/kvm_para.h b/linux-headers/asm-arm/kvm_para.h
584
index XXXXXXX..XXXXXXX 100644
585
--- a/linux-headers/asm-arm/kvm_para.h
586
+++ b/linux-headers/asm-arm/kvm_para.h
587
@@ -1 +1,2 @@
588
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
589
#include <asm-generic/kvm_para.h>
590
diff --git a/linux-headers/asm-arm/unistd.h b/linux-headers/asm-arm/unistd.h
591
index XXXXXXX..XXXXXXX 100644
592
--- a/linux-headers/asm-arm/unistd.h
593
+++ b/linux-headers/asm-arm/unistd.h
594
@@ -XXX,XX +XXX,XX @@
595
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
596
/*
597
* arch/arm/include/asm/unistd.h
598
*
599
@@ -XXX,XX +XXX,XX @@
600
#define __ARM_NR_usr26            (__ARM_NR_BASE+3)
601
#define __ARM_NR_usr32            (__ARM_NR_BASE+4)
602
#define __ARM_NR_set_tls        (__ARM_NR_BASE+5)
603
+#define __ARM_NR_get_tls        (__ARM_NR_BASE+6)
604
605
#endif /* __ASM_ARM_UNISTD_H */
606
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
607
index XXXXXXX..XXXXXXX 100644
608
--- a/linux-headers/asm-arm64/kvm.h
609
+++ b/linux-headers/asm-arm64/kvm.h
610
@@ -XXX,XX +XXX,XX @@
611
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
612
/*
613
* Copyright (C) 2012,2013 - ARM Ltd
614
* Author: Marc Zyngier <marc.zyngier@arm.com>
615
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
616
617
#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
618
619
+/* Physical Timer EL0 Registers */
620
+#define KVM_REG_ARM_PTIMER_CTL        ARM64_SYS_REG(3, 3, 14, 2, 1)
621
+#define KVM_REG_ARM_PTIMER_CVAL        ARM64_SYS_REG(3, 3, 14, 2, 2)
622
+#define KVM_REG_ARM_PTIMER_CNT        ARM64_SYS_REG(3, 3, 14, 0, 1)
623
+
624
+/* EL0 Virtual Timer Registers */
625
#define KVM_REG_ARM_TIMER_CTL        ARM64_SYS_REG(3, 3, 14, 3, 1)
626
#define KVM_REG_ARM_TIMER_CNT        ARM64_SYS_REG(3, 3, 14, 3, 2)
627
#define KVM_REG_ARM_TIMER_CVAL        ARM64_SYS_REG(3, 3, 14, 0, 2)
628
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
629
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
630
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
631
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES    3
632
+#define KVM_DEV_ARM_ITS_CTRL_RESET        4
633
634
/* Device Control API on vcpu fd */
635
#define KVM_ARM_VCPU_PMU_V3_CTRL    0
636
diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h
637
index XXXXXXX..XXXXXXX 100644
638
--- a/linux-headers/asm-arm64/unistd.h
639
+++ b/linux-headers/asm-arm64/unistd.h
640
@@ -XXX,XX +XXX,XX @@
641
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
642
/*
643
* Copyright (C) 2012 ARM Ltd.
644
*
645
diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
646
index XXXXXXX..XXXXXXX 100644
647
--- a/linux-headers/asm-powerpc/epapr_hcalls.h
648
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
649
@@ -XXX,XX +XXX,XX @@
650
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
651
/*
652
* ePAPR hcall interface
653
*
654
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
655
index XXXXXXX..XXXXXXX 100644
656
--- a/linux-headers/asm-powerpc/kvm.h
657
+++ b/linux-headers/asm-powerpc/kvm.h
658
@@ -XXX,XX +XXX,XX @@
659
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
660
/*
661
* This program is free software; you can redistribute it and/or modify
662
* it under the terms of the GNU General Public License, version 2, as
663
diff --git a/linux-headers/asm-powerpc/kvm_para.h b/linux-headers/asm-powerpc/kvm_para.h
664
index XXXXXXX..XXXXXXX 100644
665
--- a/linux-headers/asm-powerpc/kvm_para.h
666
+++ b/linux-headers/asm-powerpc/kvm_para.h
667
@@ -XXX,XX +XXX,XX @@
668
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
669
/*
670
* This program is free software; you can redistribute it and/or modify
671
* it under the terms of the GNU General Public License, version 2, as
672
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
673
index XXXXXXX..XXXXXXX 100644
674
--- a/linux-headers/asm-powerpc/unistd.h
675
+++ b/linux-headers/asm-powerpc/unistd.h
676
@@ -XXX,XX +XXX,XX @@
677
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
678
/*
679
* This file contains the system call numbers.
680
*
681
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
682
index XXXXXXX..XXXXXXX 100644
683
--- a/linux-headers/asm-s390/kvm.h
684
+++ b/linux-headers/asm-s390/kvm.h
685
@@ -XXX,XX +XXX,XX @@
686
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
687
#ifndef __LINUX_KVM_S390_H
688
#define __LINUX_KVM_S390_H
689
/*
690
diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h
691
index XXXXXXX..XXXXXXX 100644
692
--- a/linux-headers/asm-s390/kvm_para.h
693
+++ b/linux-headers/asm-s390/kvm_para.h
694
@@ -XXX,XX +XXX,XX @@
695
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
696
/*
697
* User API definitions for paravirtual devices on s390
698
*
699
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
700
index XXXXXXX..XXXXXXX 100644
701
--- a/linux-headers/asm-s390/unistd.h
702
+++ b/linux-headers/asm-s390/unistd.h
703
@@ -XXX,XX +XXX,XX @@
704
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
705
/*
706
* S390 version
707
*
708
@@ -XXX,XX +XXX,XX @@
709
#define __NR_pwritev2        377
710
#define __NR_s390_guarded_storage    378
711
#define __NR_statx        379
712
-#define NR_syscalls 380
713
+#define __NR_s390_sthyi        380
714
+#define NR_syscalls 381
715
716
/*
717
* There are some system calls that are not present on 64 bit, some
718
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
719
index XXXXXXX..XXXXXXX 100644
720
--- a/linux-headers/asm-x86/kvm.h
721
+++ b/linux-headers/asm-x86/kvm.h
722
@@ -XXX,XX +XXX,XX @@
723
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
724
#ifndef _ASM_X86_KVM_H
725
#define _ASM_X86_KVM_H
726
727
diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h
728
index XXXXXXX..XXXXXXX 100644
729
--- a/linux-headers/asm-x86/kvm_para.h
730
+++ b/linux-headers/asm-x86/kvm_para.h
731
@@ -XXX,XX +XXX,XX @@
732
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
733
#ifndef _ASM_X86_KVM_PARA_H
734
#define _ASM_X86_KVM_PARA_H
735
736
@@ -XXX,XX +XXX,XX @@ struct kvm_vcpu_pv_apf_data {
737
#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK
738
#define KVM_PV_EOI_DISABLED 0x0
739
740
-
741
#endif /* _ASM_X86_KVM_PARA_H */
742
diff --git a/linux-headers/asm-x86/unistd.h b/linux-headers/asm-x86/unistd.h
743
index XXXXXXX..XXXXXXX 100644
744
--- a/linux-headers/asm-x86/unistd.h
745
+++ b/linux-headers/asm-x86/unistd.h
746
@@ -XXX,XX +XXX,XX @@
747
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
748
#ifndef _ASM_X86_UNISTD_H
749
#define _ASM_X86_UNISTD_H
750
751
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
752
index XXXXXXX..XXXXXXX 100644
753
--- a/linux-headers/linux/kvm.h
754
+++ b/linux-headers/linux/kvm.h
755
@@ -XXX,XX +XXX,XX @@
756
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
757
#ifndef __LINUX_KVM_H
758
#define __LINUX_KVM_H
759
760
@@ -XXX,XX +XXX,XX @@ struct kvm_ppc_resize_hpt {
761
#define KVM_CAP_PPC_SMT_POSSIBLE 147
762
#define KVM_CAP_HYPERV_SYNIC2 148
763
#define KVM_CAP_HYPERV_VP_INDEX 149
764
+#define KVM_CAP_S390_AIS_MIGRATION 150
765
766
#ifdef KVM_CAP_IRQ_ROUTING
767
768
diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h
769
index XXXXXXX..XXXXXXX 100644
770
--- a/linux-headers/linux/kvm_para.h
771
+++ b/linux-headers/linux/kvm_para.h
772
@@ -XXX,XX +XXX,XX @@
773
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
774
#ifndef __LINUX_KVM_PARA_H
775
#define __LINUX_KVM_PARA_H
776
777
diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h
778
index XXXXXXX..XXXXXXX 100644
779
--- a/linux-headers/linux/psci.h
780
+++ b/linux-headers/linux/psci.h
781
@@ -XXX,XX +XXX,XX @@
782
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
783
/*
784
* ARM Power State and Coordination Interface (PSCI) header
785
*
786
diff --git a/linux-headers/linux/userfaultfd.h b/linux-headers/linux/userfaultfd.h
787
index XXXXXXX..XXXXXXX 100644
788
--- a/linux-headers/linux/userfaultfd.h
789
+++ b/linux-headers/linux/userfaultfd.h
790
@@ -XXX,XX +XXX,XX @@
791
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
792
/*
793
* include/linux/userfaultfd.h
794
*
795
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
796
index XXXXXXX..XXXXXXX 100644
797
--- a/linux-headers/linux/vfio.h
798
+++ b/linux-headers/linux/vfio.h
799
@@ -XXX,XX +XXX,XX @@
800
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
801
/*
802
* VFIO API definition
803
*
804
diff --git a/linux-headers/linux/vfio_ccw.h b/linux-headers/linux/vfio_ccw.h
805
index XXXXXXX..XXXXXXX 100644
806
--- a/linux-headers/linux/vfio_ccw.h
807
+++ b/linux-headers/linux/vfio_ccw.h
808
@@ -XXX,XX +XXX,XX @@
809
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
810
/*
811
* Interfaces for vfio-ccw
812
*
813
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
814
index XXXXXXX..XXXXXXX 100644
815
--- a/linux-headers/linux/vhost.h
816
+++ b/linux-headers/linux/vhost.h
817
@@ -XXX,XX +XXX,XX @@
818
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
819
#ifndef _LINUX_VHOST_H
820
#define _LINUX_VHOST_H
821
/* Userspace interface for in-kernel virtio accelerators. */
822
--
51
--
823
2.7.4
52
2.20.1
824
53
825
54
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
In the "add/subtract (extended register)" encoding group, the "opt"
2
field in bits [23:22] must be zero. Correctly UNDEF the unallocated
3
encodings where this field is not zero.
2
4
3
Don't set TX FIFO UNDERFLOW interrupt after transmitting the commands.
5
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Also update interrupts after reading out the interrupt status.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Message-id: 20190125182626.9221-6-peter.maydell@linaro.org
9
---
10
target/arm/translate-a64.c | 3 ++-
11
1 file changed, 2 insertions(+), 1 deletion(-)
5
12
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
7
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-12-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/ssi/xilinx_spips.c | 4 +---
14
1 file changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
15
--- a/target/arm/translate-a64.c
19
+++ b/hw/ssi/xilinx_spips.c
16
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
17
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
21
uint8_t addr_length;
18
int imm3 = extract32(insn, 10, 3);
22
19
int option = extract32(insn, 13, 3);
23
if (fifo8_is_empty(&s->tx_fifo)) {
20
int rm = extract32(insn, 16, 5);
24
- if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
21
+ int opt = extract32(insn, 22, 2);
25
- s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
22
bool setflags = extract32(insn, 29, 1);
26
- }
23
bool sub_op = extract32(insn, 30, 1);
27
xilinx_spips_update_ixr(s);
24
bool sf = extract32(insn, 31, 1);
28
return;
25
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
29
} else if (s->snoop_state == SNOOP_STRIPING) {
26
TCGv_i64 tcg_rd;
30
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
27
TCGv_i64 tcg_result;
31
ret = s->regs[addr] & IXR_ALL;
28
32
s->regs[addr] = 0;
29
- if (imm3 > 4) {
33
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
30
+ if (imm3 > 4 || opt != 0) {
34
+ xilinx_spips_update_ixr(s);
31
unallocated_encoding(s);
35
return ret;
32
return;
36
case R_INTR_MASK:
33
}
37
mask = IXR_ALL;
38
--
34
--
39
2.7.4
35
2.20.1
40
36
41
37
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
In the encoding groups
2
* floating-point data-processing (1 source)
3
* floating-point data-processing (2 source)
4
* floating-point data-processing (3 source)
5
* floating-point immediate
6
* floating-point compare
7
* floating-ponit conditional compare
8
* floating-point conditional select
2
9
3
Voiding the ITS caches is not supposed to happen via
10
bit 31 is M and bit 29 is S (and bit 30 is 0, already checked at
4
individual register writes. So we introduced a dedicated
11
this point in the decode). None of these groups allocate any
5
ITS KVM device ioctl to perform a cold reset of the ITS:
12
encoding for M=1 or S=1. We checked this in disas_fp_compare(),
6
KVM_DEV_ARM_VGIC_GRP_CTRL/KVM_DEV_ARM_ITS_CTRL_RESET. Let's
13
disas_fp_ccomp() and disas_fp_csel(), but missed it in disas_fp_1src(),
7
use this latter if the kernel supports it.
14
disas_fp_2src(), disas_fp_3src() and disas_fp_imm().
8
15
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
16
We also missed that in the fp immediate encoding the imm5 field
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
must be all zeroes.
11
Message-id: 1511883692-11511-5-git-send-email-eric.auger@redhat.com
18
19
Correctly UNDEF the unallocated encodings here.
20
21
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
24
Message-id: 20190125182626.9221-7-peter.maydell@linaro.org
13
---
25
---
14
hw/intc/arm_gicv3_its_kvm.c | 9 ++++++++-
26
target/arm/translate-a64.c | 22 +++++++++++++++++++++-
15
1 file changed, 8 insertions(+), 1 deletion(-)
27
1 file changed, 21 insertions(+), 1 deletion(-)
16
28
17
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_its_kvm.c
31
--- a/target/arm/translate-a64.c
20
+++ b/hw/intc/arm_gicv3_its_kvm.c
32
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_reset(DeviceState *dev)
33
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
22
34
*/
23
c->parent_reset(dev);
35
static void disas_fp_1src(DisasContext *s, uint32_t insn)
24
36
{
25
- error_report("ITS KVM: full reset is not supported by QEMU");
37
+ int mos = extract32(insn, 29, 3);
26
+ if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
38
int type = extract32(insn, 22, 2);
27
+ KVM_DEV_ARM_ITS_CTRL_RESET)) {
39
int opcode = extract32(insn, 15, 6);
28
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
40
int rn = extract32(insn, 5, 5);
29
+ KVM_DEV_ARM_ITS_CTRL_RESET, NULL, true, &error_abort);
41
int rd = extract32(insn, 0, 5);
42
43
+ if (mos) {
44
+ unallocated_encoding(s);
30
+ return;
45
+ return;
31
+ }
46
+ }
32
+
47
+
33
+ error_report("ITS KVM: full reset is not supported by the host kernel");
48
switch (opcode) {
34
49
case 0x4: case 0x5: case 0x7:
35
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
50
{
36
GITS_CTLR)) {
51
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_half(DisasContext *s, int opcode,
52
*/
53
static void disas_fp_2src(DisasContext *s, uint32_t insn)
54
{
55
+ int mos = extract32(insn, 29, 3);
56
int type = extract32(insn, 22, 2);
57
int rd = extract32(insn, 0, 5);
58
int rn = extract32(insn, 5, 5);
59
int rm = extract32(insn, 16, 5);
60
int opcode = extract32(insn, 12, 4);
61
62
- if (opcode > 8) {
63
+ if (opcode > 8 || mos) {
64
unallocated_encoding(s);
65
return;
66
}
67
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
68
*/
69
static void disas_fp_3src(DisasContext *s, uint32_t insn)
70
{
71
+ int mos = extract32(insn, 29, 3);
72
int type = extract32(insn, 22, 2);
73
int rd = extract32(insn, 0, 5);
74
int rn = extract32(insn, 5, 5);
75
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
76
bool o0 = extract32(insn, 15, 1);
77
bool o1 = extract32(insn, 21, 1);
78
79
+ if (mos) {
80
+ unallocated_encoding(s);
81
+ return;
82
+ }
83
+
84
switch (type) {
85
case 0:
86
if (!fp_access_check(s)) {
87
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8)
88
static void disas_fp_imm(DisasContext *s, uint32_t insn)
89
{
90
int rd = extract32(insn, 0, 5);
91
+ int imm5 = extract32(insn, 5, 5);
92
int imm8 = extract32(insn, 13, 8);
93
int type = extract32(insn, 22, 2);
94
+ int mos = extract32(insn, 29, 3);
95
uint64_t imm;
96
TCGv_i64 tcg_res;
97
TCGMemOp sz;
98
99
+ if (mos || imm5) {
100
+ unallocated_encoding(s);
101
+ return;
102
+ }
103
+
104
switch (type) {
105
case 0:
106
sz = MO_32;
37
--
107
--
38
2.7.4
108
2.20.1
39
109
40
110
diff view generated by jsdifflib
1
In do_ats_write(), rather than using the FSR value from get_phys_addr(),
1
In the AdvSIMD scalar x indexed element and vector x indexed element
2
construct the PAR values using the information in the ARMMMUFaultInfo
2
encoding group, the SDOT and UDOT instructions are vector only,
3
struct. This allows us to create a PAR of the correct format regardless
3
and their opcode is unallocated in the scalar group. Correctly
4
of what the translation table format is.
4
UNDEF this unallocated encoding.
5
5
6
For the moment we leave the condition for "when should this be a
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
64 bit PAR" as it was previously; this will need to be fixed to
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
properly support AArch32 Hyp mode.
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-8-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
9
13
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-11-git-send-email-peter.maydell@linaro.org
15
---
16
target/arm/helper.c | 16 ++++++++++------
17
1 file changed, 10 insertions(+), 6 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
16
--- a/target/arm/translate-a64.c
22
+++ b/target/arm/helper.c
17
+++ b/target/arm/translate-a64.c
23
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
24
hwaddr phys_addr;
19
break;
25
target_ulong page_size;
20
case 0x0e: /* SDOT */
26
int prot;
21
case 0x1e: /* UDOT */
27
- uint32_t fsr;
22
- if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
28
+ uint32_t fsr_unused;
23
+ if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
29
bool ret;
24
unallocated_encoding(s);
30
uint64_t par64;
25
return;
31
MemTxAttrs attrs = {};
32
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
33
ARMCacheAttrs cacheattrs = {};
34
35
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
36
- &prot, &page_size, &fsr, &fi, &cacheattrs);
37
+ &prot, &page_size, &fsr_unused, &fi, &cacheattrs);
38
+ /* TODO: this is not the correct condition to use to decide whether
39
+ * to report a PAR in 64-bit or 32-bit format.
40
+ */
41
if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
42
- /* fsr is a DFSR/IFSR value for the long descriptor
43
- * translation table format, but with WnR always clear.
44
- * Convert it to a 64-bit PAR.
45
- */
46
+ /* Create a 64-bit PAR */
47
par64 = (1 << 11); /* LPAE bit always set */
48
if (!ret) {
49
par64 |= phys_addr & ~0xfffULL;
50
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
51
par64 |= (uint64_t)cacheattrs.attrs << 56; /* ATTR */
52
par64 |= cacheattrs.shareability << 7; /* SH */
53
} else {
54
+ uint32_t fsr = arm_fi_to_lfsc(&fi);
55
+
56
par64 |= 1; /* F */
57
par64 |= (fsr & 0x3f) << 1; /* FS */
58
/* Note that S2WLK and FSTAGE are always zero, because we don't
59
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
60
par64 |= (1 << 9); /* NS */
61
}
62
} else {
63
+ uint32_t fsr = arm_fi_to_sfsc(&fi);
64
+
65
par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) |
66
((fsr & 0xf) << 1) | 1;
67
}
26
}
68
--
27
--
69
2.7.4
28
2.20.1
70
29
71
30
diff view generated by jsdifflib
1
All of the callers of get_phys_addr() and arm_tlb_fill() now ignore
1
The tcg_register_iommu_notifier() code has a GArray of
2
the FSR values they return, so we can just remove the argument
2
TCGIOMMUNotifier structs which it has registered by passing
3
entirely.
3
memory_region_register_iommu_notifier() a pointer to the embedded
4
IOMMUNotifier field. Unfortunately, if we need to enlarge the
5
array via g_array_set_size() this can cause a realloc(), which
6
invalidates the pointer that memory_region_register_iommu_notifier()
7
put into the MemoryRegion's iommu_notify list. This can result
8
in segfaults.
4
9
10
Switch the GArray to holding pointers to the TCGIOMMUNotifier
11
structs, so that we can individually allocate and free them.
12
13
Cc: qemu-stable@nongnu.org
14
Fixes: 1f871c5e6b0f30644a60a ("exec.c: Handle IOMMUs in address_space_translate_for_iotlb()")
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
Message-id: 20190128174241.5860-1-peter.maydell@linaro.org
8
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
9
Message-id: 1512503192-2239-12-git-send-email-peter.maydell@linaro.org
10
---
18
---
11
target/arm/internals.h | 2 +-
19
exec.c | 10 ++++++----
12
target/arm/helper.c | 45 ++++++++++++++-------------------------------
20
1 file changed, 6 insertions(+), 4 deletions(-)
13
target/arm/op_helper.c | 3 +--
14
3 files changed, 16 insertions(+), 34 deletions(-)
15
21
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
22
diff --git a/exec.c b/exec.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
24
--- a/exec.c
19
+++ b/target/arm/internals.h
25
+++ b/exec.c
20
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
26
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
21
/* Do a page table walk and add page to TLB if possible */
27
int i;
22
bool arm_tlb_fill(CPUState *cpu, vaddr address,
28
23
MMUAccessType access_type, int mmu_idx,
29
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
24
- uint32_t *fsr, ARMMMUFaultInfo *fi);
30
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
25
+ ARMMMUFaultInfo *fi);
31
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
26
32
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
27
/* Return true if the stage 1 translation regime is using LPAE format page
33
break;
28
* tables */
34
}
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
30
index XXXXXXX..XXXXXXX 100644
36
if (i == cpu->iommu_notifiers->len) {
31
--- a/target/arm/helper.c
37
/* Not found, add a new entry at the end of the array */
32
+++ b/target/arm/helper.c
38
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
33
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
39
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
34
static bool get_phys_addr(CPUARMState *env, target_ulong address,
40
+ notifier = g_new0(TCGIOMMUNotifier, 1);
35
MMUAccessType access_type, ARMMMUIdx mmu_idx,
41
+ g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
36
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
42
37
- target_ulong *page_size, uint32_t *fsr,
43
notifier->mr = mr;
38
+ target_ulong *page_size,
44
notifier->iommu_idx = iommu_idx;
39
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
45
@@ -XXX,XX +XXX,XX @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
40
46
TCGIOMMUNotifier *notifier;
41
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
47
42
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
48
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
43
hwaddr phys_addr;
49
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
44
target_ulong page_size;
50
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
45
int prot;
51
memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
46
- uint32_t fsr_unused;
52
+ g_free(notifier);
47
bool ret;
48
uint64_t par64;
49
MemTxAttrs attrs = {};
50
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
51
ARMCacheAttrs cacheattrs = {};
52
53
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
54
- &prot, &page_size, &fsr_unused, &fi, &cacheattrs);
55
+ &prot, &page_size, &fi, &cacheattrs);
56
/* TODO: this is not the correct condition to use to decide whether
57
* to report a PAR in 64-bit or 32-bit format.
58
*/
59
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
60
target_ulong page_size;
61
hwaddr physaddr;
62
int prot;
63
- uint32_t fsr;
64
65
v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, &sattrs);
66
if (!sattrs.nsc || sattrs.ns) {
67
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
68
return false;
69
}
53
}
70
if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx,
54
g_array_free(cpu->iommu_notifiers, true);
71
- &physaddr, &attrs, &prot, &page_size, &fsr, &fi, NULL)) {
55
}
72
+ &physaddr, &attrs, &prot, &page_size, &fi, NULL)) {
56
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
73
/* the MPU lookup failed */
57
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
74
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
75
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
76
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
77
* @attrs: set to the memory transaction attributes to use
78
* @prot: set to the permissions for the page containing phys_ptr
79
* @page_size: set to the size of the page containing phys_ptr
80
- * @fsr: set to the DFSR/IFSR value on failure
81
* @fi: set to fault info if the translation fails
82
* @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
83
*/
84
static bool get_phys_addr(CPUARMState *env, target_ulong address,
85
MMUAccessType access_type, ARMMMUIdx mmu_idx,
86
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
87
- target_ulong *page_size, uint32_t *fsr,
88
+ target_ulong *page_size,
89
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
90
{
91
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
92
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
93
94
ret = get_phys_addr(env, address, access_type,
95
stage_1_mmu_idx(mmu_idx), &ipa, attrs,
96
- prot, page_size, fsr, fi, cacheattrs);
97
+ prot, page_size, fi, cacheattrs);
98
99
/* If S1 fails or S2 is disabled, return early. */
100
if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) {
101
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
102
phys_ptr, attrs, &s2_prot,
103
page_size, fi,
104
cacheattrs != NULL ? &cacheattrs2 : NULL);
105
- *fsr = arm_fi_to_lfsc(fi);
106
fi->s2addr = ipa;
107
/* Combine the S1 and S2 perms. */
108
*prot &= s2_prot;
109
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
110
/* PMSAv8 */
111
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
112
phys_ptr, attrs, prot, fi);
113
- *fsr = arm_fi_to_sfsc(fi);
114
} else if (arm_feature(env, ARM_FEATURE_V7)) {
115
/* PMSAv7 */
116
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
117
phys_ptr, prot, fi);
118
- *fsr = arm_fi_to_sfsc(fi);
119
} else {
120
/* Pre-v7 MPU */
121
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
122
phys_ptr, prot, fi);
123
- *fsr = arm_fi_to_sfsc(fi);
124
}
125
qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
126
" mmu_idx %u -> %s (prot %c%c%c)\n",
127
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
128
}
58
}
129
59
130
if (regime_using_lpae_format(env, mmu_idx)) {
60
- cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
131
- bool ret = get_phys_addr_lpae(env, address, access_type, mmu_idx,
61
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier *));
132
- phys_ptr, attrs, prot, page_size,
62
#endif
133
- fi, cacheattrs);
134
-
135
- *fsr = arm_fi_to_lfsc(fi);
136
- return ret;
137
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx,
138
+ phys_ptr, attrs, prot, page_size,
139
+ fi, cacheattrs);
140
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
141
- bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
142
- phys_ptr, attrs, prot, page_size, fi);
143
-
144
- *fsr = arm_fi_to_sfsc(fi);
145
- return ret;
146
+ return get_phys_addr_v6(env, address, access_type, mmu_idx,
147
+ phys_ptr, attrs, prot, page_size, fi);
148
} else {
149
- bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
150
+ return get_phys_addr_v5(env, address, access_type, mmu_idx,
151
phys_ptr, prot, page_size, fi);
152
-
153
- *fsr = arm_fi_to_sfsc(fi);
154
- return ret;
155
}
156
}
63
}
157
64
158
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
159
* fsr with ARM DFSR/IFSR fault register format value on failure.
160
*/
161
bool arm_tlb_fill(CPUState *cs, vaddr address,
162
- MMUAccessType access_type, int mmu_idx, uint32_t *fsr,
163
+ MMUAccessType access_type, int mmu_idx,
164
ARMMMUFaultInfo *fi)
165
{
166
ARMCPU *cpu = ARM_CPU(cs);
167
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
168
169
ret = get_phys_addr(env, address, access_type,
170
core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
171
- &attrs, &prot, &page_size, fsr, fi, NULL);
172
+ &attrs, &prot, &page_size, fi, NULL);
173
if (!ret) {
174
/* Map a single [sub]page. */
175
phys_addr &= TARGET_PAGE_MASK;
176
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
177
target_ulong page_size;
178
int prot;
179
bool ret;
180
- uint32_t fsr;
181
ARMMMUFaultInfo fi = {};
182
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
183
184
*attrs = (MemTxAttrs) {};
185
186
ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
187
- attrs, &prot, &page_size, &fsr, &fi, NULL);
188
+ attrs, &prot, &page_size, &fi, NULL);
189
190
if (ret) {
191
return -1;
192
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/target/arm/op_helper.c
195
+++ b/target/arm/op_helper.c
196
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
197
int mmu_idx, uintptr_t retaddr)
198
{
199
bool ret;
200
- uint32_t fsr = 0;
201
ARMMMUFaultInfo fi = {};
202
203
- ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
204
+ ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fi);
205
if (unlikely(ret)) {
206
ARMCPU *cpu = ARM_CPU(cs);
207
208
--
65
--
209
2.7.4
66
2.20.1
210
67
211
68
diff view generated by jsdifflib
1
All the callers of arm_ldq_ptw() and arm_ldl_ptw() ignore the value
1
The FCMLA (by element) instruction exists in the
2
that those functions store in the fsr argument on failure: if they
2
"vector x indexed element" encoding group, but not in
3
return failure to their callers they will always overwrite the fsr
3
the "scalar x indexed element" group. Correctly UNDEF
4
value with something else.
4
the unallocated encodings.
5
5
6
Remove the argument from these functions and S1_ptw_translate().
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
This will simplify removing fsr from the calling functions.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190129140411.682-2-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
8
13
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
13
Message-id: 1512503192-2239-3-git-send-email-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 24 +++++++++++-------------
16
1 file changed, 11 insertions(+), 13 deletions(-)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
16
--- a/target/arm/translate-a64.c
21
+++ b/target/arm/helper.c
17
+++ b/target/arm/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
23
/* Translate a S1 pagetable walk through S2 if needed. */
19
case 0x13: /* FCMLA #90 */
24
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
20
case 0x15: /* FCMLA #180 */
25
hwaddr addr, MemTxAttrs txattrs,
21
case 0x17: /* FCMLA #270 */
26
- uint32_t *fsr,
22
- if (!dc_isar_feature(aa64_fcma, s)) {
27
ARMMMUFaultInfo *fi)
23
+ if (is_scalar || !dc_isar_feature(aa64_fcma, s)) {
28
{
24
unallocated_encoding(s);
29
if ((mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1) &&
25
return;
30
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
31
hwaddr s2pa;
32
int s2prot;
33
int ret;
34
+ uint32_t fsr;
35
36
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
37
- &txattrs, &s2prot, &s2size, fsr, fi, NULL);
38
+ &txattrs, &s2prot, &s2size, &fsr, fi, NULL);
39
if (ret) {
40
fi->s2addr = addr;
41
fi->stage2 = true;
42
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
43
* (but not if it was for a debug access).
44
*/
45
static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
46
- ARMMMUIdx mmu_idx, uint32_t *fsr,
47
- ARMMMUFaultInfo *fi)
48
+ ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
49
{
50
ARMCPU *cpu = ARM_CPU(cs);
51
CPUARMState *env = &cpu->env;
52
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
53
54
attrs.secure = is_secure;
55
as = arm_addressspace(cs, attrs);
56
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi);
57
+ addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
58
if (fi->s1ptw) {
59
return 0;
60
}
61
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
62
}
63
64
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
65
- ARMMMUIdx mmu_idx, uint32_t *fsr,
66
- ARMMMUFaultInfo *fi)
67
+ ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
68
{
69
ARMCPU *cpu = ARM_CPU(cs);
70
CPUARMState *env = &cpu->env;
71
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
72
73
attrs.secure = is_secure;
74
as = arm_addressspace(cs, attrs);
75
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi);
76
+ addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
77
if (fi->s1ptw) {
78
return 0;
79
}
80
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
81
goto do_fault;
82
}
83
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
84
- mmu_idx, fsr, fi);
85
+ mmu_idx, fi);
86
type = (desc & 3);
87
domain = (desc >> 5) & 0x0f;
88
if (regime_el(env, mmu_idx) == 1) {
89
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
90
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
91
}
92
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
93
- mmu_idx, fsr, fi);
94
+ mmu_idx, fi);
95
switch (desc & 3) {
96
case 0: /* Page translation fault. */
97
code = 7;
98
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
99
goto do_fault;
100
}
101
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
102
- mmu_idx, fsr, fi);
103
+ mmu_idx, fi);
104
type = (desc & 3);
105
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
106
/* Section translation fault, or attempt to use the encoding
107
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
108
/* Lookup l2 entry. */
109
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
110
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
111
- mmu_idx, fsr, fi);
112
+ mmu_idx, fi);
113
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
114
switch (desc & 3) {
115
case 0: /* Page translation fault. */
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
117
descaddr |= (address >> (stride * (4 - level))) & indexmask;
118
descaddr &= ~7ULL;
119
nstable = extract32(tableattrs, 4, 1);
120
- descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi);
121
+ descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
122
if (fi->s1ptw) {
123
goto do_fault;
124
}
26
}
125
--
27
--
126
2.7.4
28
2.20.1
127
29
128
30
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
In disas_simd_indexed(), for the case of "complex fp", each indexable
2
element is a complex pair, so the total size is twice that indicated
3
in the 'size' field in the encoding. We were trying to do this
4
"double the size" operation with a left shift by 1, but this is
5
incorrect because the 'size' field is a MO_8/MO_16/MO_32/MO_64
6
value, and doubling the size should be done by a simple increment.
2
7
3
Add support for Micron (Numonyx) n25q512a11 and n25q512a13 flashes.
8
This meant we were mishandling FCMLA (by element) of values where
9
the real and imaginary parts are 32-bit floats, and would incorrectly
10
UNDEF this encoding. (No other insns take this code path, and for
11
16-bit floats it happens that 1 << 1 and 1 + 1 are both the same).
4
12
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
13
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
6
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-5-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
16
Message-id: 20190129140411.682-3-peter.maydell@linaro.org
12
---
17
---
13
hw/block/m25p80.c | 2 ++
18
target/arm/translate-a64.c | 2 +-
14
1 file changed, 2 insertions(+)
19
1 file changed, 1 insertion(+), 1 deletion(-)
15
20
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
23
--- a/target/arm/translate-a64.c
19
+++ b/hw/block/m25p80.c
24
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
21
{ INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) },
26
22
{ INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) },
27
case 2: /* complex fp */
23
{ INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
28
/* Each indexable element is a complex pair. */
24
+ { INFO("n25q512a11", 0x20bb20, 0, 64 << 10, 1024, ER_4K) },
29
- size <<= 1;
25
+ { INFO("n25q512a13", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
30
+ size += 1;
26
{ INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
31
switch (size) {
27
{ INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
32
case MO_32:
28
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
33
if (h && !is_q) {
29
--
34
--
30
2.7.4
35
2.20.1
31
36
32
37
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav8() return a fault type in the ARMMMUFaultInfo
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
structure, which we convert to the FSC at the callsite.
3
2
3
Whenever we notice that a counter overflow has occurred, send an
4
interrupt. This is made more reliable with the addition of a timer in a
5
follow-on commit.
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190124162401.5111-2-aaron@os.amperecomputing.com
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-9-git-send-email-peter.maydell@linaro.org
9
---
11
---
10
target/arm/helper.c | 29 ++++++++++++++++++-----------
12
target/arm/helper.c | 61 +++++++++++++++++++++++++++++++++++++--------
11
1 file changed, 18 insertions(+), 11 deletions(-)
13
1 file changed, 51 insertions(+), 10 deletions(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
18
static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
20
/* Definitions for the PMU registers */
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
21
#define PMCRN_MASK 0xf800
20
hwaddr *phys_ptr, MemTxAttrs *txattrs,
22
#define PMCRN_SHIFT 11
21
- int *prot, uint32_t *fsr, uint32_t *mregion)
23
+#define PMCRLC 0x40
22
+ int *prot, ARMMMUFaultInfo *fi, uint32_t *mregion)
24
#define PMCRDP 0x10
23
{
25
#define PMCRD 0x8
24
/* Perform a PMSAv8 MPU lookup (without also doing the SAU check
26
#define PMCRC 0x4
25
* that a full phys-to-virt translation does).
27
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
26
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
28
return enabled && !prohibited && !filtered;
27
/* Multiple regions match -- always a failure (unlike
29
}
28
* PMSAv7 where highest-numbered-region wins)
30
29
*/
31
+static void pmu_update_irq(CPUARMState *env)
30
- *fsr = 0x00d; /* permission fault */
32
+{
31
+ fi->type = ARMFault_Permission;
33
+ ARMCPU *cpu = arm_env_get_cpu(env);
32
+ fi->level = 1;
34
+ qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
33
return true;
35
+ (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
34
}
36
+}
35
37
+
36
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
38
/*
37
39
* Ensure c15_ccnt is the guest-visible count so that operations such as
38
if (!hit) {
40
* enabling/disabling the counter or filtering, modifying the count itself,
39
/* background fault */
41
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
40
- *fsr = 0;
42
eff_cycles /= 64;
41
+ fi->type = ARMFault_Background;
43
}
42
return true;
44
45
- env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
46
+ uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
47
+
48
+ uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
49
+ 1ull << 63 : 1ull << 31;
50
+ if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
51
+ env->cp15.c9_pmovsr |= (1 << 31);
52
+ pmu_update_irq(env);
53
+ }
54
+
55
+ env->cp15.c15_ccnt = new_pmccntr;
43
}
56
}
44
57
env->cp15.c15_ccnt_delta = cycles;
45
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
58
}
59
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
60
}
61
62
if (pmu_counter_enabled(env, counter)) {
63
- env->cp15.c14_pmevcntr[counter] =
64
- count - env->cp15.c14_pmevcntr_delta[counter];
65
+ uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
66
+
67
+ if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
68
+ env->cp15.c9_pmovsr |= (1 << counter);
69
+ pmu_update_irq(env);
70
+ }
71
+ env->cp15.c14_pmevcntr[counter] = new_pmevcntr;
72
}
73
env->cp15.c14_pmevcntr_delta[counter] = count;
74
}
75
@@ -XXX,XX +XXX,XX @@ static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
/* counter is SW_INCR */
77
(env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
78
pmevcntr_op_start(env, i);
79
- env->cp15.c14_pmevcntr[i]++;
80
+
81
+ /*
82
+ * Detect if this write causes an overflow since we can't predict
83
+ * PMSWINC overflows like we can for other events
84
+ */
85
+ uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
86
+
87
+ if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
88
+ env->cp15.c9_pmovsr |= (1 << i);
89
+ pmu_update_irq(env);
90
+ }
91
+
92
+ env->cp15.c14_pmevcntr[i] = new_pmswinc;
93
+
94
pmevcntr_op_finish(env, i);
46
}
95
}
47
}
96
}
48
97
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
49
- *fsr = 0x00d; /* Permission fault */
98
{
50
+ fi->type = ARMFault_Permission;
99
value &= pmu_counter_mask(env);
51
+ fi->level = 1;
100
env->cp15.c9_pmovsr &= ~value;
52
return !(*prot & (1 << access_type));
101
+ pmu_update_irq(env);
53
}
102
}
54
103
55
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
104
static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
105
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
57
MMUAccessType access_type, ARMMMUIdx mmu_idx,
58
hwaddr *phys_ptr, MemTxAttrs *txattrs,
59
- int *prot, uint32_t *fsr)
60
+ int *prot, ARMMMUFaultInfo *fi)
61
{
106
{
62
uint32_t secure = regime_is_secure(env, mmu_idx);
107
value &= pmu_counter_mask(env);
63
V8M_SAttributes sattrs = {};
108
env->cp15.c9_pmovsr |= value;
64
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
109
+ pmu_update_irq(env);
65
* (including possibly emulating an SG instruction).
66
*/
67
if (sattrs.ns != !secure) {
68
- *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
69
+ if (sattrs.nsc) {
70
+ fi->type = ARMFault_QEMU_NSCExec;
71
+ } else {
72
+ fi->type = ARMFault_QEMU_SFault;
73
+ }
74
*phys_ptr = address;
75
*prot = 0;
76
return true;
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
78
* If we added it we would need to do so as a special case
79
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
80
*/
81
- *fsr = M_FAKE_FSR_SFAULT;
82
+ fi->type = ARMFault_QEMU_SFault;
83
*phys_ptr = address;
84
*prot = 0;
85
return true;
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
87
}
88
89
return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
90
- txattrs, prot, fsr, NULL);
91
+ txattrs, prot, fi, NULL);
92
}
110
}
93
111
94
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
112
static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
95
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
113
@@ -XXX,XX +XXX,XX @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
96
if (arm_feature(env, ARM_FEATURE_V8)) {
114
/* We have no event counters so only the C bit can be changed */
97
/* PMSAv8 */
115
value &= pmu_counter_mask(env);
98
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
116
env->cp15.c9_pminten |= value;
99
- phys_ptr, attrs, prot, fsr);
117
+ pmu_update_irq(env);
100
+ phys_ptr, attrs, prot, fi);
118
}
101
+ *fsr = arm_fi_to_sfsc(fi);
119
102
} else if (arm_feature(env, ARM_FEATURE_V7)) {
120
static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
103
/* PMSAv7 */
121
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
104
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
122
{
105
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
123
value &= pmu_counter_mask(env);
106
uint32_t tt_resp;
124
env->cp15.c9_pminten &= ~value;
107
bool r, rw, nsr, nsrw, mrvalid;
125
+ pmu_update_irq(env);
108
int prot;
126
}
109
+ ARMMMUFaultInfo fi = {};
127
110
MemTxAttrs attrs = {};
128
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
111
hwaddr phys_addr;
129
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
112
- uint32_t fsr;
130
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
113
ARMMMUIdx mmu_idx;
131
.writefn = pmcntenclr_write },
114
uint32_t mregion;
132
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
115
bool targetpriv;
133
- .access = PL0_RW,
116
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
134
+ .access = PL0_RW, .type = ARM_CP_IO,
117
if (arm_current_el(env) != 0 || alt) {
135
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
118
/* We can ignore the return value as prot is always set */
136
.accessfn = pmreg_access,
119
pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
137
.writefn = pmovsr_write,
120
- &phys_addr, &attrs, &prot, &fsr, &mregion);
138
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
121
+ &phys_addr, &attrs, &prot, &fi, &mregion);
139
{ .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
122
if (mregion == -1) {
140
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
123
mrvalid = false;
141
.access = PL0_RW, .accessfn = pmreg_access,
124
mregion = 0;
142
- .type = ARM_CP_ALIAS,
143
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
144
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
145
.writefn = pmovsr_write,
146
.raw_writefn = raw_write },
147
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
148
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
149
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
150
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
151
.writefn = pmswinc_write },
152
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
153
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
154
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
155
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
156
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
157
.writefn = pmswinc_write },
158
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
159
.access = PL0_RW, .type = ARM_CP_ALIAS,
160
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
161
/* PMOVSSET is not implemented in v7 before v7ve */
162
{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
163
.access = PL0_RW, .accessfn = pmreg_access,
164
- .type = ARM_CP_ALIAS,
165
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
166
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
167
.writefn = pmovsset_write,
168
.raw_writefn = raw_write },
169
{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
170
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
171
.access = PL0_RW, .accessfn = pmreg_access,
172
- .type = ARM_CP_ALIAS,
173
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
174
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
175
.writefn = pmovsset_write,
176
.raw_writefn = raw_write },
125
--
177
--
126
2.7.4
178
2.20.1
127
179
128
180
diff view generated by jsdifflib
1
For M profile, we currently have an mmu index MNegPri for
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
"requested execution priority negative". This fails to
2
3
distinguish "requested execution priority negative, privileged"
3
Make PMU overflow interrupts more accurate by using a timer to predict
4
from "requested execution priority negative, usermode", but
4
when they will overflow rather than waiting for an event to occur which
5
the two can return different results for MPU lookups. Fix this
5
allows us to otherwise check them.
6
by splitting MNegPri into MNegPriPriv and MNegPriUser, and
6
7
similarly for the Secure equivalent MSNegPri.
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
This takes us from 6 M profile MMU modes to 8, which means
9
Message-id: 20190124162401.5111-3-aaron@os.amperecomputing.com
10
we need to bump NB_MMU_MODES; this is OK since the point
11
where we are forced to reduce TLB sizes is 9 MMU modes.
12
13
(It would in theory be possible to stick with 6 MMU indexes:
14
{mpu-disabled,user,privileged} x {secure,nonsecure} since
15
in the MPU-disabled case the result of an MPU lookup is
16
always the same for both user and privileged code. However
17
we would then need to rework the TB flags handling to put
18
user/priv into the TB flags separately from the mmuidx.
19
Adding an extra couple of mmu indexes is simpler.)
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 1512153879-5291-5-git-send-email-peter.maydell@linaro.org
24
---
11
---
25
target/arm/cpu.h | 54 ++++++++++++++++++++++++++++++--------------------
12
target/arm/cpu.h | 10 +++++++
26
target/arm/internals.h | 6 ++++--
13
target/arm/cpu.c | 12 ++++++++
27
target/arm/helper.c | 11 ++++++----
14
target/arm/helper.c | 72 +++++++++++++++++++++++++++++++++++++++++++--
28
target/arm/translate.c | 8 ++++++--
15
3 files changed, 92 insertions(+), 2 deletions(-)
29
4 files changed, 50 insertions(+), 29 deletions(-)
30
16
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ enum {
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
36
#define ARM_CPU_VIRQ 2
22
37
#define ARM_CPU_VFIQ 3
23
/* Timers used by the generic (architected) timer */
38
24
QEMUTimer *gt_timer[NUM_GTIMERS];
39
-#define NB_MMU_MODES 7
25
+ /*
40
+#define NB_MMU_MODES 8
26
+ * Timer used by the PMU. Its state is restored after migration by
41
/* ARM-specific extra insn start words:
27
+ * pmu_op_finish() - it does not need other handling during migration
42
* 1: Conditional execution bits
28
+ */
43
* 2: Partial exception syndrome for data aborts
29
+ QEMUTimer *pmu_timer;
44
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
30
/* GPIO outputs for generic timer */
45
* They have the following different MMU indexes:
31
qemu_irq gt_timer_outputs[NUM_GTIMERS];
46
* User
32
/* GPIO output for GICv3 maintenance interrupt signal */
47
* Privileged
33
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env);
48
- * Execution priority negative (this is like privileged, but the
34
void pmu_op_start(CPUARMState *env);
49
- * MPU HFNMIENA bit means that it may have different access permission
35
void pmu_op_finish(CPUARMState *env);
50
- * check results to normal privileged code, so can't share a TLB).
36
51
+ * User, execution priority negative (ie the MPU HFNMIENA bit may apply)
37
+/*
52
+ * Privileged, execution priority negative (ditto)
38
+ * Called when a PMU counter is due to overflow
53
* If the CPU supports the v8M Security Extension then there are also:
39
+ */
54
* Secure User
40
+void arm_pmu_timer_cb(void *opaque);
55
* Secure Privileged
41
+
56
- * Secure, execution priority negative
42
/**
57
+ * Secure User, execution priority negative
43
* Functions to register as EL change hooks for PMU mode filtering
58
+ * Secure Privileged, execution priority negative
59
*
60
* The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
61
* are not quite the same -- different CPU types (most notably M profile
62
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
63
* The constant names here are patterned after the general style of the names
64
* of the AT/ATS operations.
65
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
66
+ * For M profile we arrange them to have a bit for priv, a bit for negpri
67
+ * and a bit for secure.
68
*/
44
*/
69
#define ARM_MMU_IDX_A 0x10 /* A profile */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
70
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
46
index XXXXXXX..XXXXXXX 100644
71
#define ARM_MMU_IDX_M 0x40 /* M profile */
47
--- a/target/arm/cpu.c
72
48
+++ b/target/arm/cpu.c
73
+/* meanings of the bits for M profile mmu idx values */
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
74
+#define ARM_MMU_IDX_M_PRIV 0x1
50
QLIST_REMOVE(hook, node);
75
+#define ARM_MMU_IDX_M_NEGPRI 0x2
51
g_free(hook);
76
+#define ARM_MMU_IDX_M_S 0x4
52
}
77
+
53
+#ifndef CONFIG_USER_ONLY
78
#define ARM_MMU_IDX_TYPE_MASK (~0x7)
54
+ if (cpu->pmu_timer) {
79
#define ARM_MMU_IDX_COREIDX_MASK 0x7
55
+ timer_del(cpu->pmu_timer);
80
56
+ timer_deinit(cpu->pmu_timer);
81
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
57
+ timer_free(cpu->pmu_timer);
82
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
83
ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
84
ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
85
- ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
86
- ARMMMUIdx_MSUser = 3 | ARM_MMU_IDX_M,
87
- ARMMMUIdx_MSPriv = 4 | ARM_MMU_IDX_M,
88
- ARMMMUIdx_MSNegPri = 5 | ARM_MMU_IDX_M,
89
+ ARMMMUIdx_MUserNegPri = 2 | ARM_MMU_IDX_M,
90
+ ARMMMUIdx_MPrivNegPri = 3 | ARM_MMU_IDX_M,
91
+ ARMMMUIdx_MSUser = 4 | ARM_MMU_IDX_M,
92
+ ARMMMUIdx_MSPriv = 5 | ARM_MMU_IDX_M,
93
+ ARMMMUIdx_MSUserNegPri = 6 | ARM_MMU_IDX_M,
94
+ ARMMMUIdx_MSPrivNegPri = 7 | ARM_MMU_IDX_M,
95
/* Indexes below here don't have TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
*/
98
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
99
ARMMMUIdxBit_S2NS = 1 << 6,
100
ARMMMUIdxBit_MUser = 1 << 0,
101
ARMMMUIdxBit_MPriv = 1 << 1,
102
- ARMMMUIdxBit_MNegPri = 1 << 2,
103
- ARMMMUIdxBit_MSUser = 1 << 3,
104
- ARMMMUIdxBit_MSPriv = 1 << 4,
105
- ARMMMUIdxBit_MSNegPri = 1 << 5,
106
+ ARMMMUIdxBit_MUserNegPri = 1 << 2,
107
+ ARMMMUIdxBit_MPrivNegPri = 1 << 3,
108
+ ARMMMUIdxBit_MSUser = 1 << 4,
109
+ ARMMMUIdxBit_MSPriv = 1 << 5,
110
+ ARMMMUIdxBit_MSUserNegPri = 1 << 6,
111
+ ARMMMUIdxBit_MSPrivNegPri = 1 << 7,
112
} ARMMMUIdxBit;
113
114
#define MMU_USER_IDX 0
115
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
116
case ARM_MMU_IDX_A:
117
return mmu_idx & 3;
118
case ARM_MMU_IDX_M:
119
- return (mmu_idx == ARMMMUIdx_MUser || mmu_idx == ARMMMUIdx_MSUser)
120
- ? 0 : 1;
121
+ return mmu_idx & ARM_MMU_IDX_M_PRIV;
122
default:
123
g_assert_not_reached();
124
}
125
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
126
bool secstate)
127
{
128
int el = arm_current_el(env);
129
- ARMMMUIdx mmu_idx;
130
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
131
132
- if (el == 0) {
133
- mmu_idx = secstate ? ARMMMUIdx_MSUser : ARMMMUIdx_MUser;
134
- } else {
135
- mmu_idx = secstate ? ARMMMUIdx_MSPriv : ARMMMUIdx_MPriv;
136
+ if (el != 0) {
137
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
138
}
139
140
if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
141
- mmu_idx = secstate ? ARMMMUIdx_MSNegPri : ARMMMUIdx_MNegPri;
142
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
143
+ }
58
+ }
144
+
59
+#endif
145
+ if (secstate) {
60
}
146
+ mmu_idx |= ARM_MMU_IDX_M_S;
61
147
}
62
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
148
63
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
149
return mmu_idx;
64
arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
150
diff --git a/target/arm/internals.h b/target/arm/internals.h
65
arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
151
index XXXXXXX..XXXXXXX 100644
66
}
152
--- a/target/arm/internals.h
67
+
153
+++ b/target/arm/internals.h
68
+#ifndef CONFIG_USER_ONLY
154
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
69
+ cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, arm_pmu_timer_cb,
155
case ARMMMUIdx_S1NSE1:
70
+ cpu);
156
case ARMMMUIdx_S1E2:
71
+#endif
157
case ARMMMUIdx_S2NS:
72
} else {
158
+ case ARMMMUIdx_MPrivNegPri:
73
cpu->id_aa64dfr0 &= ~0xf00;
159
+ case ARMMMUIdx_MUserNegPri:
74
cpu->pmceid0 = 0;
160
case ARMMMUIdx_MPriv:
161
- case ARMMMUIdx_MNegPri:
162
case ARMMMUIdx_MUser:
163
return false;
164
case ARMMMUIdx_S1E3:
165
case ARMMMUIdx_S1SE0:
166
case ARMMMUIdx_S1SE1:
167
+ case ARMMMUIdx_MSPrivNegPri:
168
+ case ARMMMUIdx_MSUserNegPri:
169
case ARMMMUIdx_MSPriv:
170
- case ARMMMUIdx_MSNegPri:
171
case ARMMMUIdx_MSUser:
172
return true;
173
default:
174
diff --git a/target/arm/helper.c b/target/arm/helper.c
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
175
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
176
--- a/target/arm/helper.c
77
--- a/target/arm/helper.c
177
+++ b/target/arm/helper.c
78
+++ b/target/arm/helper.c
178
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
79
@@ -XXX,XX +XXX,XX @@ typedef struct pm_event {
179
case ARMMMUIdx_S1SE1:
80
* counters hold a difference from the return value from this function
180
case ARMMMUIdx_S1NSE0:
81
*/
181
case ARMMMUIdx_S1NSE1:
82
uint64_t (*get_count)(CPUARMState *);
182
+ case ARMMMUIdx_MPrivNegPri:
83
+ /*
183
+ case ARMMMUIdx_MUserNegPri:
84
+ * Return how many nanoseconds it will take (at a minimum) for count events
184
case ARMMMUIdx_MPriv:
85
+ * to occur. A negative value indicates the counter will never overflow, or
185
- case ARMMMUIdx_MNegPri:
86
+ * that the counter has otherwise arranged for the overflow bit to be set
186
case ARMMMUIdx_MUser:
87
+ * and the PMU interrupt to be raised on overflow.
187
+ case ARMMMUIdx_MSPrivNegPri:
88
+ */
188
+ case ARMMMUIdx_MSUserNegPri:
89
+ int64_t (*ns_per_count)(uint64_t);
189
case ARMMMUIdx_MSPriv:
90
} pm_event;
190
- case ARMMMUIdx_MSNegPri:
91
191
case ARMMMUIdx_MSUser:
92
static bool event_always_supported(CPUARMState *env)
192
return 1;
93
@@ -XXX,XX +XXX,XX @@ static uint64_t swinc_get_count(CPUARMState *env)
193
default:
94
return 0;
194
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
95
}
195
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
96
196
case R_V7M_MPU_CTRL_ENABLE_MASK:
97
+static int64_t swinc_ns_per(uint64_t ignored)
197
/* Enabled, but not for HardFault and NMI */
98
+{
198
- return mmu_idx == ARMMMUIdx_MNegPri ||
99
+ return -1;
199
- mmu_idx == ARMMMUIdx_MSNegPri;
100
+}
200
+ return mmu_idx & ARM_MMU_IDX_M_NEGPRI;
101
+
201
case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
102
/*
202
/* Enabled for all cases */
103
* Return the underlying cycle count for the PMU cycle counters. If we're in
203
return false;
104
* usermode, simply return 0.
204
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
105
@@ -XXX,XX +XXX,XX @@ static uint64_t cycles_get_count(CPUARMState *env)
205
case ARMMMUIdx_S1NSE0:
106
}
206
case ARMMMUIdx_MUser:
107
207
case ARMMMUIdx_MSUser:
108
#ifndef CONFIG_USER_ONLY
208
+ case ARMMMUIdx_MUserNegPri:
109
+static int64_t cycles_ns_per(uint64_t cycles)
209
+ case ARMMMUIdx_MSUserNegPri:
110
+{
210
return true;
111
+ return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
211
default:
112
+}
212
return false;
113
+
213
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
static bool instructions_supported(CPUARMState *env)
214
index XXXXXXX..XXXXXXX 100644
115
{
215
--- a/target/arm/translate.c
116
return use_icount == 1 /* Precise instruction counting */;
216
+++ b/target/arm/translate.c
117
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
217
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
118
{
218
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
119
return (uint64_t)cpu_get_icount_raw();
219
case ARMMMUIdx_MUser:
120
}
220
case ARMMMUIdx_MPriv:
121
+
221
- case ARMMMUIdx_MNegPri:
122
+static int64_t instructions_ns_per(uint64_t icount)
222
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
123
+{
223
+ case ARMMMUIdx_MUserNegPri:
124
+ return cpu_icount_to_ns((int64_t)icount);
224
+ case ARMMMUIdx_MPrivNegPri:
125
+}
225
+ return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
126
#endif
226
case ARMMMUIdx_MSUser:
127
227
case ARMMMUIdx_MSPriv:
128
static const pm_event pm_events[] = {
228
- case ARMMMUIdx_MSNegPri:
129
{ .number = 0x000, /* SW_INCR */
229
return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
130
.supported = event_always_supported,
230
+ case ARMMMUIdx_MSUserNegPri:
131
.get_count = swinc_get_count,
231
+ case ARMMMUIdx_MSPrivNegPri:
132
+ .ns_per_count = swinc_ns_per,
232
+ return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
133
},
233
case ARMMMUIdx_S2NS:
134
#ifndef CONFIG_USER_ONLY
234
default:
135
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
235
g_assert_not_reached();
136
.supported = instructions_supported,
137
.get_count = instructions_get_count,
138
+ .ns_per_count = instructions_ns_per,
139
},
140
{ .number = 0x011, /* CPU_CYCLES, Cycle */
141
.supported = event_always_supported,
142
.get_count = cycles_get_count,
143
+ .ns_per_count = cycles_ns_per,
144
}
145
#endif
146
};
147
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
148
void pmccntr_op_finish(CPUARMState *env)
149
{
150
if (pmu_counter_enabled(env, 31)) {
151
- uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
152
+#ifndef CONFIG_USER_ONLY
153
+ /* Calculate when the counter will next overflow */
154
+ uint64_t remaining_cycles = -env->cp15.c15_ccnt;
155
+ if (!(env->cp15.c9_pmcr & PMCRLC)) {
156
+ remaining_cycles = (uint32_t)remaining_cycles;
157
+ }
158
+ int64_t overflow_in = cycles_ns_per(remaining_cycles);
159
160
+ if (overflow_in > 0) {
161
+ int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
162
+ overflow_in;
163
+ ARMCPU *cpu = arm_env_get_cpu(env);
164
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
165
+ }
166
+#endif
167
+
168
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
169
if (env->cp15.c9_pmcr & PMCRD) {
170
/* Increment once every 64 processor clock cycles */
171
prev_cycles /= 64;
172
}
173
-
174
env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
175
}
176
}
177
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
178
static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
179
{
180
if (pmu_counter_enabled(env, counter)) {
181
+#ifndef CONFIG_USER_ONLY
182
+ uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
183
+ uint16_t event_idx = supported_event_map[event];
184
+ uint64_t delta = UINT32_MAX -
185
+ (uint32_t)env->cp15.c14_pmevcntr[counter] + 1;
186
+ int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
187
+
188
+ if (overflow_in > 0) {
189
+ int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
190
+ overflow_in;
191
+ ARMCPU *cpu = arm_env_get_cpu(env);
192
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
193
+ }
194
+#endif
195
+
196
env->cp15.c14_pmevcntr_delta[counter] -=
197
env->cp15.c14_pmevcntr[counter];
198
}
199
@@ -XXX,XX +XXX,XX @@ void pmu_post_el_change(ARMCPU *cpu, void *ignored)
200
pmu_op_finish(&cpu->env);
201
}
202
203
+void arm_pmu_timer_cb(void *opaque)
204
+{
205
+ ARMCPU *cpu = opaque;
206
+
207
+ /*
208
+ * Update all the counter values based on the current underlying counts,
209
+ * triggering interrupts to be raised, if necessary. pmu_op_finish() also
210
+ * has the effect of setting the cpu->pmu_timer to the next earliest time a
211
+ * counter may expire.
212
+ */
213
+ pmu_op_start(&cpu->env);
214
+ pmu_op_finish(&cpu->env);
215
+}
216
+
217
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
218
uint64_t value)
219
{
236
--
220
--
237
2.7.4
221
2.20.1
238
222
239
223
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that do_ats_write() is entirely in control of whether to
3
These bits become writable with the ARMv8.3-PAuth extension.
4
generate a 32-bit PAR or a 64-bit PAR, we can make it use the
5
correct (complicated) condition for doing so.
6
4
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190129143511.12311-1-richard.henderson@linaro.org
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1512503192-2239-13-git-send-email-peter.maydell@linaro.org
13
[PMM: Rebased Edgar's patch on top of get_phys_addr() refactoring;
14
use arm_s1_regime_using_lpae_format() rather than
15
regime_using_lpae_format() because the latter will assert
16
if passed ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1;
17
updated commit message appropriately]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
target/arm/helper.c | 33 +++++++++++++++++++++++++++++----
10
target/arm/helper.c | 6 ++++++
21
1 file changed, 29 insertions(+), 4 deletions(-)
11
1 file changed, 6 insertions(+)
22
12
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
26
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
17
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
28
int prot;
18
if (cpu_isar_feature(aa64_lor, cpu)) {
29
bool ret;
19
valid_mask |= SCR_TLOR;
30
uint64_t par64;
20
}
31
+ bool format64 = false;
21
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
32
MemTxAttrs attrs = {};
22
+ valid_mask |= SCR_API | SCR_APK;
33
ARMMMUFaultInfo fi = {};
34
ARMCacheAttrs cacheattrs = {};
35
36
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
37
&prot, &page_size, &fi, &cacheattrs);
38
- /* TODO: this is not the correct condition to use to decide whether
39
- * to report a PAR in 64-bit or 32-bit format.
40
- */
41
- if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
42
+
43
+ if (is_a64(env)) {
44
+ format64 = true;
45
+ } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
46
+ /*
47
+ * ATS1Cxx:
48
+ * * TTBCR.EAE determines whether the result is returned using the
49
+ * 32-bit or the 64-bit PAR format
50
+ * * Instructions executed in Hyp mode always use the 64bit format
51
+ *
52
+ * ATS1S2NSOxx uses the 64bit format if any of the following is true:
53
+ * * The Non-secure TTBCR.EAE bit is set to 1
54
+ * * The implementation includes EL2, and the value of HCR.VM is 1
55
+ *
56
+ * ATS1Hx always uses the 64bit format (not supported yet).
57
+ */
58
+ format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
59
+
60
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
61
+ if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
62
+ format64 |= env->cp15.hcr_el2 & HCR_VM;
63
+ } else {
64
+ format64 |= arm_current_el(env) == 2;
65
+ }
66
+ }
67
+ }
23
+ }
68
+
24
69
+ if (format64) {
25
/* Clear all-context RES0 bits. */
70
/* Create a 64-bit PAR */
26
value &= valid_mask;
71
par64 = (1 << 11); /* LPAE bit always set */
27
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
72
if (!ret) {
28
if (cpu_isar_feature(aa64_lor, cpu)) {
29
valid_mask |= HCR_TLOR;
30
}
31
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
32
+ valid_mask |= HCR_API | HCR_APK;
33
+ }
34
35
/* Clear RES0 bits. */
36
value &= valid_mask;
73
--
37
--
74
2.7.4
38
2.20.1
75
39
76
40
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Julia Suvorova <jusual@mail.ru>
2
2
3
Make tx/rx_data_bytes more generic so they can be reused (when adding
3
Until now, the set_pc logic was unclear, which raised questions about
4
support for the Zynqmp Generic QSPI).
4
whether it should be used directly, applying a value to PC or adding
5
additional checks, for example, set the Thumb bit in Arm cpu. Let's set
6
the set_pc logic for “Configure the PC, as was done in the ELF file”
7
and implement synchronize_with_tb hook for preserving PC to cpu_tb_exec.
5
8
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Signed-off-by: Julia Suvorova <jusual@mail.ru>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20190129121817.7109-1-jusual@mail.ru
9
Message-id: 20171126231634.9531-9-frasse.iglesias@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
hw/ssi/xilinx_spips.c | 64 +++++++++++++++++++++++++++++----------------------
15
include/qom/cpu.h | 16 ++++++++++++++--
13
1 file changed, 37 insertions(+), 27 deletions(-)
16
hw/arm/boot.c | 4 ----
17
target/arm/arm-powerctl.c | 3 ---
18
target/arm/cpu.c | 26 +++++++++++++++++++++++++-
19
target/arm/cpu64.c | 15 ---------------
20
5 files changed, 39 insertions(+), 25 deletions(-)
14
21
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
22
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
24
--- a/include/qom/cpu.h
18
+++ b/hw/ssi/xilinx_spips.c
25
+++ b/include/qom/cpu.h
26
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
27
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
28
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
29
* @get_memory_mapping: Callback for obtaining the memory mappings.
30
- * @set_pc: Callback for setting the Program Counter register.
31
+ * @set_pc: Callback for setting the Program Counter register. This
32
+ * should have the semantics used by the target architecture when
33
+ * setting the PC from a source such as an ELF file entry point;
34
+ * for example on Arm it will also set the Thumb mode bit based
35
+ * on the least significant bit of the new PC value.
36
+ * If the target behaviour here is anything other than "set
37
+ * the PC register to the value passed in" then the target must
38
+ * also implement the synchronize_from_tb hook.
39
* @synchronize_from_tb: Callback for synchronizing state from a TCG
40
- * #TranslationBlock.
41
+ * #TranslationBlock. This is called when we abandon execution
42
+ * of a TB before starting it, and must set all parts of the CPU
43
+ * state which the previous TB in the chain may not have updated.
44
+ * This always includes at least the program counter; some targets
45
+ * will need to do more. If this hook is not implemented then the
46
+ * default is to call @set_pc(tb->pc).
47
* @handle_mmu_fault: Callback for handling an MMU fault.
48
* @get_phys_page_debug: Callback for obtaining a physical address.
49
* @get_phys_page_attrs_debug: Callback for obtaining a physical address and the
50
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/boot.c
53
+++ b/hw/arm/boot.c
54
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
55
g_assert_not_reached();
56
}
57
58
- if (!env->aarch64) {
59
- env->thumb = info->entry & 1;
60
- entry &= 0xfffffffe;
61
- }
62
cpu_set_pc(cs, entry);
63
} else {
64
/* If we are booting Linux then we need to check whether we are
65
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/arm-powerctl.c
68
+++ b/target/arm/arm-powerctl.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
70
71
if (info->target_aa64) {
72
target_cpu->env.xregs[0] = info->context_id;
73
- target_cpu->env.thumb = false;
74
} else {
75
target_cpu->env.regs[0] = info->context_id;
76
- target_cpu->env.thumb = info->entry & 1;
77
- info->entry &= 0xfffffffe;
78
}
79
80
/* Start the new CPU at the requested address */
81
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/cpu.c
84
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@
85
@@ -XXX,XX +XXX,XX @@
20
/* config register */
86
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
21
#define R_CONFIG (0x00 / 4)
22
#define IFMODE (1U << 31)
23
-#define ENDIAN (1 << 26)
24
+#define R_CONFIG_ENDIAN (1 << 26)
25
#define MODEFAIL_GEN_EN (1 << 17)
26
#define MAN_START_COM (1 << 16)
27
#define MAN_START_EN (1 << 15)
28
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
29
}
30
}
31
32
-static inline void rx_data_bytes(XilinxSPIPS *s, uint8_t *value, int max)
33
+static inline void tx_data_bytes(Fifo8 *fifo, uint32_t value, int num, bool be)
34
{
87
{
35
int i;
88
ARMCPU *cpu = ARM_CPU(cs);
36
+ for (i = 0; i < num && !fifo8_is_full(fifo); ++i) {
89
+ CPUARMState *env = &cpu->env;
37
+ if (be) {
90
38
+ fifo8_push(fifo, (uint8_t)(value >> 24));
91
- cpu->env.regs[15] = value;
39
+ value <<= 8;
92
+ if (is_a64(env)) {
40
+ } else {
93
+ env->pc = value;
41
+ fifo8_push(fifo, (uint8_t)value);
94
+ env->thumb = 0;
42
+ value >>= 8;
95
+ } else {
43
+ }
96
+ env->regs[15] = value & ~1;
97
+ env->thumb = value & 1;
44
+ }
98
+ }
45
+}
99
+}
46
100
+
47
- for (i = 0; i < max && !fifo8_is_empty(&s->rx_fifo); ++i) {
101
+static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
48
- value[i] = fifo8_pop(&s->rx_fifo);
49
+static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
50
+{
102
+{
51
+ int i;
103
+ ARMCPU *cpu = ARM_CPU(cs);
104
+ CPUARMState *env = &cpu->env;
52
+
105
+
53
+ for (i = 0; i < max && !fifo8_is_empty(fifo); ++i) {
106
+ /*
54
+ value[i] = fifo8_pop(fifo);
107
+ * It's OK to look at env for the current mode here, because it's
55
}
108
+ * never possible for an AArch64 TB to chain to an AArch32 TB.
56
+ return max - i;
109
+ */
110
+ if (is_a64(env)) {
111
+ env->pc = tb->pc;
112
+ } else {
113
+ env->regs[15] = tb->pc;
114
+ }
57
}
115
}
58
116
59
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
117
static bool arm_cpu_has_work(CPUState *cs)
60
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
118
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
61
uint32_t mask = ~0;
119
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
62
uint32_t ret;
120
cc->dump_state = arm_cpu_dump_state;
63
uint8_t rx_buf[4];
121
cc->set_pc = arm_cpu_set_pc;
64
+ int shortfall;
122
+ cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
65
123
cc->gdb_read_register = arm_cpu_gdb_read_register;
66
addr >>= 2;
124
cc->gdb_write_register = arm_cpu_gdb_write_register;
67
switch (addr) {
125
#ifdef CONFIG_USER_ONLY
68
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
126
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
69
break;
127
index XXXXXXX..XXXXXXX 100644
70
case R_RX_DATA:
128
--- a/target/arm/cpu64.c
71
memset(rx_buf, 0, sizeof(rx_buf));
129
+++ b/target/arm/cpu64.c
72
- rx_data_bytes(s, rx_buf, s->num_txrx_bytes);
130
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_finalizefn(Object *obj)
73
- ret = s->regs[R_CONFIG] & ENDIAN ? cpu_to_be32(*(uint32_t *)rx_buf)
131
{
74
- : cpu_to_le32(*(uint32_t *)rx_buf);
75
+ shortfall = rx_data_bytes(&s->rx_fifo, rx_buf, s->num_txrx_bytes);
76
+ ret = s->regs[R_CONFIG] & R_CONFIG_ENDIAN ?
77
+ cpu_to_be32(*(uint32_t *)rx_buf) :
78
+ cpu_to_le32(*(uint32_t *)rx_buf);
79
+ if (!(s->regs[R_CONFIG] & R_CONFIG_ENDIAN)) {
80
+ ret <<= 8 * shortfall;
81
+ }
82
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
83
xilinx_spips_update_ixr(s);
84
return ret;
85
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
86
87
}
132
}
88
133
89
-static inline void tx_data_bytes(XilinxSPIPS *s, uint32_t value, int num)
134
-static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
90
-{
135
-{
91
- int i;
136
- ARMCPU *cpu = ARM_CPU(cs);
92
- for (i = 0; i < num && !fifo8_is_full(&s->tx_fifo); ++i) {
137
- /* It's OK to look at env for the current mode here, because it's
93
- if (s->regs[R_CONFIG] & ENDIAN) {
138
- * never possible for an AArch64 TB to chain to an AArch32 TB.
94
- fifo8_push(&s->tx_fifo, (uint8_t)(value >> 24));
139
- * (Otherwise we would need to use synchronize_from_tb instead.)
95
- value <<= 8;
140
- */
96
- } else {
141
- if (is_a64(&cpu->env)) {
97
- fifo8_push(&s->tx_fifo, (uint8_t)value);
142
- cpu->env.pc = value;
98
- value >>= 8;
143
- } else {
99
- }
144
- cpu->env.regs[15] = value;
100
- }
145
- }
101
-}
146
-}
102
-
147
-
103
static void xilinx_spips_write(void *opaque, hwaddr addr,
148
static gchar *aarch64_gdb_arch_name(CPUState *cs)
104
uint64_t value, unsigned size)
105
{
149
{
106
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
150
return g_strdup("aarch64");
107
mask = 0;
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
108
break;
152
CPUClass *cc = CPU_CLASS(oc);
109
case R_TX_DATA:
153
110
- tx_data_bytes(s, (uint32_t)value, s->num_txrx_bytes);
154
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
111
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, s->num_txrx_bytes,
155
- cc->set_pc = aarch64_cpu_set_pc;
112
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
156
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
113
goto no_reg_update;
157
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
114
case R_TXD1:
158
cc->gdb_num_core_regs = 34;
115
- tx_data_bytes(s, (uint32_t)value, 1);
116
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 1,
117
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
118
goto no_reg_update;
119
case R_TXD2:
120
- tx_data_bytes(s, (uint32_t)value, 2);
121
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 2,
122
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
123
goto no_reg_update;
124
case R_TXD3:
125
- tx_data_bytes(s, (uint32_t)value, 3);
126
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3,
127
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
128
goto no_reg_update;
129
}
130
s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
131
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
132
133
while (cache_entry < LQSPI_CACHE_SIZE) {
134
for (i = 0; i < 64; ++i) {
135
- tx_data_bytes(s, 0, 1);
136
+ tx_data_bytes(&s->tx_fifo, 0, 1, false);
137
}
138
xilinx_spips_flush_txfifo(s);
139
for (i = 0; i < 64; ++i) {
140
- rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 1);
141
+ rx_data_bytes(&s->rx_fifo, &q->lqspi_buf[cache_entry++], 1);
142
}
143
}
144
145
--
159
--
146
2.7.4
160
2.20.1
147
161
148
162
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Update striping functionality to be big-endian bit order (as according to
3
Drop the pac properties. This approach cannot work as written
4
the Zynq-7000 Technical Reference Manual). Output thereafter the even bits
4
because the properties are applied before arm_cpu_reset, which
5
into the flash memory connected to the lower QSPI bus and the odd bits into
5
zeros SCTLR_EL1 (amongst everything else).
6
the flash memory connected to the upper QSPI bus.
7
6
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
We can re-introduce the properties if they turn out to be useful.
9
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
8
But since linux 5.0 enables all of the keys, they may not be.
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
11
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Fixes: 1ae9cfbd470
12
Message-id: 20171126231634.9531-7-frasse.iglesias@gmail.com
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
14
---
15
hw/ssi/xilinx_spips.c | 19 ++++++++++---------
15
target/arm/cpu.c | 3 +++
16
1 file changed, 10 insertions(+), 9 deletions(-)
16
target/arm/cpu64.c | 60 ----------------------------------------------
17
2 files changed, 3 insertions(+), 60 deletions(-)
17
18
18
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/ssi/xilinx_spips.c
21
--- a/target/arm/cpu.c
21
+++ b/hw/ssi/xilinx_spips.c
22
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
23
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
23
xilinx_spips_update_cs_lines(s);
24
env->pstate = PSTATE_MODE_EL0t;
25
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
26
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
27
+ /* Enable all PAC keys. */
28
+ env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
29
+ SCTLR_EnDA | SCTLR_EnDB);
30
/* Enable all PAC instructions */
31
env->cp15.hcr_el2 |= HCR_API;
32
env->cp15.scr_el3 |= SCR_API;
33
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu64.c
36
+++ b/target/arm/cpu64.c
37
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
38
error_propagate(errp, err);
24
}
39
}
25
40
26
-/* N way (num) in place bit striper. Lay out row wise bits (LSB to MSB)
41
-#ifdef CONFIG_USER_ONLY
27
+/* N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
42
-static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
28
* column wise (from element 0 to N-1). num is the length of x, and dir
43
- void *opaque, Error **errp)
29
* reverses the direction of the transform. Best illustrated by example:
44
-{
30
* Each digit in the below array is a single bit (num == 3):
45
- ARMCPU *cpu = ARM_CPU(obj);
31
*
46
- const uint64_t *bit = opaque;
32
- * {{ 76543210, } ----- stripe (dir == false) -----> {{ FCheb630, }
47
- bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
33
- * { hgfedcba, } { GDAfc741, }
48
-
34
- * { HGFEDCBA, }} <---- upstripe (dir == true) ----- { HEBgda52, }}
49
- visit_type_bool(v, name, &enabled, errp);
35
+ * {{ 76543210, } ----- stripe (dir == false) -----> {{ 741gdaFC, }
50
-}
36
+ * { hgfedcba, } { 630fcHEB, }
51
-
37
+ * { HGFEDCBA, }} <---- upstripe (dir == true) ----- { 52hebGDA, }}
52
-static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
38
*/
53
- void *opaque, Error **errp)
39
54
-{
40
static inline void stripe8(uint8_t *x, int num, bool dir)
55
- ARMCPU *cpu = ARM_CPU(obj);
41
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
56
- Error *err = NULL;
42
uint8_t r[num];
57
- const uint64_t *bit = opaque;
43
memset(r, 0, sizeof(uint8_t) * num);
58
- bool enabled;
44
int idx[2] = {0, 0};
59
-
45
- int bit[2] = {0, 0};
60
- visit_type_bool(v, name, &enabled, errp);
46
+ int bit[2] = {0, 7};
61
-
47
int d = dir;
62
- if (!err) {
48
63
- if (enabled) {
49
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
64
- cpu->env.cp15.sctlr_el[1] |= *bit;
50
- for (bit[0] = 0; bit[0] < 8; ++bit[0]) {
65
- } else {
51
- r[idx[d]] |= x[idx[!d]] & 1 << bit[!d] ? 1 << bit[d] : 0;
66
- cpu->env.cp15.sctlr_el[1] &= ~*bit;
52
+ for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
67
- }
53
+ r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
68
- }
54
idx[1] = (idx[1] + 1) % num;
69
- error_propagate(errp, err);
55
if (!idx[1]) {
70
-}
56
- bit[1]++;
71
-#endif
57
+ bit[1]--;
72
-
58
}
73
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
59
}
74
* otherwise, a CPU with as many features enabled as our emulation supports.
60
}
75
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
61
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
62
}
77
*/
63
78
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
64
for (i = 0; i < num_effective_busses(s); ++i) {
79
cpu->dcz_blocksize = 7; /* 512 bytes */
65
+ int bus = num_effective_busses(s) - 1 - i;
80
-
66
DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
81
- /*
67
- tx_rx[i] = ssi_transfer(s->spi[i], (uint32_t)tx_rx[i]);
82
- * Note that Linux will enable enable all of the keys at once.
68
+ tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
83
- * But doing it this way will allow experimentation beyond that.
69
DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
84
- */
70
}
85
- {
71
86
- static const uint64_t apia_bit = SCTLR_EnIA;
87
- static const uint64_t apib_bit = SCTLR_EnIB;
88
- static const uint64_t apda_bit = SCTLR_EnDA;
89
- static const uint64_t apdb_bit = SCTLR_EnDB;
90
-
91
- object_property_add(obj, "apia", "bool", cpu_max_get_packey,
92
- cpu_max_set_packey, NULL,
93
- (void *)&apia_bit, &error_fatal);
94
- object_property_add(obj, "apib", "bool", cpu_max_get_packey,
95
- cpu_max_set_packey, NULL,
96
- (void *)&apib_bit, &error_fatal);
97
- object_property_add(obj, "apda", "bool", cpu_max_get_packey,
98
- cpu_max_set_packey, NULL,
99
- (void *)&apda_bit, &error_fatal);
100
- object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
101
- cpu_max_set_packey, NULL,
102
- (void *)&apdb_bit, &error_fatal);
103
-
104
- /* Enable all PAC keys by default. */
105
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
106
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
107
- }
108
#endif
109
110
cpu->sve_max_vq = ARM_MAX_VQ;
72
--
111
--
73
2.7.4
112
2.20.1
74
113
75
114
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move the FlashCMD enum, XilinxQSPIPS and XilinxSPIPSClass structures to the
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
header for consistency (struct XilinxSPIPS is found there). Also move out
4
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
5
a define and remove two double included headers (while touching the code).
6
Finally, add 4 byte address commands to the FlashCMD enum.
7
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Message-id: 20171126231634.9531-6-frasse.iglesias@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
6
---
16
include/hw/ssi/xilinx_spips.h | 34 ++++++++++++++++++++++++++++++++++
7
linux-user/elfload.c | 9 +++++++++
17
hw/ssi/xilinx_spips.c | 35 -----------------------------------
8
1 file changed, 9 insertions(+)
18
2 files changed, 34 insertions(+), 35 deletions(-)
19
9
20
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/ssi/xilinx_spips.h
12
--- a/linux-user/elfload.c
23
+++ b/include/hw/ssi/xilinx_spips.h
13
+++ b/linux-user/elfload.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPS XilinxSPIPS;
14
@@ -XXX,XX +XXX,XX @@ enum {
25
15
ARM_HWCAP_A64_ASIMDDP = 1 << 20,
26
#define XLNX_SPIPS_R_MAX (0x100 / 4)
16
ARM_HWCAP_A64_SHA512 = 1 << 21,
27
17
ARM_HWCAP_A64_SVE = 1 << 22,
28
+/* Bite off 4k chunks at a time */
18
+ ARM_HWCAP_A64_ASIMDFHM = 1 << 23,
29
+#define LQSPI_CACHE_SIZE 1024
19
+ ARM_HWCAP_A64_DIT = 1 << 24,
30
+
20
+ ARM_HWCAP_A64_USCAT = 1 << 25,
31
+typedef enum {
21
+ ARM_HWCAP_A64_ILRCPC = 1 << 26,
32
+ READ = 0x3, READ_4 = 0x13,
22
+ ARM_HWCAP_A64_FLAGM = 1 << 27,
33
+ FAST_READ = 0xb, FAST_READ_4 = 0x0c,
23
+ ARM_HWCAP_A64_SSBS = 1 << 28,
34
+ DOR = 0x3b, DOR_4 = 0x3c,
24
+ ARM_HWCAP_A64_SB = 1 << 29,
35
+ QOR = 0x6b, QOR_4 = 0x6c,
25
+ ARM_HWCAP_A64_PACA = 1 << 30,
36
+ DIOR = 0xbb, DIOR_4 = 0xbc,
26
+ ARM_HWCAP_A64_PACG = 1UL << 31,
37
+ QIOR = 0xeb, QIOR_4 = 0xec,
38
+
39
+ PP = 0x2, PP_4 = 0x12,
40
+ DPP = 0xa2,
41
+ QPP = 0x32, QPP_4 = 0x34,
42
+} FlashCMD;
43
+
44
struct XilinxSPIPS {
45
SysBusDevice parent_obj;
46
47
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
48
uint32_t regs[XLNX_SPIPS_R_MAX];
49
};
27
};
50
28
51
+typedef struct {
29
#define ELF_HWCAP get_elf_hwcap()
52
+ XilinxSPIPS parent_obj;
53
+
54
+ uint8_t lqspi_buf[LQSPI_CACHE_SIZE];
55
+ hwaddr lqspi_cached_addr;
56
+ Error *migration_blocker;
57
+ bool mmio_execution_enabled;
58
+} XilinxQSPIPS;
59
+
60
+typedef struct XilinxSPIPSClass {
61
+ SysBusDeviceClass parent_class;
62
+
63
+ const MemoryRegionOps *reg_ops;
64
+
65
+ uint32_t rx_fifo_size;
66
+ uint32_t tx_fifo_size;
67
+} XilinxSPIPSClass;
68
+
69
#define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
70
#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
71
72
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/ssi/xilinx_spips.c
75
+++ b/hw/ssi/xilinx_spips.c
76
@@ -XXX,XX +XXX,XX @@
77
#include "sysemu/sysemu.h"
78
#include "hw/ptimer.h"
79
#include "qemu/log.h"
80
-#include "qemu/fifo8.h"
81
-#include "hw/ssi/ssi.h"
82
#include "qemu/bitops.h"
83
#include "hw/ssi/xilinx_spips.h"
84
#include "qapi/error.h"
85
@@ -XXX,XX +XXX,XX @@
86
87
/* 16MB per linear region */
88
#define LQSPI_ADDRESS_BITS 24
89
-/* Bite off 4k chunks at a time */
90
-#define LQSPI_CACHE_SIZE 1024
91
92
#define SNOOP_CHECKING 0xFF
93
#define SNOOP_NONE 0xFE
94
#define SNOOP_STRIPING 0
95
96
-typedef enum {
97
- READ = 0x3,
98
- FAST_READ = 0xb,
99
- DOR = 0x3b,
100
- QOR = 0x6b,
101
- DIOR = 0xbb,
102
- QIOR = 0xeb,
103
-
104
- PP = 0x2,
105
- DPP = 0xa2,
106
- QPP = 0x32,
107
-} FlashCMD;
108
-
109
-typedef struct {
110
- XilinxSPIPS parent_obj;
111
-
112
- uint8_t lqspi_buf[LQSPI_CACHE_SIZE];
113
- hwaddr lqspi_cached_addr;
114
- Error *migration_blocker;
115
- bool mmio_execution_enabled;
116
-} XilinxQSPIPS;
117
-
118
-typedef struct XilinxSPIPSClass {
119
- SysBusDeviceClass parent_class;
120
-
121
- const MemoryRegionOps *reg_ops;
122
-
123
- uint32_t rx_fifo_size;
124
- uint32_t tx_fifo_size;
125
-} XilinxSPIPSClass;
126
-
127
static inline int num_effective_busses(XilinxSPIPS *s)
128
{
129
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
130
--
30
--
131
2.7.4
31
2.20.1
132
32
133
33
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The ctz32() routine could return a value greater than
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
TC6393XB_GPIOS=16, because the device has 24 GPIO level
5
bits but we only implement 16 outgoing lines. This could
6
lead to an OOB array access. Mask 'level' to avoid it.
7
8
Reported-by: Moguofang <moguofang@huawei.com>
9
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
10
Message-id: 20171212041539.25700-1-ppandit@redhat.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
hw/display/tc6393xb.c | 1 +
7
linux-user/elfload.c | 1 +
15
1 file changed, 1 insertion(+)
8
1 file changed, 1 insertion(+)
16
9
17
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/display/tc6393xb.c
12
--- a/linux-user/elfload.c
20
+++ b/hw/display/tc6393xb.c
13
+++ b/linux-user/elfload.c
21
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_handler_update(TC6393xbState *s)
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
22
int bit;
15
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
23
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
24
level = s->gpio_level & s->gpio_dir;
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
25
+ level &= MAKE_64BIT_MASK(0, TC6393XB_GPIOS);
18
+ GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
26
19
27
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
20
#undef GET_FEATURE_ID
28
bit = ctz32(diff);
21
29
--
22
--
30
2.7.4
23
2.20.1
31
24
32
25
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for zero pumping according to the transfer size register.
3
Initialize the keys to a non-zero value on process start.
4
4
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20171126231634.9531-10-frasse.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
include/hw/ssi/xilinx_spips.h | 2 ++
9
linux-user/aarch64/target_syscall.h | 2 ++
12
hw/ssi/xilinx_spips.c | 47 ++++++++++++++++++++++++++++++++++++-------
10
linux-user/aarch64/cpu_loop.c | 31 +++++++++++++++++++++++++++--
13
2 files changed, 42 insertions(+), 7 deletions(-)
11
2 files changed, 31 insertions(+), 2 deletions(-)
14
12
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
13
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
15
--- a/linux-user/aarch64/target_syscall.h
18
+++ b/include/hw/ssi/xilinx_spips.h
16
+++ b/linux-user/aarch64/target_syscall.h
19
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
17
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
20
uint32_t rx_discard;
18
#define TARGET_PR_SVE_SET_VL 50
21
19
#define TARGET_PR_SVE_GET_VL 51
22
uint32_t regs[XLNX_SPIPS_R_MAX];
20
21
+void arm_init_pauth_key(ARMPACKey *key);
23
+
22
+
24
+ bool man_start_com;
23
#endif /* AARCH64_TARGET_SYSCALL_H */
25
};
24
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
26
27
typedef struct {
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
29
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/ssi/xilinx_spips.c
26
--- a/linux-user/aarch64/cpu_loop.c
31
+++ b/hw/ssi/xilinx_spips.c
27
+++ b/linux-user/aarch64/cpu_loop.c
32
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
33
FIELD(CMND, DUMMY_CYCLES, 2, 6)
34
#define R_CMND_DMA_EN (1 << 1)
35
#define R_CMND_PUSH_WAIT (1 << 0)
36
+#define R_TRANSFER_SIZE (0xc4 / 4)
37
#define R_LQSPI_STS (0xA4 / 4)
38
#define LQSPI_STS_WR_RECVD (1 << 1)
39
40
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
41
s->link_state_next_when = 0;
42
s->snoop_state = SNOOP_CHECKING;
43
s->cmd_dummies = 0;
44
+ s->man_start_com = false;
45
xilinx_spips_update_ixr(s);
46
xilinx_spips_update_cs_lines(s);
47
}
48
@@ -XXX,XX +XXX,XX @@ static inline void tx_data_bytes(Fifo8 *fifo, uint32_t value, int num, bool be)
49
}
29
}
50
}
30
}
51
31
52
+static void xilinx_spips_check_zero_pump(XilinxSPIPS *s)
32
+static uint64_t arm_rand64(void)
53
+{
33
+{
54
+ if (!s->regs[R_TRANSFER_SIZE]) {
34
+ int shift = 64 - clz64(RAND_MAX);
55
+ return;
35
+ int i, n = 64 / shift + (64 % shift != 0);
36
+ uint64_t ret = 0;
37
+
38
+ for (i = 0; i < n; i++) {
39
+ ret = (ret << shift) | rand();
56
+ }
40
+ }
57
+ if (!fifo8_is_empty(&s->tx_fifo) && s->regs[R_CMND] & R_CMND_PUSH_WAIT) {
41
+ return ret;
58
+ return;
59
+ }
60
+ /*
61
+ * The zero pump must never fill tx fifo such that rx overflow is
62
+ * possible
63
+ */
64
+ while (s->regs[R_TRANSFER_SIZE] &&
65
+ s->rx_fifo.num + s->tx_fifo.num < RXFF_A_Q - 3) {
66
+ /* endianess just doesn't matter when zero pumping */
67
+ tx_data_bytes(&s->tx_fifo, 0, 4, false);
68
+ s->regs[R_TRANSFER_SIZE] &= ~0x03ull;
69
+ s->regs[R_TRANSFER_SIZE] -= 4;
70
+ }
71
+}
42
+}
72
+
43
+
73
+static void xilinx_spips_check_flush(XilinxSPIPS *s)
44
+void arm_init_pauth_key(ARMPACKey *key)
74
+{
45
+{
75
+ if (s->man_start_com ||
46
+ key->lo = arm_rand64();
76
+ (!fifo8_is_empty(&s->tx_fifo) &&
47
+ key->hi = arm_rand64();
77
+ !(s->regs[R_CONFIG] & MAN_START_EN))) {
78
+ xilinx_spips_check_zero_pump(s);
79
+ xilinx_spips_flush_txfifo(s);
80
+ }
81
+ if (fifo8_is_empty(&s->tx_fifo) && !s->regs[R_TRANSFER_SIZE]) {
82
+ s->man_start_com = false;
83
+ }
84
+ xilinx_spips_update_ixr(s);
85
+}
48
+}
86
+
49
+
87
static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
50
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
88
{
51
{
52
- CPUState *cpu = ENV_GET_CPU(env);
53
- TaskState *ts = cpu->opaque;
54
+ ARMCPU *cpu = arm_env_get_cpu(env);
55
+ CPUState *cs = CPU(cpu);
56
+ TaskState *ts = cs->opaque;
57
struct image_info *info = ts->info;
89
int i;
58
int i;
90
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
59
91
uint64_t value, unsigned size)
60
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
92
{
61
}
93
int mask = ~0;
62
#endif
94
- int man_start_com = 0;
63
95
XilinxSPIPS *s = opaque;
64
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
96
65
+ arm_init_pauth_key(&env->apia_key);
97
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value);
66
+ arm_init_pauth_key(&env->apib_key);
98
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
67
+ arm_init_pauth_key(&env->apda_key);
99
switch (addr) {
68
+ arm_init_pauth_key(&env->apdb_key);
100
case R_CONFIG:
69
+ arm_init_pauth_key(&env->apga_key);
101
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
70
+ }
102
- if (value & MAN_START_COM) {
71
+
103
- man_start_com = 1;
72
ts->stack_base = info->start_stack;
104
+ if ((value & MAN_START_COM) && (s->regs[R_CONFIG] & MAN_START_EN)) {
73
ts->heap_base = info->brk;
105
+ s->man_start_com = true;
74
/* This will be filled in on the first SYS_HEAPINFO call. */
106
}
107
break;
108
case R_INTR_STATUS:
109
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
110
s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
111
no_reg_update:
112
xilinx_spips_update_cs_lines(s);
113
- if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
114
- (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
115
- xilinx_spips_flush_txfifo(s);
116
- }
117
+ xilinx_spips_check_flush(s);
118
xilinx_spips_update_cs_lines(s);
119
xilinx_spips_update_ixr(s);
120
}
121
--
75
--
122
2.7.4
76
2.20.1
123
77
124
78
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
Add support for the bank address register access commands (BRRD/BRWR) and
3
Since QEMU does not support the ARMv8.2-LVA, Large Virtual Address,
4
the BULK_ERASE (0x60) command.
4
extension (yet), the VA address space is 48-bits plus a sign bit. User
5
mode can only handle the positive half of the address space, so that
6
makes a limit of 48 bits.
5
7
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
(With LVA, it would be 53 and 52 bits respectively.)
7
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
9
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
The incorrectly large address space conflicts with PAuth instructions,
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
which use bits 48-54 and 56-63 for the pointer authentication code. This
10
Message-id: 20171126231634.9531-4-frasse.iglesias@gmail.com
12
also conflicts with (as yet unsupported by QEMU) data tagging and with
13
the ARMv8.5-MTE extension.
14
15
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
18
---
13
hw/block/m25p80.c | 7 +++++++
19
target/arm/cpu.h | 2 +-
14
1 file changed, 7 insertions(+)
20
1 file changed, 1 insertion(+), 1 deletion(-)
15
21
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
24
--- a/target/arm/cpu.h
19
+++ b/hw/block/m25p80.c
25
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
26
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu);
21
WRDI = 0x4,
27
22
RDSR = 0x5,
28
#if defined(TARGET_AARCH64)
23
WREN = 0x6,
29
# define TARGET_PHYS_ADDR_SPACE_BITS 48
24
+ BRRD = 0x16,
30
-# define TARGET_VIRT_ADDR_SPACE_BITS 64
25
+ BRWR = 0x17,
31
+# define TARGET_VIRT_ADDR_SPACE_BITS 48
26
JEDEC_READ = 0x9f,
32
#else
27
+ BULK_ERASE_60 = 0x60,
33
# define TARGET_PHYS_ADDR_SPACE_BITS 40
28
BULK_ERASE = 0xc7,
34
# define TARGET_VIRT_ADDR_SPACE_BITS 32
29
READ_FSR = 0x70,
30
RDCR = 0x15,
31
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
32
s->write_enable = false;
33
}
34
break;
35
+ case BRWR:
36
case EXTEND_ADDR_WRITE:
37
s->ear = s->data[0];
38
break;
39
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
40
s->state = STATE_READING_DATA;
41
break;
42
43
+ case BULK_ERASE_60:
44
case BULK_ERASE:
45
if (s->write_enable) {
46
DB_PRINT_L(0, "chip erase\n");
47
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
48
case EX_4BYTE_ADDR:
49
s->four_bytes_address_mode = false;
50
break;
51
+ case BRRD:
52
case EXTEND_ADDR_READ:
53
s->data[0] = s->ear;
54
s->pos = 0;
55
s->len = 1;
56
s->state = STATE_READING_DATA;
57
break;
58
+ case BRWR:
59
case EXTEND_ADDR_WRITE:
60
if (s->write_enable) {
61
s->needed_bytes = 1;
62
--
35
--
63
2.7.4
36
2.20.1
64
37
65
38
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
Add support for SST READ ID 0x90/0xAB commands for reading out the flash
3
A flawed test lead to the instructions always being treated as
4
manufacturer ID and device ID.
4
unallocated encodings.
5
5
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Fixes: https://bugs.launchpad.net/bugs/1813460
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
8
Message-id: 20171126231634.9531-3-frasse.iglesias@gmail.com
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/block/m25p80.c | 32 ++++++++++++++++++++++++++++++++
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 32 insertions(+)
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
13
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/m25p80.c
16
--- a/target/arm/translate-a64.c
17
+++ b/hw/block/m25p80.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
18
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
19
DPP = 0xa2,
19
if (!dc_isar_feature(aa64_pauth, s)) {
20
QPP = 0x32,
20
goto do_unallocated;
21
QPP_4 = 0x34,
21
}
22
+ RDID_90 = 0x90,
22
- if (op3 != 2 || op3 != 3) {
23
+ RDID_AB = 0xab,
23
+ if ((op3 & ~1) != 2) {
24
24
goto do_unallocated;
25
ERASE_4K = 0x20,
25
}
26
ERASE4_4K = 0x21,
26
if (s->pauth_active) {
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
MAN_MACRONIX,
29
MAN_NUMONYX,
30
MAN_WINBOND,
31
+ MAN_SST,
32
MAN_GENERIC,
33
} Manufacturer;
34
35
@@ -XXX,XX +XXX,XX @@ static inline Manufacturer get_man(Flash *s)
36
return MAN_SPANSION;
37
case 0xC2:
38
return MAN_MACRONIX;
39
+ case 0xBF:
40
+ return MAN_SST;
41
default:
42
return MAN_GENERIC;
43
}
44
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
45
case WEVCR:
46
s->enh_volatile_cfg = s->data[0];
47
break;
48
+ case RDID_90:
49
+ case RDID_AB:
50
+ if (get_man(s) == MAN_SST) {
51
+ if (s->cur_addr <= 1) {
52
+ if (s->cur_addr) {
53
+ s->data[0] = s->pi->id[2];
54
+ s->data[1] = s->pi->id[0];
55
+ } else {
56
+ s->data[0] = s->pi->id[0];
57
+ s->data[1] = s->pi->id[2];
58
+ }
59
+ s->pos = 0;
60
+ s->len = 2;
61
+ s->data_read_loop = true;
62
+ s->state = STATE_READING_DATA;
63
+ } else {
64
+ qemu_log_mask(LOG_GUEST_ERROR,
65
+ "M25P80: Invalid read id address\n");
66
+ }
67
+ } else {
68
+ qemu_log_mask(LOG_GUEST_ERROR,
69
+ "M25P80: Read id (command 0x90/0xAB) is not supported"
70
+ " by device\n");
71
+ }
72
+ break;
73
default:
74
break;
75
}
76
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
77
case PP4:
78
case PP4_4:
79
case DIE_ERASE:
80
+ case RDID_90:
81
+ case RDID_AB:
82
s->needed_bytes = get_addr_length(s);
83
s->pos = 0;
84
s->len = 0;
85
--
27
--
86
2.7.4
28
2.20.1
87
29
88
30
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
Add support for the Zynq Ultrascale MPSoc Generic QSPI.
3
The nRF51 contains three regions of non-volatile memory (NVM):
4
4
- CODE (R/W): contains code
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
- FICR (R): Factory information like code size, chip id etc.
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
- UICR (R/W): Changeable configuration data. Lock bits, Code
7
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
protection configuration, Bootloader address, Nordic SoftRadio
8
Message-id: 20171126231634.9531-13-frasse.iglesias@gmail.com
8
configuration, Firmware configuration.
9
10
Read and write access to the memories is managed by the
11
Non-volatile memory controller.
12
13
Memory schema:
14
[ CPU ] -+- [ NVM, either FICR, UICR or CODE ]
15
| |
16
\- [ NVMC ]
17
18
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
Tested-by: Joel Stanley <joel@jms.id.au>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20190201023357.22596-2-stefanha@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
24
---
11
include/hw/ssi/xilinx_spips.h | 32 ++-
25
hw/nvram/Makefile.objs | 1 +
12
hw/ssi/xilinx_spips.c | 579 ++++++++++++++++++++++++++++++++++++----
26
include/hw/nvram/nrf51_nvm.h | 64 ++++++
13
default-configs/arm-softmmu.mak | 2 +-
27
hw/nvram/nrf51_nvm.c | 388 +++++++++++++++++++++++++++++++++++
14
3 files changed, 564 insertions(+), 49 deletions(-)
28
3 files changed, 453 insertions(+)
15
29
create mode 100644 include/hw/nvram/nrf51_nvm.h
16
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
30
create mode 100644 hw/nvram/nrf51_nvm.c
31
32
diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
17
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/ssi/xilinx_spips.h
34
--- a/hw/nvram/Makefile.objs
19
+++ b/include/hw/ssi/xilinx_spips.h
35
+++ b/hw/nvram/Makefile.objs
36
@@ -XXX,XX +XXX,XX @@ common-obj-y += fw_cfg.o
37
common-obj-y += chrp_nvram.o
38
common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
39
obj-$(CONFIG_PSERIES) += spapr_nvram.o
40
+obj-$(CONFIG_NRF51_SOC) += nrf51_nvm.o
41
diff --git a/include/hw/nvram/nrf51_nvm.h b/include/hw/nvram/nrf51_nvm.h
42
new file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/include/hw/nvram/nrf51_nvm.h
20
@@ -XXX,XX +XXX,XX @@
46
@@ -XXX,XX +XXX,XX @@
21
#define XILINX_SPIPS_H
47
+/*
22
48
+ * Nordic Semiconductor nRF51 non-volatile memory
23
#include "hw/ssi/ssi.h"
49
+ *
24
-#include "qemu/fifo8.h"
50
+ * It provides an interface to erase regions in flash memory.
25
+#include "qemu/fifo32.h"
51
+ * Furthermore it provides the user and factory information registers.
26
+#include "hw/stream.h"
52
+ *
27
53
+ * QEMU interface:
28
typedef struct XilinxSPIPS XilinxSPIPS;
54
+ * + sysbus MMIO regions 0: NVMC peripheral registers
29
55
+ * + sysbus MMIO regions 1: FICR peripheral registers
30
#define XLNX_SPIPS_R_MAX (0x100 / 4)
56
+ * + sysbus MMIO regions 2: UICR peripheral registers
31
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
57
+ * + flash-size property: flash size in bytes.
32
58
+ *
33
/* Bite off 4k chunks at a time */
59
+ * Accuracy of the peripheral model:
34
#define LQSPI_CACHE_SIZE 1024
60
+ * + Code regions (MPU configuration) are disregarded.
35
@@ -XXX,XX +XXX,XX @@ typedef struct {
61
+ *
36
bool mmio_execution_enabled;
62
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
37
} XilinxQSPIPS;
63
+ *
38
64
+ * This code is licensed under the GPL version 2 or later. See
39
+typedef struct {
65
+ * the COPYING file in the top-level directory.
40
+ XilinxQSPIPS parent_obj;
66
+ *
41
+
67
+ */
42
+ StreamSlave *dma;
68
+#ifndef NRF51_NVM_H
43
+ uint8_t dma_buf[4];
69
+#define NRF51_NVM_H
44
+ int gqspi_irqline;
70
+
45
+
71
+#include "hw/sysbus.h"
46
+ uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX];
72
+#define TYPE_NRF51_NVM "nrf51_soc.nvm"
47
+
73
+#define NRF51_NVM(obj) OBJECT_CHECK(NRF51NVMState, (obj), TYPE_NRF51_NVM)
48
+ /* GQSPI has seperate tx/rx fifos */
74
+
49
+ Fifo8 rx_fifo_g;
75
+#define NRF51_UICR_FIXTURE_SIZE 64
50
+ Fifo8 tx_fifo_g;
76
+
51
+ Fifo32 fifo_g;
77
+#define NRF51_NVMC_SIZE 0x1000
52
+ /*
78
+
53
+ * At the end of each generic command, misaligned extra bytes are discard
79
+#define NRF51_NVMC_READY 0x400
54
+ * or padded to tx and rx respectively to round it out (and avoid need for
80
+#define NRF51_NVMC_READY_READY 0x01
55
+ * individual byte access. Since we use byte fifos, keep track of the
81
+#define NRF51_NVMC_CONFIG 0x504
56
+ * alignment WRT to word access.
82
+#define NRF51_NVMC_CONFIG_MASK 0x03
57
+ */
83
+#define NRF51_NVMC_CONFIG_WEN 0x01
58
+ uint8_t rx_fifo_g_align;
84
+#define NRF51_NVMC_CONFIG_EEN 0x02
59
+ uint8_t tx_fifo_g_align;
85
+#define NRF51_NVMC_ERASEPCR1 0x508
60
+ bool man_start_com_g;
86
+#define NRF51_NVMC_ERASEPCR0 0x510
61
+} XlnxZynqMPQSPIPS;
87
+#define NRF51_NVMC_ERASEALL 0x50C
62
+
88
+#define NRF51_NVMC_ERASEUICR 0x514
63
typedef struct XilinxSPIPSClass {
89
+#define NRF51_NVMC_ERASE 0x01
64
SysBusDeviceClass parent_class;
90
+
65
91
+#define NRF51_UICR_SIZE 0x100
66
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPSClass {
92
+
67
93
+typedef struct NRF51NVMState {
68
#define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
94
+ SysBusDevice parent_obj;
69
#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
95
+
70
+#define TYPE_XLNX_ZYNQMP_QSPIPS "xlnx.usmp-gqspi"
96
+ MemoryRegion mmio;
71
97
+ MemoryRegion ficr;
72
#define XILINX_SPIPS(obj) \
98
+ MemoryRegion uicr;
73
OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS)
99
+ MemoryRegion flash;
74
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPSClass {
100
+
75
#define XILINX_QSPIPS(obj) \
101
+ uint32_t uicr_content[NRF51_UICR_FIXTURE_SIZE];
76
OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS)
102
+ uint32_t flash_size;
77
103
+ uint8_t *storage;
78
+#define XLNX_ZYNQMP_QSPIPS(obj) \
104
+
79
+ OBJECT_CHECK(XlnxZynqMPQSPIPS, (obj), TYPE_XLNX_ZYNQMP_QSPIPS)
105
+ uint32_t config;
80
+
106
+
81
#endif /* XILINX_SPIPS_H */
107
+} NRF51NVMState;
82
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
108
+
83
index XXXXXXX..XXXXXXX 100644
109
+
84
--- a/hw/ssi/xilinx_spips.c
110
+#endif
85
+++ b/hw/ssi/xilinx_spips.c
111
diff --git a/hw/nvram/nrf51_nvm.c b/hw/nvram/nrf51_nvm.c
112
new file mode 100644
113
index XXXXXXX..XXXXXXX
114
--- /dev/null
115
+++ b/hw/nvram/nrf51_nvm.c
86
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
87
#include "hw/ssi/xilinx_spips.h"
117
+/*
88
#include "qapi/error.h"
118
+ * Nordic Semiconductor nRF51 non-volatile memory
89
#include "hw/register.h"
119
+ *
90
+#include "sysemu/dma.h"
120
+ * It provides an interface to erase regions in flash memory.
91
#include "migration/blocker.h"
121
+ * Furthermore it provides the user and factory information registers.
92
122
+ *
93
#ifndef XILINX_SPIPS_ERR_DEBUG
123
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
94
@@ -XXX,XX +XXX,XX @@
124
+ *
95
#define R_INTR_DIS (0x0C / 4)
125
+ * See nRF51 reference manual and product sheet sections:
96
#define R_INTR_MASK (0x10 / 4)
126
+ * + Non-Volatile Memory Controller (NVMC)
97
#define IXR_TX_FIFO_UNDERFLOW (1 << 6)
127
+ * + Factory Information Configuration Registers (FICR)
98
+/* Poll timeout not implemented */
128
+ * + User Information Configuration Registers (UICR)
99
+#define IXR_RX_FIFO_EMPTY (1 << 11)
129
+ *
100
+#define IXR_GENERIC_FIFO_FULL (1 << 10)
130
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
101
+#define IXR_GENERIC_FIFO_NOT_FULL (1 << 9)
131
+ *
102
+#define IXR_TX_FIFO_EMPTY (1 << 8)
132
+ * This code is licensed under the GPL version 2 or later. See
103
+#define IXR_GENERIC_FIFO_EMPTY (1 << 7)
133
+ * the COPYING file in the top-level directory.
104
#define IXR_RX_FIFO_FULL (1 << 5)
105
#define IXR_RX_FIFO_NOT_EMPTY (1 << 4)
106
#define IXR_TX_FIFO_FULL (1 << 3)
107
#define IXR_TX_FIFO_NOT_FULL (1 << 2)
108
#define IXR_TX_FIFO_MODE_FAIL (1 << 1)
109
#define IXR_RX_FIFO_OVERFLOW (1 << 0)
110
-#define IXR_ALL ((IXR_TX_FIFO_UNDERFLOW<<1)-1)
111
+#define IXR_ALL ((1 << 13) - 1)
112
+#define GQSPI_IXR_MASK 0xFBE
113
+#define IXR_SELF_CLEAR \
114
+(IXR_GENERIC_FIFO_EMPTY \
115
+| IXR_GENERIC_FIFO_FULL \
116
+| IXR_GENERIC_FIFO_NOT_FULL \
117
+| IXR_TX_FIFO_EMPTY \
118
+| IXR_TX_FIFO_FULL \
119
+| IXR_TX_FIFO_NOT_FULL \
120
+| IXR_RX_FIFO_EMPTY \
121
+| IXR_RX_FIFO_FULL \
122
+| IXR_RX_FIFO_NOT_EMPTY)
123
124
#define R_EN (0x14 / 4)
125
#define R_DELAY (0x18 / 4)
126
@@ -XXX,XX +XXX,XX @@
127
128
#define R_MOD_ID (0xFC / 4)
129
130
+#define R_GQSPI_SELECT (0x144 / 4)
131
+ FIELD(GQSPI_SELECT, GENERIC_QSPI_EN, 0, 1)
132
+#define R_GQSPI_ISR (0x104 / 4)
133
+#define R_GQSPI_IER (0x108 / 4)
134
+#define R_GQSPI_IDR (0x10c / 4)
135
+#define R_GQSPI_IMR (0x110 / 4)
136
+#define R_GQSPI_TX_THRESH (0x128 / 4)
137
+#define R_GQSPI_RX_THRESH (0x12c / 4)
138
+#define R_GQSPI_CNFG (0x100 / 4)
139
+ FIELD(GQSPI_CNFG, MODE_EN, 30, 2)
140
+ FIELD(GQSPI_CNFG, GEN_FIFO_START_MODE, 29, 1)
141
+ FIELD(GQSPI_CNFG, GEN_FIFO_START, 28, 1)
142
+ FIELD(GQSPI_CNFG, ENDIAN, 26, 1)
143
+ /* Poll timeout not implemented */
144
+ FIELD(GQSPI_CNFG, EN_POLL_TIMEOUT, 20, 1)
145
+ /* QEMU doesnt care about any of these last three */
146
+ FIELD(GQSPI_CNFG, BR, 3, 3)
147
+ FIELD(GQSPI_CNFG, CPH, 2, 1)
148
+ FIELD(GQSPI_CNFG, CPL, 1, 1)
149
+#define R_GQSPI_GEN_FIFO (0x140 / 4)
150
+#define R_GQSPI_TXD (0x11c / 4)
151
+#define R_GQSPI_RXD (0x120 / 4)
152
+#define R_GQSPI_FIFO_CTRL (0x14c / 4)
153
+ FIELD(GQSPI_FIFO_CTRL, RX_FIFO_RESET, 2, 1)
154
+ FIELD(GQSPI_FIFO_CTRL, TX_FIFO_RESET, 1, 1)
155
+ FIELD(GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET, 0, 1)
156
+#define R_GQSPI_GFIFO_THRESH (0x150 / 4)
157
+#define R_GQSPI_DATA_STS (0x15c / 4)
158
+/* We use the snapshot register to hold the core state for the currently
159
+ * or most recently executed command. So the generic fifo format is defined
160
+ * for the snapshot register
161
+ */
134
+ */
162
+#define R_GQSPI_GF_SNAPSHOT (0x160 / 4)
135
+
163
+ FIELD(GQSPI_GF_SNAPSHOT, POLL, 19, 1)
136
+#include "qemu/osdep.h"
164
+ FIELD(GQSPI_GF_SNAPSHOT, STRIPE, 18, 1)
137
+#include "qapi/error.h"
165
+ FIELD(GQSPI_GF_SNAPSHOT, RECIEVE, 17, 1)
138
+#include "qemu/log.h"
166
+ FIELD(GQSPI_GF_SNAPSHOT, TRANSMIT, 16, 1)
139
+#include "exec/address-spaces.h"
167
+ FIELD(GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT, 14, 2)
140
+#include "hw/arm/nrf51.h"
168
+ FIELD(GQSPI_GF_SNAPSHOT, CHIP_SELECT, 12, 2)
141
+#include "hw/nvram/nrf51_nvm.h"
169
+ FIELD(GQSPI_GF_SNAPSHOT, SPI_MODE, 10, 2)
142
+
170
+ FIELD(GQSPI_GF_SNAPSHOT, EXPONENT, 9, 1)
143
+/*
171
+ FIELD(GQSPI_GF_SNAPSHOT, DATA_XFER, 8, 1)
144
+ * FICR Registers Assignments
172
+ FIELD(GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA, 0, 8)
145
+ * CODEPAGESIZE 0x010
173
+#define R_GQSPI_MOD_ID (0x168 / 4)
146
+ * CODESIZE 0x014
174
+#define R_GQSPI_MOD_ID_VALUE 0x010A0000
147
+ * CLENR0 0x028
175
/* size of TXRX FIFOs */
148
+ * PPFC 0x02C
176
-#define RXFF_A 32
149
+ * NUMRAMBLOCK 0x034
177
-#define TXFF_A 32
150
+ * SIZERAMBLOCKS 0x038
178
+#define RXFF_A (128)
151
+ * SIZERAMBLOCK[0] 0x038
179
+#define TXFF_A (128)
152
+ * SIZERAMBLOCK[1] 0x03C
180
153
+ * SIZERAMBLOCK[2] 0x040
181
#define RXFF_A_Q (64 * 4)
154
+ * SIZERAMBLOCK[3] 0x044
182
#define TXFF_A_Q (64 * 4)
155
+ * CONFIGID 0x05C
183
@@ -XXX,XX +XXX,XX @@ static inline int num_effective_busses(XilinxSPIPS *s)
156
+ * DEVICEID[0] 0x060
184
s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
157
+ * DEVICEID[1] 0x064
185
}
158
+ * ER[0] 0x080
186
159
+ * ER[1] 0x084
187
-static inline bool xilinx_spips_cs_is_set(XilinxSPIPS *s, int i, int field)
160
+ * ER[2] 0x088
188
-{
161
+ * ER[3] 0x08C
189
- return ~field & (1 << i) && (s->regs[R_CONFIG] & MANUAL_CS
162
+ * IR[0] 0x090
190
- || !fifo8_is_empty(&s->tx_fifo));
163
+ * IR[1] 0x094
191
-}
164
+ * IR[2] 0x098
192
-
165
+ * IR[3] 0x09C
193
-static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
166
+ * DEVICEADDRTYPE 0x0A0
194
+static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
167
+ * DEVICEADDR[0] 0x0A4
195
{
168
+ * DEVICEADDR[1] 0x0A8
196
- int i, j;
169
+ * OVERRIDEEN 0x0AC
197
- bool found = false;
170
+ * NRF_1MBIT[0] 0x0B0
198
- int field = s->regs[R_CONFIG] >> CS_SHIFT;
171
+ * NRF_1MBIT[1] 0x0B4
199
+ int i;
172
+ * NRF_1MBIT[2] 0x0B8
200
173
+ * NRF_1MBIT[3] 0x0BC
201
for (i = 0; i < s->num_cs; i++) {
174
+ * NRF_1MBIT[4] 0x0C0
202
- for (j = 0; j < num_effective_busses(s); j++) {
175
+ * BLE_1MBIT[0] 0x0EC
203
- int upage = !!(s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE);
176
+ * BLE_1MBIT[1] 0x0F0
204
- int cs_to_set = (j * s->num_cs + i + upage) %
177
+ * BLE_1MBIT[2] 0x0F4
205
- (s->num_cs * s->num_busses);
178
+ * BLE_1MBIT[3] 0x0F8
206
-
179
+ * BLE_1MBIT[4] 0x0FC
207
- if (xilinx_spips_cs_is_set(s, i, field) && !found) {
180
+ */
208
- DB_PRINT_L(0, "selecting slave %d\n", i);
181
+static const uint32_t ficr_content[64] = {
209
- qemu_set_irq(s->cs_lines[cs_to_set], 0);
182
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
210
- if (s->cs_lines_state[cs_to_set]) {
183
+ 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
211
- s->cs_lines_state[cs_to_set] = false;
184
+ 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
212
- s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
185
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
213
- }
186
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
214
- } else {
187
+ 0x12345678, 0x9ABCDEF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
215
- DB_PRINT_L(0, "deselecting slave %d\n", i);
188
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
216
- qemu_set_irq(s->cs_lines[cs_to_set], 1);
189
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
217
- s->cs_lines_state[cs_to_set] = true;
190
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
218
- }
191
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
219
- }
192
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
220
- if (xilinx_spips_cs_is_set(s, i, field)) {
193
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
221
- found = true;
194
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
222
+ bool old_state = s->cs_lines_state[i];
195
+};
223
+ bool new_state = field & (1 << i);
196
+
224
+
197
+static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
225
+ if (old_state != new_state) {
198
+{
226
+ s->cs_lines_state[i] = new_state;
199
+ assert(offset < sizeof(ficr_content));
227
+ s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
200
+ return ficr_content[offset / 4];
228
+ DB_PRINT_L(1, "%sselecting slave %d\n", new_state ? "" : "de", i);
201
+}
229
}
202
+
230
+ qemu_set_irq(s->cs_lines[i], !new_state);
203
+static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
231
}
204
+ unsigned int size)
232
- if (!found) {
205
+{
233
+ if (!(field & ((1 << s->num_cs) - 1))) {
206
+ /* Intentionally do nothing */
234
s->snoop_state = SNOOP_CHECKING;
207
+}
235
s->cmd_dummies = 0;
208
+
236
s->link_state = 1;
209
+static const MemoryRegionOps ficr_ops = {
237
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
210
+ .read = ficr_read,
238
}
211
+ .write = ficr_write,
239
}
212
+ .impl.min_access_size = 4,
240
213
+ .impl.max_access_size = 4,
241
+static void xlnx_zynqmp_qspips_update_cs_lines(XlnxZynqMPQSPIPS *s)
214
+ .endianness = DEVICE_LITTLE_ENDIAN
242
+{
215
+};
243
+ if (s->regs[R_GQSPI_GF_SNAPSHOT]) {
216
+
244
+ int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT);
217
+/*
245
+ xilinx_spips_update_cs(XILINX_SPIPS(s), field);
218
+ * UICR Registers Assignments
219
+ * CLENR0 0x000
220
+ * RBPCONF 0x004
221
+ * XTALFREQ 0x008
222
+ * FWID 0x010
223
+ * BOOTLOADERADDR 0x014
224
+ * NRFFW[0] 0x014
225
+ * NRFFW[1] 0x018
226
+ * NRFFW[2] 0x01C
227
+ * NRFFW[3] 0x020
228
+ * NRFFW[4] 0x024
229
+ * NRFFW[5] 0x028
230
+ * NRFFW[6] 0x02C
231
+ * NRFFW[7] 0x030
232
+ * NRFFW[8] 0x034
233
+ * NRFFW[9] 0x038
234
+ * NRFFW[10] 0x03C
235
+ * NRFFW[11] 0x040
236
+ * NRFFW[12] 0x044
237
+ * NRFFW[13] 0x048
238
+ * NRFFW[14] 0x04C
239
+ * NRFHW[0] 0x050
240
+ * NRFHW[1] 0x054
241
+ * NRFHW[2] 0x058
242
+ * NRFHW[3] 0x05C
243
+ * NRFHW[4] 0x060
244
+ * NRFHW[5] 0x064
245
+ * NRFHW[6] 0x068
246
+ * NRFHW[7] 0x06C
247
+ * NRFHW[8] 0x070
248
+ * NRFHW[9] 0x074
249
+ * NRFHW[10] 0x078
250
+ * NRFHW[11] 0x07C
251
+ * CUSTOMER[0] 0x080
252
+ * CUSTOMER[1] 0x084
253
+ * CUSTOMER[2] 0x088
254
+ * CUSTOMER[3] 0x08C
255
+ * CUSTOMER[4] 0x090
256
+ * CUSTOMER[5] 0x094
257
+ * CUSTOMER[6] 0x098
258
+ * CUSTOMER[7] 0x09C
259
+ * CUSTOMER[8] 0x0A0
260
+ * CUSTOMER[9] 0x0A4
261
+ * CUSTOMER[10] 0x0A8
262
+ * CUSTOMER[11] 0x0AC
263
+ * CUSTOMER[12] 0x0B0
264
+ * CUSTOMER[13] 0x0B4
265
+ * CUSTOMER[14] 0x0B8
266
+ * CUSTOMER[15] 0x0BC
267
+ * CUSTOMER[16] 0x0C0
268
+ * CUSTOMER[17] 0x0C4
269
+ * CUSTOMER[18] 0x0C8
270
+ * CUSTOMER[19] 0x0CC
271
+ * CUSTOMER[20] 0x0D0
272
+ * CUSTOMER[21] 0x0D4
273
+ * CUSTOMER[22] 0x0D8
274
+ * CUSTOMER[23] 0x0DC
275
+ * CUSTOMER[24] 0x0E0
276
+ * CUSTOMER[25] 0x0E4
277
+ * CUSTOMER[26] 0x0E8
278
+ * CUSTOMER[27] 0x0EC
279
+ * CUSTOMER[28] 0x0F0
280
+ * CUSTOMER[29] 0x0F4
281
+ * CUSTOMER[30] 0x0F8
282
+ * CUSTOMER[31] 0x0FC
283
+ */
284
+
285
+static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
286
+{
287
+ NRF51NVMState *s = NRF51_NVM(opaque);
288
+
289
+ assert(offset < sizeof(s->uicr_content));
290
+ return s->uicr_content[offset / 4];
291
+}
292
+
293
+static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
294
+ unsigned int size)
295
+{
296
+ NRF51NVMState *s = NRF51_NVM(opaque);
297
+
298
+ assert(offset < sizeof(s->uicr_content));
299
+ s->uicr_content[offset / 4] = value;
300
+}
301
+
302
+static const MemoryRegionOps uicr_ops = {
303
+ .read = uicr_read,
304
+ .write = uicr_write,
305
+ .impl.min_access_size = 4,
306
+ .impl.max_access_size = 4,
307
+ .endianness = DEVICE_LITTLE_ENDIAN
308
+};
309
+
310
+
311
+static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
312
+{
313
+ NRF51NVMState *s = NRF51_NVM(opaque);
314
+ uint64_t r = 0;
315
+
316
+ switch (offset) {
317
+ case NRF51_NVMC_READY:
318
+ r = NRF51_NVMC_READY_READY;
319
+ break;
320
+ case NRF51_NVMC_CONFIG:
321
+ r = s->config;
322
+ break;
323
+ default:
324
+ qemu_log_mask(LOG_GUEST_ERROR,
325
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
326
+ break;
246
+ }
327
+ }
247
+}
328
+
248
+
329
+ return r;
249
+static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
330
+}
250
+{
331
+
251
+ int field = ~((s->regs[R_CONFIG] & CS) >> CS_SHIFT);
332
+static void io_write(void *opaque, hwaddr offset, uint64_t value,
252
+
333
+ unsigned int size)
253
+ /* In dual parallel, mirror low CS to both */
334
+{
254
+ if (num_effective_busses(s) == 2) {
335
+ NRF51NVMState *s = NRF51_NVM(opaque);
255
+ /* Single bit chip-select for qspi */
336
+
256
+ field &= 0x1;
337
+ switch (offset) {
257
+ field |= field << 1;
338
+ case NRF51_NVMC_CONFIG:
258
+ /* Dual stack U-Page */
339
+ s->config = value & NRF51_NVMC_CONFIG_MASK;
259
+ } else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM &&
340
+ break;
260
+ s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) {
341
+ case NRF51_NVMC_ERASEPCR0:
261
+ /* Single bit chip-select for qspi */
342
+ case NRF51_NVMC_ERASEPCR1:
262
+ field &= 0x1;
343
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
263
+ /* change from CS0 to CS1 */
344
+ /* Mask in-page sub address */
264
+ field <<= 1;
345
+ value &= ~(NRF51_PAGE_SIZE - 1);
265
+ }
346
+ if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
266
+ /* Auto CS */
347
+ memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
267
+ if (!(s->regs[R_CONFIG] & MANUAL_CS) &&
348
+ memory_region_flush_rom_device(&s->flash, value,
268
+ fifo8_is_empty(&s->tx_fifo)) {
349
+ NRF51_PAGE_SIZE);
269
+ field = 0;
270
+ }
271
+ xilinx_spips_update_cs(s, field);
272
+}
273
+
274
static void xilinx_spips_update_ixr(XilinxSPIPS *s)
275
{
276
- if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE) {
277
- return;
278
+ if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
279
+ s->regs[R_INTR_STATUS] &= ~IXR_SELF_CLEAR;
280
+ s->regs[R_INTR_STATUS] |=
281
+ (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
282
+ (s->rx_fifo.num >= s->regs[R_RX_THRES] ?
283
+ IXR_RX_FIFO_NOT_EMPTY : 0) |
284
+ (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
285
+ (fifo8_is_empty(&s->tx_fifo) ? IXR_TX_FIFO_EMPTY : 0) |
286
+ (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0);
287
}
288
- /* These are set/cleared as they occur */
289
- s->regs[R_INTR_STATUS] &= (IXR_TX_FIFO_UNDERFLOW | IXR_RX_FIFO_OVERFLOW |
290
- IXR_TX_FIFO_MODE_FAIL);
291
- /* these are pure functions of fifo state, set them here */
292
- s->regs[R_INTR_STATUS] |=
293
- (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
294
- (s->rx_fifo.num >= s->regs[R_RX_THRES] ? IXR_RX_FIFO_NOT_EMPTY : 0) |
295
- (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
296
- (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0);
297
- /* drive external interrupt pin */
298
int new_irqline = !!(s->regs[R_INTR_MASK] & s->regs[R_INTR_STATUS] &
299
IXR_ALL);
300
if (new_irqline != s->irqline) {
301
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_ixr(XilinxSPIPS *s)
302
}
303
}
304
305
+static void xlnx_zynqmp_qspips_update_ixr(XlnxZynqMPQSPIPS *s)
306
+{
307
+ uint32_t gqspi_int;
308
+ int new_irqline;
309
+
310
+ s->regs[R_GQSPI_ISR] &= ~IXR_SELF_CLEAR;
311
+ s->regs[R_GQSPI_ISR] |=
312
+ (fifo32_is_empty(&s->fifo_g) ? IXR_GENERIC_FIFO_EMPTY : 0) |
313
+ (fifo32_is_full(&s->fifo_g) ? IXR_GENERIC_FIFO_FULL : 0) |
314
+ (s->fifo_g.fifo.num < s->regs[R_GQSPI_GFIFO_THRESH] ?
315
+ IXR_GENERIC_FIFO_NOT_FULL : 0) |
316
+ (fifo8_is_empty(&s->rx_fifo_g) ? IXR_RX_FIFO_EMPTY : 0) |
317
+ (fifo8_is_full(&s->rx_fifo_g) ? IXR_RX_FIFO_FULL : 0) |
318
+ (s->rx_fifo_g.num >= s->regs[R_GQSPI_RX_THRESH] ?
319
+ IXR_RX_FIFO_NOT_EMPTY : 0) |
320
+ (fifo8_is_empty(&s->tx_fifo_g) ? IXR_TX_FIFO_EMPTY : 0) |
321
+ (fifo8_is_full(&s->tx_fifo_g) ? IXR_TX_FIFO_FULL : 0) |
322
+ (s->tx_fifo_g.num < s->regs[R_GQSPI_TX_THRESH] ?
323
+ IXR_TX_FIFO_NOT_FULL : 0);
324
+
325
+ /* GQSPI Interrupt Trigger Status */
326
+ gqspi_int = (~s->regs[R_GQSPI_IMR]) & s->regs[R_GQSPI_ISR] & GQSPI_IXR_MASK;
327
+ new_irqline = !!(gqspi_int & IXR_ALL);
328
+
329
+ /* drive external interrupt pin */
330
+ if (new_irqline != s->gqspi_irqline) {
331
+ s->gqspi_irqline = new_irqline;
332
+ qemu_set_irq(XILINX_SPIPS(s)->irq, s->gqspi_irqline);
333
+ }
334
+}
335
+
336
static void xilinx_spips_reset(DeviceState *d)
337
{
338
XilinxSPIPS *s = XILINX_SPIPS(d);
339
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
340
xilinx_spips_update_cs_lines(s);
341
}
342
343
+static void xlnx_zynqmp_qspips_reset(DeviceState *d)
344
+{
345
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(d);
346
+ int i;
347
+
348
+ xilinx_spips_reset(d);
349
+
350
+ for (i = 0; i < XLNX_ZYNQMP_SPIPS_R_MAX; i++) {
351
+ s->regs[i] = 0;
352
+ }
353
+ fifo8_reset(&s->rx_fifo_g);
354
+ fifo8_reset(&s->rx_fifo_g);
355
+ fifo32_reset(&s->fifo_g);
356
+ s->regs[R_GQSPI_TX_THRESH] = 1;
357
+ s->regs[R_GQSPI_RX_THRESH] = 1;
358
+ s->regs[R_GQSPI_GFIFO_THRESH] = 1;
359
+ s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
360
+ s->man_start_com_g = false;
361
+ s->gqspi_irqline = 0;
362
+ xlnx_zynqmp_qspips_update_ixr(s);
363
+}
364
+
365
/* N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
366
* column wise (from element 0 to N-1). num is the length of x, and dir
367
* reverses the direction of the transform. Best illustrated by example:
368
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
369
memcpy(x, r, sizeof(uint8_t) * num);
370
}
371
372
+static void xlnx_zynqmp_qspips_flush_fifo_g(XlnxZynqMPQSPIPS *s)
373
+{
374
+ while (s->regs[R_GQSPI_DATA_STS] || !fifo32_is_empty(&s->fifo_g)) {
375
+ uint8_t tx_rx[2] = { 0 };
376
+ int num_stripes = 1;
377
+ uint8_t busses;
378
+ int i;
379
+
380
+ if (!s->regs[R_GQSPI_DATA_STS]) {
381
+ uint8_t imm;
382
+
383
+ s->regs[R_GQSPI_GF_SNAPSHOT] = fifo32_pop(&s->fifo_g);
384
+ DB_PRINT_L(0, "GQSPI command: %x\n", s->regs[R_GQSPI_GF_SNAPSHOT]);
385
+ if (!s->regs[R_GQSPI_GF_SNAPSHOT]) {
386
+ DB_PRINT_L(0, "Dummy GQSPI Delay Command Entry, Do nothing");
387
+ continue;
388
+ }
350
+ }
389
+ xlnx_zynqmp_qspips_update_cs_lines(s);
351
+ } else {
390
+
352
+ qemu_log_mask(LOG_GUEST_ERROR,
391
+ imm = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA);
353
+ "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
392
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) {
354
+ __func__, offset);
393
+ /* immedate transfer */
355
+ }
394
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) ||
356
+ break;
395
+ ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) {
357
+ case NRF51_NVMC_ERASEALL:
396
+ s->regs[R_GQSPI_DATA_STS] = 1;
358
+ if (value == NRF51_NVMC_ERASE) {
397
+ /* CS setup/hold - do nothing */
359
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
398
+ } else {
360
+ memset(s->storage, 0xFF, s->flash_size);
399
+ s->regs[R_GQSPI_DATA_STS] = 0;
361
+ memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
400
+ }
362
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
401
+ } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, EXPONENT)) {
402
+ if (imm > 31) {
403
+ qemu_log_mask(LOG_UNIMP, "QSPI exponential transfer too"
404
+ " long - 2 ^ %" PRId8 " requested\n", imm);
405
+ }
406
+ s->regs[R_GQSPI_DATA_STS] = 1ul << imm;
407
+ } else {
363
+ } else {
408
+ s->regs[R_GQSPI_DATA_STS] = imm;
364
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
365
+ __func__);
409
+ }
366
+ }
410
+ }
367
+ }
411
+ /* Zero length transfer check */
368
+ break;
412
+ if (!s->regs[R_GQSPI_DATA_STS]) {
369
+ case NRF51_NVMC_ERASEUICR:
413
+ continue;
370
+ if (value == NRF51_NVMC_ERASE) {
371
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
414
+ }
372
+ }
415
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE) &&
373
+ break;
416
+ fifo8_is_full(&s->rx_fifo_g)) {
374
+
417
+ /* No space in RX fifo for transfer - try again later */
375
+ default:
418
+ return;
376
+ qemu_log_mask(LOG_GUEST_ERROR,
419
+ }
377
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
420
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, STRIPE) &&
421
+ (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) ||
422
+ ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE))) {
423
+ num_stripes = 2;
424
+ }
425
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) {
426
+ tx_rx[0] = ARRAY_FIELD_EX32(s->regs,
427
+ GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA);
428
+ } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT)) {
429
+ for (i = 0; i < num_stripes; ++i) {
430
+ if (!fifo8_is_empty(&s->tx_fifo_g)) {
431
+ tx_rx[i] = fifo8_pop(&s->tx_fifo_g);
432
+ s->tx_fifo_g_align++;
433
+ } else {
434
+ return;
435
+ }
436
+ }
437
+ }
438
+ if (num_stripes == 1) {
439
+ /* mirror */
440
+ tx_rx[1] = tx_rx[0];
441
+ }
442
+ busses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT);
443
+ for (i = 0; i < 2; ++i) {
444
+ DB_PRINT_L(1, "bus %d tx = %02x\n", i, tx_rx[i]);
445
+ tx_rx[i] = ssi_transfer(XILINX_SPIPS(s)->spi[i], tx_rx[i]);
446
+ DB_PRINT_L(1, "bus %d rx = %02x\n", i, tx_rx[i]);
447
+ }
448
+ if (s->regs[R_GQSPI_DATA_STS] > 1 &&
449
+ busses == 0x3 && num_stripes == 2) {
450
+ s->regs[R_GQSPI_DATA_STS] -= 2;
451
+ } else if (s->regs[R_GQSPI_DATA_STS] > 0) {
452
+ s->regs[R_GQSPI_DATA_STS]--;
453
+ }
454
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) {
455
+ for (i = 0; i < 2; ++i) {
456
+ if (busses & (1 << i)) {
457
+ DB_PRINT_L(1, "bus %d push_byte = %02x\n", i, tx_rx[i]);
458
+ fifo8_push(&s->rx_fifo_g, tx_rx[i]);
459
+ s->rx_fifo_g_align++;
460
+ }
461
+ }
462
+ }
463
+ if (!s->regs[R_GQSPI_DATA_STS]) {
464
+ for (; s->tx_fifo_g_align % 4; s->tx_fifo_g_align++) {
465
+ fifo8_pop(&s->tx_fifo_g);
466
+ }
467
+ for (; s->rx_fifo_g_align % 4; s->rx_fifo_g_align++) {
468
+ fifo8_push(&s->rx_fifo_g, 0);
469
+ }
470
+ }
471
+ }
378
+ }
472
+}
379
+}
473
+
380
+
474
static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
381
+static const MemoryRegionOps io_ops = {
475
{
382
+ .read = io_read,
476
if (!qs) {
383
+ .write = io_write,
477
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_check_flush(XilinxSPIPS *s)
384
+ .impl.min_access_size = 4,
478
xilinx_spips_update_ixr(s);
385
+ .impl.max_access_size = 4,
479
}
386
+ .endianness = DEVICE_LITTLE_ENDIAN,
480
387
+};
481
+static void xlnx_zynqmp_qspips_check_flush(XlnxZynqMPQSPIPS *s)
388
+
482
+{
389
+
483
+ bool gqspi_has_work = s->regs[R_GQSPI_DATA_STS] ||
390
+static void flash_write(void *opaque, hwaddr offset, uint64_t value,
484
+ !fifo32_is_empty(&s->fifo_g);
391
+ unsigned int size)
485
+
392
+{
486
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) {
393
+ NRF51NVMState *s = NRF51_NVM(opaque);
487
+ if (s->man_start_com_g || (gqspi_has_work &&
394
+
488
+ !ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE))) {
395
+ if (s->config & NRF51_NVMC_CONFIG_WEN) {
489
+ xlnx_zynqmp_qspips_flush_fifo_g(s);
396
+ uint32_t oldval;
490
+ }
397
+
398
+ assert(offset + size <= s->flash_size);
399
+
400
+ /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
401
+ oldval = ldl_le_p(s->storage + offset);
402
+ oldval &= value;
403
+ stl_le_p(s->storage + offset, oldval);
404
+
405
+ memory_region_flush_rom_device(&s->flash, offset, size);
491
+ } else {
406
+ } else {
492
+ xilinx_spips_check_flush(XILINX_SPIPS(s));
407
+ qemu_log_mask(LOG_GUEST_ERROR,
408
+ "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
409
+ __func__, offset);
493
+ }
410
+ }
494
+ if (!gqspi_has_work) {
411
+}
495
+ s->man_start_com_g = false;
412
+
413
+
414
+
415
+static const MemoryRegionOps flash_ops = {
416
+ .write = flash_write,
417
+ .valid.min_access_size = 4,
418
+ .valid.max_access_size = 4,
419
+ .endianness = DEVICE_LITTLE_ENDIAN,
420
+};
421
+
422
+static void nrf51_nvm_init(Object *obj)
423
+{
424
+ NRF51NVMState *s = NRF51_NVM(obj);
425
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
426
+
427
+ memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
428
+ NRF51_NVMC_SIZE);
429
+ sysbus_init_mmio(sbd, &s->mmio);
430
+
431
+ memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
432
+ sizeof(ficr_content));
433
+ sysbus_init_mmio(sbd, &s->ficr);
434
+
435
+ memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
436
+ sizeof(s->uicr_content));
437
+ sysbus_init_mmio(sbd, &s->uicr);
438
+}
439
+
440
+static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
441
+{
442
+ NRF51NVMState *s = NRF51_NVM(dev);
443
+ Error *err = NULL;
444
+
445
+ memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
446
+ "nrf51_soc.flash", s->flash_size, &err);
447
+ if (err) {
448
+ error_propagate(errp, err);
449
+ return;
496
+ }
450
+ }
497
+ xlnx_zynqmp_qspips_update_ixr(s);
451
+
498
+}
452
+ s->storage = memory_region_get_ram_ptr(&s->flash);
499
+
453
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
500
static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
454
+}
501
{
455
+
502
int i;
456
+static void nrf51_nvm_reset(DeviceState *dev)
503
@@ -XXX,XX +XXX,XX @@ static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
457
+{
504
return max - i;
458
+ NRF51NVMState *s = NRF51_NVM(dev);
505
}
459
+
506
460
+ s->config = 0x00;
507
+static const void *pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
461
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
508
+{
462
+}
509
+ void *ret;
463
+
510
+
464
+static Property nrf51_nvm_properties[] = {
511
+ if (max == 0 || max > fifo->num) {
465
+ DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
512
+ abort();
466
+ DEFINE_PROP_END_OF_LIST(),
513
+ }
467
+};
514
+ *num = MIN(fifo->capacity - fifo->head, max);
468
+
515
+ ret = &fifo->data[fifo->head];
469
+static const VMStateDescription vmstate_nvm = {
516
+ fifo->head += *num;
470
+ .name = "nrf51_soc.nvm",
517
+ fifo->head %= fifo->capacity;
518
+ fifo->num -= *num;
519
+ return ret;
520
+}
521
+
522
+static void xlnx_zynqmp_qspips_notify(void *opaque)
523
+{
524
+ XlnxZynqMPQSPIPS *rq = XLNX_ZYNQMP_QSPIPS(opaque);
525
+ XilinxSPIPS *s = XILINX_SPIPS(rq);
526
+ Fifo8 *recv_fifo;
527
+
528
+ if (ARRAY_FIELD_EX32(rq->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) {
529
+ if (!(ARRAY_FIELD_EX32(rq->regs, GQSPI_CNFG, MODE_EN) == 2)) {
530
+ return;
531
+ }
532
+ recv_fifo = &rq->rx_fifo_g;
533
+ } else {
534
+ if (!(s->regs[R_CMND] & R_CMND_DMA_EN)) {
535
+ return;
536
+ }
537
+ recv_fifo = &s->rx_fifo;
538
+ }
539
+ while (recv_fifo->num >= 4
540
+ && stream_can_push(rq->dma, xlnx_zynqmp_qspips_notify, rq))
541
+ {
542
+ size_t ret;
543
+ uint32_t num;
544
+ const void *rxd = pop_buf(recv_fifo, 4, &num);
545
+
546
+ memcpy(rq->dma_buf, rxd, num);
547
+
548
+ ret = stream_push(rq->dma, rq->dma_buf, 4);
549
+ assert(ret == 4);
550
+ xlnx_zynqmp_qspips_check_flush(rq);
551
+ }
552
+}
553
+
554
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
555
unsigned size)
556
{
557
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
558
ret <<= 8 * shortfall;
559
}
560
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
561
+ xilinx_spips_check_flush(s);
562
xilinx_spips_update_ixr(s);
563
return ret;
564
}
565
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
566
567
}
568
569
+static uint64_t xlnx_zynqmp_qspips_read(void *opaque,
570
+ hwaddr addr, unsigned size)
571
+{
572
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(opaque);
573
+ uint32_t reg = addr / 4;
574
+ uint32_t ret;
575
+ uint8_t rx_buf[4];
576
+ int shortfall;
577
+
578
+ if (reg <= R_MOD_ID) {
579
+ return xilinx_spips_read(opaque, addr, size);
580
+ } else {
581
+ switch (reg) {
582
+ case R_GQSPI_RXD:
583
+ if (fifo8_is_empty(&s->rx_fifo_g)) {
584
+ qemu_log_mask(LOG_GUEST_ERROR,
585
+ "Read from empty GQSPI RX FIFO\n");
586
+ return 0;
587
+ }
588
+ memset(rx_buf, 0, sizeof(rx_buf));
589
+ shortfall = rx_data_bytes(&s->rx_fifo_g, rx_buf,
590
+ XILINX_SPIPS(s)->num_txrx_bytes);
591
+ ret = ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN) ?
592
+ cpu_to_be32(*(uint32_t *)rx_buf) :
593
+ cpu_to_le32(*(uint32_t *)rx_buf);
594
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN)) {
595
+ ret <<= 8 * shortfall;
596
+ }
597
+ xlnx_zynqmp_qspips_check_flush(s);
598
+ xlnx_zynqmp_qspips_update_ixr(s);
599
+ return ret;
600
+ default:
601
+ return s->regs[reg];
602
+ }
603
+ }
604
+}
605
+
606
static void xilinx_spips_write(void *opaque, hwaddr addr,
607
uint64_t value, unsigned size)
608
{
609
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
610
}
611
}
612
613
+static void xlnx_zynqmp_qspips_write(void *opaque, hwaddr addr,
614
+ uint64_t value, unsigned size)
615
+{
616
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(opaque);
617
+ uint32_t reg = addr / 4;
618
+
619
+ if (reg <= R_MOD_ID) {
620
+ xilinx_qspips_write(opaque, addr, value, size);
621
+ } else {
622
+ switch (reg) {
623
+ case R_GQSPI_CNFG:
624
+ if (FIELD_EX32(value, GQSPI_CNFG, GEN_FIFO_START) &&
625
+ ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE)) {
626
+ s->man_start_com_g = true;
627
+ }
628
+ s->regs[reg] = value & ~(R_GQSPI_CNFG_GEN_FIFO_START_MASK);
629
+ break;
630
+ case R_GQSPI_GEN_FIFO:
631
+ if (!fifo32_is_full(&s->fifo_g)) {
632
+ fifo32_push(&s->fifo_g, value);
633
+ }
634
+ break;
635
+ case R_GQSPI_TXD:
636
+ tx_data_bytes(&s->tx_fifo_g, (uint32_t)value, 4,
637
+ ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN));
638
+ break;
639
+ case R_GQSPI_FIFO_CTRL:
640
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET)) {
641
+ fifo32_reset(&s->fifo_g);
642
+ }
643
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, TX_FIFO_RESET)) {
644
+ fifo8_reset(&s->tx_fifo_g);
645
+ }
646
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, RX_FIFO_RESET)) {
647
+ fifo8_reset(&s->rx_fifo_g);
648
+ }
649
+ break;
650
+ case R_GQSPI_IDR:
651
+ s->regs[R_GQSPI_IMR] |= value;
652
+ break;
653
+ case R_GQSPI_IER:
654
+ s->regs[R_GQSPI_IMR] &= ~value;
655
+ break;
656
+ case R_GQSPI_ISR:
657
+ s->regs[R_GQSPI_ISR] &= ~value;
658
+ break;
659
+ case R_GQSPI_IMR:
660
+ case R_GQSPI_RXD:
661
+ case R_GQSPI_GF_SNAPSHOT:
662
+ case R_GQSPI_MOD_ID:
663
+ break;
664
+ default:
665
+ s->regs[reg] = value;
666
+ break;
667
+ }
668
+ xlnx_zynqmp_qspips_update_cs_lines(s);
669
+ xlnx_zynqmp_qspips_check_flush(s);
670
+ xlnx_zynqmp_qspips_update_cs_lines(s);
671
+ xlnx_zynqmp_qspips_update_ixr(s);
672
+ }
673
+ xlnx_zynqmp_qspips_notify(s);
674
+}
675
+
676
static const MemoryRegionOps qspips_ops = {
677
.read = xilinx_spips_read,
678
.write = xilinx_qspips_write,
679
.endianness = DEVICE_LITTLE_ENDIAN,
680
};
681
682
+static const MemoryRegionOps xlnx_zynqmp_qspips_ops = {
683
+ .read = xlnx_zynqmp_qspips_read,
684
+ .write = xlnx_zynqmp_qspips_write,
685
+ .endianness = DEVICE_LITTLE_ENDIAN,
686
+};
687
+
688
#define LQSPI_CACHE_SIZE 1024
689
690
static void lqspi_load_cache(void *opaque, hwaddr addr)
691
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
692
}
693
694
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
695
- "spi", XLNX_SPIPS_R_MAX * 4);
696
+ "spi", XLNX_ZYNQMP_SPIPS_R_MAX * 4);
697
sysbus_init_mmio(sbd, &s->iomem);
698
699
s->irqline = -1;
700
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
701
}
702
}
703
704
+static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
705
+{
706
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(dev);
707
+ XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
708
+
709
+ xilinx_qspips_realize(dev, errp);
710
+ fifo8_create(&s->rx_fifo_g, xsc->rx_fifo_size);
711
+ fifo8_create(&s->tx_fifo_g, xsc->tx_fifo_size);
712
+ fifo32_create(&s->fifo_g, 32);
713
+}
714
+
715
+static void xlnx_zynqmp_qspips_init(Object *obj)
716
+{
717
+ XlnxZynqMPQSPIPS *rq = XLNX_ZYNQMP_QSPIPS(obj);
718
+
719
+ object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SLAVE,
720
+ (Object **)&rq->dma,
721
+ object_property_allow_set_link,
722
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
723
+ NULL);
724
+}
725
+
726
static int xilinx_spips_post_load(void *opaque, int version_id)
727
{
728
xilinx_spips_update_ixr((XilinxSPIPS *)opaque);
729
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xilinx_spips = {
730
}
731
};
732
733
+static int xlnx_zynqmp_qspips_post_load(void *opaque, int version_id)
734
+{
735
+ XlnxZynqMPQSPIPS *s = (XlnxZynqMPQSPIPS *)opaque;
736
+ XilinxSPIPS *qs = XILINX_SPIPS(s);
737
+
738
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN) &&
739
+ fifo8_is_empty(&qs->rx_fifo) && fifo8_is_empty(&qs->tx_fifo)) {
740
+ xlnx_zynqmp_qspips_update_ixr(s);
741
+ xlnx_zynqmp_qspips_update_cs_lines(s);
742
+ }
743
+ return 0;
744
+}
745
+
746
+static const VMStateDescription vmstate_xilinx_qspips = {
747
+ .name = "xilinx_qspips",
748
+ .version_id = 1,
471
+ .version_id = 1,
749
+ .minimum_version_id = 1,
472
+ .minimum_version_id = 1,
750
+ .fields = (VMStateField[]) {
473
+ .fields = (VMStateField[]) {
751
+ VMSTATE_STRUCT(parent_obj, XilinxQSPIPS, 0,
474
+ VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
752
+ vmstate_xilinx_spips, XilinxSPIPS),
475
+ NRF51_UICR_FIXTURE_SIZE),
476
+ VMSTATE_UINT32(config, NRF51NVMState),
753
+ VMSTATE_END_OF_LIST()
477
+ VMSTATE_END_OF_LIST()
754
+ }
478
+ }
755
+};
479
+};
756
+
480
+
757
+static const VMStateDescription vmstate_xlnx_zynqmp_qspips = {
481
+static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
758
+ .name = "xlnx_zynqmp_qspips",
759
+ .version_id = 1,
760
+ .minimum_version_id = 1,
761
+ .post_load = xlnx_zynqmp_qspips_post_load,
762
+ .fields = (VMStateField[]) {
763
+ VMSTATE_STRUCT(parent_obj, XlnxZynqMPQSPIPS, 0,
764
+ vmstate_xilinx_qspips, XilinxQSPIPS),
765
+ VMSTATE_FIFO8(tx_fifo_g, XlnxZynqMPQSPIPS),
766
+ VMSTATE_FIFO8(rx_fifo_g, XlnxZynqMPQSPIPS),
767
+ VMSTATE_FIFO32(fifo_g, XlnxZynqMPQSPIPS),
768
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPQSPIPS, XLNX_ZYNQMP_SPIPS_R_MAX),
769
+ VMSTATE_END_OF_LIST()
770
+ }
771
+};
772
+
773
static Property xilinx_qspips_properties[] = {
774
/* We had to turn this off for 2.10 as it is not compatible with migration.
775
* It can be enabled but will prevent the device to be migrated.
776
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
777
xsc->tx_fifo_size = TXFF_A;
778
}
779
780
+static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
781
+{
482
+{
782
+ DeviceClass *dc = DEVICE_CLASS(klass);
483
+ DeviceClass *dc = DEVICE_CLASS(klass);
783
+ XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
484
+
784
+
485
+ dc->props = nrf51_nvm_properties;
785
+ dc->realize = xlnx_zynqmp_qspips_realize;
486
+ dc->vmsd = &vmstate_nvm;
786
+ dc->reset = xlnx_zynqmp_qspips_reset;
487
+ dc->realize = nrf51_nvm_realize;
787
+ dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
488
+ dc->reset = nrf51_nvm_reset;
788
+ xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
489
+}
789
+ xsc->rx_fifo_size = RXFF_A_Q;
490
+
790
+ xsc->tx_fifo_size = TXFF_A_Q;
491
+static const TypeInfo nrf51_nvm_info = {
791
+}
492
+ .name = TYPE_NRF51_NVM,
792
+
493
+ .parent = TYPE_SYS_BUS_DEVICE,
793
static const TypeInfo xilinx_spips_info = {
494
+ .instance_size = sizeof(NRF51NVMState),
794
.name = TYPE_XILINX_SPIPS,
495
+ .instance_init = nrf51_nvm_init,
795
.parent = TYPE_SYS_BUS_DEVICE,
496
+ .class_init = nrf51_nvm_class_init
796
@@ -XXX,XX +XXX,XX @@ static const TypeInfo xilinx_qspips_info = {
497
+};
797
.class_init = xilinx_qspips_class_init,
498
+
798
};
499
+static void nrf51_nvm_register_types(void)
799
500
+{
800
+static const TypeInfo xlnx_zynqmp_qspips_info = {
501
+ type_register_static(&nrf51_nvm_info);
801
+ .name = TYPE_XLNX_ZYNQMP_QSPIPS,
502
+}
802
+ .parent = TYPE_XILINX_QSPIPS,
503
+
803
+ .instance_size = sizeof(XlnxZynqMPQSPIPS),
504
+type_init(nrf51_nvm_register_types)
804
+ .instance_init = xlnx_zynqmp_qspips_init,
805
+ .class_init = xlnx_zynqmp_qspips_class_init,
806
+};
807
+
808
static void xilinx_spips_register_types(void)
809
{
810
type_register_static(&xilinx_spips_info);
811
type_register_static(&xilinx_qspips_info);
812
+ type_register_static(&xlnx_zynqmp_qspips_info);
813
}
814
815
type_init(xilinx_spips_register_types)
816
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
817
index XXXXXXX..XXXXXXX 100644
818
--- a/default-configs/arm-softmmu.mak
819
+++ b/default-configs/arm-softmmu.mak
820
@@ -XXX,XX +XXX,XX @@ CONFIG_SMBIOS=y
821
CONFIG_ASPEED_SOC=y
822
CONFIG_GPIO_KEY=y
823
CONFIG_MSF2=y
824
-
825
CONFIG_FW_CFG_DMA=y
826
+CONFIG_XILINX_AXI=y
827
--
505
--
828
2.7.4
506
2.20.1
829
507
830
508
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
From the very beginning, post_load() was called from common
3
Instantiates UICR, FICR, FLASH and NVMC in nRF51 SOC.
4
reset. This is not standard and obliged to discriminate the
5
reset case from the restore case using the iidr value.
6
4
7
Let's get rid of that call.
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 1511883692-11511-2-git-send-email-eric.auger@redhat.com
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190201023357.22596-3-stefanha@redhat.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/intc/arm_gicv3_its_common.c | 2 --
12
include/hw/arm/nrf51_soc.h | 2 ++
15
hw/intc/arm_gicv3_its_kvm.c | 4 ----
13
hw/arm/nrf51_soc.c | 41 +++++++++++++++++++++++++++-----------
16
2 files changed, 6 deletions(-)
14
2 files changed, 31 insertions(+), 12 deletions(-)
17
15
18
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gicv3_its_common.c
18
--- a/include/hw/arm/nrf51_soc.h
21
+++ b/hw/intc/arm_gicv3_its_common.c
19
+++ b/include/hw/arm/nrf51_soc.h
22
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_common_reset(DeviceState *dev)
20
@@ -XXX,XX +XXX,XX @@
23
s->creadr = 0;
21
#include "hw/char/nrf51_uart.h"
24
s->iidr = 0;
22
#include "hw/misc/nrf51_rng.h"
25
memset(&s->baser, 0, sizeof(s->baser));
23
#include "hw/gpio/nrf51_gpio.h"
26
-
24
+#include "hw/nvram/nrf51_nvm.h"
27
- gicv3_its_post_load(s, 0);
25
#include "hw/timer/nrf51_timer.h"
28
}
26
29
27
#define TYPE_NRF51_SOC "nrf51-soc"
30
static void gicv3_its_common_class_init(ObjectClass *klass, void *data)
28
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
31
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
29
30
NRF51UARTState uart;
31
NRF51RNGState rng;
32
+ NRF51NVMState nvm;
33
NRF51GPIOState gpio;
34
NRF51TimerState timer[NRF51_NUM_TIMERS];
35
36
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
32
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/arm_gicv3_its_kvm.c
38
--- a/hw/arm/nrf51_soc.c
34
+++ b/hw/intc/arm_gicv3_its_kvm.c
39
+++ b/hw/arm/nrf51_soc.c
35
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
40
@@ -XXX,XX +XXX,XX @@
36
{
41
* are supported in the future, add a sub-class of NRF51SoC for
37
int i;
42
* the specific variants
38
43
*/
39
- if (!s->iidr) {
44
-#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
45
-#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
46
+#define NRF51822_FLASH_PAGES 256
47
+#define NRF51822_SRAM_PAGES 16
48
+#define NRF51822_FLASH_SIZE (NRF51822_FLASH_PAGES * NRF51_PAGE_SIZE)
49
+#define NRF51822_SRAM_SIZE (NRF51822_SRAM_PAGES * NRF51_PAGE_SIZE)
50
51
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
52
53
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
54
55
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
56
57
- memory_region_init_rom(&s->flash, OBJECT(s), "nrf51.flash", s->flash_size,
58
- &err);
59
- if (err) {
60
- error_propagate(errp, err);
40
- return;
61
- return;
41
- }
62
- }
63
- memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
42
-
64
-
43
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
65
memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
44
GITS_IIDR, &s->iidr, true, &error_abort);
66
&err);
67
if (err) {
68
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
69
qdev_get_gpio_in(DEVICE(&s->cpu),
70
BASE_TO_IRQ(NRF51_RNG_BASE)));
71
72
+ /* UICR, FICR, NVMC, FLASH */
73
+ object_property_set_uint(OBJECT(&s->nvm), s->flash_size, "flash-size",
74
+ &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
+
80
+ object_property_set_bool(OBJECT(&s->nvm), true, "realized", &err);
81
+ if (err) {
82
+ error_propagate(errp, err);
83
+ return;
84
+ }
85
+
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 0);
87
+ memory_region_add_subregion_overlap(&s->container, NRF51_NVMC_BASE, mr, 0);
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 1);
89
+ memory_region_add_subregion_overlap(&s->container, NRF51_FICR_BASE, mr, 0);
90
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 2);
91
+ memory_region_add_subregion_overlap(&s->container, NRF51_UICR_BASE, mr, 0);
92
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 3);
93
+ memory_region_add_subregion_overlap(&s->container, NRF51_FLASH_BASE, mr, 0);
94
+
95
/* GPIO */
96
object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
97
if (err) {
98
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
99
100
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
101
NRF51_IOMEM_SIZE);
102
- create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
103
- NRF51_FICR_SIZE);
104
create_unimplemented_device("nrf51_soc.private",
105
NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
108
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
109
TYPE_NRF51_RNG);
110
111
+ sysbus_init_child_obj(obj, "nvm", &s->nvm, sizeof(s->nvm), TYPE_NRF51_NVM);
112
+
113
sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
114
TYPE_NRF51_GPIO);
45
115
46
--
116
--
47
2.7.4
117
2.20.1
48
118
49
119
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
Add support for the RX discard and RX drain functionality. Also transmit
3
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
4
one byte per dummy cycle (to the flash memories) with commands that require
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
these.
5
Acked-by: Thomas Huth <thuth@redhat.com>
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Message-id: 20190201023357.22596-4-stefanha@redhat.com
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-8-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
include/hw/ssi/xilinx_spips.h | 6 ++
10
tests/microbit-test.c | 108 ++++++++++++++++++++++++++++++++++++++++++
14
hw/ssi/xilinx_spips.c | 167 +++++++++++++++++++++++++++++++++++++-----
11
1 file changed, 108 insertions(+)
15
2 files changed, 155 insertions(+), 18 deletions(-)
16
12
17
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
13
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/ssi/xilinx_spips.h
15
--- a/tests/microbit-test.c
20
+++ b/include/hw/ssi/xilinx_spips.h
16
+++ b/tests/microbit-test.c
21
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
22
uint8_t num_busses;
23
24
uint8_t snoop_state;
25
+ int cmd_dummies;
26
+ uint8_t link_state;
27
+ uint8_t link_state_next;
28
+ uint8_t link_state_next_when;
29
qemu_irq *cs_lines;
30
+ bool *cs_lines_state;
31
SSIBus **spi;
32
33
Fifo8 rx_fifo;
34
Fifo8 tx_fifo;
35
36
uint8_t num_txrx_bytes;
37
+ uint32_t rx_discard;
38
39
uint32_t regs[XLNX_SPIPS_R_MAX];
40
};
41
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/ssi/xilinx_spips.c
44
+++ b/hw/ssi/xilinx_spips.c
45
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
46
#include "qemu/bitops.h"
18
#include "hw/arm/nrf51.h"
47
#include "hw/ssi/xilinx_spips.h"
19
#include "hw/char/nrf51_uart.h"
48
#include "qapi/error.h"
20
#include "hw/gpio/nrf51_gpio.h"
49
+#include "hw/register.h"
21
+#include "hw/nvram/nrf51_nvm.h"
50
#include "migration/blocker.h"
22
#include "hw/timer/nrf51_timer.h"
51
23
#include "hw/i2c/microbit_i2c.h"
52
#ifndef XILINX_SPIPS_ERR_DEBUG
24
53
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void test_microbit_i2c(void)
54
#define LQSPI_CFG_DUMMY_SHIFT 8
26
qtest_quit(qts);
55
#define LQSPI_CFG_INST_CODE 0xFF
56
57
+#define R_CMND (0xc0 / 4)
58
+ #define R_CMND_RXFIFO_DRAIN (1 << 19)
59
+ FIELD(CMND, PARTIAL_BYTE_LEN, 16, 3)
60
+#define R_CMND_EXT_ADD (1 << 15)
61
+ FIELD(CMND, RX_DISCARD, 8, 7)
62
+ FIELD(CMND, DUMMY_CYCLES, 2, 6)
63
+#define R_CMND_DMA_EN (1 << 1)
64
+#define R_CMND_PUSH_WAIT (1 << 0)
65
#define R_LQSPI_STS (0xA4 / 4)
66
#define LQSPI_STS_WR_RECVD (1 << 1)
67
68
@@ -XXX,XX +XXX,XX @@
69
#define LQSPI_ADDRESS_BITS 24
70
71
#define SNOOP_CHECKING 0xFF
72
-#define SNOOP_NONE 0xFE
73
+#define SNOOP_ADDR 0xF0
74
+#define SNOOP_NONE 0xEE
75
#define SNOOP_STRIPING 0
76
77
static inline int num_effective_busses(XilinxSPIPS *s)
78
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
79
if (xilinx_spips_cs_is_set(s, i, field) && !found) {
80
DB_PRINT_L(0, "selecting slave %d\n", i);
81
qemu_set_irq(s->cs_lines[cs_to_set], 0);
82
+ if (s->cs_lines_state[cs_to_set]) {
83
+ s->cs_lines_state[cs_to_set] = false;
84
+ s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
85
+ }
86
} else {
87
DB_PRINT_L(0, "deselecting slave %d\n", i);
88
qemu_set_irq(s->cs_lines[cs_to_set], 1);
89
+ s->cs_lines_state[cs_to_set] = true;
90
}
91
}
92
if (xilinx_spips_cs_is_set(s, i, field)) {
93
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
94
}
95
if (!found) {
96
s->snoop_state = SNOOP_CHECKING;
97
+ s->cmd_dummies = 0;
98
+ s->link_state = 1;
99
+ s->link_state_next = 1;
100
+ s->link_state_next_when = 0;
101
DB_PRINT_L(1, "moving to snoop check state\n");
102
}
103
}
27
}
104
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
28
105
/* FIXME: move magic number definition somewhere sensible */
29
+#define FLASH_SIZE (256 * NRF51_PAGE_SIZE)
106
s->regs[R_MOD_ID] = 0x01090106;
30
+
107
s->regs[R_LQSPI_CFG] = R_LQSPI_CFG_RESET;
31
+static void fill_and_erase(QTestState *qts, hwaddr base, hwaddr size,
108
+ s->link_state = 1;
32
+ uint32_t address_reg)
109
+ s->link_state_next = 1;
110
+ s->link_state_next_when = 0;
111
s->snoop_state = SNOOP_CHECKING;
112
+ s->cmd_dummies = 0;
113
xilinx_spips_update_ixr(s);
114
xilinx_spips_update_cs_lines(s);
115
}
116
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
117
memcpy(x, r, sizeof(uint8_t) * num);
118
}
119
120
+static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
121
+{
33
+{
122
+ if (!qs) {
34
+ hwaddr i;
123
+ /* The SPI device is not a QSPI device */
35
+
124
+ return -1;
36
+ /* Erase Page */
37
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
38
+ qtest_writel(qts, NRF51_NVMC_BASE + address_reg, base);
39
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
40
+
41
+ /* Check memory */
42
+ for (i = 0; i < size / 4; i++) {
43
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, 0xFFFFFFFF);
125
+ }
44
+ }
126
+
45
+
127
+ switch (command) { /* check for dummies */
46
+ /* Fill memory */
128
+ case READ: /* no dummy bytes/cycles */
47
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
129
+ case PP:
48
+ for (i = 0; i < size / 4; i++) {
130
+ case DPP:
49
+ qtest_writel(qts, base + i * 4, i);
131
+ case QPP:
50
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, i);
132
+ case READ_4:
133
+ case PP_4:
134
+ case QPP_4:
135
+ return 0;
136
+ case FAST_READ:
137
+ case DOR:
138
+ case QOR:
139
+ case DOR_4:
140
+ case QOR_4:
141
+ return 1;
142
+ case DIOR:
143
+ case FAST_READ_4:
144
+ case DIOR_4:
145
+ return 2;
146
+ case QIOR:
147
+ case QIOR_4:
148
+ return 5;
149
+ default:
150
+ return -1;
151
+ }
51
+ }
52
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
152
+}
53
+}
153
+
54
+
154
+static inline uint8_t get_addr_length(XilinxSPIPS *s, uint8_t cmd)
55
+static void test_nrf51_nvmc(void)
155
+{
56
+{
156
+ switch (cmd) {
57
+ uint32_t value;
157
+ case PP_4:
58
+ hwaddr i;
158
+ case QPP_4:
59
+ QTestState *qts = qtest_init("-M microbit");
159
+ case READ_4:
60
+
160
+ case QIOR_4:
61
+ /* Test always ready */
161
+ case FAST_READ_4:
62
+ value = qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_READY);
162
+ case DOR_4:
63
+ g_assert_cmpuint(value & 0x01, ==, 0x01);
163
+ case QOR_4:
64
+
164
+ case DIOR_4:
65
+ /* Test write-read config register */
165
+ return 4;
66
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x03);
166
+ default:
67
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
167
+ return (s->regs[R_CMND] & R_CMND_EXT_ADD) ? 4 : 3;
68
+ ==, 0x03);
168
+ }
69
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
70
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
71
+ ==, 0x00);
72
+
73
+ /* Test PCR0 */
74
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
75
+ NRF51_NVMC_ERASEPCR0);
76
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
77
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR0);
78
+
79
+ /* Test PCR1 */
80
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
81
+ NRF51_NVMC_ERASEPCR1);
82
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
83
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR1);
84
+
85
+ /* Erase all */
86
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
87
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
88
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
89
+
90
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
91
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
92
+ qtest_writel(qts, NRF51_FLASH_BASE + i * 4, i);
93
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4), ==, i);
94
+ }
95
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
96
+
97
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
98
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
99
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
100
+
101
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
102
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4),
103
+ ==, 0xFFFFFFFF);
104
+ }
105
+
106
+ /* Erase UICR */
107
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
108
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
109
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
110
+
111
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
112
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
113
+ ==, 0xFFFFFFFF);
114
+ }
115
+
116
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
117
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
118
+ qtest_writel(qts, NRF51_UICR_BASE + i * 4, i);
119
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), ==, i);
120
+ }
121
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
122
+
123
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
124
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
125
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
126
+
127
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
128
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
129
+ ==, 0xFFFFFFFF);
130
+ }
131
+
132
+ qtest_quit(qts);
169
+}
133
+}
170
+
134
+
171
static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
135
static void test_nrf51_gpio(void)
172
{
136
{
173
int debug_level = 0;
137
size_t i;
174
+ XilinxQSPIPS *q = (XilinxQSPIPS *) object_dynamic_cast(OBJECT(s),
138
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
175
+ TYPE_XILINX_QSPIPS);
139
176
140
qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart);
177
for (;;) {
141
qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
178
int i;
142
+ qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
179
uint8_t tx = 0;
143
qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
180
uint8_t tx_rx[num_effective_busses(s)];
144
qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c);
181
+ uint8_t dummy_cycles = 0;
145
182
+ uint8_t addr_length;
183
184
if (fifo8_is_empty(&s->tx_fifo)) {
185
if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
186
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
187
tx_rx[i] = fifo8_pop(&s->tx_fifo);
188
}
189
stripe8(tx_rx, num_effective_busses(s), false);
190
- } else {
191
+ } else if (s->snoop_state >= SNOOP_ADDR) {
192
tx = fifo8_pop(&s->tx_fifo);
193
for (i = 0; i < num_effective_busses(s); ++i) {
194
tx_rx[i] = tx;
195
}
196
+ } else {
197
+ /* Extract a dummy byte and generate dummy cycles according to the
198
+ * link state */
199
+ tx = fifo8_pop(&s->tx_fifo);
200
+ dummy_cycles = 8 / s->link_state;
201
}
202
203
for (i = 0; i < num_effective_busses(s); ++i) {
204
int bus = num_effective_busses(s) - 1 - i;
205
- DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
206
- tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
207
- DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
208
+ if (dummy_cycles) {
209
+ int d;
210
+ for (d = 0; d < dummy_cycles; ++d) {
211
+ tx_rx[0] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[0]);
212
+ }
213
+ } else {
214
+ DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
215
+ tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
216
+ DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
217
+ }
218
}
219
220
- if (fifo8_is_full(&s->rx_fifo)) {
221
+ if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) {
222
+ DB_PRINT_L(debug_level, "dircarding drained rx byte\n");
223
+ /* Do nothing */
224
+ } else if (s->rx_discard) {
225
+ DB_PRINT_L(debug_level, "dircarding discarded rx byte\n");
226
+ s->rx_discard -= 8 / s->link_state;
227
+ } else if (fifo8_is_full(&s->rx_fifo)) {
228
s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
229
DB_PRINT_L(0, "rx FIFO overflow");
230
} else if (s->snoop_state == SNOOP_STRIPING) {
231
stripe8(tx_rx, num_effective_busses(s), true);
232
for (i = 0; i < num_effective_busses(s); ++i) {
233
fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[i]);
234
+ DB_PRINT_L(debug_level, "pushing striped rx byte\n");
235
}
236
} else {
237
+ DB_PRINT_L(debug_level, "pushing unstriped rx byte\n");
238
fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
239
}
240
241
+ if (s->link_state_next_when) {
242
+ s->link_state_next_when--;
243
+ if (!s->link_state_next_when) {
244
+ s->link_state = s->link_state_next;
245
+ }
246
+ }
247
+
248
DB_PRINT_L(debug_level, "initial snoop state: %x\n",
249
(unsigned)s->snoop_state);
250
switch (s->snoop_state) {
251
case (SNOOP_CHECKING):
252
- switch (tx) { /* new instruction code */
253
- case READ: /* 3 address bytes, no dummy bytes/cycles */
254
- case PP:
255
+ /* Store the count of dummy bytes in the txfifo */
256
+ s->cmd_dummies = xilinx_spips_num_dummies(q, tx);
257
+ addr_length = get_addr_length(s, tx);
258
+ if (s->cmd_dummies < 0) {
259
+ s->snoop_state = SNOOP_NONE;
260
+ } else {
261
+ s->snoop_state = SNOOP_ADDR + addr_length - 1;
262
+ }
263
+ switch (tx) {
264
case DPP:
265
- case QPP:
266
- s->snoop_state = 3;
267
- break;
268
- case FAST_READ: /* 3 address bytes, 1 dummy byte */
269
case DOR:
270
+ case DOR_4:
271
+ s->link_state_next = 2;
272
+ s->link_state_next_when = addr_length + s->cmd_dummies;
273
+ break;
274
+ case QPP:
275
+ case QPP_4:
276
case QOR:
277
- case DIOR: /* FIXME: these vary between vendor - set to spansion */
278
- s->snoop_state = 4;
279
+ case QOR_4:
280
+ s->link_state_next = 4;
281
+ s->link_state_next_when = addr_length + s->cmd_dummies;
282
+ break;
283
+ case DIOR:
284
+ case DIOR_4:
285
+ s->link_state = 2;
286
break;
287
- case QIOR: /* 3 address bytes, 2 dummy bytes */
288
- s->snoop_state = 6;
289
+ case QIOR:
290
+ case QIOR_4:
291
+ s->link_state = 4;
292
break;
293
- default:
294
+ }
295
+ break;
296
+ case (SNOOP_ADDR):
297
+ /* Address has been transmitted, transmit dummy cycles now if
298
+ * needed */
299
+ if (s->cmd_dummies < 0) {
300
s->snoop_state = SNOOP_NONE;
301
+ } else {
302
+ s->snoop_state = s->cmd_dummies;
303
}
304
break;
305
case (SNOOP_STRIPING):
306
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
307
uint64_t value, unsigned size)
308
{
309
XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
310
+ XilinxSPIPS *s = XILINX_SPIPS(opaque);
311
312
xilinx_spips_write(opaque, addr, value, size);
313
addr >>= 2;
314
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
315
if (addr == R_LQSPI_CFG) {
316
xilinx_qspips_invalidate_mmio_ptr(q);
317
}
318
+ if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) {
319
+ fifo8_reset(&s->rx_fifo);
320
+ }
321
}
322
323
static const MemoryRegionOps qspips_ops = {
324
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
325
}
326
327
s->cs_lines = g_new0(qemu_irq, s->num_cs * s->num_busses);
328
+ s->cs_lines_state = g_new0(bool, s->num_cs * s->num_busses);
329
for (i = 0, cs = s->cs_lines; i < s->num_busses; ++i, cs += s->num_cs) {
330
ssi_auto_connect_slaves(DEVICE(s), cs, s->spi[i]);
331
}
332
--
146
--
333
2.7.4
147
2.20.1
334
148
335
149
diff view generated by jsdifflib