1
A grab-bag of minor stuff for the end of the year. My to-review
1
Hi; here's the first arm pullreq for the 8.2 cycle. These are
2
queue is not empty, but it it at least in single figures...
2
pretty much all bug fixes (mostly for the experimental FEAT_RME),
3
rather than any major features.
3
4
4
-- PMM
5
-- PMM
5
6
6
The following changes since commit 5bfbd8170ce7acb98a1834ff49ed7340b0837144:
7
The following changes since commit b0dd9a7d6dd15a6898e9c585b521e6bec79b25aa:
7
8
8
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-for-6.0-pull-request' into staging (2020-12-14 20:32:38 +0000)
9
Open 8.2 development tree (2023-08-22 07:14:07 -0700)
9
10
10
are available in the Git repository at:
11
are available in the Git repository at:
11
12
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201215
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230824
13
14
14
for you to fetch changes up to 23af268566069183285bebbdf95b1b37cb7c0942:
15
for you to fetch changes up to cd1e4db73646006039f25879af3bff55b2295ff3:
15
16
16
hw/block/m25p80: Fix Numonyx fast read dummy cycle count (2020-12-15 13:39:30 +0000)
17
target/arm: Fix 64-bit SSRA (2023-08-22 17:31:14 +0100)
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
target-arm queue:
20
target-arm queue:
20
* gdbstub: Correct misparsing of vCont C/S requests
21
* hw/gpio/nrf51: implement DETECT signal
21
* openrisc: Move pic_cpu code into CPU object proper
22
* accel/kvm: Specify default IPA size for arm64
22
* nios2: Move IIC code into CPU object proper
23
* ptw: refactor, fix some FEAT_RME bugs
23
* Improve reporting of ROM overlap errors
24
* target/arm: Adjust PAR_EL1.SH for Device and Normal-NC memory types
24
* xlnx-versal: Add USB support
25
* target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK
25
* hw/misc/zynq_slcr: Avoid #DIV/0! error
26
* Fix SME ST1Q
26
* Numonyx: Fix dummy cycles and check for SPI mode on cmds
27
* Fix 64-bit SSRA
27
28
28
----------------------------------------------------------------
29
----------------------------------------------------------------
29
Joe Komlodi (4):
30
Akihiko Odaki (6):
30
hw/block/m25p80: Make Numonyx config field names more accurate
31
kvm: Introduce kvm_arch_get_default_type hook
31
hw/block/m25p80: Fix when VCFG XIP bit is set for Numonyx
32
accel/kvm: Specify default IPA size for arm64
32
hw/block/m25p80: Check SPI mode before running some Numonyx commands
33
mips: Report an error when KVM_VM_MIPS_VZ is unavailable
33
hw/block/m25p80: Fix Numonyx fast read dummy cycle count
34
accel/kvm: Use negative KVM type for error propagation
35
accel/kvm: Free as when an error occurred
36
accel/kvm: Make kvm_dirty_ring_reaper_init() void
34
37
35
Peter Maydell (11):
38
Chris Laplante (6):
36
gdbstub: Correct misparsing of vCont C/S requests
39
hw/gpio/nrf51: implement DETECT signal
37
hw/openrisc/openrisc_sim: Use IRQ splitter when connecting IRQ to multiple CPUs
40
qtest: factor out qtest_install_gpio_out_intercept
38
hw/openrisc/openrisc_sim: Abstract out "get IRQ x of CPU y"
41
qtest: implement named interception of out-GPIO
39
target/openrisc: Move pic_cpu code into CPU object proper
42
qtest: bail from irq_intercept_in if name is specified
40
target/nios2: Move IIC code into CPU object proper
43
qtest: irq_intercept_[out/in]: return FAIL if no intercepts are installed
41
target/nios2: Move nios2_check_interrupts() into target/nios2
44
qtest: microbit-test: add tests for nRF51 DETECT
42
target/nios2: Use deposit32() to update ipending register
43
hw/core/loader.c: Track last-seen ROM in rom_check_and_register_reset()
44
hw/core/loader.c: Improve reporting of ROM overlap errors
45
elf_ops.h: Don't truncate name of the ROM blobs we create
46
elf_ops.h: Be more verbose with ROM blob names
47
45
48
Philippe Mathieu-Daudé (1):
46
Jean-Philippe Brucker (6):
49
hw/misc/zynq_slcr: Avoid #DIV/0! error
47
target/arm/ptw: Load stage-2 tables from realm physical space
48
target/arm/helper: Fix tlbmask and tlbbits for TLBI VAE2*
49
target/arm: Skip granule protection checks for AT instructions
50
target/arm: Pass security space rather than flag for AT instructions
51
target/arm/helper: Check SCR_EL3.{NSE, NS} encoding for AT instructions
52
target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK
50
53
51
Sai Pavan Boddu (2):
54
Peter Maydell (15):
52
usb: Add versal-usb2-ctrl-regs module
55
target/arm/ptw: Don't set fi->s1ptw for UnsuppAtomicUpdate fault
53
usb: xlnx-usb-subsystem: Add xilinx usb subsystem
56
target/arm/ptw: Don't report GPC faults on stage 1 ptw as stage2 faults
57
target/arm/ptw: Set s1ns bit in fault info more consistently
58
target/arm/ptw: Pass ptw into get_phys_addr_pmsa*() and get_phys_addr_disabled()
59
target/arm/ptw: Pass ARMSecurityState to regime_translation_disabled()
60
target/arm/ptw: Pass an ARMSecuritySpace to arm_hcr_el2_eff_secstate()
61
target/arm: Pass an ARMSecuritySpace to arm_is_el2_enabled_secstate()
62
target/arm/ptw: Only fold in NSTable bit effects in Secure state
63
target/arm/ptw: Remove last uses of ptw->in_secure
64
target/arm/ptw: Remove S1Translate::in_secure
65
target/arm/ptw: Drop S1Translate::out_secure
66
target/arm/ptw: Set attributes correctly for MMU disabled data accesses
67
target/arm/ptw: Check for block descriptors at invalid levels
68
target/arm/ptw: Report stage 2 fault level for stage 2 faults on stage 1 ptw
69
target/arm: Adjust PAR_EL1.SH for Device and Normal-NC memory types
54
70
55
Vikram Garhwal (2):
71
Richard Henderson (2):
56
usb: Add DWC3 model
72
target/arm: Fix SME ST1Q
57
arm: xlnx-versal: Connect usb to virt-versal
73
target/arm: Fix 64-bit SSRA
58
74
59
include/hw/arm/xlnx-versal.h | 9 +
75
include/hw/gpio/nrf51_gpio.h | 1 +
60
include/hw/elf_ops.h | 5 +-
76
include/sysemu/kvm.h | 2 +
61
include/hw/usb/hcd-dwc3.h | 55 +++
77
target/arm/cpu.h | 19 ++--
62
include/hw/usb/xlnx-usb-subsystem.h | 45 ++
78
target/arm/internals.h | 25 ++---
63
include/hw/usb/xlnx-versal-usb2-ctrl-regs.h | 45 ++
79
target/mips/kvm_mips.h | 9 --
64
target/nios2/cpu.h | 3 -
80
tests/qtest/libqtest.h | 11 +++
65
target/openrisc/cpu.h | 1 -
81
accel/kvm/kvm-all.c | 19 ++--
66
gdbstub.c | 2 +-
82
hw/arm/virt.c | 2 +-
67
hw/arm/xlnx-versal-virt.c | 55 +++
83
hw/gpio/nrf51_gpio.c | 14 ++-
68
hw/arm/xlnx-versal.c | 26 ++
84
hw/mips/loongson3_virt.c | 2 -
69
hw/block/m25p80.c | 158 +++++--
85
hw/ppc/spapr.c | 2 +-
70
hw/core/loader.c | 67 ++-
86
softmmu/qtest.c | 52 +++++++---
71
hw/intc/nios2_iic.c | 95 ----
87
target/arm/cpu.c | 6 ++
72
hw/misc/zynq_slcr.c | 5 +
88
target/arm/helper.c | 207 ++++++++++++++++++++++++++++----------
73
hw/nios2/10m50_devboard.c | 13 +-
89
target/arm/kvm.c | 7 ++
74
hw/nios2/cpu_pic.c | 67 ---
90
target/arm/ptw.c | 231 ++++++++++++++++++++++++++-----------------
75
hw/openrisc/openrisc_sim.c | 46 +-
91
target/arm/tcg/sme_helper.c | 2 +-
76
hw/openrisc/pic_cpu.c | 61 ---
92
target/arm/tcg/translate.c | 2 +-
77
hw/usb/hcd-dwc3.c | 689 ++++++++++++++++++++++++++++
93
target/i386/kvm/kvm.c | 5 +
78
hw/usb/xlnx-usb-subsystem.c | 94 ++++
94
target/mips/kvm.c | 3 +-
79
hw/usb/xlnx-versal-usb2-ctrl-regs.c | 229 +++++++++
95
target/ppc/kvm.c | 5 +
80
softmmu/vl.c | 1 -
96
target/riscv/kvm.c | 5 +
81
target/nios2/cpu.c | 29 ++
97
target/s390x/kvm/kvm.c | 5 +
82
target/nios2/op_helper.c | 9 +
98
tests/qtest/libqtest.c | 6 ++
83
target/openrisc/cpu.c | 32 ++
99
tests/qtest/microbit-test.c | 44 +++++++++
84
MAINTAINERS | 1 -
100
target/arm/trace-events | 7 +-
85
hw/intc/meson.build | 1 -
101
26 files changed, 494 insertions(+), 199 deletions(-)
86
hw/nios2/meson.build | 2 +-
87
hw/openrisc/Kconfig | 1 +
88
hw/openrisc/meson.build | 2 +-
89
hw/usb/Kconfig | 10 +
90
hw/usb/meson.build | 3 +
91
32 files changed, 1557 insertions(+), 304 deletions(-)
92
create mode 100644 include/hw/usb/hcd-dwc3.h
93
create mode 100644 include/hw/usb/xlnx-usb-subsystem.h
94
create mode 100644 include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
95
delete mode 100644 hw/intc/nios2_iic.c
96
delete mode 100644 hw/nios2/cpu_pic.c
97
delete mode 100644 hw/openrisc/pic_cpu.c
98
create mode 100644 hw/usb/hcd-dwc3.c
99
create mode 100644 hw/usb/xlnx-usb-subsystem.c
100
create mode 100644 hw/usb/xlnx-versal-usb2-ctrl-regs.c
101
diff view generated by jsdifflib
New patch
1
From: Chris Laplante <chris@laplante.io>
1
2
3
Implement nRF51 DETECT signal in the GPIO peripheral.
4
5
The reference manual makes mention of a per-pin DETECT signal, but these
6
are not exposed to the user. See https://devzone.nordicsemi.com/f/nordic-q-a/39858/gpio-per-pin-detect-signal-available
7
for more information. Currently, I don't see a reason to model these.
8
9
Signed-off-by: Chris Laplante <chris@laplante.io>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20230728160324.1159090-2-chris@laplante.io
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/hw/gpio/nrf51_gpio.h | 1 +
15
hw/gpio/nrf51_gpio.c | 14 +++++++++++++-
16
2 files changed, 14 insertions(+), 1 deletion(-)
17
18
diff --git a/include/hw/gpio/nrf51_gpio.h b/include/hw/gpio/nrf51_gpio.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/gpio/nrf51_gpio.h
21
+++ b/include/hw/gpio/nrf51_gpio.h
22
@@ -XXX,XX +XXX,XX @@ struct NRF51GPIOState {
23
uint32_t old_out_connected;
24
25
qemu_irq output[NRF51_GPIO_PINS];
26
+ qemu_irq detect;
27
};
28
29
30
diff --git a/hw/gpio/nrf51_gpio.c b/hw/gpio/nrf51_gpio.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/gpio/nrf51_gpio.c
33
+++ b/hw/gpio/nrf51_gpio.c
34
@@ -XXX,XX +XXX,XX @@ static void update_state(NRF51GPIOState *s)
35
int pull;
36
size_t i;
37
bool connected_out, dir, connected_in, out, in, input;
38
+ bool assert_detect = false;
39
40
for (i = 0; i < NRF51_GPIO_PINS; i++) {
41
pull = pull_value(s->cnf[i]);
42
@@ -XXX,XX +XXX,XX @@ static void update_state(NRF51GPIOState *s)
43
qemu_log_mask(LOG_GUEST_ERROR,
44
"GPIO pin %zu short circuited\n", i);
45
}
46
- if (!connected_in) {
47
+ if (connected_in) {
48
+ uint32_t detect_config = extract32(s->cnf[i], 16, 2);
49
+ if ((detect_config == 2) && (in == 1)) {
50
+ assert_detect = true;
51
+ }
52
+ if ((detect_config == 3) && (in == 0)) {
53
+ assert_detect = true;
54
+ }
55
+ } else {
56
/*
57
* Floating input: the output stimulates IN if connected,
58
* otherwise pull-up/pull-down resistors put a value on both
59
@@ -XXX,XX +XXX,XX @@ static void update_state(NRF51GPIOState *s)
60
}
61
update_output_irq(s, i, connected_out, out);
62
}
63
+
64
+ qemu_set_irq(s->detect, assert_detect);
65
}
66
67
/*
68
@@ -XXX,XX +XXX,XX @@ static void nrf51_gpio_init(Object *obj)
69
70
qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
71
qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
72
+ qdev_init_gpio_out_named(DEVICE(s), &s->detect, "detect", 1);
73
}
74
75
static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
76
--
77
2.34.1
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Chris Laplante <chris@laplante.io>
2
2
3
Numonyx chips determine the number of cycles to wait based on bits 7:4
3
Signed-off-by: Chris Laplante <chris@laplante.io>
4
in the volatile configuration register.
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
5
Message-id: 20230728160324.1159090-3-chris@laplante.io
6
However, if these bits are 0x0 or 0xF, the number of dummy cycles to
7
wait is 10 for QIOR and QIOR4 commands or when in QIO mode, and otherwise 8 for
8
the currently supported fast read commands. [1]
9
10
[1]
11
https://www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25q/die-rev-b/mt25q_qlkt_u_02g_cbb_0.pdf?rev=9b167fbf2b3645efba6385949a72e453
12
13
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
14
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
15
Message-id: 1605568264-26376-5-git-send-email-komlodi@xilinx.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
7
---
18
hw/block/m25p80.c | 30 +++++++++++++++++++++++++++---
8
softmmu/qtest.c | 16 ++++++++++------
19
1 file changed, 27 insertions(+), 3 deletions(-)
9
1 file changed, 10 insertions(+), 6 deletions(-)
20
10
21
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
11
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/block/m25p80.c
13
--- a/softmmu/qtest.c
24
+++ b/hw/block/m25p80.c
14
+++ b/softmmu/qtest.c
25
@@ -XXX,XX +XXX,XX @@ static uint8_t numonyx_mode(Flash *s)
15
@@ -XXX,XX +XXX,XX @@ void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
26
}
16
process_command_cb = pc_cb;
27
}
17
}
28
18
29
+static uint8_t numonyx_extract_cfg_num_dummies(Flash *s)
19
+static void qtest_install_gpio_out_intercept(DeviceState *dev, const char *name, int n)
30
+{
20
+{
31
+ uint8_t num_dummies;
21
+ qemu_irq *disconnected = g_new0(qemu_irq, 1);
32
+ uint8_t mode;
22
+ qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
33
+ assert(get_man(s) == MAN_NUMONYX);
23
+ disconnected, n);
34
+
24
+
35
+ mode = numonyx_mode(s);
25
+ *disconnected = qdev_intercept_gpio_out(dev, icpt, name, n);
36
+ num_dummies = extract32(s->volatile_cfg, 4, 4);
37
+
38
+ if (num_dummies == 0x0 || num_dummies == 0xf) {
39
+ switch (s->cmd_in_progress) {
40
+ case QIOR:
41
+ case QIOR4:
42
+ num_dummies = 10;
43
+ break;
44
+ default:
45
+ num_dummies = (mode == MODE_QIO) ? 10 : 8;
46
+ break;
47
+ }
48
+ }
49
+
50
+ return num_dummies;
51
+}
26
+}
52
+
27
+
53
static void decode_fast_read_cmd(Flash *s)
28
static void qtest_process_command(CharBackend *chr, gchar **words)
54
{
29
{
55
s->needed_bytes = get_addr_length(s);
30
const gchar *command;
56
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
31
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
57
s->needed_bytes += 8;
32
if (words[0][14] == 'o') {
58
break;
33
int i;
59
case MAN_NUMONYX:
34
for (i = 0; i < ngl->num_out; ++i) {
60
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
35
- qemu_irq *disconnected = g_new0(qemu_irq, 1);
61
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
36
- qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
62
break;
37
- disconnected, i);
63
case MAN_MACRONIX:
38
-
64
if (extract32(s->volatile_cfg, 6, 2) == 1) {
39
- *disconnected = qdev_intercept_gpio_out(dev, icpt,
65
@@ -XXX,XX +XXX,XX @@ static void decode_dio_read_cmd(Flash *s)
40
- ngl->name, i);
66
);
41
+ qtest_install_gpio_out_intercept(dev, ngl->name, i);
67
break;
42
}
68
case MAN_NUMONYX:
43
} else {
69
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
44
qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
70
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
71
break;
72
case MAN_MACRONIX:
73
switch (extract32(s->volatile_cfg, 6, 2)) {
74
@@ -XXX,XX +XXX,XX @@ static void decode_qio_read_cmd(Flash *s)
75
);
76
break;
77
case MAN_NUMONYX:
78
- s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
79
+ s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
80
break;
81
case MAN_MACRONIX:
82
switch (extract32(s->volatile_cfg, 6, 2)) {
83
--
45
--
84
2.20.1
46
2.34.1
85
86
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Chris Laplante <chris@laplante.io>
2
2
3
Some Numonyx flash commands cannot be executed in DIO and QIO mode, such as
3
Adds qtest_irq_intercept_out_named method, which utilizes a new optional
4
trying to do DPP or DOR when in QIO mode.
4
name parameter to the irq_intercept_out qtest command.
5
5
6
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
6
Signed-off-by: Chris Laplante <chris@laplante.io>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Message-id: 20230728160324.1159090-4-chris@laplante.io
8
Message-id: 1605568264-26376-4-git-send-email-komlodi@xilinx.com
8
Reviewed-by: Peter Maydell <peter.maydell@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 | 114 ++++++++++++++++++++++++++++++++++++++--------
11
tests/qtest/libqtest.h | 11 +++++++++++
12
1 file changed, 95 insertions(+), 19 deletions(-)
12
softmmu/qtest.c | 18 ++++++++++--------
13
tests/qtest/libqtest.c | 6 ++++++
14
3 files changed, 27 insertions(+), 8 deletions(-)
13
15
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
16
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/m25p80.c
18
--- a/tests/qtest/libqtest.h
17
+++ b/hw/block/m25p80.c
19
+++ b/tests/qtest/libqtest.h
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
20
@@ -XXX,XX +XXX,XX @@ void qtest_irq_intercept_in(QTestState *s, const char *string);
19
MAN_GENERIC,
21
*/
20
} Manufacturer;
22
void qtest_irq_intercept_out(QTestState *s, const char *string);
21
23
22
+typedef enum {
24
+/**
23
+ MODE_STD = 0,
25
+ * qtest_irq_intercept_out_named:
24
+ MODE_DIO = 1,
26
+ * @s: #QTestState instance to operate on.
25
+ MODE_QIO = 2
27
+ * @qom_path: QOM path of a device.
26
+} SPIMode;
28
+ * @name: Name of the GPIO out pin
29
+ *
30
+ * Associate a qtest irq with the named GPIO-out pin of the device
31
+ * whose path is specified by @string and whose name is @name.
32
+ */
33
+void qtest_irq_intercept_out_named(QTestState *s, const char *qom_path, const char *name);
27
+
34
+
28
#define M25P80_INTERNAL_DATA_BUFFER_SZ 16
35
/**
29
36
* qtest_set_irq_in:
30
struct Flash {
37
* @s: QTestState instance to operate on.
31
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
38
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
32
trace_m25p80_reset_done(s);
39
index XXXXXXX..XXXXXXX 100644
40
--- a/softmmu/qtest.c
41
+++ b/softmmu/qtest.c
42
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
43
|| strcmp(words[0], "irq_intercept_in") == 0) {
44
DeviceState *dev;
45
NamedGPIOList *ngl;
46
+ bool is_outbound;
47
48
g_assert(words[1]);
49
+ is_outbound = words[0][14] == 'o';
50
dev = DEVICE(object_resolve_path(words[1], NULL));
51
if (!dev) {
52
qtest_send_prefix(chr);
53
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
54
}
55
56
QLIST_FOREACH(ngl, &dev->gpios, node) {
57
- /* We don't support intercept of named GPIOs yet */
58
- if (ngl->name) {
59
- continue;
60
- }
61
- if (words[0][14] == 'o') {
62
- int i;
63
- for (i = 0; i < ngl->num_out; ++i) {
64
- qtest_install_gpio_out_intercept(dev, ngl->name, i);
65
+ /* We don't support inbound interception of named GPIOs yet */
66
+ if (is_outbound) {
67
+ /* NULL is valid and matchable, for "unnamed GPIO" */
68
+ if (g_strcmp0(ngl->name, words[2]) == 0) {
69
+ int i;
70
+ for (i = 0; i < ngl->num_out; ++i) {
71
+ qtest_install_gpio_out_intercept(dev, ngl->name, i);
72
+ }
73
}
74
} else {
75
qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
76
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/tests/qtest/libqtest.c
79
+++ b/tests/qtest/libqtest.c
80
@@ -XXX,XX +XXX,XX @@ void qtest_irq_intercept_out(QTestState *s, const char *qom_path)
81
qtest_rsp(s);
33
}
82
}
34
83
35
+static uint8_t numonyx_mode(Flash *s)
84
+void qtest_irq_intercept_out_named(QTestState *s, const char *qom_path, const char *name)
36
+{
85
+{
37
+ if (!(s->enh_volatile_cfg & EVCFG_QUAD_IO_DISABLED)) {
86
+ qtest_sendf(s, "irq_intercept_out %s %s\n", qom_path, name);
38
+ return MODE_QIO;
87
+ qtest_rsp(s);
39
+ } else if (!(s->enh_volatile_cfg & EVCFG_DUAL_IO_DISABLED)) {
40
+ return MODE_DIO;
41
+ } else {
42
+ return MODE_STD;
43
+ }
44
+}
88
+}
45
+
89
+
46
static void decode_fast_read_cmd(Flash *s)
90
void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
47
{
91
{
48
s->needed_bytes = get_addr_length(s);
92
qtest_sendf(s, "irq_intercept_in %s\n", qom_path);
49
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
50
case ERASE4_32K:
51
case ERASE_SECTOR:
52
case ERASE4_SECTOR:
53
- case READ:
54
- case READ4:
55
- case DPP:
56
- case QPP:
57
- case QPP_4:
58
case PP:
59
case PP4:
60
- case PP4_4:
61
case DIE_ERASE:
62
case RDID_90:
63
case RDID_AB:
64
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
65
s->len = 0;
66
s->state = STATE_COLLECTING_DATA;
67
break;
68
+ case READ:
69
+ case READ4:
70
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
71
+ s->needed_bytes = get_addr_length(s);
72
+ s->pos = 0;
73
+ s->len = 0;
74
+ s->state = STATE_COLLECTING_DATA;
75
+ } else {
76
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
77
+ "DIO or QIO mode\n", s->cmd_in_progress);
78
+ }
79
+ break;
80
+ case DPP:
81
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
82
+ s->needed_bytes = get_addr_length(s);
83
+ s->pos = 0;
84
+ s->len = 0;
85
+ s->state = STATE_COLLECTING_DATA;
86
+ } else {
87
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
88
+ "QIO mode\n", s->cmd_in_progress);
89
+ }
90
+ break;
91
+ case QPP:
92
+ case QPP_4:
93
+ case PP4_4:
94
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
95
+ s->needed_bytes = get_addr_length(s);
96
+ s->pos = 0;
97
+ s->len = 0;
98
+ s->state = STATE_COLLECTING_DATA;
99
+ } else {
100
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
101
+ "DIO mode\n", s->cmd_in_progress);
102
+ }
103
+ break;
104
105
case FAST_READ:
106
case FAST_READ4:
107
+ decode_fast_read_cmd(s);
108
+ break;
109
case DOR:
110
case DOR4:
111
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
112
+ decode_fast_read_cmd(s);
113
+ } else {
114
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
115
+ "QIO mode\n", s->cmd_in_progress);
116
+ }
117
+ break;
118
case QOR:
119
case QOR4:
120
- decode_fast_read_cmd(s);
121
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
122
+ decode_fast_read_cmd(s);
123
+ } else {
124
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
125
+ "DIO mode\n", s->cmd_in_progress);
126
+ }
127
break;
128
129
case DIOR:
130
case DIOR4:
131
- decode_dio_read_cmd(s);
132
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
133
+ decode_dio_read_cmd(s);
134
+ } else {
135
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
136
+ "QIO mode\n", s->cmd_in_progress);
137
+ }
138
break;
139
140
case QIOR:
141
case QIOR4:
142
- decode_qio_read_cmd(s);
143
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
144
+ decode_qio_read_cmd(s);
145
+ } else {
146
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
147
+ "DIO mode\n", s->cmd_in_progress);
148
+ }
149
break;
150
151
case WRSR:
152
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
153
break;
154
155
case JEDEC_READ:
156
- trace_m25p80_populated_jedec(s);
157
- for (i = 0; i < s->pi->id_len; i++) {
158
- s->data[i] = s->pi->id[i];
159
- }
160
- for (; i < SPI_NOR_MAX_ID_LEN; i++) {
161
- s->data[i] = 0;
162
- }
163
+ if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
164
+ trace_m25p80_populated_jedec(s);
165
+ for (i = 0; i < s->pi->id_len; i++) {
166
+ s->data[i] = s->pi->id[i];
167
+ }
168
+ for (; i < SPI_NOR_MAX_ID_LEN; i++) {
169
+ s->data[i] = 0;
170
+ }
171
172
- s->len = SPI_NOR_MAX_ID_LEN;
173
- s->pos = 0;
174
- s->state = STATE_READING_DATA;
175
+ s->len = SPI_NOR_MAX_ID_LEN;
176
+ s->pos = 0;
177
+ s->state = STATE_READING_DATA;
178
+ } else {
179
+ qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute JEDEC read "
180
+ "in DIO or QIO mode\n");
181
+ }
182
break;
183
184
case RDCR:
185
--
93
--
186
2.20.1
94
2.34.1
187
188
diff view generated by jsdifflib
New patch
1
From: Chris Laplante <chris@laplante.io>
1
2
3
Named interception of in-GPIOs is not supported yet.
4
5
Signed-off-by: Chris Laplante <chris@laplante.io>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20230728160324.1159090-5-chris@laplante.io
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
softmmu/qtest.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/softmmu/qtest.c
16
+++ b/softmmu/qtest.c
17
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
18
|| strcmp(words[0], "irq_intercept_in") == 0) {
19
DeviceState *dev;
20
NamedGPIOList *ngl;
21
+ bool is_named;
22
bool is_outbound;
23
24
g_assert(words[1]);
25
+ is_named = words[2] != NULL;
26
is_outbound = words[0][14] == 'o';
27
dev = DEVICE(object_resolve_path(words[1], NULL));
28
if (!dev) {
29
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
30
return;
31
}
32
33
+ if (is_named && !is_outbound) {
34
+ qtest_send_prefix(chr);
35
+ qtest_send(chr, "FAIL Interception of named in-GPIOs not yet supported\n");
36
+ return;
37
+ }
38
+
39
if (irq_intercept_dev) {
40
qtest_send_prefix(chr);
41
if (irq_intercept_dev != dev) {
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
From: Chris Laplante <chris@laplante.io>
1
2
3
This is much better than just silently failing with OK.
4
5
Signed-off-by: Chris Laplante <chris@laplante.io>
6
Message-id: 20230728160324.1159090-6-chris@laplante.io
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
softmmu/qtest.c | 12 ++++++++++--
11
1 file changed, 10 insertions(+), 2 deletions(-)
12
13
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/softmmu/qtest.c
16
+++ b/softmmu/qtest.c
17
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
18
NamedGPIOList *ngl;
19
bool is_named;
20
bool is_outbound;
21
+ bool interception_succeeded = false;
22
23
g_assert(words[1]);
24
is_named = words[2] != NULL;
25
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
26
for (i = 0; i < ngl->num_out; ++i) {
27
qtest_install_gpio_out_intercept(dev, ngl->name, i);
28
}
29
+ interception_succeeded = true;
30
}
31
} else {
32
qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
33
ngl->num_in);
34
+ interception_succeeded = true;
35
}
36
}
37
- irq_intercept_dev = dev;
38
+
39
qtest_send_prefix(chr);
40
- qtest_send(chr, "OK\n");
41
+ if (interception_succeeded) {
42
+ irq_intercept_dev = dev;
43
+ qtest_send(chr, "OK\n");
44
+ } else {
45
+ qtest_send(chr, "FAIL No intercepts installed\n");
46
+ }
47
} else if (strcmp(words[0], "set_irq_in") == 0) {
48
DeviceState *dev;
49
qemu_irq irq;
50
--
51
2.34.1
diff view generated by jsdifflib
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
1
From: Chris Laplante <chris@laplante.io>
2
2
3
This patch adds skeleton model of dwc3 usb controller attached to
3
Exercise the DETECT mechanism of the GPIO peripheral.
4
xhci-sysbus device. It defines global register space of DWC3 controller,
5
global registers control the AXI/AHB interfaces properties, external FIFO
6
support and event count support. All of which are unimplemented at
7
present,we are only supporting core reset and read of ID register.
8
4
9
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
5
Signed-off-by: Chris Laplante <chris@laplante.io>
10
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20230728160324.1159090-7-chris@laplante.io
12
Message-id: 1607023357-5096-3-git-send-email-sai.pavan.boddu@xilinx.com
8
[PMM: fixed coding style nits]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
include/hw/usb/hcd-dwc3.h | 55 +++
11
tests/qtest/microbit-test.c | 44 +++++++++++++++++++++++++++++++++++++
16
hw/usb/hcd-dwc3.c | 689 ++++++++++++++++++++++++++++++++++++++
12
1 file changed, 44 insertions(+)
17
hw/usb/Kconfig | 5 +
18
hw/usb/meson.build | 1 +
19
4 files changed, 750 insertions(+)
20
create mode 100644 include/hw/usb/hcd-dwc3.h
21
create mode 100644 hw/usb/hcd-dwc3.c
22
13
23
diff --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h
14
diff --git a/tests/qtest/microbit-test.c b/tests/qtest/microbit-test.c
24
new file mode 100644
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX
16
--- a/tests/qtest/microbit-test.c
26
--- /dev/null
17
+++ b/tests/qtest/microbit-test.c
27
+++ b/include/hw/usb/hcd-dwc3.h
18
@@ -XXX,XX +XXX,XX @@ static void test_nrf51_gpio(void)
28
@@ -XXX,XX +XXX,XX @@
19
qtest_quit(qts);
29
+/*
20
}
30
+ * QEMU model of the USB DWC3 host controller emulation.
21
31
+ *
22
+static void test_nrf51_gpio_detect(void)
32
+ * Copyright (c) 2020 Xilinx Inc.
23
+{
33
+ *
24
+ QTestState *qts = qtest_init("-M microbit");
34
+ * Written by Vikram Garhwal<fnu.vikram@xilinx.com>
25
+ int i;
35
+ *
36
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ * of this software and associated documentation files (the "Software"), to deal
38
+ * in the Software without restriction, including without limitation the rights
39
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ * copies of the Software, and to permit persons to whom the Software is
41
+ * furnished to do so, subject to the following conditions:
42
+ *
43
+ * The above copyright notice and this permission notice shall be included in
44
+ * all copies or substantial portions of the Software.
45
+ *
46
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ * THE SOFTWARE.
53
+ */
54
+#ifndef HCD_DWC3_H
55
+#define HCD_DWC3_H
56
+
26
+
57
+#include "hw/usb/hcd-xhci.h"
27
+ /* Connect input buffer on pins 1-7, configure SENSE for high level */
58
+#include "hw/usb/hcd-xhci-sysbus.h"
28
+ for (i = 1; i <= 7; i++) {
59
+
29
+ qtest_writel(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START + i * 4,
60
+#define TYPE_USB_DWC3 "usb_dwc3"
30
+ deposit32(0, 16, 2, 2));
61
+
62
+#define USB_DWC3(obj) \
63
+ OBJECT_CHECK(USBDWC3, (obj), TYPE_USB_DWC3)
64
+
65
+#define USB_DWC3_R_MAX ((0x530 / 4) + 1)
66
+#define DWC3_SIZE 0x10000
67
+
68
+typedef struct USBDWC3 {
69
+ SysBusDevice parent_obj;
70
+ MemoryRegion iomem;
71
+ XHCISysbusState sysbus_xhci;
72
+
73
+ uint32_t regs[USB_DWC3_R_MAX];
74
+ RegisterInfo regs_info[USB_DWC3_R_MAX];
75
+
76
+ struct {
77
+ uint8_t mode;
78
+ uint32_t dwc_usb3_user;
79
+ } cfg;
80
+
81
+} USBDWC3;
82
+
83
+#endif
84
diff --git a/hw/usb/hcd-dwc3.c b/hw/usb/hcd-dwc3.c
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/hw/usb/hcd-dwc3.c
89
@@ -XXX,XX +XXX,XX @@
90
+/*
91
+ * QEMU model of the USB DWC3 host controller emulation.
92
+ *
93
+ * This model defines global register space of DWC3 controller. Global
94
+ * registers control the AXI/AHB interfaces properties, external FIFO support
95
+ * and event count support. All of which are unimplemented at present. We are
96
+ * only supporting core reset and read of ID register.
97
+ *
98
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal<fnu.vikram@xilinx.com>
99
+ *
100
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
101
+ * of this software and associated documentation files (the "Software"), to deal
102
+ * in the Software without restriction, including without limitation the rights
103
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
104
+ * copies of the Software, and to permit persons to whom the Software is
105
+ * furnished to do so, subject to the following conditions:
106
+ *
107
+ * The above copyright notice and this permission notice shall be included in
108
+ * all copies or substantial portions of the Software.
109
+ *
110
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
111
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
112
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
113
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
114
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
115
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
116
+ * THE SOFTWARE.
117
+ */
118
+
119
+#include "qemu/osdep.h"
120
+#include "hw/sysbus.h"
121
+#include "hw/register.h"
122
+#include "qemu/bitops.h"
123
+#include "qemu/log.h"
124
+#include "qom/object.h"
125
+#include "migration/vmstate.h"
126
+#include "hw/qdev-properties.h"
127
+#include "hw/usb/hcd-dwc3.h"
128
+#include "qapi/error.h"
129
+
130
+#ifndef USB_DWC3_ERR_DEBUG
131
+#define USB_DWC3_ERR_DEBUG 0
132
+#endif
133
+
134
+#define HOST_MODE 1
135
+#define FIFO_LEN 0x1000
136
+
137
+REG32(GSBUSCFG0, 0x00)
138
+ FIELD(GSBUSCFG0, DATRDREQINFO, 28, 4)
139
+ FIELD(GSBUSCFG0, DESRDREQINFO, 24, 4)
140
+ FIELD(GSBUSCFG0, DATWRREQINFO, 20, 4)
141
+ FIELD(GSBUSCFG0, DESWRREQINFO, 16, 4)
142
+ FIELD(GSBUSCFG0, RESERVED_15_12, 12, 4)
143
+ FIELD(GSBUSCFG0, DATBIGEND, 11, 1)
144
+ FIELD(GSBUSCFG0, DESBIGEND, 10, 1)
145
+ FIELD(GSBUSCFG0, RESERVED_9_8, 8, 2)
146
+ FIELD(GSBUSCFG0, INCR256BRSTENA, 7, 1)
147
+ FIELD(GSBUSCFG0, INCR128BRSTENA, 6, 1)
148
+ FIELD(GSBUSCFG0, INCR64BRSTENA, 5, 1)
149
+ FIELD(GSBUSCFG0, INCR32BRSTENA, 4, 1)
150
+ FIELD(GSBUSCFG0, INCR16BRSTENA, 3, 1)
151
+ FIELD(GSBUSCFG0, INCR8BRSTENA, 2, 1)
152
+ FIELD(GSBUSCFG0, INCR4BRSTENA, 1, 1)
153
+ FIELD(GSBUSCFG0, INCRBRSTENA, 0, 1)
154
+REG32(GSBUSCFG1, 0x04)
155
+ FIELD(GSBUSCFG1, RESERVED_31_13, 13, 19)
156
+ FIELD(GSBUSCFG1, EN1KPAGE, 12, 1)
157
+ FIELD(GSBUSCFG1, PIPETRANSLIMIT, 8, 4)
158
+ FIELD(GSBUSCFG1, RESERVED_7_0, 0, 8)
159
+REG32(GTXTHRCFG, 0x08)
160
+ FIELD(GTXTHRCFG, RESERVED_31, 31, 1)
161
+ FIELD(GTXTHRCFG, RESERVED_30, 30, 1)
162
+ FIELD(GTXTHRCFG, USBTXPKTCNTSEL, 29, 1)
163
+ FIELD(GTXTHRCFG, RESERVED_28, 28, 1)
164
+ FIELD(GTXTHRCFG, USBTXPKTCNT, 24, 4)
165
+ FIELD(GTXTHRCFG, USBMAXTXBURSTSIZE, 16, 8)
166
+ FIELD(GTXTHRCFG, RESERVED_15, 15, 1)
167
+ FIELD(GTXTHRCFG, RESERVED_14, 14, 1)
168
+ FIELD(GTXTHRCFG, RESERVED_13_11, 11, 3)
169
+ FIELD(GTXTHRCFG, RESERVED_10_0, 0, 11)
170
+REG32(GRXTHRCFG, 0x0c)
171
+ FIELD(GRXTHRCFG, RESERVED_31_30, 30, 2)
172
+ FIELD(GRXTHRCFG, USBRXPKTCNTSEL, 29, 1)
173
+ FIELD(GRXTHRCFG, RESERVED_28, 28, 1)
174
+ FIELD(GRXTHRCFG, USBRXPKTCNT, 24, 4)
175
+ FIELD(GRXTHRCFG, USBMAXRXBURSTSIZE, 19, 5)
176
+ FIELD(GRXTHRCFG, RESERVED_18_16, 16, 3)
177
+ FIELD(GRXTHRCFG, RESERVED_15, 15, 1)
178
+ FIELD(GRXTHRCFG, RESERVED_14_13, 13, 2)
179
+ FIELD(GRXTHRCFG, RESVISOCOUTSPC, 0, 13)
180
+REG32(GCTL, 0x10)
181
+ FIELD(GCTL, PWRDNSCALE, 19, 13)
182
+ FIELD(GCTL, MASTERFILTBYPASS, 18, 1)
183
+ FIELD(GCTL, BYPSSETADDR, 17, 1)
184
+ FIELD(GCTL, U2RSTECN, 16, 1)
185
+ FIELD(GCTL, FRMSCLDWN, 14, 2)
186
+ FIELD(GCTL, PRTCAPDIR, 12, 2)
187
+ FIELD(GCTL, CORESOFTRESET, 11, 1)
188
+ FIELD(GCTL, U1U2TIMERSCALE, 9, 1)
189
+ FIELD(GCTL, DEBUGATTACH, 8, 1)
190
+ FIELD(GCTL, RAMCLKSEL, 6, 2)
191
+ FIELD(GCTL, SCALEDOWN, 4, 2)
192
+ FIELD(GCTL, DISSCRAMBLE, 3, 1)
193
+ FIELD(GCTL, U2EXIT_LFPS, 2, 1)
194
+ FIELD(GCTL, GBLHIBERNATIONEN, 1, 1)
195
+ FIELD(GCTL, DSBLCLKGTNG, 0, 1)
196
+REG32(GPMSTS, 0x14)
197
+REG32(GSTS, 0x18)
198
+ FIELD(GSTS, CBELT, 20, 12)
199
+ FIELD(GSTS, RESERVED_19_12, 12, 8)
200
+ FIELD(GSTS, SSIC_IP, 11, 1)
201
+ FIELD(GSTS, OTG_IP, 10, 1)
202
+ FIELD(GSTS, BC_IP, 9, 1)
203
+ FIELD(GSTS, ADP_IP, 8, 1)
204
+ FIELD(GSTS, HOST_IP, 7, 1)
205
+ FIELD(GSTS, DEVICE_IP, 6, 1)
206
+ FIELD(GSTS, CSRTIMEOUT, 5, 1)
207
+ FIELD(GSTS, BUSERRADDRVLD, 4, 1)
208
+ FIELD(GSTS, RESERVED_3_2, 2, 2)
209
+ FIELD(GSTS, CURMOD, 0, 2)
210
+REG32(GUCTL1, 0x1c)
211
+ FIELD(GUCTL1, RESUME_OPMODE_HS_HOST, 10, 1)
212
+REG32(GSNPSID, 0x20)
213
+REG32(GGPIO, 0x24)
214
+ FIELD(GGPIO, GPO, 16, 16)
215
+ FIELD(GGPIO, GPI, 0, 16)
216
+REG32(GUID, 0x28)
217
+REG32(GUCTL, 0x2c)
218
+ FIELD(GUCTL, REFCLKPER, 22, 10)
219
+ FIELD(GUCTL, NOEXTRDL, 21, 1)
220
+ FIELD(GUCTL, RESERVED_20_18, 18, 3)
221
+ FIELD(GUCTL, SPRSCTRLTRANSEN, 17, 1)
222
+ FIELD(GUCTL, RESBWHSEPS, 16, 1)
223
+ FIELD(GUCTL, RESERVED_15, 15, 1)
224
+ FIELD(GUCTL, USBHSTINAUTORETRYEN, 14, 1)
225
+ FIELD(GUCTL, ENOVERLAPCHK, 13, 1)
226
+ FIELD(GUCTL, EXTCAPSUPPTEN, 12, 1)
227
+ FIELD(GUCTL, INSRTEXTRFSBODI, 11, 1)
228
+ FIELD(GUCTL, DTCT, 9, 2)
229
+ FIELD(GUCTL, DTFT, 0, 9)
230
+REG32(GBUSERRADDRLO, 0x30)
231
+REG32(GBUSERRADDRHI, 0x34)
232
+REG32(GHWPARAMS0, 0x40)
233
+ FIELD(GHWPARAMS0, GHWPARAMS0_31_24, 24, 8)
234
+ FIELD(GHWPARAMS0, GHWPARAMS0_23_16, 16, 8)
235
+ FIELD(GHWPARAMS0, GHWPARAMS0_15_8, 8, 8)
236
+ FIELD(GHWPARAMS0, GHWPARAMS0_7_6, 6, 2)
237
+ FIELD(GHWPARAMS0, GHWPARAMS0_5_3, 3, 3)
238
+ FIELD(GHWPARAMS0, GHWPARAMS0_2_0, 0, 3)
239
+REG32(GHWPARAMS1, 0x44)
240
+ FIELD(GHWPARAMS1, GHWPARAMS1_31, 31, 1)
241
+ FIELD(GHWPARAMS1, GHWPARAMS1_30, 30, 1)
242
+ FIELD(GHWPARAMS1, GHWPARAMS1_29, 29, 1)
243
+ FIELD(GHWPARAMS1, GHWPARAMS1_28, 28, 1)
244
+ FIELD(GHWPARAMS1, GHWPARAMS1_27, 27, 1)
245
+ FIELD(GHWPARAMS1, GHWPARAMS1_26, 26, 1)
246
+ FIELD(GHWPARAMS1, GHWPARAMS1_25_24, 24, 2)
247
+ FIELD(GHWPARAMS1, GHWPARAMS1_23, 23, 1)
248
+ FIELD(GHWPARAMS1, GHWPARAMS1_22_21, 21, 2)
249
+ FIELD(GHWPARAMS1, GHWPARAMS1_20_15, 15, 6)
250
+ FIELD(GHWPARAMS1, GHWPARAMS1_14_12, 12, 3)
251
+ FIELD(GHWPARAMS1, GHWPARAMS1_11_9, 9, 3)
252
+ FIELD(GHWPARAMS1, GHWPARAMS1_8_6, 6, 3)
253
+ FIELD(GHWPARAMS1, GHWPARAMS1_5_3, 3, 3)
254
+ FIELD(GHWPARAMS1, GHWPARAMS1_2_0, 0, 3)
255
+REG32(GHWPARAMS2, 0x48)
256
+REG32(GHWPARAMS3, 0x4c)
257
+ FIELD(GHWPARAMS3, GHWPARAMS3_31, 31, 1)
258
+ FIELD(GHWPARAMS3, GHWPARAMS3_30_23, 23, 8)
259
+ FIELD(GHWPARAMS3, GHWPARAMS3_22_18, 18, 5)
260
+ FIELD(GHWPARAMS3, GHWPARAMS3_17_12, 12, 6)
261
+ FIELD(GHWPARAMS3, GHWPARAMS3_11, 11, 1)
262
+ FIELD(GHWPARAMS3, GHWPARAMS3_10, 10, 1)
263
+ FIELD(GHWPARAMS3, GHWPARAMS3_9_8, 8, 2)
264
+ FIELD(GHWPARAMS3, GHWPARAMS3_7_6, 6, 2)
265
+ FIELD(GHWPARAMS3, GHWPARAMS3_5_4, 4, 2)
266
+ FIELD(GHWPARAMS3, GHWPARAMS3_3_2, 2, 2)
267
+ FIELD(GHWPARAMS3, GHWPARAMS3_1_0, 0, 2)
268
+REG32(GHWPARAMS4, 0x50)
269
+ FIELD(GHWPARAMS4, GHWPARAMS4_31_28, 28, 4)
270
+ FIELD(GHWPARAMS4, GHWPARAMS4_27_24, 24, 4)
271
+ FIELD(GHWPARAMS4, GHWPARAMS4_23, 23, 1)
272
+ FIELD(GHWPARAMS4, GHWPARAMS4_22, 22, 1)
273
+ FIELD(GHWPARAMS4, GHWPARAMS4_21, 21, 1)
274
+ FIELD(GHWPARAMS4, GHWPARAMS4_20_17, 17, 4)
275
+ FIELD(GHWPARAMS4, GHWPARAMS4_16_13, 13, 4)
276
+ FIELD(GHWPARAMS4, GHWPARAMS4_12, 12, 1)
277
+ FIELD(GHWPARAMS4, GHWPARAMS4_11, 11, 1)
278
+ FIELD(GHWPARAMS4, GHWPARAMS4_10_9, 9, 2)
279
+ FIELD(GHWPARAMS4, GHWPARAMS4_8_7, 7, 2)
280
+ FIELD(GHWPARAMS4, GHWPARAMS4_6, 6, 1)
281
+ FIELD(GHWPARAMS4, GHWPARAMS4_5_0, 0, 6)
282
+REG32(GHWPARAMS5, 0x54)
283
+ FIELD(GHWPARAMS5, GHWPARAMS5_31_28, 28, 4)
284
+ FIELD(GHWPARAMS5, GHWPARAMS5_27_22, 22, 6)
285
+ FIELD(GHWPARAMS5, GHWPARAMS5_21_16, 16, 6)
286
+ FIELD(GHWPARAMS5, GHWPARAMS5_15_10, 10, 6)
287
+ FIELD(GHWPARAMS5, GHWPARAMS5_9_4, 4, 6)
288
+ FIELD(GHWPARAMS5, GHWPARAMS5_3_0, 0, 4)
289
+REG32(GHWPARAMS6, 0x58)
290
+ FIELD(GHWPARAMS6, GHWPARAMS6_31_16, 16, 16)
291
+ FIELD(GHWPARAMS6, BUSFLTRSSUPPORT, 15, 1)
292
+ FIELD(GHWPARAMS6, BCSUPPORT, 14, 1)
293
+ FIELD(GHWPARAMS6, OTG_SS_SUPPORT, 13, 1)
294
+ FIELD(GHWPARAMS6, ADPSUPPORT, 12, 1)
295
+ FIELD(GHWPARAMS6, HNPSUPPORT, 11, 1)
296
+ FIELD(GHWPARAMS6, SRPSUPPORT, 10, 1)
297
+ FIELD(GHWPARAMS6, GHWPARAMS6_9_8, 8, 2)
298
+ FIELD(GHWPARAMS6, GHWPARAMS6_7, 7, 1)
299
+ FIELD(GHWPARAMS6, GHWPARAMS6_6, 6, 1)
300
+ FIELD(GHWPARAMS6, GHWPARAMS6_5_0, 0, 6)
301
+REG32(GHWPARAMS7, 0x5c)
302
+ FIELD(GHWPARAMS7, GHWPARAMS7_31_16, 16, 16)
303
+ FIELD(GHWPARAMS7, GHWPARAMS7_15_0, 0, 16)
304
+REG32(GDBGFIFOSPACE, 0x60)
305
+ FIELD(GDBGFIFOSPACE, SPACE_AVAILABLE, 16, 16)
306
+ FIELD(GDBGFIFOSPACE, RESERVED_15_9, 9, 7)
307
+ FIELD(GDBGFIFOSPACE, FIFO_QUEUE_SELECT, 0, 9)
308
+REG32(GUCTL2, 0x9c)
309
+ FIELD(GUCTL2, RESERVED_31_26, 26, 6)
310
+ FIELD(GUCTL2, EN_HP_PM_TIMER, 19, 7)
311
+ FIELD(GUCTL2, NOLOWPWRDUR, 15, 4)
312
+ FIELD(GUCTL2, RST_ACTBITLATER, 14, 1)
313
+ FIELD(GUCTL2, RESERVED_13, 13, 1)
314
+ FIELD(GUCTL2, DISABLECFC, 11, 1)
315
+REG32(GUSB2PHYCFG, 0x100)
316
+ FIELD(GUSB2PHYCFG, U2_FREECLK_EXISTS, 30, 1)
317
+ FIELD(GUSB2PHYCFG, ULPI_LPM_WITH_OPMODE_CHK, 29, 1)
318
+ FIELD(GUSB2PHYCFG, RESERVED_25, 25, 1)
319
+ FIELD(GUSB2PHYCFG, LSTRD, 22, 3)
320
+ FIELD(GUSB2PHYCFG, LSIPD, 19, 3)
321
+ FIELD(GUSB2PHYCFG, ULPIEXTVBUSINDIACTOR, 18, 1)
322
+ FIELD(GUSB2PHYCFG, ULPIEXTVBUSDRV, 17, 1)
323
+ FIELD(GUSB2PHYCFG, RESERVED_16, 16, 1)
324
+ FIELD(GUSB2PHYCFG, ULPIAUTORES, 15, 1)
325
+ FIELD(GUSB2PHYCFG, RESERVED_14, 14, 1)
326
+ FIELD(GUSB2PHYCFG, USBTRDTIM, 10, 4)
327
+ FIELD(GUSB2PHYCFG, XCVRDLY, 9, 1)
328
+ FIELD(GUSB2PHYCFG, ENBLSLPM, 8, 1)
329
+ FIELD(GUSB2PHYCFG, PHYSEL, 7, 1)
330
+ FIELD(GUSB2PHYCFG, SUSPENDUSB20, 6, 1)
331
+ FIELD(GUSB2PHYCFG, FSINTF, 5, 1)
332
+ FIELD(GUSB2PHYCFG, ULPI_UTMI_SEL, 4, 1)
333
+ FIELD(GUSB2PHYCFG, PHYIF, 3, 1)
334
+ FIELD(GUSB2PHYCFG, TOUTCAL, 0, 3)
335
+REG32(GUSB2I2CCTL, 0x140)
336
+REG32(GUSB2PHYACC_ULPI, 0x180)
337
+ FIELD(GUSB2PHYACC_ULPI, RESERVED_31_27, 27, 5)
338
+ FIELD(GUSB2PHYACC_ULPI, DISUIPIDRVR, 26, 1)
339
+ FIELD(GUSB2PHYACC_ULPI, NEWREGREQ, 25, 1)
340
+ FIELD(GUSB2PHYACC_ULPI, VSTSDONE, 24, 1)
341
+ FIELD(GUSB2PHYACC_ULPI, VSTSBSY, 23, 1)
342
+ FIELD(GUSB2PHYACC_ULPI, REGWR, 22, 1)
343
+ FIELD(GUSB2PHYACC_ULPI, REGADDR, 16, 6)
344
+ FIELD(GUSB2PHYACC_ULPI, EXTREGADDR, 8, 8)
345
+ FIELD(GUSB2PHYACC_ULPI, REGDATA, 0, 8)
346
+REG32(GTXFIFOSIZ0, 0x200)
347
+ FIELD(GTXFIFOSIZ0, TXFSTADDR_N, 16, 16)
348
+ FIELD(GTXFIFOSIZ0, TXFDEP_N, 0, 16)
349
+REG32(GTXFIFOSIZ1, 0x204)
350
+ FIELD(GTXFIFOSIZ1, TXFSTADDR_N, 16, 16)
351
+ FIELD(GTXFIFOSIZ1, TXFDEP_N, 0, 16)
352
+REG32(GTXFIFOSIZ2, 0x208)
353
+ FIELD(GTXFIFOSIZ2, TXFSTADDR_N, 16, 16)
354
+ FIELD(GTXFIFOSIZ2, TXFDEP_N, 0, 16)
355
+REG32(GTXFIFOSIZ3, 0x20c)
356
+ FIELD(GTXFIFOSIZ3, TXFSTADDR_N, 16, 16)
357
+ FIELD(GTXFIFOSIZ3, TXFDEP_N, 0, 16)
358
+REG32(GTXFIFOSIZ4, 0x210)
359
+ FIELD(GTXFIFOSIZ4, TXFSTADDR_N, 16, 16)
360
+ FIELD(GTXFIFOSIZ4, TXFDEP_N, 0, 16)
361
+REG32(GTXFIFOSIZ5, 0x214)
362
+ FIELD(GTXFIFOSIZ5, TXFSTADDR_N, 16, 16)
363
+ FIELD(GTXFIFOSIZ5, TXFDEP_N, 0, 16)
364
+REG32(GRXFIFOSIZ0, 0x280)
365
+ FIELD(GRXFIFOSIZ0, RXFSTADDR_N, 16, 16)
366
+ FIELD(GRXFIFOSIZ0, RXFDEP_N, 0, 16)
367
+REG32(GRXFIFOSIZ1, 0x284)
368
+ FIELD(GRXFIFOSIZ1, RXFSTADDR_N, 16, 16)
369
+ FIELD(GRXFIFOSIZ1, RXFDEP_N, 0, 16)
370
+REG32(GRXFIFOSIZ2, 0x288)
371
+ FIELD(GRXFIFOSIZ2, RXFSTADDR_N, 16, 16)
372
+ FIELD(GRXFIFOSIZ2, RXFDEP_N, 0, 16)
373
+REG32(GEVNTADRLO_0, 0x300)
374
+REG32(GEVNTADRHI_0, 0x304)
375
+REG32(GEVNTSIZ_0, 0x308)
376
+ FIELD(GEVNTSIZ_0, EVNTINTRPTMASK, 31, 1)
377
+ FIELD(GEVNTSIZ_0, RESERVED_30_16, 16, 15)
378
+ FIELD(GEVNTSIZ_0, EVENTSIZ, 0, 16)
379
+REG32(GEVNTCOUNT_0, 0x30c)
380
+ FIELD(GEVNTCOUNT_0, EVNT_HANDLER_BUSY, 31, 1)
381
+ FIELD(GEVNTCOUNT_0, RESERVED_30_16, 16, 15)
382
+ FIELD(GEVNTCOUNT_0, EVNTCOUNT, 0, 16)
383
+REG32(GEVNTADRLO_1, 0x310)
384
+REG32(GEVNTADRHI_1, 0x314)
385
+REG32(GEVNTSIZ_1, 0x318)
386
+ FIELD(GEVNTSIZ_1, EVNTINTRPTMASK, 31, 1)
387
+ FIELD(GEVNTSIZ_1, RESERVED_30_16, 16, 15)
388
+ FIELD(GEVNTSIZ_1, EVENTSIZ, 0, 16)
389
+REG32(GEVNTCOUNT_1, 0x31c)
390
+ FIELD(GEVNTCOUNT_1, EVNT_HANDLER_BUSY, 31, 1)
391
+ FIELD(GEVNTCOUNT_1, RESERVED_30_16, 16, 15)
392
+ FIELD(GEVNTCOUNT_1, EVNTCOUNT, 0, 16)
393
+REG32(GEVNTADRLO_2, 0x320)
394
+REG32(GEVNTADRHI_2, 0x324)
395
+REG32(GEVNTSIZ_2, 0x328)
396
+ FIELD(GEVNTSIZ_2, EVNTINTRPTMASK, 31, 1)
397
+ FIELD(GEVNTSIZ_2, RESERVED_30_16, 16, 15)
398
+ FIELD(GEVNTSIZ_2, EVENTSIZ, 0, 16)
399
+REG32(GEVNTCOUNT_2, 0x32c)
400
+ FIELD(GEVNTCOUNT_2, EVNT_HANDLER_BUSY, 31, 1)
401
+ FIELD(GEVNTCOUNT_2, RESERVED_30_16, 16, 15)
402
+ FIELD(GEVNTCOUNT_2, EVNTCOUNT, 0, 16)
403
+REG32(GEVNTADRLO_3, 0x330)
404
+REG32(GEVNTADRHI_3, 0x334)
405
+REG32(GEVNTSIZ_3, 0x338)
406
+ FIELD(GEVNTSIZ_3, EVNTINTRPTMASK, 31, 1)
407
+ FIELD(GEVNTSIZ_3, RESERVED_30_16, 16, 15)
408
+ FIELD(GEVNTSIZ_3, EVENTSIZ, 0, 16)
409
+REG32(GEVNTCOUNT_3, 0x33c)
410
+ FIELD(GEVNTCOUNT_3, EVNT_HANDLER_BUSY, 31, 1)
411
+ FIELD(GEVNTCOUNT_3, RESERVED_30_16, 16, 15)
412
+ FIELD(GEVNTCOUNT_3, EVNTCOUNT, 0, 16)
413
+REG32(GHWPARAMS8, 0x500)
414
+REG32(GTXFIFOPRIDEV, 0x510)
415
+ FIELD(GTXFIFOPRIDEV, RESERVED_31_N, 6, 26)
416
+ FIELD(GTXFIFOPRIDEV, GTXFIFOPRIDEV, 0, 6)
417
+REG32(GTXFIFOPRIHST, 0x518)
418
+ FIELD(GTXFIFOPRIHST, RESERVED_31_16, 3, 29)
419
+ FIELD(GTXFIFOPRIHST, GTXFIFOPRIHST, 0, 3)
420
+REG32(GRXFIFOPRIHST, 0x51c)
421
+ FIELD(GRXFIFOPRIHST, RESERVED_31_16, 3, 29)
422
+ FIELD(GRXFIFOPRIHST, GRXFIFOPRIHST, 0, 3)
423
+REG32(GDMAHLRATIO, 0x524)
424
+ FIELD(GDMAHLRATIO, RESERVED_31_13, 13, 19)
425
+ FIELD(GDMAHLRATIO, HSTRXFIFO, 8, 5)
426
+ FIELD(GDMAHLRATIO, RESERVED_7_5, 5, 3)
427
+ FIELD(GDMAHLRATIO, HSTTXFIFO, 0, 5)
428
+REG32(GFLADJ, 0x530)
429
+ FIELD(GFLADJ, GFLADJ_REFCLK_240MHZDECR_PLS1, 31, 1)
430
+ FIELD(GFLADJ, GFLADJ_REFCLK_240MHZ_DECR, 24, 7)
431
+ FIELD(GFLADJ, GFLADJ_REFCLK_LPM_SEL, 23, 1)
432
+ FIELD(GFLADJ, RESERVED_22, 22, 1)
433
+ FIELD(GFLADJ, GFLADJ_REFCLK_FLADJ, 8, 14)
434
+ FIELD(GFLADJ, GFLADJ_30MHZ_SDBND_SEL, 7, 1)
435
+ FIELD(GFLADJ, GFLADJ_30MHZ, 0, 6)
436
+
437
+#define DWC3_GLOBAL_OFFSET 0xC100
438
+static void reset_csr(USBDWC3 * s)
439
+{
440
+ int i = 0;
441
+ /*
442
+ * We reset all CSR regs except GCTL, GUCTL, GSTS, GSNPSID, GGPIO, GUID,
443
+ * GUSB2PHYCFGn registers and GUSB3PIPECTLn registers. We will skip PHY
444
+ * register as we don't implement them.
445
+ */
446
+ for (i = 0; i < USB_DWC3_R_MAX; i++) {
447
+ switch (i) {
448
+ case R_GCTL:
449
+ break;
450
+ case R_GSTS:
451
+ break;
452
+ case R_GSNPSID:
453
+ break;
454
+ case R_GGPIO:
455
+ break;
456
+ case R_GUID:
457
+ break;
458
+ case R_GUCTL:
459
+ break;
460
+ case R_GHWPARAMS0...R_GHWPARAMS7:
461
+ break;
462
+ case R_GHWPARAMS8:
463
+ break;
464
+ default:
465
+ register_reset(&s->regs_info[i]);
466
+ break;
467
+ }
468
+ }
31
+ }
469
+
32
+
470
+ xhci_sysbus_reset(DEVICE(&s->sysbus_xhci));
33
+ qtest_irq_intercept_out_named(qts, "/machine/nrf51/gpio", "detect");
34
+
35
+ for (i = 1; i <= 7; i++) {
36
+ /* Set pin high */
37
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", i, 1);
38
+ uint32_t actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN);
39
+ g_assert_cmpuint(actual, ==, 1 << i);
40
+
41
+ /* Check that DETECT is high */
42
+ g_assert_true(qtest_get_irq(qts, 0));
43
+
44
+ /* Set pin low, check that DETECT goes low. */
45
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", i, 0);
46
+ actual = qtest_readl(qts, NRF51_GPIO_BASE + NRF51_GPIO_REG_IN);
47
+ g_assert_cmpuint(actual, ==, 0x0);
48
+ g_assert_false(qtest_get_irq(qts, 0));
49
+ }
50
+
51
+ /* Set pin 0 high, check that DETECT doesn't fire */
52
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 1);
53
+ g_assert_false(qtest_get_irq(qts, 0));
54
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
55
+
56
+ /* Set pins 1, 2, and 3 high, then set 3 low. Check DETECT is still high */
57
+ for (i = 1; i <= 3; i++) {
58
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", i, 1);
59
+ }
60
+ g_assert_true(qtest_get_irq(qts, 0));
61
+ qtest_set_irq_in(qts, "/machine/nrf51", "unnamed-gpio-in", 3, 0);
62
+ g_assert_true(qtest_get_irq(qts, 0));
471
+}
63
+}
472
+
64
+
473
+static void usb_dwc3_gctl_postw(RegisterInfo *reg, uint64_t val64)
65
static void timer_task(QTestState *qts, hwaddr task)
474
+{
66
{
475
+ USBDWC3 *s = USB_DWC3(reg->opaque);
67
qtest_writel(qts, NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK);
476
+
68
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
477
+ if (ARRAY_FIELD_EX32(s->regs, GCTL, CORESOFTRESET)) {
69
478
+ reset_csr(s);
70
qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart);
479
+ }
71
qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
480
+}
72
+ qtest_add_func("/microbit/nrf51/gpio_detect", test_nrf51_gpio_detect);
481
+
73
qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
482
+static void usb_dwc3_guid_postw(RegisterInfo *reg, uint64_t val64)
74
qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
483
+{
75
qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c);
484
+ USBDWC3 *s = USB_DWC3(reg->opaque);
485
+
486
+ s->regs[R_GUID] = s->cfg.dwc_usb3_user;
487
+}
488
+
489
+static const RegisterAccessInfo usb_dwc3_regs_info[] = {
490
+ { .name = "GSBUSCFG0", .addr = A_GSBUSCFG0,
491
+ .ro = 0xf300,
492
+ .unimp = 0xffffffff,
493
+ },{ .name = "GSBUSCFG1", .addr = A_GSBUSCFG1,
494
+ .reset = 0x300,
495
+ .ro = 0xffffe0ff,
496
+ .unimp = 0xffffffff,
497
+ },{ .name = "GTXTHRCFG", .addr = A_GTXTHRCFG,
498
+ .ro = 0xd000ffff,
499
+ .unimp = 0xffffffff,
500
+ },{ .name = "GRXTHRCFG", .addr = A_GRXTHRCFG,
501
+ .ro = 0xd007e000,
502
+ .unimp = 0xffffffff,
503
+ },{ .name = "GCTL", .addr = A_GCTL,
504
+ .reset = 0x30c13004, .post_write = usb_dwc3_gctl_postw,
505
+ },{ .name = "GPMSTS", .addr = A_GPMSTS,
506
+ .ro = 0xfffffff,
507
+ .unimp = 0xffffffff,
508
+ },{ .name = "GSTS", .addr = A_GSTS,
509
+ .reset = 0x7e800000,
510
+ .ro = 0xffffffcf,
511
+ .w1c = 0x30,
512
+ .unimp = 0xffffffff,
513
+ },{ .name = "GUCTL1", .addr = A_GUCTL1,
514
+ .reset = 0x198a,
515
+ .ro = 0x7800,
516
+ .unimp = 0xffffffff,
517
+ },{ .name = "GSNPSID", .addr = A_GSNPSID,
518
+ .reset = 0x5533330a,
519
+ .ro = 0xffffffff,
520
+ },{ .name = "GGPIO", .addr = A_GGPIO,
521
+ .ro = 0xffff,
522
+ .unimp = 0xffffffff,
523
+ },{ .name = "GUID", .addr = A_GUID,
524
+ .reset = 0x12345678, .post_write = usb_dwc3_guid_postw,
525
+ },{ .name = "GUCTL", .addr = A_GUCTL,
526
+ .reset = 0x0c808010,
527
+ .ro = 0x1c8000,
528
+ .unimp = 0xffffffff,
529
+ },{ .name = "GBUSERRADDRLO", .addr = A_GBUSERRADDRLO,
530
+ .ro = 0xffffffff,
531
+ },{ .name = "GBUSERRADDRHI", .addr = A_GBUSERRADDRHI,
532
+ .ro = 0xffffffff,
533
+ },{ .name = "GHWPARAMS0", .addr = A_GHWPARAMS0,
534
+ .ro = 0xffffffff,
535
+ },{ .name = "GHWPARAMS1", .addr = A_GHWPARAMS1,
536
+ .ro = 0xffffffff,
537
+ },{ .name = "GHWPARAMS2", .addr = A_GHWPARAMS2,
538
+ .ro = 0xffffffff,
539
+ },{ .name = "GHWPARAMS3", .addr = A_GHWPARAMS3,
540
+ .ro = 0xffffffff,
541
+ },{ .name = "GHWPARAMS4", .addr = A_GHWPARAMS4,
542
+ .ro = 0xffffffff,
543
+ },{ .name = "GHWPARAMS5", .addr = A_GHWPARAMS5,
544
+ .ro = 0xffffffff,
545
+ },{ .name = "GHWPARAMS6", .addr = A_GHWPARAMS6,
546
+ .ro = 0xffffffff,
547
+ },{ .name = "GHWPARAMS7", .addr = A_GHWPARAMS7,
548
+ .ro = 0xffffffff,
549
+ },{ .name = "GDBGFIFOSPACE", .addr = A_GDBGFIFOSPACE,
550
+ .reset = 0xa0000,
551
+ .ro = 0xfffffe00,
552
+ .unimp = 0xffffffff,
553
+ },{ .name = "GUCTL2", .addr = A_GUCTL2,
554
+ .reset = 0x40d,
555
+ .ro = 0x2000,
556
+ .unimp = 0xffffffff,
557
+ },{ .name = "GUSB2PHYCFG", .addr = A_GUSB2PHYCFG,
558
+ .reset = 0x40102410,
559
+ .ro = 0x1e014030,
560
+ .unimp = 0xffffffff,
561
+ },{ .name = "GUSB2I2CCTL", .addr = A_GUSB2I2CCTL,
562
+ .ro = 0xffffffff,
563
+ .unimp = 0xffffffff,
564
+ },{ .name = "GUSB2PHYACC_ULPI", .addr = A_GUSB2PHYACC_ULPI,
565
+ .ro = 0xfd000000,
566
+ .unimp = 0xffffffff,
567
+ },{ .name = "GTXFIFOSIZ0", .addr = A_GTXFIFOSIZ0,
568
+ .reset = 0x2c7000a,
569
+ .unimp = 0xffffffff,
570
+ },{ .name = "GTXFIFOSIZ1", .addr = A_GTXFIFOSIZ1,
571
+ .reset = 0x2d10103,
572
+ .unimp = 0xffffffff,
573
+ },{ .name = "GTXFIFOSIZ2", .addr = A_GTXFIFOSIZ2,
574
+ .reset = 0x3d40103,
575
+ .unimp = 0xffffffff,
576
+ },{ .name = "GTXFIFOSIZ3", .addr = A_GTXFIFOSIZ3,
577
+ .reset = 0x4d70083,
578
+ .unimp = 0xffffffff,
579
+ },{ .name = "GTXFIFOSIZ4", .addr = A_GTXFIFOSIZ4,
580
+ .reset = 0x55a0083,
581
+ .unimp = 0xffffffff,
582
+ },{ .name = "GTXFIFOSIZ5", .addr = A_GTXFIFOSIZ5,
583
+ .reset = 0x5dd0083,
584
+ .unimp = 0xffffffff,
585
+ },{ .name = "GRXFIFOSIZ0", .addr = A_GRXFIFOSIZ0,
586
+ .reset = 0x1c20105,
587
+ .unimp = 0xffffffff,
588
+ },{ .name = "GRXFIFOSIZ1", .addr = A_GRXFIFOSIZ1,
589
+ .reset = 0x2c70000,
590
+ .unimp = 0xffffffff,
591
+ },{ .name = "GRXFIFOSIZ2", .addr = A_GRXFIFOSIZ2,
592
+ .reset = 0x2c70000,
593
+ .unimp = 0xffffffff,
594
+ },{ .name = "GEVNTADRLO_0", .addr = A_GEVNTADRLO_0,
595
+ .unimp = 0xffffffff,
596
+ },{ .name = "GEVNTADRHI_0", .addr = A_GEVNTADRHI_0,
597
+ .unimp = 0xffffffff,
598
+ },{ .name = "GEVNTSIZ_0", .addr = A_GEVNTSIZ_0,
599
+ .ro = 0x7fff0000,
600
+ .unimp = 0xffffffff,
601
+ },{ .name = "GEVNTCOUNT_0", .addr = A_GEVNTCOUNT_0,
602
+ .ro = 0x7fff0000,
603
+ .unimp = 0xffffffff,
604
+ },{ .name = "GEVNTADRLO_1", .addr = A_GEVNTADRLO_1,
605
+ .unimp = 0xffffffff,
606
+ },{ .name = "GEVNTADRHI_1", .addr = A_GEVNTADRHI_1,
607
+ .unimp = 0xffffffff,
608
+ },{ .name = "GEVNTSIZ_1", .addr = A_GEVNTSIZ_1,
609
+ .ro = 0x7fff0000,
610
+ .unimp = 0xffffffff,
611
+ },{ .name = "GEVNTCOUNT_1", .addr = A_GEVNTCOUNT_1,
612
+ .ro = 0x7fff0000,
613
+ .unimp = 0xffffffff,
614
+ },{ .name = "GEVNTADRLO_2", .addr = A_GEVNTADRLO_2,
615
+ .unimp = 0xffffffff,
616
+ },{ .name = "GEVNTADRHI_2", .addr = A_GEVNTADRHI_2,
617
+ .unimp = 0xffffffff,
618
+ },{ .name = "GEVNTSIZ_2", .addr = A_GEVNTSIZ_2,
619
+ .ro = 0x7fff0000,
620
+ .unimp = 0xffffffff,
621
+ },{ .name = "GEVNTCOUNT_2", .addr = A_GEVNTCOUNT_2,
622
+ .ro = 0x7fff0000,
623
+ .unimp = 0xffffffff,
624
+ },{ .name = "GEVNTADRLO_3", .addr = A_GEVNTADRLO_3,
625
+ .unimp = 0xffffffff,
626
+ },{ .name = "GEVNTADRHI_3", .addr = A_GEVNTADRHI_3,
627
+ .unimp = 0xffffffff,
628
+ },{ .name = "GEVNTSIZ_3", .addr = A_GEVNTSIZ_3,
629
+ .ro = 0x7fff0000,
630
+ .unimp = 0xffffffff,
631
+ },{ .name = "GEVNTCOUNT_3", .addr = A_GEVNTCOUNT_3,
632
+ .ro = 0x7fff0000,
633
+ .unimp = 0xffffffff,
634
+ },{ .name = "GHWPARAMS8", .addr = A_GHWPARAMS8,
635
+ .ro = 0xffffffff,
636
+ },{ .name = "GTXFIFOPRIDEV", .addr = A_GTXFIFOPRIDEV,
637
+ .ro = 0xffffffc0,
638
+ .unimp = 0xffffffff,
639
+ },{ .name = "GTXFIFOPRIHST", .addr = A_GTXFIFOPRIHST,
640
+ .ro = 0xfffffff8,
641
+ .unimp = 0xffffffff,
642
+ },{ .name = "GRXFIFOPRIHST", .addr = A_GRXFIFOPRIHST,
643
+ .ro = 0xfffffff8,
644
+ .unimp = 0xffffffff,
645
+ },{ .name = "GDMAHLRATIO", .addr = A_GDMAHLRATIO,
646
+ .ro = 0xffffe0e0,
647
+ .unimp = 0xffffffff,
648
+ },{ .name = "GFLADJ", .addr = A_GFLADJ,
649
+ .reset = 0xc83f020,
650
+ .rsvd = 0x40,
651
+ .ro = 0x400040,
652
+ .unimp = 0xffffffff,
653
+ }
654
+};
655
+
656
+static void usb_dwc3_reset(DeviceState *dev)
657
+{
658
+ USBDWC3 *s = USB_DWC3(dev);
659
+ unsigned int i;
660
+
661
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
662
+ switch (i) {
663
+ case R_GHWPARAMS0...R_GHWPARAMS7:
664
+ break;
665
+ case R_GHWPARAMS8:
666
+ break;
667
+ default:
668
+ register_reset(&s->regs_info[i]);
669
+ };
670
+ }
671
+
672
+ xhci_sysbus_reset(DEVICE(&s->sysbus_xhci));
673
+}
674
+
675
+static const MemoryRegionOps usb_dwc3_ops = {
676
+ .read = register_read_memory,
677
+ .write = register_write_memory,
678
+ .endianness = DEVICE_LITTLE_ENDIAN,
679
+ .valid = {
680
+ .min_access_size = 4,
681
+ .max_access_size = 4,
682
+ },
683
+};
684
+
685
+static void usb_dwc3_realize(DeviceState *dev, Error **errp)
686
+{
687
+ USBDWC3 *s = USB_DWC3(dev);
688
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
689
+ Error *err = NULL;
690
+
691
+ sysbus_realize(SYS_BUS_DEVICE(&s->sysbus_xhci), &err);
692
+ if (err) {
693
+ error_propagate(errp, err);
694
+ return;
695
+ }
696
+
697
+ memory_region_add_subregion(&s->iomem, 0,
698
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sysbus_xhci), 0));
699
+ sysbus_init_mmio(sbd, &s->iomem);
700
+
701
+ /*
702
+ * Device Configuration
703
+ */
704
+ s->regs[R_GHWPARAMS0] = 0x40204048 | s->cfg.mode;
705
+ s->regs[R_GHWPARAMS1] = 0x222493b;
706
+ s->regs[R_GHWPARAMS2] = 0x12345678;
707
+ s->regs[R_GHWPARAMS3] = 0x618c088;
708
+ s->regs[R_GHWPARAMS4] = 0x47822004;
709
+ s->regs[R_GHWPARAMS5] = 0x4202088;
710
+ s->regs[R_GHWPARAMS6] = 0x7850c20;
711
+ s->regs[R_GHWPARAMS7] = 0x0;
712
+ s->regs[R_GHWPARAMS8] = 0x478;
713
+}
714
+
715
+static void usb_dwc3_init(Object *obj)
716
+{
717
+ USBDWC3 *s = USB_DWC3(obj);
718
+ RegisterInfoArray *reg_array;
719
+
720
+ memory_region_init(&s->iomem, obj, TYPE_USB_DWC3, DWC3_SIZE);
721
+ reg_array =
722
+ register_init_block32(DEVICE(obj), usb_dwc3_regs_info,
723
+ ARRAY_SIZE(usb_dwc3_regs_info),
724
+ s->regs_info, s->regs,
725
+ &usb_dwc3_ops,
726
+ USB_DWC3_ERR_DEBUG,
727
+ USB_DWC3_R_MAX * 4);
728
+ memory_region_add_subregion(&s->iomem,
729
+ DWC3_GLOBAL_OFFSET,
730
+ &reg_array->mem);
731
+ object_initialize_child(obj, "dwc3-xhci", &s->sysbus_xhci,
732
+ TYPE_XHCI_SYSBUS);
733
+ qdev_alias_all_properties(DEVICE(&s->sysbus_xhci), obj);
734
+
735
+ s->cfg.mode = HOST_MODE;
736
+}
737
+
738
+static const VMStateDescription vmstate_usb_dwc3 = {
739
+ .name = "usb-dwc3",
740
+ .version_id = 1,
741
+ .fields = (VMStateField[]) {
742
+ VMSTATE_UINT32_ARRAY(regs, USBDWC3, USB_DWC3_R_MAX),
743
+ VMSTATE_UINT8(cfg.mode, USBDWC3),
744
+ VMSTATE_UINT32(cfg.dwc_usb3_user, USBDWC3),
745
+ VMSTATE_END_OF_LIST()
746
+ }
747
+};
748
+
749
+static Property usb_dwc3_properties[] = {
750
+ DEFINE_PROP_UINT32("DWC_USB3_USERID", USBDWC3, cfg.dwc_usb3_user,
751
+ 0x12345678),
752
+ DEFINE_PROP_END_OF_LIST(),
753
+};
754
+
755
+static void usb_dwc3_class_init(ObjectClass *klass, void *data)
756
+{
757
+ DeviceClass *dc = DEVICE_CLASS(klass);
758
+
759
+ dc->reset = usb_dwc3_reset;
760
+ dc->realize = usb_dwc3_realize;
761
+ dc->vmsd = &vmstate_usb_dwc3;
762
+ device_class_set_props(dc, usb_dwc3_properties);
763
+}
764
+
765
+static const TypeInfo usb_dwc3_info = {
766
+ .name = TYPE_USB_DWC3,
767
+ .parent = TYPE_SYS_BUS_DEVICE,
768
+ .instance_size = sizeof(USBDWC3),
769
+ .class_init = usb_dwc3_class_init,
770
+ .instance_init = usb_dwc3_init,
771
+};
772
+
773
+static void usb_dwc3_register_types(void)
774
+{
775
+ type_register_static(&usb_dwc3_info);
776
+}
777
+
778
+type_init(usb_dwc3_register_types)
779
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
780
index XXXXXXX..XXXXXXX 100644
781
--- a/hw/usb/Kconfig
782
+++ b/hw/usb/Kconfig
783
@@ -XXX,XX +XXX,XX @@ config IMX_USBPHY
784
bool
785
default y
786
depends on USB
787
+
788
+config USB_DWC3
789
+ bool
790
+ select USB_XHCI_SYSBUS
791
+ select REGISTER
792
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
793
index XXXXXXX..XXXXXXX 100644
794
--- a/hw/usb/meson.build
795
+++ b/hw/usb/meson.build
796
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_USB_XHCI_SYSBUS', if_true: files('hcd-xhci-sysbus.c
797
softmmu_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: files('hcd-xhci-nec.c'))
798
softmmu_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c'))
799
softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
800
+softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c'))
801
802
softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
803
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
804
--
76
--
805
2.20.1
77
2.34.1
806
807
diff view generated by jsdifflib
New patch
1
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
3
kvm_arch_get_default_type() returns the default KVM type. This hook is
4
particularly useful to derive a KVM type that is valid for "none"
5
machine model, which is used by libvirt to probe the availability of
6
KVM.
7
8
For MIPS, the existing mips_kvm_type() is reused. This function ensures
9
the availability of VZ which is mandatory to use KVM on the current
10
QEMU.
11
12
Cc: qemu-stable@nongnu.org
13
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Message-id: 20230727073134.134102-2-akihiko.odaki@daynix.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
[PMM: added doc comment for new function]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
---
20
include/sysemu/kvm.h | 2 ++
21
target/mips/kvm_mips.h | 9 ---------
22
accel/kvm/kvm-all.c | 4 +++-
23
hw/mips/loongson3_virt.c | 2 --
24
target/arm/kvm.c | 5 +++++
25
target/i386/kvm/kvm.c | 5 +++++
26
target/mips/kvm.c | 2 +-
27
target/ppc/kvm.c | 5 +++++
28
target/riscv/kvm.c | 5 +++++
29
target/s390x/kvm/kvm.c | 5 +++++
30
10 files changed, 31 insertions(+), 13 deletions(-)
31
32
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/sysemu/kvm.h
35
+++ b/include/sysemu/kvm.h
36
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cpu);
37
38
int kvm_arch_put_registers(CPUState *cpu, int level);
39
40
+int kvm_arch_get_default_type(MachineState *ms);
41
+
42
int kvm_arch_init(MachineState *ms, KVMState *s);
43
44
int kvm_arch_init_vcpu(CPUState *cpu);
45
diff --git a/target/mips/kvm_mips.h b/target/mips/kvm_mips.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/mips/kvm_mips.h
48
+++ b/target/mips/kvm_mips.h
49
@@ -XXX,XX +XXX,XX @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
50
int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
51
int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
52
53
-#ifdef CONFIG_KVM
54
-int mips_kvm_type(MachineState *machine, const char *vm_type);
55
-#else
56
-static inline int mips_kvm_type(MachineState *machine, const char *vm_type)
57
-{
58
- return 0;
59
-}
60
-#endif
61
-
62
#endif /* KVM_MIPS_H */
63
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/accel/kvm/kvm-all.c
66
+++ b/accel/kvm/kvm-all.c
67
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
68
KVMState *s;
69
const KVMCapabilityInfo *missing_cap;
70
int ret;
71
- int type = 0;
72
+ int type;
73
uint64_t dirty_log_manual_caps;
74
75
qemu_mutex_init(&kml_slots_lock);
76
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
77
type = mc->kvm_type(ms, kvm_type);
78
} else if (mc->kvm_type) {
79
type = mc->kvm_type(ms, NULL);
80
+ } else {
81
+ type = kvm_arch_get_default_type(ms);
82
}
83
84
do {
85
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/mips/loongson3_virt.c
88
+++ b/hw/mips/loongson3_virt.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "qemu/datadir.h"
91
#include "qapi/error.h"
92
#include "elf.h"
93
-#include "kvm_mips.h"
94
#include "hw/char/serial.h"
95
#include "hw/intc/loongson_liointc.h"
96
#include "hw/mips/mips.h"
97
@@ -XXX,XX +XXX,XX @@ static void loongson3v_machine_class_init(ObjectClass *oc, void *data)
98
mc->max_cpus = LOONGSON_MAX_VCPUS;
99
mc->default_ram_id = "loongson3.highram";
100
mc->default_ram_size = 1600 * MiB;
101
- mc->kvm_type = mips_kvm_type;
102
mc->minimum_page_bits = 14;
103
mc->default_nic = "virtio-net-pci";
104
}
105
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/kvm.c
108
+++ b/target/arm/kvm.c
109
@@ -XXX,XX +XXX,XX @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
110
return ret > 0 ? ret : 40;
111
}
112
113
+int kvm_arch_get_default_type(MachineState *ms)
114
+{
115
+ return 0;
116
+}
117
+
118
int kvm_arch_init(MachineState *ms, KVMState *s)
119
{
120
int ret = 0;
121
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/i386/kvm/kvm.c
124
+++ b/target/i386/kvm/kvm.c
125
@@ -XXX,XX +XXX,XX @@ static void register_smram_listener(Notifier *n, void *unused)
126
&smram_address_space, 1, "kvm-smram");
127
}
128
129
+int kvm_arch_get_default_type(MachineState *ms)
130
+{
131
+ return 0;
132
+}
133
+
134
int kvm_arch_init(MachineState *ms, KVMState *s)
135
{
136
uint64_t identity_base = 0xfffbc000;
137
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/mips/kvm.c
140
+++ b/target/mips/kvm.c
141
@@ -XXX,XX +XXX,XX @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
142
abort();
143
}
144
145
-int mips_kvm_type(MachineState *machine, const char *vm_type)
146
+int kvm_arch_get_default_type(MachineState *machine)
147
{
148
#if defined(KVM_CAP_MIPS_VZ)
149
int r;
150
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/ppc/kvm.c
153
+++ b/target/ppc/kvm.c
154
@@ -XXX,XX +XXX,XX @@ static int kvm_ppc_register_host_cpu_type(void);
155
static void kvmppc_get_cpu_characteristics(KVMState *s);
156
static int kvmppc_get_dec_bits(void);
157
158
+int kvm_arch_get_default_type(MachineState *ms)
159
+{
160
+ return 0;
161
+}
162
+
163
int kvm_arch_init(MachineState *ms, KVMState *s)
164
{
165
cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
166
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/riscv/kvm.c
169
+++ b/target/riscv/kvm.c
170
@@ -XXX,XX +XXX,XX @@ int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
171
return 0;
172
}
173
174
+int kvm_arch_get_default_type(MachineState *ms)
175
+{
176
+ return 0;
177
+}
178
+
179
int kvm_arch_init(MachineState *ms, KVMState *s)
180
{
181
return 0;
182
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/s390x/kvm/kvm.c
185
+++ b/target/s390x/kvm/kvm.c
186
@@ -XXX,XX +XXX,XX @@ static void ccw_machine_class_foreach(ObjectClass *oc, void *opaque)
187
mc->default_cpu_type = S390_CPU_TYPE_NAME("host");
188
}
189
190
+int kvm_arch_get_default_type(MachineState *ms)
191
+{
192
+ return 0;
193
+}
194
+
195
int kvm_arch_init(MachineState *ms, KVMState *s)
196
{
197
object_class_foreach(ccw_machine_class_foreach, TYPE_S390_CCW_MACHINE,
198
--
199
2.34.1
200
201
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
Before this change, the default KVM type, which is used for non-virt
4
machine models, was 0.
5
6
The kernel documentation says:
7
> On arm64, the physical address size for a VM (IPA Size limit) is
8
> limited to 40bits by default. The limit can be configured if the host
9
> supports the extension KVM_CAP_ARM_VM_IPA_SIZE. When supported, use
10
> KVM_VM_TYPE_ARM_IPA_SIZE(IPA_Bits) to set the size in the machine type
11
> identifier, where IPA_Bits is the maximum width of any physical
12
> address used by the VM. The IPA_Bits is encoded in bits[7-0] of the
13
> machine type identifier.
14
>
15
> e.g, to configure a guest to use 48bit physical address size::
16
>
17
> vm_fd = ioctl(dev_fd, KVM_CREATE_VM, KVM_VM_TYPE_ARM_IPA_SIZE(48));
18
>
19
> The requested size (IPA_Bits) must be:
20
>
21
> == =========================================================
22
> 0 Implies default size, 40bits (for backward compatibility)
23
> N Implies N bits, where N is a positive integer such that,
24
> 32 <= N <= Host_IPA_Limit
25
> == =========================================================
26
27
> Host_IPA_Limit is the maximum possible value for IPA_Bits on the host
28
> and is dependent on the CPU capability and the kernel configuration.
29
> The limit can be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the
30
> KVM_CHECK_EXTENSION ioctl() at run-time.
31
>
32
> Creation of the VM will fail if the requested IPA size (whether it is
33
> implicit or explicit) is unsupported on the host.
34
https://docs.kernel.org/virt/kvm/api.html#kvm-create-vm
35
36
So if Host_IPA_Limit < 40, specifying 0 as the type will fail. This
37
actually confused libvirt, which uses "none" machine model to probe the
38
KVM availability, on M2 MacBook Air.
39
40
Fix this by using Host_IPA_Limit as the default type when
41
KVM_CAP_ARM_VM_IPA_SIZE is available.
42
43
Cc: qemu-stable@nongnu.org
44
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
45
Message-id: 20230727073134.134102-3-akihiko.odaki@daynix.com
46
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
---
49
target/arm/kvm.c | 4 +++-
50
1 file changed, 3 insertions(+), 1 deletion(-)
51
52
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/kvm.c
55
+++ b/target/arm/kvm.c
56
@@ -XXX,XX +XXX,XX @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
57
58
int kvm_arch_get_default_type(MachineState *ms)
59
{
60
- return 0;
61
+ bool fixed_ipa;
62
+ int size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
63
+ return fixed_ipa ? 0 : size;
64
}
65
66
int kvm_arch_init(MachineState *ms, KVMState *s)
67
--
68
2.34.1
diff view generated by jsdifflib
1
In nios2_cpu_set_irq(), use deposit32() rather than raw shift-and-mask
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
operations to set the appropriate bit in the ipending register.
3
2
3
On MIPS, QEMU requires KVM_VM_MIPS_VZ type for KVM. Report an error in
4
such a case as other architectures do when an error occurred during KVM
5
type decision.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Message-id: 20230727073134.134102-4-akihiko.odaki@daynix.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20201129174022.26530-4-peter.maydell@linaro.org
7
---
12
---
8
target/nios2/cpu.c | 3 +--
13
target/mips/kvm.c | 1 +
9
1 file changed, 1 insertion(+), 2 deletions(-)
14
1 file changed, 1 insertion(+)
10
15
11
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
16
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/nios2/cpu.c
18
--- a/target/mips/kvm.c
14
+++ b/target/nios2/cpu.c
19
+++ b/target/mips/kvm.c
15
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_set_irq(void *opaque, int irq, int level)
20
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_default_type(MachineState *machine)
16
CPUNios2State *env = &cpu->env;
21
}
17
CPUState *cs = CPU(cpu);
22
#endif
18
23
19
- env->regs[CR_IPENDING] &= ~(1 << irq);
24
+ error_report("KVM_VM_MIPS_VZ type is not available");
20
- env->regs[CR_IPENDING] |= !!level << irq;
25
return -1;
21
+ env->regs[CR_IPENDING] = deposit32(env->regs[CR_IPENDING], irq, 1, !!level);
26
}
22
23
env->irq_pending = env->regs[CR_IPENDING] & env->regs[CR_IENABLE];
24
27
25
--
28
--
26
2.20.1
29
2.34.1
27
30
28
31
diff view generated by jsdifflib
1
The openrisc code uses an old style of interrupt handling, where a
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
separate standalone set of qemu_irqs invoke a function
3
openrisc_pic_cpu_handler() which signals the interrupt to the CPU
4
proper by directly calling cpu_interrupt() and cpu_reset_interrupt().
5
Because CPU objects now inherit (indirectly) from TYPE_DEVICE, they
6
can have GPIO input lines themselves, and the neater modern way to
7
implement this is to simply have the CPU object itself provide the
8
input IRQ lines.
9
2
10
Create GPIO inputs to the OpenRISC CPU object, and make the only user
3
On MIPS, kvm_arch_get_default_type() returns a negative value when an
11
of cpu_openrisc_pic_init() wire up directly to those instead.
4
error occurred so handle the case. Also, let other machines return
5
negative values when errors occur and declare returning a negative
6
value as the correct way to propagate an error that happened when
7
determining KVM type.
12
8
13
This allows us to delete the hw/openrisc/pic_cpu.c file entirely.
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Message-id: 20230727073134.134102-5-akihiko.odaki@daynix.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
---
15
accel/kvm/kvm-all.c | 5 +++++
16
hw/arm/virt.c | 2 +-
17
hw/ppc/spapr.c | 2 +-
18
3 files changed, 7 insertions(+), 2 deletions(-)
14
19
15
This fixes a trivial memory leak reported by Coverity of the IRQs
20
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
16
allocated in cpu_openrisc_pic_init().
17
18
Fixes: Coverity CID 1421934
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stafford Horne <shorne@gmail.com>
21
Message-id: 20201127225127.14770-4-peter.maydell@linaro.org
22
---
23
target/openrisc/cpu.h | 1 -
24
hw/openrisc/openrisc_sim.c | 3 +-
25
hw/openrisc/pic_cpu.c | 61 --------------------------------------
26
target/openrisc/cpu.c | 32 ++++++++++++++++++++
27
hw/openrisc/meson.build | 2 +-
28
5 files changed, 34 insertions(+), 65 deletions(-)
29
delete mode 100644 hw/openrisc/pic_cpu.c
30
31
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
32
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
33
--- a/target/openrisc/cpu.h
22
--- a/accel/kvm/kvm-all.c
34
+++ b/target/openrisc/cpu.h
23
+++ b/accel/kvm/kvm-all.c
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUOpenRISCState {
24
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
36
uint32_t picmr; /* Interrupt mask register */
25
type = kvm_arch_get_default_type(ms);
37
uint32_t picsr; /* Interrupt contrl register*/
26
}
38
#endif
27
39
- void *irq[32]; /* Interrupt irq input */
28
+ if (type < 0) {
40
} CPUOpenRISCState;
29
+ ret = -EINVAL;
41
30
+ goto err;
42
/**
43
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/openrisc/openrisc_sim.c
46
+++ b/hw/openrisc/openrisc_sim.c
47
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
48
49
static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
50
{
51
- return cpus[cpunum]->env.irq[irq_pin];
52
+ return qdev_get_gpio_in_named(DEVICE(cpus[cpunum]), "IRQ", irq_pin);
53
}
54
55
static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
56
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
57
fprintf(stderr, "Unable to find CPU definition!\n");
58
exit(1);
59
}
60
- cpu_openrisc_pic_init(cpus[n]);
61
62
cpu_openrisc_clock_init(cpus[n]);
63
64
diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
65
deleted file mode 100644
66
index XXXXXXX..XXXXXXX
67
--- a/hw/openrisc/pic_cpu.c
68
+++ /dev/null
69
@@ -XXX,XX +XXX,XX @@
70
-/*
71
- * OpenRISC Programmable Interrupt Controller support.
72
- *
73
- * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
74
- * Feng Gao <gf91597@gmail.com>
75
- *
76
- * This library is free software; you can redistribute it and/or
77
- * modify it under the terms of the GNU Lesser General Public
78
- * License as published by the Free Software Foundation; either
79
- * version 2.1 of the License, or (at your option) any later version.
80
- *
81
- * This library is distributed in the hope that it will be useful,
82
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
83
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
84
- * Lesser General Public License for more details.
85
- *
86
- * You should have received a copy of the GNU Lesser General Public
87
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
88
- */
89
-
90
-#include "qemu/osdep.h"
91
-#include "hw/irq.h"
92
-#include "cpu.h"
93
-
94
-/* OpenRISC pic handler */
95
-static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
96
-{
97
- OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
98
- CPUState *cs = CPU(cpu);
99
- uint32_t irq_bit;
100
-
101
- if (irq > 31 || irq < 0) {
102
- return;
103
- }
104
-
105
- irq_bit = 1U << irq;
106
-
107
- if (level) {
108
- cpu->env.picsr |= irq_bit;
109
- } else {
110
- cpu->env.picsr &= ~irq_bit;
111
- }
112
-
113
- if (cpu->env.picsr & cpu->env.picmr) {
114
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
115
- } else {
116
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
117
- cpu->env.picsr = 0;
118
- }
119
-}
120
-
121
-void cpu_openrisc_pic_init(OpenRISCCPU *cpu)
122
-{
123
- int i;
124
- qemu_irq *qi;
125
- qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, cpu, NR_IRQS);
126
-
127
- for (i = 0; i < NR_IRQS; i++) {
128
- cpu->env.irq[i] = qi[i];
129
- }
130
-}
131
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/openrisc/cpu.c
134
+++ b/target/openrisc/cpu.c
135
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset(DeviceState *dev)
136
#endif
137
}
138
139
+#ifndef CONFIG_USER_ONLY
140
+static void openrisc_cpu_set_irq(void *opaque, int irq, int level)
141
+{
142
+ OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
143
+ CPUState *cs = CPU(cpu);
144
+ uint32_t irq_bit;
145
+
146
+ if (irq > 31 || irq < 0) {
147
+ return;
148
+ }
31
+ }
149
+
32
+
150
+ irq_bit = 1U << irq;
33
do {
151
+
34
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
152
+ if (level) {
35
} while (ret == -EINTR);
153
+ cpu->env.picsr |= irq_bit;
36
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
154
+ } else {
37
index XXXXXXX..XXXXXXX 100644
155
+ cpu->env.picsr &= ~irq_bit;
38
--- a/hw/arm/virt.c
156
+ }
39
+++ b/hw/arm/virt.c
157
+
40
@@ -XXX,XX +XXX,XX @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
158
+ if (cpu->env.picsr & cpu->env.picmr) {
41
"require an IPA range (%d bits) larger than "
159
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
42
"the one supported by the host (%d bits)",
160
+ } else {
43
requested_pa_size, max_vm_pa_size);
161
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
44
- exit(1);
162
+ cpu->env.picsr = 0;
45
+ return -1;
163
+ }
46
}
164
+}
47
/*
165
+#endif
48
* We return the requested PA log size, unless KVM only supports
166
+
49
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
167
static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
50
index XXXXXXX..XXXXXXX 100644
168
{
51
--- a/hw/ppc/spapr.c
169
CPUState *cs = CPU(dev);
52
+++ b/hw/ppc/spapr.c
170
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_initfn(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static int spapr_kvm_type(MachineState *machine, const char *vm_type)
171
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
54
}
172
55
173
cpu_set_cpustate_pointers(cpu);
56
error_report("Unknown kvm-type specified '%s'", vm_type);
174
+
57
- exit(1);
175
+#ifndef CONFIG_USER_ONLY
58
+ return -1;
176
+ qdev_init_gpio_in_named(DEVICE(cpu), openrisc_cpu_set_irq, "IRQ", NR_IRQS);
177
+#endif
178
}
59
}
179
60
180
/* CPU models */
61
/*
181
diff --git a/hw/openrisc/meson.build b/hw/openrisc/meson.build
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/openrisc/meson.build
184
+++ b/hw/openrisc/meson.build
185
@@ -XXX,XX +XXX,XX @@
186
openrisc_ss = ss.source_set()
187
-openrisc_ss.add(files('pic_cpu.c', 'cputimer.c'))
188
+openrisc_ss.add(files('cputimer.c'))
189
openrisc_ss.add(when: 'CONFIG_OR1K_SIM', if_true: files('openrisc_sim.c'))
190
191
hw_arch += {'openrisc': openrisc_ss}
192
--
62
--
193
2.20.1
63
2.34.1
194
64
195
65
diff view generated by jsdifflib
New patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
2
3
An error may occur after s->as is allocated, for example if the
4
KVM_CREATE_VM ioctl call fails.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Message-id: 20230727073134.134102-6-akihiko.odaki@daynix.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
[PMM: tweaked commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
accel/kvm/kvm-all.c | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/kvm/kvm-all.c
18
+++ b/accel/kvm/kvm-all.c
19
@@ -XXX,XX +XXX,XX @@ err:
20
if (s->fd != -1) {
21
close(s->fd);
22
}
23
+ g_free(s->as);
24
g_free(s->memory_listener.slots);
25
26
return ret;
27
--
28
2.34.1
diff view generated by jsdifflib
1
The Nios2 architecture supports two different interrupt controller
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
options:
3
2
4
* The IIC (Internal Interrupt Controller) is part of the CPU itself;
3
The returned value was always zero and had no meaning.
5
it has 32 IRQ input lines and no NMI support. Interrupt status is
6
queried and controlled via the CPU's ipending and istatus
7
registers.
8
4
9
* The EIC (External Interrupt Controller) interface allows the CPU
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
to connect to an external interrupt controller. The interface
6
Message-id: 20230727073134.134102-7-akihiko.odaki@daynix.com
11
allows the interrupt controller to present a packet of information
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
containing:
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
- handler address
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
- interrupt level
10
---
15
- register set
11
accel/kvm/kvm-all.c | 9 ++-------
16
- NMI mode
12
1 file changed, 2 insertions(+), 7 deletions(-)
17
13
18
QEMU does not model an EIC currently. We do model the IIC, but its
14
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
19
implementation is split across code in hw/nios2/cpu_pic.c and
20
hw/intc/nios2_iic.c. The code in those two files has no state of its
21
own -- the IIC state is in the Nios2CPU state struct.
22
23
Because CPU objects now inherit (indirectly) from TYPE_DEVICE, they
24
can have GPIO input lines themselves, so we can implement the IIC
25
directly in the CPU object the same way that real hardware does.
26
27
Create named "IRQ" GPIO inputs to the Nios2 CPU object, and make the
28
only user of the IIC wire up directly to those instead.
29
30
Note that the old code had an "NMI" concept which was entirely unused
31
and also as far as I can see not architecturally correct, since only
32
the EIC has a concept of an NMI.
33
34
This fixes a Coverity-reported trivial memory leak of the IRQ array
35
allocated in nios2_cpu_pic_init().
36
37
Fixes: Coverity CID 1421916
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
40
Message-id: 20201129174022.26530-2-peter.maydell@linaro.org
41
Reviewed-by: Wentong Wu <wentong.wu@intel.com>
42
Tested-by: Wentong Wu <wentong.wu@intel.com>
43
---
44
target/nios2/cpu.h | 1 -
45
hw/intc/nios2_iic.c | 95 ---------------------------------------
46
hw/nios2/10m50_devboard.c | 13 +-----
47
hw/nios2/cpu_pic.c | 31 -------------
48
target/nios2/cpu.c | 30 +++++++++++++
49
MAINTAINERS | 1 -
50
hw/intc/meson.build | 1 -
51
7 files changed, 32 insertions(+), 140 deletions(-)
52
delete mode 100644 hw/intc/nios2_iic.c
53
54
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
55
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
56
--- a/target/nios2/cpu.h
16
--- a/accel/kvm/kvm-all.c
57
+++ b/target/nios2/cpu.h
17
+++ b/accel/kvm/kvm-all.c
58
@@ -XXX,XX +XXX,XX @@ void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
18
@@ -XXX,XX +XXX,XX @@ static void *kvm_dirty_ring_reaper_thread(void *data)
59
MMUAccessType access_type,
19
return NULL;
60
int mmu_idx, uintptr_t retaddr);
20
}
61
21
62
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu);
22
-static int kvm_dirty_ring_reaper_init(KVMState *s)
63
void nios2_check_interrupts(CPUNios2State *env);
23
+static void kvm_dirty_ring_reaper_init(KVMState *s)
64
24
{
65
void do_nios2_semihosting(CPUNios2State *env);
25
struct KVMDirtyRingReaper *r = &s->reaper;
66
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
26
67
deleted file mode 100644
27
qemu_thread_create(&r->reaper_thr, "kvm-reaper",
68
index XXXXXXX..XXXXXXX
28
kvm_dirty_ring_reaper_thread,
69
--- a/hw/intc/nios2_iic.c
29
s, QEMU_THREAD_JOINABLE);
70
+++ /dev/null
71
@@ -XXX,XX +XXX,XX @@
72
-/*
73
- * QEMU Altera Internal Interrupt Controller.
74
- *
75
- * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
76
- *
77
- * This library is free software; you can redistribute it and/or
78
- * modify it under the terms of the GNU Lesser General Public
79
- * License as published by the Free Software Foundation; either
80
- * version 2.1 of the License, or (at your option) any later version.
81
- *
82
- * This library is distributed in the hope that it will be useful,
83
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
84
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
85
- * Lesser General Public License for more details.
86
- *
87
- * You should have received a copy of the GNU Lesser General Public
88
- * License along with this library; if not, see
89
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
90
- */
91
-
30
-
92
-#include "qemu/osdep.h"
31
- return 0;
93
-#include "qemu/module.h"
32
}
94
-#include "qapi/error.h"
33
95
-
34
static int kvm_dirty_ring_init(KVMState *s)
96
-#include "hw/irq.h"
35
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
97
-#include "hw/sysbus.h"
98
-#include "cpu.h"
99
-#include "qom/object.h"
100
-
101
-#define TYPE_ALTERA_IIC "altera,iic"
102
-OBJECT_DECLARE_SIMPLE_TYPE(AlteraIIC, ALTERA_IIC)
103
-
104
-struct AlteraIIC {
105
- SysBusDevice parent_obj;
106
- void *cpu;
107
- qemu_irq parent_irq;
108
-};
109
-
110
-static void update_irq(AlteraIIC *pv)
111
-{
112
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
113
-
114
- qemu_set_irq(pv->parent_irq,
115
- env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
116
-}
117
-
118
-static void irq_handler(void *opaque, int irq, int level)
119
-{
120
- AlteraIIC *pv = opaque;
121
- CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
122
-
123
- env->regs[CR_IPENDING] &= ~(1 << irq);
124
- env->regs[CR_IPENDING] |= !!level << irq;
125
-
126
- update_irq(pv);
127
-}
128
-
129
-static void altera_iic_init(Object *obj)
130
-{
131
- AlteraIIC *pv = ALTERA_IIC(obj);
132
-
133
- qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
134
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &pv->parent_irq);
135
-}
136
-
137
-static void altera_iic_realize(DeviceState *dev, Error **errp)
138
-{
139
- struct AlteraIIC *pv = ALTERA_IIC(dev);
140
-
141
- pv->cpu = object_property_get_link(OBJECT(dev), "cpu", &error_abort);
142
-}
143
-
144
-static void altera_iic_class_init(ObjectClass *klass, void *data)
145
-{
146
- DeviceClass *dc = DEVICE_CLASS(klass);
147
-
148
- /* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
149
- dc->user_creatable = false;
150
- dc->realize = altera_iic_realize;
151
-}
152
-
153
-static TypeInfo altera_iic_info = {
154
- .name = TYPE_ALTERA_IIC,
155
- .parent = TYPE_SYS_BUS_DEVICE,
156
- .instance_size = sizeof(AlteraIIC),
157
- .instance_init = altera_iic_init,
158
- .class_init = altera_iic_class_init,
159
-};
160
-
161
-static void altera_iic_register(void)
162
-{
163
- type_register_static(&altera_iic_info);
164
-}
165
-
166
-type_init(altera_iic_register)
167
diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/hw/nios2/10m50_devboard.c
170
+++ b/hw/nios2/10m50_devboard.c
171
@@ -XXX,XX +XXX,XX @@ static void nios2_10m50_ghrd_init(MachineState *machine)
172
ram_addr_t tcm_size = 0x1000; /* 1 kiB, but QEMU limit is 4 kiB */
173
ram_addr_t ram_base = 0x08000000;
174
ram_addr_t ram_size = 0x08000000;
175
- qemu_irq *cpu_irq, irq[32];
176
+ qemu_irq irq[32];
177
int i;
178
179
/* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
180
@@ -XXX,XX +XXX,XX @@ static void nios2_10m50_ghrd_init(MachineState *machine)
181
182
/* Create CPU -- FIXME */
183
cpu = NIOS2_CPU(cpu_create(TYPE_NIOS2_CPU));
184
-
185
- /* Register: CPU interrupt controller (PIC) */
186
- cpu_irq = nios2_cpu_pic_init(cpu);
187
-
188
- /* Register: Internal Interrupt Controller (IIC) */
189
- dev = qdev_new("altera,iic");
190
- object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu));
191
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
192
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
193
for (i = 0; i < 32; i++) {
194
- irq[i] = qdev_get_gpio_in(dev, i);
195
+ irq[i] = qdev_get_gpio_in_named(DEVICE(cpu), "IRQ", i);
196
}
36
}
197
37
198
/* Register: Altera 16550 UART */
38
if (s->kvm_dirty_ring_size) {
199
diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
39
- ret = kvm_dirty_ring_reaper_init(s);
200
index XXXXXXX..XXXXXXX 100644
40
- if (ret) {
201
--- a/hw/nios2/cpu_pic.c
41
- goto err;
202
+++ b/hw/nios2/cpu_pic.c
203
@@ -XXX,XX +XXX,XX @@
204
205
#include "boot.h"
206
207
-static void nios2_pic_cpu_handler(void *opaque, int irq, int level)
208
-{
209
- Nios2CPU *cpu = opaque;
210
- CPUNios2State *env = &cpu->env;
211
- CPUState *cs = CPU(cpu);
212
- int type = irq ? CPU_INTERRUPT_NMI : CPU_INTERRUPT_HARD;
213
-
214
- if (type == CPU_INTERRUPT_HARD) {
215
- env->irq_pending = level;
216
-
217
- if (level && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
218
- env->irq_pending = 0;
219
- cpu_interrupt(cs, type);
220
- } else if (!level) {
221
- env->irq_pending = 0;
222
- cpu_reset_interrupt(cs, type);
223
- }
42
- }
224
- } else {
43
+ kvm_dirty_ring_reaper_init(s);
225
- if (level) {
226
- cpu_interrupt(cs, type);
227
- } else {
228
- cpu_reset_interrupt(cs, type);
229
- }
230
- }
231
-}
232
-
233
void nios2_check_interrupts(CPUNios2State *env)
234
{
235
if (env->irq_pending &&
236
@@ -XXX,XX +XXX,XX @@ void nios2_check_interrupts(CPUNios2State *env)
237
cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
238
}
44
}
239
}
45
240
-
46
if (kvm_check_extension(kvm_state, KVM_CAP_BINARY_STATS_FD)) {
241
-qemu_irq *nios2_cpu_pic_init(Nios2CPU *cpu)
242
-{
243
- return qemu_allocate_irqs(nios2_pic_cpu_handler, cpu, 2);
244
-}
245
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
246
index XXXXXXX..XXXXXXX 100644
247
--- a/target/nios2/cpu.c
248
+++ b/target/nios2/cpu.c
249
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_reset(DeviceState *dev)
250
#endif
251
}
252
253
+#ifndef CONFIG_USER_ONLY
254
+static void nios2_cpu_set_irq(void *opaque, int irq, int level)
255
+{
256
+ Nios2CPU *cpu = opaque;
257
+ CPUNios2State *env = &cpu->env;
258
+ CPUState *cs = CPU(cpu);
259
+
260
+ env->regs[CR_IPENDING] &= ~(1 << irq);
261
+ env->regs[CR_IPENDING] |= !!level << irq;
262
+
263
+ env->irq_pending = env->regs[CR_IPENDING] & env->regs[CR_IENABLE];
264
+
265
+ if (env->irq_pending && (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
266
+ env->irq_pending = 0;
267
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
268
+ } else if (!env->irq_pending) {
269
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
270
+ }
271
+}
272
+#endif
273
+
274
static void nios2_cpu_initfn(Object *obj)
275
{
276
Nios2CPU *cpu = NIOS2_CPU(obj);
277
@@ -XXX,XX +XXX,XX @@ static void nios2_cpu_initfn(Object *obj)
278
279
#if !defined(CONFIG_USER_ONLY)
280
mmu_init(&cpu->env);
281
+
282
+ /*
283
+ * These interrupt lines model the IIC (internal interrupt
284
+ * controller). QEMU does not currently support the EIC
285
+ * (external interrupt controller) -- if we did it would be
286
+ * a separate device in hw/intc with a custom interface to
287
+ * the CPU, and boards using it would not wire up these IRQ lines.
288
+ */
289
+ qdev_init_gpio_in_named(DEVICE(cpu), nios2_cpu_set_irq, "IRQ", 32);
290
#endif
291
}
292
293
diff --git a/MAINTAINERS b/MAINTAINERS
294
index XXXXXXX..XXXXXXX 100644
295
--- a/MAINTAINERS
296
+++ b/MAINTAINERS
297
@@ -XXX,XX +XXX,XX @@ M: Marek Vasut <marex@denx.de>
298
S: Maintained
299
F: target/nios2/
300
F: hw/nios2/
301
-F: hw/intc/nios2_iic.c
302
F: disas/nios2.c
303
F: default-configs/nios2-softmmu.mak
304
305
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
306
index XXXXXXX..XXXXXXX 100644
307
--- a/hw/intc/meson.build
308
+++ b/hw/intc/meson.build
309
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
310
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
311
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
312
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
313
-specific_ss.add(when: 'CONFIG_NIOS2', if_true: files('nios2_iic.c'))
314
specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
315
specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
316
specific_ss.add(when: 'CONFIG_OPENPIC_KVM', if_true: files('openpic_kvm.c'))
317
--
47
--
318
2.20.1
48
2.34.1
319
49
320
50
diff view generated by jsdifflib
New patch
1
For an Unsupported Atomic Update fault where the stage 1 translation
2
table descriptor update can't be done because it's to an unsupported
3
memory type, this is a stage 1 abort (per the Arm ARM R_VSXXT). This
4
means we should not set fi->s1ptw, because this will cause the code
5
in the get_phys_addr_lpae() error-exit path to mark it as stage 2.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230807141514.19075-2-peter.maydell@linaro.org
10
---
11
target/arm/ptw.c | 1 -
12
1 file changed, 1 deletion(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
19
20
if (unlikely(!host)) {
21
fi->type = ARMFault_UnsuppAtomicUpdate;
22
- fi->s1ptw = true;
23
return 0;
24
}
25
26
--
27
2.34.1
diff view generated by jsdifflib
New patch
1
In S1_ptw_translate() we set up the ARMMMUFaultInfo if the attempt to
2
translate the page descriptor address into a physical address fails.
3
This used to only be possible if we are doing a stage 2 ptw for that
4
descriptor address, and so the code always sets fi->stage2 and
5
fi->s1ptw to true. However, with FEAT_RME it is also possible for
6
the lookup of the page descriptor address to fail because of a
7
Granule Protection Check fault. These should not be reported as
8
stage 2, otherwise arm_deliver_fault() will incorrectly set
9
HPFAR_EL2. Similarly the s1ptw bit should only be set for stage 2
10
faults on stage 1 translation table walks, i.e. not for GPC faults.
1
11
12
Add a comment to the the other place where we might detect a
13
stage2-fault-on-stage-1-ptw, in arm_casq_ptw(), noting why we know in
14
that case that it must really be a stage 2 fault and not a GPC fault.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20230807141514.19075-3-peter.maydell@linaro.org
19
---
20
target/arm/ptw.c | 10 ++++++++--
21
1 file changed, 8 insertions(+), 2 deletions(-)
22
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/ptw.c
26
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
28
fi->type = ARMFault_GPCFOnWalk;
29
}
30
fi->s2addr = addr;
31
- fi->stage2 = true;
32
- fi->s1ptw = true;
33
+ fi->stage2 = regime_is_stage2(s2_mmu_idx);
34
+ fi->s1ptw = fi->stage2;
35
fi->s1ns = !is_secure;
36
return false;
37
}
38
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
39
env->tlb_fi = NULL;
40
41
if (unlikely(flags & TLB_INVALID_MASK)) {
42
+ /*
43
+ * We know this must be a stage 2 fault because the granule
44
+ * protection table does not separately track read and write
45
+ * permission, so all GPC faults are caught in S1_ptw_translate():
46
+ * we only get here for "readable but not writeable".
47
+ */
48
assert(fi->type != ARMFault_None);
49
fi->s2addr = ptw->out_virt;
50
fi->stage2 = true;
51
--
52
2.34.1
diff view generated by jsdifflib
1
In rom_check_and_register_reset() we detect overlaps by looking at
1
The s1ns bit in ARMMMUFaultInfo is documented as "true if
2
whether the ROM blob we're currently examining is in the same address
2
we faulted on a non-secure IPA while in secure state". Both the
3
space and starts before the previous ROM blob ends. (This works
3
places which look at this bit only do so after having confirmed
4
because the ROM list is kept sorted in order by AddressSpace and then
4
that this is a stage 2 fault and we're dealing with Secure EL2,
5
by address.)
5
which leaves the ptw.c code free to set the bit to any random
6
value in the other cases.
6
7
7
Instead of keeping the AddressSpace and last address of the previous ROM
8
Instead of taking advantage of that freedom, consistently
8
blob in local variables, just keep a pointer to it.
9
make the bit be set to false for the "not a stage 2 fault
9
10
for Secure EL2" cases. This removes some cases where we
10
This will allow us to print more useful information when we do detect
11
were using an 'is_secure' boolean and leaving the reader
11
an overlap.
12
guessing about whether that was the right thing for Realm
13
and Root cases.
12
14
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20201129203923.10622-2-peter.maydell@linaro.org
17
Message-id: 20230807141514.19075-4-peter.maydell@linaro.org
16
---
18
---
17
hw/core/loader.c | 23 +++++++++++++++--------
19
target/arm/ptw.c | 19 +++++++++++++++----
18
1 file changed, 15 insertions(+), 8 deletions(-)
20
1 file changed, 15 insertions(+), 4 deletions(-)
19
21
20
diff --git a/hw/core/loader.c b/hw/core/loader.c
22
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/loader.c
24
--- a/target/arm/ptw.c
23
+++ b/hw/core/loader.c
25
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@ static void rom_reset(void *unused)
26
@@ -XXX,XX +XXX,XX @@ static ARMSecuritySpace S2_security_space(ARMSecuritySpace s1_space,
25
}
27
}
26
}
28
}
27
29
28
+/* Return true if two consecutive ROMs in the ROM list overlap */
30
+static bool fault_s1ns(ARMSecuritySpace space, ARMMMUIdx s2_mmu_idx)
29
+static bool roms_overlap(Rom *last_rom, Rom *this_rom)
30
+{
31
+{
31
+ if (!last_rom) {
32
+ /*
32
+ return false;
33
+ * For stage 2 faults in Secure EL22, S1NS indicates
33
+ }
34
+ * whether the faulting IPA is in the Secure or NonSecure
34
+ return last_rom->as == this_rom->as &&
35
+ * IPA space. For all other kinds of fault, it is false.
35
+ last_rom->addr + last_rom->romsize > this_rom->addr;
36
+ */
37
+ return space == ARMSS_Secure && regime_is_stage2(s2_mmu_idx)
38
+ && s2_mmu_idx == ARMMMUIdx_Stage2_S;
36
+}
39
+}
37
+
40
+
38
int rom_check_and_register_reset(void)
41
/* Translate a S1 pagetable walk through S2 if needed. */
39
{
42
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
40
- hwaddr addr = 0;
43
hwaddr addr, ARMMMUFaultInfo *fi)
41
MemoryRegionSection section;
44
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
42
- Rom *rom;
45
fi->s2addr = addr;
43
- AddressSpace *as = NULL;
46
fi->stage2 = true;
44
+ Rom *rom, *last_rom = NULL;
47
fi->s1ptw = true;
45
48
- fi->s1ns = !is_secure;
46
QTAILQ_FOREACH(rom, &roms, next) {
49
+ fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx);
47
if (rom->fw_file) {
50
return false;
48
continue;
49
}
51
}
50
if (!rom->mr) {
52
}
51
- if ((addr > rom->addr) && (as == rom->as)) {
53
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
52
+ if (roms_overlap(last_rom, rom)) {
54
fi->s2addr = addr;
53
fprintf(stderr, "rom: requested regions overlap "
55
fi->stage2 = regime_is_stage2(s2_mmu_idx);
54
"(rom %s. free=0x" TARGET_FMT_plx
56
fi->s1ptw = fi->stage2;
55
", addr=0x" TARGET_FMT_plx ")\n",
57
- fi->s1ns = !is_secure;
56
- rom->name, addr, rom->addr);
58
+ fi->s1ns = fault_s1ns(ptw->in_space, s2_mmu_idx);
57
+ rom->name, last_rom->addr + last_rom->romsize,
59
return false;
58
+ rom->addr);
60
}
59
return -1;
61
60
}
62
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val,
61
- addr = rom->addr;
63
fi->s2addr = ptw->out_virt;
62
- addr += rom->romsize;
64
fi->stage2 = true;
63
- as = rom->as;
65
fi->s1ptw = true;
64
+ last_rom = rom;
66
- fi->s1ns = !ptw->in_secure;
67
+ fi->s1ns = fault_s1ns(ptw->in_space, ptw->in_ptw_idx);
68
return 0;
65
}
69
}
66
section = memory_region_find(rom->mr ? rom->mr : get_system_memory(),
70
67
rom->addr, 1);
71
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
72
fi->level = level;
73
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
74
fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
75
- fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
76
+ fi->s1ns = fault_s1ns(ptw->in_space, mmu_idx);
77
return true;
78
}
79
68
--
80
--
69
2.20.1
81
2.34.1
70
71
diff view generated by jsdifflib
New patch
1
In commit 6d2654ffacea813916176 we created the S1Translate struct and
2
used it to plumb through various arguments that we were previously
3
passing one-at-a-time to get_phys_addr_v5(), get_phys_addr_v6(), and
4
get_phys_addr_lpae(). Extend that pattern to get_phys_addr_pmsav5(),
5
get_phys_addr_pmsav7(), get_phys_addr_pmsav8() and
6
get_phys_addr_disabled(), so that all the get_phys_addr_* functions
7
we call from get_phys_addr_nogpc() take the S1Translate struct rather
8
than the mmu_idx and is_secure bool.
1
9
10
(This refactoring is a prelude to having the called functions look
11
at ptw->is_space rather than using an is_secure boolean.)
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230807141514.19075-5-peter.maydell@linaro.org
16
---
17
target/arm/ptw.c | 57 ++++++++++++++++++++++++++++++------------------
18
1 file changed, 36 insertions(+), 21 deletions(-)
19
20
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/ptw.c
23
+++ b/target/arm/ptw.c
24
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
25
return true;
26
}
27
28
-static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
29
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
30
- bool is_secure, GetPhysAddrResult *result,
31
+static bool get_phys_addr_pmsav5(CPUARMState *env,
32
+ S1Translate *ptw,
33
+ uint32_t address,
34
+ MMUAccessType access_type,
35
+ GetPhysAddrResult *result,
36
ARMMMUFaultInfo *fi)
37
{
38
int n;
39
uint32_t mask;
40
uint32_t base;
41
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
42
bool is_user = regime_is_user(env, mmu_idx);
43
+ bool is_secure = arm_space_is_secure(ptw->in_space);
44
45
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
46
/* MPU disabled. */
47
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
48
return regime_sctlr(env, mmu_idx) & SCTLR_BR;
49
}
50
51
-static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
52
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
53
- bool secure, GetPhysAddrResult *result,
54
+static bool get_phys_addr_pmsav7(CPUARMState *env,
55
+ S1Translate *ptw,
56
+ uint32_t address,
57
+ MMUAccessType access_type,
58
+ GetPhysAddrResult *result,
59
ARMMMUFaultInfo *fi)
60
{
61
ARMCPU *cpu = env_archcpu(env);
62
int n;
63
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
64
bool is_user = regime_is_user(env, mmu_idx);
65
+ bool secure = arm_space_is_secure(ptw->in_space);
66
67
result->f.phys_addr = address;
68
result->f.lg_page_size = TARGET_PAGE_BITS;
69
@@ -XXX,XX +XXX,XX @@ void v8m_security_lookup(CPUARMState *env, uint32_t address,
70
}
71
}
72
73
-static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
74
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
75
- bool secure, GetPhysAddrResult *result,
76
+static bool get_phys_addr_pmsav8(CPUARMState *env,
77
+ S1Translate *ptw,
78
+ uint32_t address,
79
+ MMUAccessType access_type,
80
+ GetPhysAddrResult *result,
81
ARMMMUFaultInfo *fi)
82
{
83
V8M_SAttributes sattrs = {};
84
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
85
+ bool secure = arm_space_is_secure(ptw->in_space);
86
bool ret;
87
88
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
89
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
90
* MMU disabled. S1 addresses within aa64 translation regimes are
91
* still checked for bounds -- see AArch64.S1DisabledOutput().
92
*/
93
-static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
94
+static bool get_phys_addr_disabled(CPUARMState *env,
95
+ S1Translate *ptw,
96
+ target_ulong address,
97
MMUAccessType access_type,
98
- ARMMMUIdx mmu_idx, bool is_secure,
99
GetPhysAddrResult *result,
100
ARMMMUFaultInfo *fi)
101
{
102
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
103
+ bool is_secure = arm_space_is_secure(ptw->in_space);
104
uint8_t memattr = 0x00; /* Device nGnRnE */
105
uint8_t shareability = 0; /* non-shareable */
106
int r_el;
107
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
108
case ARMMMUIdx_Phys_Root:
109
case ARMMMUIdx_Phys_Realm:
110
/* Checking Phys early avoids special casing later vs regime_el. */
111
- return get_phys_addr_disabled(env, address, access_type, mmu_idx,
112
- is_secure, result, fi);
113
+ return get_phys_addr_disabled(env, ptw, address, access_type,
114
+ result, fi);
115
116
case ARMMMUIdx_Stage1_E0:
117
case ARMMMUIdx_Stage1_E1:
118
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
119
120
if (arm_feature(env, ARM_FEATURE_V8)) {
121
/* PMSAv8 */
122
- ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
123
- is_secure, result, fi);
124
+ ret = get_phys_addr_pmsav8(env, ptw, address, access_type,
125
+ result, fi);
126
} else if (arm_feature(env, ARM_FEATURE_V7)) {
127
/* PMSAv7 */
128
- ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
129
- is_secure, result, fi);
130
+ ret = get_phys_addr_pmsav7(env, ptw, address, access_type,
131
+ result, fi);
132
} else {
133
/* Pre-v7 MPU */
134
- ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
135
- is_secure, result, fi);
136
+ ret = get_phys_addr_pmsav5(env, ptw, address, access_type,
137
+ result, fi);
138
}
139
qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
140
" mmu_idx %u -> %s (prot %c%c%c)\n",
141
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
142
/* Definitely a real MMU, not an MPU */
143
144
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
145
- return get_phys_addr_disabled(env, address, access_type, mmu_idx,
146
- is_secure, result, fi);
147
+ return get_phys_addr_disabled(env, ptw, address, access_type,
148
+ result, fi);
149
}
150
151
if (regime_using_lpae_format(env, mmu_idx)) {
152
--
153
2.34.1
diff view generated by jsdifflib
New patch
1
Plumb the ARMSecurityState through to regime_translation_disabled()
2
rather than just a bool is_secure.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230807141514.19075-6-peter.maydell@linaro.org
7
---
8
target/arm/ptw.c | 15 ++++++++-------
9
1 file changed, 8 insertions(+), 7 deletions(-)
10
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
14
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@ static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
16
17
/* Return true if the specified stage of address translation is disabled */
18
static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
19
- bool is_secure)
20
+ ARMSecuritySpace space)
21
{
22
uint64_t hcr_el2;
23
+ bool is_secure = arm_space_is_secure(space);
24
25
if (arm_feature(env, ARM_FEATURE_M)) {
26
switch (env->v7m.mpu_ctrl[is_secure] &
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env,
28
uint32_t base;
29
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
30
bool is_user = regime_is_user(env, mmu_idx);
31
- bool is_secure = arm_space_is_secure(ptw->in_space);
32
33
- if (regime_translation_disabled(env, mmu_idx, is_secure)) {
34
+ if (regime_translation_disabled(env, mmu_idx, ptw->in_space)) {
35
/* MPU disabled. */
36
result->f.phys_addr = address;
37
result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
38
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
39
result->f.lg_page_size = TARGET_PAGE_BITS;
40
result->f.prot = 0;
41
42
- if (regime_translation_disabled(env, mmu_idx, secure) ||
43
+ if (regime_translation_disabled(env, mmu_idx, ptw->in_space) ||
44
m_is_ppb_region(env, address)) {
45
/*
46
* MPU disabled or M profile PPB access: use default memory map.
47
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
48
* are done in arm_v7m_load_vector(), which always does a direct
49
* read using address_space_ldl(), rather than going via this function.
50
*/
51
- if (regime_translation_disabled(env, mmu_idx, secure)) { /* MPU disabled */
52
+ if (regime_translation_disabled(env, mmu_idx, arm_secure_to_space(secure))) {
53
+ /* MPU disabled */
54
hit = true;
55
} else if (m_is_ppb_region(env, address)) {
56
hit = true;
57
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
58
*/
59
ptw->in_mmu_idx = mmu_idx = s1_mmu_idx;
60
if (arm_feature(env, ARM_FEATURE_EL2) &&
61
- !regime_translation_disabled(env, ARMMMUIdx_Stage2, is_secure)) {
62
+ !regime_translation_disabled(env, ARMMMUIdx_Stage2, ptw->in_space)) {
63
return get_phys_addr_twostage(env, ptw, address, access_type,
64
result, fi);
65
}
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
67
68
/* Definitely a real MMU, not an MPU */
69
70
- if (regime_translation_disabled(env, mmu_idx, is_secure)) {
71
+ if (regime_translation_disabled(env, mmu_idx, ptw->in_space)) {
72
return get_phys_addr_disabled(env, ptw, address, access_type,
73
result, fi);
74
}
75
--
76
2.34.1
diff view generated by jsdifflib
New patch
1
arm_hcr_el2_eff_secstate() takes a bool secure, which it uses to
2
determine whether EL2 is enabled in the current security state.
3
With the advent of FEAT_RME this is no longer sufficient, because
4
EL2 can be enabled for Secure state but not for Root, and both
5
of those will pass 'secure == true' in the callsites in ptw.c.
1
6
7
As it happens in all of our callsites in ptw.c we either avoid making
8
the call or else avoid using the returned value if we're doing a
9
translation for Root, so this is not a behaviour change even if the
10
experimental FEAT_RME is enabled. But it is less confusing in the
11
ptw.c code if we avoid the use of a bool secure that duplicates some
12
of the information in the ArmSecuritySpace argument.
13
14
Make arm_hcr_el2_eff_secstate() take an ARMSecuritySpace argument
15
instead. Because we always want to know the HCR_EL2 for the
16
security state defined by the current effective value of
17
SCR_EL3.{NSE,NS}, it makes no sense to pass ARMSS_Root here,
18
and we assert that callers don't do that.
19
20
To avoid the assert(), we thus push the call to
21
arm_hcr_el2_eff_secstate() down into the cases in
22
regime_translation_disabled() that need it, rather than calling the
23
function and ignoring the result for the Root space translations.
24
All other calls to this function in ptw.c are already in places
25
where we have confirmed that the mmu_idx is a stage 2 translation
26
or that the regime EL is not 3.
27
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Message-id: 20230807141514.19075-7-peter.maydell@linaro.org
31
---
32
target/arm/cpu.h | 2 +-
33
target/arm/helper.c | 8 +++++---
34
target/arm/ptw.c | 15 +++++++--------
35
3 files changed, 13 insertions(+), 12 deletions(-)
36
37
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpu.h
40
+++ b/target/arm/cpu.h
41
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
42
* "for all purposes other than a direct read or write access of HCR_EL2."
43
* Not included here is HCR_RW.
44
*/
45
-uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
46
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space);
47
uint64_t arm_hcr_el2_eff(CPUARMState *env);
48
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
49
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
55
* Bits that are not included here:
56
* RW (read from SCR_EL3.RW as needed)
57
*/
58
-uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure)
59
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space)
60
{
61
uint64_t ret = env->cp15.hcr_el2;
62
63
- if (!arm_is_el2_enabled_secstate(env, secure)) {
64
+ assert(space != ARMSS_Root);
65
+
66
+ if (!arm_is_el2_enabled_secstate(env, arm_space_is_secure(space))) {
67
/*
68
* "This register has no effect if EL2 is not enabled in the
69
* current Security state". This is ARMv8.4-SecEL2 speak for
70
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
71
if (arm_feature(env, ARM_FEATURE_M)) {
72
return 0;
73
}
74
- return arm_hcr_el2_eff_secstate(env, arm_is_secure_below_el3(env));
75
+ return arm_hcr_el2_eff_secstate(env, arm_security_space_below_el3(env));
76
}
77
78
/*
79
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/ptw.c
82
+++ b/target/arm/ptw.c
83
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
84
ARMSecuritySpace space)
85
{
86
uint64_t hcr_el2;
87
- bool is_secure = arm_space_is_secure(space);
88
89
if (arm_feature(env, ARM_FEATURE_M)) {
90
+ bool is_secure = arm_space_is_secure(space);
91
switch (env->v7m.mpu_ctrl[is_secure] &
92
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
93
case R_V7M_MPU_CTRL_ENABLE_MASK:
94
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
95
}
96
}
97
98
- hcr_el2 = arm_hcr_el2_eff_secstate(env, is_secure);
99
100
switch (mmu_idx) {
101
case ARMMMUIdx_Stage2:
102
case ARMMMUIdx_Stage2_S:
103
/* HCR.DC means HCR.VM behaves as 1 */
104
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, space);
105
return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
106
107
case ARMMMUIdx_E10_0:
108
case ARMMMUIdx_E10_1:
109
case ARMMMUIdx_E10_1_PAN:
110
/* TGE means that EL0/1 act as if SCTLR_EL1.M is zero */
111
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, space);
112
if (hcr_el2 & HCR_TGE) {
113
return true;
114
}
115
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
116
case ARMMMUIdx_Stage1_E1:
117
case ARMMMUIdx_Stage1_E1_PAN:
118
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
119
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, space);
120
if (hcr_el2 & HCR_DC) {
121
return true;
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool fault_s1ns(ARMSecuritySpace space, ARMMMUIdx s2_mmu_idx)
124
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
125
hwaddr addr, ARMMMUFaultInfo *fi)
126
{
127
- bool is_secure = ptw->in_secure;
128
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
129
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
130
uint8_t pte_attrs;
131
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
132
}
133
134
if (regime_is_stage2(s2_mmu_idx)) {
135
- uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
136
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space);
137
138
if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) {
139
/*
140
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env,
141
ARMMMUFaultInfo *fi)
142
{
143
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
144
- bool is_secure = arm_space_is_secure(ptw->in_space);
145
uint8_t memattr = 0x00; /* Device nGnRnE */
146
uint8_t shareability = 0; /* non-shareable */
147
int r_el;
148
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env,
149
150
/* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
151
if (r_el == 1) {
152
- uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
153
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, ptw->in_space);
154
if (hcr & HCR_DC) {
155
if (hcr & HCR_DCT) {
156
memattr = 0xf0; /* Tagged, Normal, WB, RWA */
157
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
158
{
159
hwaddr ipa;
160
int s1_prot, s1_lgpgsz;
161
- bool is_secure = ptw->in_secure;
162
ARMSecuritySpace in_space = ptw->in_space;
163
bool ret, ipa_secure;
164
ARMCacheAttrs cacheattrs1;
165
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
166
}
167
168
/* Combine the S1 and S2 cache attributes. */
169
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
170
+ hcr = arm_hcr_el2_eff_secstate(env, in_space);
171
if (hcr & HCR_DC) {
172
/*
173
* HCR.DC forces the first stage attributes to
174
--
175
2.34.1
diff view generated by jsdifflib
New patch
1
Pass an ARMSecuritySpace instead of a bool secure to
2
arm_is_el2_enabled_secstate(). This doesn't change behaviour.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230807141514.19075-8-peter.maydell@linaro.org
7
---
8
target/arm/cpu.h | 13 ++++++++-----
9
target/arm/helper.c | 2 +-
10
2 files changed, 9 insertions(+), 6 deletions(-)
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
17
18
/*
19
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
20
- * This corresponds to the pseudocode EL2Enabled()
21
+ * This corresponds to the pseudocode EL2Enabled().
22
*/
23
-static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
24
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env,
25
+ ARMSecuritySpace space)
26
{
27
+ assert(space != ARMSS_Root);
28
return arm_feature(env, ARM_FEATURE_EL2)
29
- && (!secure || (env->cp15.scr_el3 & SCR_EEL2));
30
+ && (space != ARMSS_Secure || (env->cp15.scr_el3 & SCR_EEL2));
31
}
32
33
static inline bool arm_is_el2_enabled(CPUARMState *env)
34
{
35
- return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
36
+ return arm_is_el2_enabled_secstate(env, arm_security_space_below_el3(env));
37
}
38
39
#else
40
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
41
return false;
42
}
43
44
-static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
45
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env,
46
+ ARMSecuritySpace space)
47
{
48
return false;
49
}
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space)
55
56
assert(space != ARMSS_Root);
57
58
- if (!arm_is_el2_enabled_secstate(env, arm_space_is_secure(space))) {
59
+ if (!arm_is_el2_enabled_secstate(env, space)) {
60
/*
61
* "This register has no effect if EL2 is not enabled in the
62
* current Security state". This is ARMv8.4-SecEL2 speak for
63
--
64
2.34.1
diff view generated by jsdifflib
New patch
1
When we do a translation in Secure state, the NSTable bits in table
2
descriptors may downgrade us to NonSecure; we update ptw->in_secure
3
and ptw->in_space accordingly. We guard that check correctly with a
4
conditional that means it's only applied for Secure stage 1
5
translations. However, later on in get_phys_addr_lpae() we fold the
6
effects of the NSTable bits into the final descriptor attributes
7
bits, and there we do it unconditionally regardless of the CPU state.
8
That means that in Realm state (where in_secure is false) we will set
9
bit 5 in attrs, and later use it to decide to output to non-secure
10
space.
1
11
12
We don't in fact need to do this folding in at all any more (since
13
commit 2f1ff4e7b9f30c): if an NSTable bit was set then we have
14
already set ptw->in_space to ARMSS_NonSecure, and in that situation
15
we don't look at attrs bit 5. The only thing we still need to deal
16
with is the real NS bit in the final descriptor word, so we can just
17
drop the code that ORed in the NSTable bit.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20230807141514.19075-9-peter.maydell@linaro.org
22
---
23
target/arm/ptw.c | 3 +--
24
1 file changed, 1 insertion(+), 2 deletions(-)
25
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/ptw.c
29
+++ b/target/arm/ptw.c
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
31
* Extract attributes from the (modified) descriptor, and apply
32
* table descriptors. Stage 2 table descriptors do not include
33
* any attribute fields. HPD disables all the table attributes
34
- * except NSTable.
35
+ * except NSTable (which we have already handled).
36
*/
37
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
38
if (!regime_is_stage2(mmu_idx)) {
39
- attrs |= !ptw->in_secure << 5; /* NS */
40
if (!param.hpd) {
41
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
42
/*
43
--
44
2.34.1
diff view generated by jsdifflib
New patch
1
Replace the last uses of ptw->in_secure with appropriate
2
checks on ptw->in_space.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230807141514.19075-10-peter.maydell@linaro.org
7
---
8
target/arm/ptw.c | 11 +++++++----
9
1 file changed, 7 insertions(+), 4 deletions(-)
10
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
14
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
16
ARMMMUFaultInfo *fi)
17
{
18
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
19
- bool is_secure = ptw->in_secure;
20
ARMMMUIdx s1_mmu_idx;
21
22
/*
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
24
* cannot upgrade a NonSecure translation regime's attributes
25
* to Secure or Realm.
26
*/
27
- result->f.attrs.secure = is_secure;
28
result->f.attrs.space = ptw->in_space;
29
+ result->f.attrs.secure = arm_space_is_secure(ptw->in_space);
30
31
switch (mmu_idx) {
32
case ARMMMUIdx_Phys_S:
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
34
case ARMMMUIdx_Stage1_E0:
35
case ARMMMUIdx_Stage1_E1:
36
case ARMMMUIdx_Stage1_E1_PAN:
37
- /* First stage lookup uses second stage for ptw. */
38
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
39
+ /*
40
+ * First stage lookup uses second stage for ptw; only
41
+ * Secure has both S and NS IPA and starts with Stage2_S.
42
+ */
43
+ ptw->in_ptw_idx = (ptw->in_space == ARMSS_Secure) ?
44
+ ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
45
break;
46
47
case ARMMMUIdx_Stage2:
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
We no longer look at the in_secure field of the S1Translate struct
2
anyway, so we can remove it and all the code which sets it.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230807141514.19075-11-peter.maydell@linaro.org
7
---
8
target/arm/ptw.c | 13 -------------
9
1 file changed, 13 deletions(-)
10
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
14
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
16
* value being Stage2 vs Stage2_S distinguishes those.
17
*/
18
ARMSecuritySpace in_space;
19
- /*
20
- * in_secure: whether the translation regime is a Secure one.
21
- * This is always equal to arm_space_is_secure(in_space).
22
- * If a Secure ptw is "downgraded" to NonSecure by an NSTable bit,
23
- * this field is updated accordingly.
24
- */
25
- bool in_secure;
26
/*
27
* in_debug: is this a QEMU debug access (gdbstub, etc)? Debug
28
* accesses will not update the guest page table access flags
29
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
30
S1Translate s2ptw = {
31
.in_mmu_idx = s2_mmu_idx,
32
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
33
- .in_secure = arm_space_is_secure(s2_space),
34
.in_space = s2_space,
35
.in_debug = true,
36
};
37
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
38
QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
39
QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
40
ptw->in_ptw_idx += 1;
41
- ptw->in_secure = false;
42
ptw->in_space = ARMSS_NonSecure;
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
46
47
ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
48
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
49
- ptw->in_secure = ipa_secure;
50
ptw->in_space = ipa_space;
51
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
52
53
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
54
{
55
S1Translate ptw = {
56
.in_mmu_idx = mmu_idx,
57
- .in_secure = is_secure,
58
.in_space = arm_secure_to_space(is_secure),
59
};
60
return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
61
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
62
}
63
64
ptw.in_space = ss;
65
- ptw.in_secure = arm_space_is_secure(ss);
66
return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
67
}
68
69
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
70
S1Translate ptw = {
71
.in_mmu_idx = mmu_idx,
72
.in_space = ss,
73
- .in_secure = arm_space_is_secure(ss),
74
.in_debug = true,
75
};
76
GetPhysAddrResult res = {};
77
--
78
2.34.1
diff view generated by jsdifflib
1
Instead of making the ROM blob name something like:
1
We only use S1Translate::out_secure in two places, where we are
2
phdr #0: /home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf
2
setting up MemTxAttrs for a page table load. We can use
3
make it a little more self-explanatory for people who don't know
3
arm_space_is_secure(ptw->out_space) instead, which guarantees
4
ELF format details:
4
that we're setting the MemTxAttrs secure and space fields
5
/home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf ELF program header segment 0
5
consistently, and allows us to drop the out_secure field in
6
S1Translate entirely.
6
7
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201129203923.10622-5-peter.maydell@linaro.org
10
Message-id: 20230807141514.19075-12-peter.maydell@linaro.org
10
---
11
---
11
include/hw/elf_ops.h | 3 ++-
12
target/arm/ptw.c | 7 ++-----
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
1 file changed, 2 insertions(+), 5 deletions(-)
13
14
14
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/elf_ops.h
17
--- a/target/arm/ptw.c
17
+++ b/include/hw/elf_ops.h
18
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
if (mem_size != 0) {
20
* Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
20
if (load_rom) {
21
*/
21
g_autofree char *label =
22
bool in_s1_is_el0;
22
- g_strdup_printf("phdr #%d: %s", i, name);
23
- bool out_secure;
23
+ g_strdup_printf("%s ELF program header segment %d",
24
bool out_rw;
24
+ name, i);
25
bool out_be;
25
26
ARMSecuritySpace out_space;
26
/*
27
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
27
* rom_add_elf_program() takes its own reference to
28
pte_attrs = s2.cacheattrs.attrs;
29
ptw->out_host = NULL;
30
ptw->out_rw = false;
31
- ptw->out_secure = s2.f.attrs.secure;
32
ptw->out_space = s2.f.attrs.space;
33
} else {
34
#ifdef CONFIG_TCG
35
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
36
ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
37
ptw->out_rw = full->prot & PAGE_WRITE;
38
pte_attrs = full->pte_attrs;
39
- ptw->out_secure = full->attrs.secure;
40
ptw->out_space = full->attrs.space;
41
#else
42
g_assert_not_reached();
43
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
44
} else {
45
/* Page tables are in MMIO. */
46
MemTxAttrs attrs = {
47
- .secure = ptw->out_secure,
48
.space = ptw->out_space,
49
+ .secure = arm_space_is_secure(ptw->out_space),
50
};
51
AddressSpace *as = arm_addressspace(cs, attrs);
52
MemTxResult result = MEMTX_OK;
53
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
54
} else {
55
/* Page tables are in MMIO. */
56
MemTxAttrs attrs = {
57
- .secure = ptw->out_secure,
58
.space = ptw->out_space,
59
+ .secure = arm_space_is_secure(ptw->out_space),
60
};
61
AddressSpace *as = arm_addressspace(cs, attrs);
62
MemTxResult result = MEMTX_OK;
28
--
63
--
29
2.20.1
64
2.34.1
30
31
diff view generated by jsdifflib
1
Currently the load_elf code assembles the ROM blob name into a
1
When the MMU is disabled, data accesses should be Device nGnRnE,
2
local 128 byte fixed-size array. Use g_strdup_printf() instead so
2
Outer Shareable, Untagged. We handle the other cases from
3
that we don't truncate the pathname if it happens to be long.
3
AArch64.S1DisabledOutput() correctly but missed this one.
4
(This matters mostly for monitor 'info roms' output and for the
4
Device nGnRnE is memattr == 0, so the only part we were missing
5
error messages if ROM blobs overlap.)
5
was that shareability should be set to 2 for both insn fetches
6
and data accesses.
6
7
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201129203923.10622-4-peter.maydell@linaro.org
10
Message-id: 20230807141514.19075-13-peter.maydell@linaro.org
10
---
11
---
11
include/hw/elf_ops.h | 4 ++--
12
target/arm/ptw.c | 12 +++++++-----
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
1 file changed, 7 insertions(+), 5 deletions(-)
13
14
14
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/elf_ops.h
17
--- a/target/arm/ptw.c
17
+++ b/include/hw/elf_ops.h
18
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env,
19
uint64_t addr, low = (uint64_t)-1, high = 0;
20
}
20
GMappedFile *mapped_file = NULL;
21
}
21
uint8_t *data = NULL;
22
}
22
- char label[128];
23
- if (memattr == 0 && access_type == MMU_INST_FETCH) {
23
int ret = ELF_LOAD_FAILED;
24
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
24
25
- memattr = 0xee; /* Normal, WT, RA, NT */
25
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
26
- } else {
26
@@ -XXX,XX +XXX,XX @@ static int glue(load_elf, SZ)(const char *name, int fd,
27
- memattr = 0x44; /* Normal, NC, No */
27
*/
28
+ if (memattr == 0) {
28
if (mem_size != 0) {
29
+ if (access_type == MMU_INST_FETCH) {
29
if (load_rom) {
30
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
30
- snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
31
+ memattr = 0xee; /* Normal, WT, RA, NT */
31
+ g_autofree char *label =
32
+ } else {
32
+ g_strdup_printf("phdr #%d: %s", i, name);
33
+ memattr = 0x44; /* Normal, NC, No */
33
34
+ }
34
/*
35
}
35
* rom_add_elf_program() takes its own reference to
36
shareability = 2; /* outer shareable */
37
}
36
--
38
--
37
2.20.1
39
2.34.1
38
39
diff view generated by jsdifflib
1
The function nios2_check_interrupts)() looks only at CPU-internal
1
The architecture doesn't permit block descriptors at any arbitrary
2
state; it belongs in target/nios2, not hw/nios2. Move it into the
2
level of the page table walk; it depends on the granule size which
3
same file as its only caller, so it can just be local to that file.
3
levels are permitted. We implemented only a partial version of this
4
check which assumes that block descriptors are valid at all levels
5
except level 3, which meant that we wouldn't deliver the Translation
6
fault for all cases of this sort of guest page table error.
4
7
5
This removes the only remaining code from cpu_pic.c, so we can delete
8
Implement the logic corresponding to the pseudocode
6
that file entirely.
9
AArch64.DecodeDescriptorType() and AArch64.BlockDescSupported().
7
10
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20201129174022.26530-3-peter.maydell@linaro.org
13
Message-id: 20230807141514.19075-14-peter.maydell@linaro.org
11
Reviewed-by: Wentong Wu <wentong.wu@intel.com>
12
Tested-by: Wentong Wu <wentong.wu@intel.com>
13
---
14
---
14
target/nios2/cpu.h | 2 --
15
target/arm/ptw.c | 25 +++++++++++++++++++++++--
15
hw/nios2/cpu_pic.c | 36 ------------------------------------
16
1 file changed, 23 insertions(+), 2 deletions(-)
16
target/nios2/op_helper.c | 9 +++++++++
17
hw/nios2/meson.build | 2 +-
18
4 files changed, 10 insertions(+), 39 deletions(-)
19
delete mode 100644 hw/nios2/cpu_pic.c
20
17
21
diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/nios2/cpu.h
20
--- a/target/arm/ptw.c
24
+++ b/target/nios2/cpu.h
21
+++ b/target/arm/ptw.c
25
@@ -XXX,XX +XXX,XX @@ void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
22
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
26
MMUAccessType access_type,
23
return INT_MIN;
27
int mmu_idx, uintptr_t retaddr);
28
29
-void nios2_check_interrupts(CPUNios2State *env);
30
-
31
void do_nios2_semihosting(CPUNios2State *env);
32
33
#define CPU_RESOLVING_TYPE TYPE_NIOS2_CPU
34
diff --git a/hw/nios2/cpu_pic.c b/hw/nios2/cpu_pic.c
35
deleted file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- a/hw/nios2/cpu_pic.c
38
+++ /dev/null
39
@@ -XXX,XX +XXX,XX @@
40
-/*
41
- * Altera Nios2 CPU PIC
42
- *
43
- * Copyright (c) 2016 Marek Vasut <marek.vasut@gmail.com>
44
- *
45
- * This library is free software; you can redistribute it and/or
46
- * modify it under the terms of the GNU Lesser General Public
47
- * License as published by the Free Software Foundation; either
48
- * version 2.1 of the License, or (at your option) any later version.
49
- *
50
- * This library is distributed in the hope that it will be useful,
51
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53
- * Lesser General Public License for more details.
54
- *
55
- * You should have received a copy of the GNU Lesser General Public
56
- * License along with this library; if not, see
57
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
58
- */
59
-
60
-#include "qemu/osdep.h"
61
-#include "cpu.h"
62
-#include "hw/irq.h"
63
-
64
-#include "qemu/config-file.h"
65
-
66
-#include "boot.h"
67
-
68
-void nios2_check_interrupts(CPUNios2State *env)
69
-{
70
- if (env->irq_pending &&
71
- (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
72
- env->irq_pending = 0;
73
- cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
74
- }
75
-}
76
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/nios2/op_helper.c
79
+++ b/target/nios2/op_helper.c
80
@@ -XXX,XX +XXX,XX @@ void helper_mmu_write(CPUNios2State *env, uint32_t rn, uint32_t v)
81
mmu_write(env, rn, v);
82
}
24
}
83
25
84
+static void nios2_check_interrupts(CPUNios2State *env)
26
+static bool lpae_block_desc_valid(ARMCPU *cpu, bool ds,
27
+ ARMGranuleSize gran, int level)
85
+{
28
+{
86
+ if (env->irq_pending &&
29
+ /*
87
+ (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
30
+ * See pseudocode AArch46.BlockDescSupported(): block descriptors
88
+ env->irq_pending = 0;
31
+ * are not valid at all levels, depending on the page size.
89
+ cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HARD);
32
+ */
33
+ switch (gran) {
34
+ case Gran4K:
35
+ return (level == 0 && ds) || level == 1 || level == 2;
36
+ case Gran16K:
37
+ return (level == 1 && ds) || level == 2;
38
+ case Gran64K:
39
+ return (level == 1 && arm_pamax(cpu) == 52) || level == 2;
40
+ default:
41
+ g_assert_not_reached();
90
+ }
42
+ }
91
+}
43
+}
92
+
44
+
93
void helper_check_interrupts(CPUNios2State *env)
45
/**
94
{
46
* get_phys_addr_lpae: perform one stage of page table walk, LPAE format
95
qemu_mutex_lock_iothread();
47
*
96
diff --git a/hw/nios2/meson.build b/hw/nios2/meson.build
48
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
97
index XXXXXXX..XXXXXXX 100644
49
new_descriptor = descriptor;
98
--- a/hw/nios2/meson.build
50
99
+++ b/hw/nios2/meson.build
51
restart_atomic_update:
100
@@ -XXX,XX +XXX,XX @@
52
- if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
101
nios2_ss = ss.source_set()
53
- /* Invalid, or the Reserved level 3 encoding */
102
-nios2_ss.add(files('boot.c', 'cpu_pic.c'))
54
+ if (!(descriptor & 1) ||
103
+nios2_ss.add(files('boot.c'))
55
+ (!(descriptor & 2) &&
104
nios2_ss.add(when: 'CONFIG_NIOS2_10M50', if_true: files('10m50_devboard.c'))
56
+ !lpae_block_desc_valid(cpu, param.ds, param.gran, level))) {
105
nios2_ss.add(when: 'CONFIG_NIOS2_GENERIC_NOMMU', if_true: files('generic_nommu.c'))
57
+ /* Invalid, or a block descriptor at an invalid level */
58
goto do_translation_fault;
59
}
106
60
107
--
61
--
108
2.20.1
62
2.34.1
109
110
diff view generated by jsdifflib
1
openrisc_sim_net_init() attempts to connect the IRQ line from the
1
When we report faults due to stage 2 faults during a stage 1
2
ethernet device to both CPUs in an SMP configuration by simply caling
2
page table walk, the 'level' parameter should be the level
3
sysbus_connect_irq() for it twice. This doesn't work, because the
3
of the walk in stage 2 that faulted, not the level of the
4
second connection simply overrides the first.
4
walk in stage 1. Correct the reporting of these faults.
5
6
Fix this by creating a TYPE_SPLIT_IRQ to split the IRQ in the SMP
7
case.
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Stafford Horne <shorne@gmail.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201127225127.14770-2-peter.maydell@linaro.org
8
Message-id: 20230807141514.19075-15-peter.maydell@linaro.org
12
---
9
---
13
hw/openrisc/openrisc_sim.c | 13 +++++++++++--
10
target/arm/ptw.c | 10 +++++++---
14
hw/openrisc/Kconfig | 1 +
11
1 file changed, 7 insertions(+), 3 deletions(-)
15
2 files changed, 12 insertions(+), 2 deletions(-)
16
12
17
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/openrisc/openrisc_sim.c
15
--- a/target/arm/ptw.c
20
+++ b/hw/openrisc/openrisc_sim.c
16
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
22
#include "hw/sysbus.h"
18
do_translation_fault:
23
#include "sysemu/qtest.h"
19
fi->type = ARMFault_Translation;
24
#include "sysemu/reset.h"
20
do_fault:
25
+#include "hw/core/split-irq.h"
21
- fi->level = level;
26
22
- /* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
27
#define KERNEL_LOAD_ADDR 0x100
23
- fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx);
28
24
+ if (fi->s1ptw) {
29
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
25
+ /* Retain the existing stage 2 fi->level */
30
26
+ assert(fi->stage2);
31
s = SYS_BUS_DEVICE(dev);
32
sysbus_realize_and_unref(s, &error_fatal);
33
- for (i = 0; i < num_cpus; i++) {
34
- sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
35
+ if (num_cpus > 1) {
36
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
37
+ qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
38
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
39
+ for (i = 0; i < num_cpus; i++) {
40
+ qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
41
+ }
42
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
43
+ } else {
27
+ } else {
44
+ sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
28
+ fi->level = level;
45
}
29
+ fi->stage2 = regime_is_stage2(mmu_idx);
46
sysbus_mmio_map(s, 0, base);
30
+ }
47
sysbus_mmio_map(s, 1, descriptors);
31
fi->s1ns = fault_s1ns(ptw->in_space, mmu_idx);
48
diff --git a/hw/openrisc/Kconfig b/hw/openrisc/Kconfig
32
return true;
49
index XXXXXXX..XXXXXXX 100644
33
}
50
--- a/hw/openrisc/Kconfig
51
+++ b/hw/openrisc/Kconfig
52
@@ -XXX,XX +XXX,XX @@ config OR1K_SIM
53
select SERIAL
54
select OPENCORES_ETH
55
select OMPIC
56
+ select SPLIT_IRQ
57
--
34
--
58
2.20.1
35
2.34.1
59
60
diff view generated by jsdifflib
1
In rom_check_and_register_reset() we report to the user if there is
1
The PAR_EL1.SH field documents that for the cases of:
2
a "ROM region overlap". This has a couple of problems:
2
* Device memory
3
* the reported information is not very easy to intepret
3
* Normal memory with both Inner and Outer Non-Cacheable
4
* the function just prints the overlap to stderr (and relies on
4
the field should be 0b10 rather than whatever was in the
5
its single callsite in vl.c to do an error_report() and exit)
5
translation table descriptor field. (In the pseudocode this
6
* only the first overlap encountered is diagnosed
6
is handled by PAREncodeShareability().) Perform this
7
7
adjustment when assembling a PAR value.
8
Make this function use error_report() and error_printf() and
9
report a more user-friendly report with all the overlaps
10
diagnosed.
11
12
Sample old output:
13
14
rom: requested regions overlap (rom dtb. free=0x0000000000008000, addr=0x0000000000000000)
15
qemu-system-aarch64: rom check and register reset failed
16
17
Sample new output:
18
19
qemu-system-aarch64: Some ROM regions are overlapping
20
These ROM regions might have been loaded by direct user request or by default.
21
They could be BIOS/firmware images, a guest kernel, initrd or some other file loaded into guest memory.
22
Check whether you intended to load all this guest code, and whether it has been built to load to the correct addresses.
23
24
The following two regions overlap (in the cpu-memory-0 address space):
25
phdr #0: /home/petmay01/linaro/qemu-misc-tests/ldmia-fault.axf (addresses 0x0000000000000000 - 0x0000000000008000)
26
dtb (addresses 0x0000000000000000 - 0x0000000000100000)
27
28
The following two regions overlap (in the cpu-memory-0 address space):
29
phdr #1: /home/petmay01/linaro/qemu-misc-tests/bad-psci-call.axf (addresses 0x0000000040000000 - 0x0000000040000010)
30
phdr #0: /home/petmay01/linaro/qemu-misc-tests/bp-test.elf (addresses 0x0000000040000000 - 0x0000000040000020)
31
8
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-id: 20201129203923.10622-3-peter.maydell@linaro.org
11
Message-id: 20230807141514.19075-16-peter.maydell@linaro.org
35
---
12
---
36
hw/core/loader.c | 48 ++++++++++++++++++++++++++++++++++++++++++------
13
target/arm/helper.c | 15 ++++++++++++++-
37
softmmu/vl.c | 1 -
14
1 file changed, 14 insertions(+), 1 deletion(-)
38
2 files changed, 42 insertions(+), 7 deletions(-)
39
15
40
diff --git a/hw/core/loader.c b/hw/core/loader.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/core/loader.c
18
--- a/target/arm/helper.c
43
+++ b/hw/core/loader.c
19
+++ b/target/arm/helper.c
44
@@ -XXX,XX +XXX,XX @@ static bool roms_overlap(Rom *last_rom, Rom *this_rom)
20
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
45
last_rom->addr + last_rom->romsize > this_rom->addr;
46
}
21
}
47
22
48
+static const char *rom_as_name(Rom *rom)
23
#ifdef CONFIG_TCG
24
+static int par_el1_shareability(GetPhysAddrResult *res)
49
+{
25
+{
50
+ const char *name = rom->as ? rom->as->name : NULL;
26
+ /*
51
+ return name ?: "anonymous";
27
+ * The PAR_EL1.SH field must be 0b10 for Device or Normal-NC
28
+ * memory -- see pseudocode PAREncodeShareability().
29
+ */
30
+ if (((res->cacheattrs.attrs & 0xf0) == 0) ||
31
+ res->cacheattrs.attrs == 0x44 || res->cacheattrs.attrs == 0x40) {
32
+ return 2;
33
+ }
34
+ return res->cacheattrs.shareability;
52
+}
35
+}
53
+
36
+
54
+static void rom_print_overlap_error_header(void)
37
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
55
+{
38
MMUAccessType access_type, ARMMMUIdx mmu_idx,
56
+ error_report("Some ROM regions are overlapping");
39
bool is_secure)
57
+ error_printf(
40
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
58
+ "These ROM regions might have been loaded by "
41
par64 |= (1 << 9); /* NS */
59
+ "direct user request or by default.\n"
60
+ "They could be BIOS/firmware images, a guest kernel, "
61
+ "initrd or some other file loaded into guest memory.\n"
62
+ "Check whether you intended to load all this guest code, and "
63
+ "whether it has been built to load to the correct addresses.\n");
64
+}
65
+
66
+static void rom_print_one_overlap_error(Rom *last_rom, Rom *rom)
67
+{
68
+ error_printf(
69
+ "\nThe following two regions overlap (in the %s address space):\n",
70
+ rom_as_name(rom));
71
+ error_printf(
72
+ " %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
73
+ last_rom->name, last_rom->addr, last_rom->addr + last_rom->romsize);
74
+ error_printf(
75
+ " %s (addresses 0x" TARGET_FMT_plx " - 0x" TARGET_FMT_plx ")\n",
76
+ rom->name, rom->addr, rom->addr + rom->romsize);
77
+}
78
+
79
int rom_check_and_register_reset(void)
80
{
81
MemoryRegionSection section;
82
Rom *rom, *last_rom = NULL;
83
+ bool found_overlap = false;
84
85
QTAILQ_FOREACH(rom, &roms, next) {
86
if (rom->fw_file) {
87
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void)
88
}
89
if (!rom->mr) {
90
if (roms_overlap(last_rom, rom)) {
91
- fprintf(stderr, "rom: requested regions overlap "
92
- "(rom %s. free=0x" TARGET_FMT_plx
93
- ", addr=0x" TARGET_FMT_plx ")\n",
94
- rom->name, last_rom->addr + last_rom->romsize,
95
- rom->addr);
96
- return -1;
97
+ if (!found_overlap) {
98
+ found_overlap = true;
99
+ rom_print_overlap_error_header();
100
+ }
101
+ rom_print_one_overlap_error(last_rom, rom);
102
+ /* Keep going through the list so we report all overlaps */
103
}
42
}
104
last_rom = rom;
43
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
105
}
44
- par64 |= res.cacheattrs.shareability << 7; /* SH */
106
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void)
45
+ par64 |= par_el1_shareability(&res) << 7; /* SH */
107
rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr);
46
} else {
108
memory_region_unref(section.mr);
47
uint32_t fsr = arm_fi_to_lfsc(&fi);
109
}
110
+ if (found_overlap) {
111
+ return -1;
112
+ }
113
+
114
qemu_register_reset(rom_reset, NULL);
115
roms_loaded = 1;
116
return 0;
117
diff --git a/softmmu/vl.c b/softmmu/vl.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/softmmu/vl.c
120
+++ b/softmmu/vl.c
121
@@ -XXX,XX +XXX,XX @@ static void qemu_machine_creation_done(void)
122
qemu_run_machine_init_done_notifiers();
123
124
if (rom_check_and_register_reset() != 0) {
125
- error_report("rom check and register reset failed");
126
exit(1);
127
}
128
48
129
--
49
--
130
2.20.1
50
2.34.1
131
132
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
The previous naming of the configuration registers made it sound like that if
3
In realm state, stage-2 translation tables are fetched from the realm
4
the bits were set the settings would be enabled, while the opposite is true.
4
physical address space (R_PGRQD).
5
5
6
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
6
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1605568264-26376-2-git-send-email-komlodi@xilinx.com
8
Message-id: 20230809123706.1842548-2-jean-philippe@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 | 12 ++++++------
11
target/arm/ptw.c | 26 ++++++++++++++++++--------
12
1 file changed, 6 insertions(+), 6 deletions(-)
12
1 file changed, 18 insertions(+), 8 deletions(-)
13
13
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/m25p80.c
16
--- a/target/arm/ptw.c
17
+++ b/hw/block/m25p80.c
17
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct FlashPartInfo {
18
@@ -XXX,XX +XXX,XX @@ static ARMMMUIdx ptw_idx_for_stage_2(CPUARMState *env, ARMMMUIdx stage2idx)
19
#define VCFG_WRAP_SEQUENTIAL 0x2
19
20
#define NVCFG_XIP_MODE_DISABLED (7 << 9)
20
/*
21
#define NVCFG_XIP_MODE_MASK (7 << 9)
21
* We're OK to check the current state of the CPU here because
22
-#define VCFG_XIP_MODE_ENABLED (1 << 3)
22
- * (1) we always invalidate all TLBs when the SCR_EL3.NS bit changes
23
+#define VCFG_XIP_MODE_DISABLED (1 << 3)
23
+ * (1) we always invalidate all TLBs when the SCR_EL3.NS or SCR_EL3.NSE bit
24
#define CFG_DUMMY_CLK_LEN 4
24
+ * changes.
25
#define NVCFG_DUMMY_CLK_POS 12
25
* (2) there's no way to do a lookup that cares about Stage 2 for a
26
#define VCFG_DUMMY_CLK_POS 4
26
* different security state to the current one for AArch64, and AArch32
27
@@ -XXX,XX +XXX,XX @@ typedef struct FlashPartInfo {
27
* never has a secure EL2. (AArch32 ATS12NSO[UP][RW] allow EL3 to do
28
#define EVCFG_VPP_ACCELERATOR (1 << 3)
28
* an NS stage 1+2 lookup while the NS bit is 0.)
29
#define EVCFG_RESET_HOLD_ENABLED (1 << 4)
29
*/
30
#define NVCFG_DUAL_IO_MASK (1 << 2)
30
- if (!arm_is_secure_below_el3(env) || !arm_el_is_aa64(env, 3)) {
31
-#define EVCFG_DUAL_IO_ENABLED (1 << 6)
31
+ if (!arm_el_is_aa64(env, 3)) {
32
+#define EVCFG_DUAL_IO_DISABLED (1 << 6)
32
return ARMMMUIdx_Phys_NS;
33
#define NVCFG_QUAD_IO_MASK (1 << 3)
33
}
34
-#define EVCFG_QUAD_IO_ENABLED (1 << 7)
34
- if (stage2idx == ARMMMUIdx_Stage2_S) {
35
+#define EVCFG_QUAD_IO_DISABLED (1 << 7)
35
- s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
36
#define NVCFG_4BYTE_ADDR_MASK (1 << 0)
36
- } else {
37
#define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
37
- s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
38
38
- }
39
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
39
- return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
40
s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
40
41
if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK)
41
+ switch (arm_security_space_below_el3(env)) {
42
!= NVCFG_XIP_MODE_DISABLED) {
42
+ case ARMSS_NonSecure:
43
- s->volatile_cfg |= VCFG_XIP_MODE_ENABLED;
43
+ return ARMMMUIdx_Phys_NS;
44
+ s->volatile_cfg |= VCFG_XIP_MODE_DISABLED;
44
+ case ARMSS_Realm:
45
}
45
+ return ARMMMUIdx_Phys_Realm;
46
s->volatile_cfg |= deposit32(s->volatile_cfg,
46
+ case ARMSS_Secure:
47
VCFG_DUMMY_CLK_POS,
47
+ if (stage2idx == ARMMMUIdx_Stage2_S) {
48
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
48
+ s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
49
s->enh_volatile_cfg |= EVCFG_VPP_ACCELERATOR;
49
+ } else {
50
s->enh_volatile_cfg |= EVCFG_RESET_HOLD_ENABLED;
50
+ s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
51
if (s->nonvolatile_cfg & NVCFG_DUAL_IO_MASK) {
51
+ }
52
- s->enh_volatile_cfg |= EVCFG_DUAL_IO_ENABLED;
52
+ return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
53
+ s->enh_volatile_cfg |= EVCFG_DUAL_IO_DISABLED;
53
+ default:
54
}
54
+ g_assert_not_reached();
55
if (s->nonvolatile_cfg & NVCFG_QUAD_IO_MASK) {
55
+ }
56
- s->enh_volatile_cfg |= EVCFG_QUAD_IO_ENABLED;
56
}
57
+ s->enh_volatile_cfg |= EVCFG_QUAD_IO_DISABLED;
57
58
}
58
static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
59
if (!(s->nonvolatile_cfg & NVCFG_4BYTE_ADDR_MASK)) {
60
s->four_bytes_address_mode = true;
61
--
59
--
62
2.20.1
60
2.34.1
63
64
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
This model is a top level integration wrapper for hcd-dwc3 and
3
When HCR_EL2.E2H is enabled, TLB entries are formed using the EL2&0
4
versal-usb2-ctrl-regs modules, this is used by xilinx versal soc's and
4
translation regime, instead of the EL2 translation regime. The TLB VAE2*
5
future xilinx usb subsystems would also be part of it.
5
instructions invalidate the regime that corresponds to the current value
6
of HCR_EL2.E2H.
6
7
7
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
8
At the moment we only invalidate the EL2 translation regime. This causes
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
problems with RMM, which issues TLBI VAE2IS instructions with
10
HCR_EL2.E2H enabled. Update vae2_tlbmask() to take HCR_EL2.E2H into
11
account.
12
13
Add vae2_tlbbits() as well, since the top-byte-ignore configuration is
14
different between the EL2&0 and EL2 regime.
15
16
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 1607023357-5096-4-git-send-email-sai.pavan.boddu@xilinx.com
18
Message-id: 20230809123706.1842548-3-jean-philippe@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
20
---
13
include/hw/usb/xlnx-usb-subsystem.h | 45 ++++++++++++++
21
target/arm/helper.c | 50 ++++++++++++++++++++++++++++++++++++---------
14
hw/usb/xlnx-usb-subsystem.c | 94 +++++++++++++++++++++++++++++
22
1 file changed, 40 insertions(+), 10 deletions(-)
15
hw/usb/Kconfig | 5 ++
16
hw/usb/meson.build | 1 +
17
4 files changed, 145 insertions(+)
18
create mode 100644 include/hw/usb/xlnx-usb-subsystem.h
19
create mode 100644 hw/usb/xlnx-usb-subsystem.c
20
23
21
diff --git a/include/hw/usb/xlnx-usb-subsystem.h b/include/hw/usb/xlnx-usb-subsystem.h
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
new file mode 100644
25
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX
26
--- a/target/arm/helper.c
24
--- /dev/null
27
+++ b/target/arm/helper.c
25
+++ b/include/hw/usb/xlnx-usb-subsystem.h
28
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
26
@@ -XXX,XX +XXX,XX @@
29
return mask;
27
+/*
30
}
28
+ * QEMU model of the Xilinx usb subsystem
31
29
+ *
32
+static int vae2_tlbmask(CPUARMState *env)
30
+ * Copyright (c) 2020 Xilinx Inc. Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
33
+{
31
+ *
34
+ uint64_t hcr = arm_hcr_el2_eff(env);
32
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ uint16_t mask;
33
+ * of this software and associated documentation files (the "Software"), to deal
34
+ * in the Software without restriction, including without limitation the rights
35
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ * copies of the Software, and to permit persons to whom the Software is
37
+ * furnished to do so, subject to the following conditions:
38
+ *
39
+ * The above copyright notice and this permission notice shall be included in
40
+ * all copies or substantial portions of the Software.
41
+ *
42
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
45
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48
+ * THE SOFTWARE.
49
+ */
50
+
36
+
51
+#ifndef _XLNX_VERSAL_USB_SUBSYSTEM_H_
37
+ if (hcr & HCR_E2H) {
52
+#define _XLNX_VERSAL_USB_SUBSYSTEM_H_
38
+ mask = ARMMMUIdxBit_E20_2 |
53
+
39
+ ARMMMUIdxBit_E20_2_PAN |
54
+#include "hw/usb/xlnx-versal-usb2-ctrl-regs.h"
40
+ ARMMMUIdxBit_E20_0;
55
+#include "hw/usb/hcd-dwc3.h"
41
+ } else {
56
+
42
+ mask = ARMMMUIdxBit_E2;
57
+#define TYPE_XILINX_VERSAL_USB2 "xlnx.versal-usb2"
58
+
59
+#define VERSAL_USB2(obj) \
60
+ OBJECT_CHECK(VersalUsb2, (obj), TYPE_XILINX_VERSAL_USB2)
61
+
62
+typedef struct VersalUsb2 {
63
+ SysBusDevice parent_obj;
64
+ MemoryRegion dwc3_mr;
65
+ MemoryRegion usb2Ctrl_mr;
66
+
67
+ VersalUsb2CtrlRegs usb2Ctrl;
68
+ USBDWC3 dwc3;
69
+} VersalUsb2;
70
+
71
+#endif
72
diff --git a/hw/usb/xlnx-usb-subsystem.c b/hw/usb/xlnx-usb-subsystem.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/usb/xlnx-usb-subsystem.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * QEMU model of the Xilinx usb subsystem
80
+ *
81
+ * Copyright (c) 2020 Xilinx Inc. Sai Pavan Boddu <sai.pava.boddu@xilinx.com>
82
+ *
83
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
84
+ * of this software and associated documentation files (the "Software"), to deal
85
+ * in the Software without restriction, including without limitation the rights
86
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
87
+ * copies of the Software, and to permit persons to whom the Software is
88
+ * furnished to do so, subject to the following conditions:
89
+ *
90
+ * The above copyright notice and this permission notice shall be included in
91
+ * all copies or substantial portions of the Software.
92
+ *
93
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
96
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
98
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
99
+ * THE SOFTWARE.
100
+ */
101
+
102
+#include "qemu/osdep.h"
103
+#include "hw/sysbus.h"
104
+#include "hw/irq.h"
105
+#include "hw/register.h"
106
+#include "qemu/bitops.h"
107
+#include "qemu/log.h"
108
+#include "qom/object.h"
109
+#include "qapi/error.h"
110
+#include "hw/qdev-properties.h"
111
+#include "hw/usb/xlnx-usb-subsystem.h"
112
+
113
+static void versal_usb2_realize(DeviceState *dev, Error **errp)
114
+{
115
+ VersalUsb2 *s = VERSAL_USB2(dev);
116
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
117
+ Error *err = NULL;
118
+
119
+ sysbus_realize(SYS_BUS_DEVICE(&s->dwc3), &err);
120
+ if (err) {
121
+ error_propagate(errp, err);
122
+ return;
123
+ }
43
+ }
124
+ sysbus_realize(SYS_BUS_DEVICE(&s->usb2Ctrl), &err);
44
+ return mask;
125
+ if (err) {
126
+ error_propagate(errp, err);
127
+ return;
128
+ }
129
+ sysbus_init_mmio(sbd, &s->dwc3_mr);
130
+ sysbus_init_mmio(sbd, &s->usb2Ctrl_mr);
131
+ qdev_pass_gpios(DEVICE(&s->dwc3.sysbus_xhci), dev, SYSBUS_DEVICE_GPIO_IRQ);
132
+}
45
+}
133
+
46
+
134
+static void versal_usb2_init(Object *obj)
47
/* Return 56 if TBI is enabled, 64 otherwise. */
48
static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
49
uint64_t addr)
50
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
51
return tlbbits_for_regime(env, mmu_idx, addr);
52
}
53
54
+static int vae2_tlbbits(CPUARMState *env, uint64_t addr)
135
+{
55
+{
136
+ VersalUsb2 *s = VERSAL_USB2(obj);
56
+ uint64_t hcr = arm_hcr_el2_eff(env);
57
+ ARMMMUIdx mmu_idx;
137
+
58
+
138
+ object_initialize_child(obj, "versal.dwc3", &s->dwc3,
59
+ /*
139
+ TYPE_USB_DWC3);
60
+ * Only the regime of the mmu_idx below is significant.
140
+ object_initialize_child(obj, "versal.usb2-ctrl", &s->usb2Ctrl,
61
+ * Regime EL2&0 has two ranges with separate TBI configuration, while EL2
141
+ TYPE_XILINX_VERSAL_USB2_CTRL_REGS);
62
+ * only has one.
142
+ memory_region_init_alias(&s->dwc3_mr, obj, "versal.dwc3_alias",
63
+ */
143
+ &s->dwc3.iomem, 0, DWC3_SIZE);
64
+ if (hcr & HCR_E2H) {
144
+ memory_region_init_alias(&s->usb2Ctrl_mr, obj, "versal.usb2Ctrl_alias",
65
+ mmu_idx = ARMMMUIdx_E20_2;
145
+ &s->usb2Ctrl.iomem, 0, USB2_REGS_R_MAX * 4);
66
+ } else {
146
+ qdev_alias_all_properties(DEVICE(&s->dwc3), obj);
67
+ mmu_idx = ARMMMUIdx_E2;
147
+ qdev_alias_all_properties(DEVICE(&s->dwc3.sysbus_xhci), obj);
68
+ }
148
+ object_property_add_alias(obj, "dma", OBJECT(&s->dwc3.sysbus_xhci), "dma");
69
+
70
+ return tlbbits_for_regime(env, mmu_idx, addr);
149
+}
71
+}
150
+
72
+
151
+static void versal_usb2_class_init(ObjectClass *klass, void *data)
73
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
152
+{
74
uint64_t value)
153
+ DeviceClass *dc = DEVICE_CLASS(klass);
75
{
154
+
76
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
155
+ dc->realize = versal_usb2_realize;
77
* flush-last-level-only.
156
+}
78
*/
157
+
79
CPUState *cs = env_cpu(env);
158
+static const TypeInfo versal_usb2_info = {
80
- int mask = e2_tlbmask(env);
159
+ .name = TYPE_XILINX_VERSAL_USB2,
81
+ int mask = vae2_tlbmask(env);
160
+ .parent = TYPE_SYS_BUS_DEVICE,
82
uint64_t pageaddr = sextract64(value << 12, 0, 56);
161
+ .instance_size = sizeof(VersalUsb2),
83
+ int bits = vae2_tlbbits(env, pageaddr);
162
+ .class_init = versal_usb2_class_init,
84
163
+ .instance_init = versal_usb2_init,
85
- tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
164
+};
86
+ tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
165
+
87
}
166
+static void versal_usb_types(void)
88
167
+{
89
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
168
+ type_register_static(&versal_usb2_info);
90
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
169
+}
91
uint64_t value)
170
+
92
{
171
+type_init(versal_usb_types)
93
CPUState *cs = env_cpu(env);
172
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
94
+ int mask = vae2_tlbmask(env);
173
index XXXXXXX..XXXXXXX 100644
95
uint64_t pageaddr = sextract64(value << 12, 0, 56);
174
--- a/hw/usb/Kconfig
96
- int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
175
+++ b/hw/usb/Kconfig
97
+ int bits = vae2_tlbbits(env, pageaddr);
176
@@ -XXX,XX +XXX,XX @@ config USB_DWC3
98
177
bool
99
- tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
178
select USB_XHCI_SYSBUS
100
- ARMMMUIdxBit_E2, bits);
179
select REGISTER
101
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
180
+
102
}
181
+config XLNX_USB_SUBSYS
103
182
+ bool
104
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
+ default y if XLNX_VERSAL
105
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
184
+ select USB_DWC3
106
do_rvae_write(env, value, vae1_tlbmask(env), true);
185
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
107
}
186
index XXXXXXX..XXXXXXX 100644
108
187
--- a/hw/usb/meson.build
109
-static int vae2_tlbmask(CPUARMState *env)
188
+++ b/hw/usb/meson.build
110
-{
189
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
111
- return ARMMMUIdxBit_E2;
190
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
112
-}
191
softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
113
-
192
specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c'))
114
static void tlbi_aa64_rvae2_write(CPUARMState *env,
193
+specific_ss.add(when: 'CONFIG_XLNX_USB_SUBSYS', if_true: files('xlnx-usb-subsystem.c'))
115
const ARMCPRegInfo *ri,
194
116
uint64_t value)
195
# emulated usb devices
196
softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c'))
197
--
117
--
198
2.20.1
118
2.34.1
199
200
diff view generated by jsdifflib
1
From: Vikram Garhwal <fnu.vikram@xilinx.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Connect VersalUsb2 subsystem to xlnx-versal SOC, its placed
3
GPC checks are not performed on the output address for AT instructions,
4
in iou of lpd domain and configure it as dual port host controller.
4
as stated by ARM DDI 0487J in D8.12.2:
5
Add the respective guest dts nodes for "xlnx-versal-virt" machine.
6
5
7
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
6
When populating PAR_EL1 with the result of an address translation
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
7
instruction, granule protection checks are not performed on the final
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
output address of a successful translation.
10
Message-id: 1607023357-5096-5-git-send-email-sai.pavan.boddu@xilinx.com
9
10
Rename get_phys_addr_with_secure(), since it's only used to handle AT
11
instructions.
12
13
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20230809123706.1842548-4-jean-philippe@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
include/hw/arm/xlnx-versal.h | 9 ++++++
18
target/arm/internals.h | 25 ++++++++++++++-----------
14
hw/arm/xlnx-versal-virt.c | 55 ++++++++++++++++++++++++++++++++++++
19
target/arm/helper.c | 8 ++++++--
15
hw/arm/xlnx-versal.c | 26 +++++++++++++++++
20
target/arm/ptw.c | 11 ++++++-----
16
3 files changed, 90 insertions(+)
21
3 files changed, 26 insertions(+), 18 deletions(-)
17
22
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
25
--- a/target/arm/internals.h
21
+++ b/include/hw/arm/xlnx-versal.h
26
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
23
#include "hw/net/cadence_gem.h"
28
} GetPhysAddrResult;
24
#include "hw/rtc/xlnx-zynqmp-rtc.h"
29
25
#include "qom/object.h"
30
/**
26
+#include "hw/usb/xlnx-usb-subsystem.h"
31
- * get_phys_addr_with_secure: get the physical address for a virtual address
27
32
+ * get_phys_addr: get the physical address for a virtual address
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
33
* @env: CPUARMState
29
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
34
* @address: virtual address to get physical address for
30
@@ -XXX,XX +XXX,XX @@ struct Versal {
35
* @access_type: 0 for read, 1 for write, 2 for execute
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
36
* @mmu_idx: MMU index indicating required translation regime
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
37
- * @is_secure: security state for the access
33
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
38
* @result: set on translation success.
34
+ VersalUsb2 usb;
39
* @fi: set to fault info if the translation fails
35
} iou;
40
*
36
} lpd;
41
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
37
42
* * for PSMAv5 based systems we don't bother to return a full FSR format
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
43
* value.
39
44
*/
40
#define VERSAL_UART0_IRQ_0 18
45
-bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
41
#define VERSAL_UART1_IRQ_0 19
46
- MMUAccessType access_type,
42
+#define VERSAL_USB0_IRQ_0 22
47
- ARMMMUIdx mmu_idx, bool is_secure,
43
#define VERSAL_GEM0_IRQ_0 56
48
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
44
#define VERSAL_GEM0_WAKE_IRQ_0 57
49
+bool get_phys_addr(CPUARMState *env, target_ulong address,
45
#define VERSAL_GEM1_IRQ_0 58
50
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
51
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
47
#define MM_OCM 0xfffc0000U
52
__attribute__((nonnull));
48
#define MM_OCM_SIZE 0x40000
53
49
54
/**
50
+#define MM_USB2_CTRL_REGS 0xFF9D0000
55
- * get_phys_addr: get the physical address for a virtual address
51
+#define MM_USB2_CTRL_REGS_SIZE 0x10000
56
+ * get_phys_addr_with_secure_nogpc: get the physical address for a virtual
52
+
57
+ * address
53
+#define MM_USB_0 0xFE200000
58
* @env: CPUARMState
54
+#define MM_USB_0_SIZE 0x10000
59
* @address: virtual address to get physical address for
55
+
60
* @access_type: 0 for read, 1 for write, 2 for execute
56
#define MM_TOP_DDR 0x0
61
* @mmu_idx: MMU index indicating required translation regime
57
#define MM_TOP_DDR_SIZE 0x80000000U
62
+ * @is_secure: security state for the access
58
#define MM_TOP_DDR_2 0x800000000ULL
63
* @result: set on translation success.
59
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
64
* @fi: set to fault info if the translation fails
65
*
66
- * Similarly, but use the security regime of @mmu_idx.
67
+ * Similar to get_phys_addr, but use the given security regime and don't perform
68
+ * a Granule Protection Check on the resulting address.
69
*/
70
-bool get_phys_addr(CPUARMState *env, target_ulong address,
71
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
72
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
73
+bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
74
+ MMUAccessType access_type,
75
+ ARMMMUIdx mmu_idx, bool is_secure,
76
+ GetPhysAddrResult *result,
77
+ ARMMMUFaultInfo *fi)
78
__attribute__((nonnull));
79
80
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/xlnx-versal-virt.c
83
--- a/target/arm/helper.c
62
+++ b/hw/arm/xlnx-versal-virt.c
84
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ struct VersalVirt {
85
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
64
uint32_t ethernet_phy[2];
86
ARMMMUFaultInfo fi = {};
65
uint32_t clk_125Mhz;
87
GetPhysAddrResult res = {};
66
uint32_t clk_25Mhz;
88
67
+ uint32_t usb;
89
- ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
68
+ uint32_t dwc;
90
- is_secure, &res, &fi);
69
} phandle;
91
+ /*
70
struct arm_boot_info binfo;
92
+ * I_MXTJT: Granule protection checks are not performed on the final address
71
93
+ * of a successful translation.
72
@@ -XXX,XX +XXX,XX @@ static void fdt_create(VersalVirt *s)
94
+ */
73
s->phandle.clk_25Mhz = qemu_fdt_alloc_phandle(s->fdt);
95
+ ret = get_phys_addr_with_secure_nogpc(env, value, access_type, mmu_idx,
74
s->phandle.clk_125Mhz = qemu_fdt_alloc_phandle(s->fdt);
96
+ is_secure, &res, &fi);
75
97
76
+ s->phandle.usb = qemu_fdt_alloc_phandle(s->fdt);
98
/*
77
+ s->phandle.dwc = qemu_fdt_alloc_phandle(s->fdt);
99
* ATS operations only do S1 or S1+S2 translations, so we never
78
/* Create /chosen node for load_dtb. */
100
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
79
qemu_fdt_add_subnode(s->fdt, "/chosen");
101
index XXXXXXX..XXXXXXX 100644
80
102
--- a/target/arm/ptw.c
81
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(VersalVirt *s)
103
+++ b/target/arm/ptw.c
82
compat, sizeof(compat));
104
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
105
return false;
83
}
106
}
84
107
85
+static void fdt_add_usb_xhci_nodes(VersalVirt *s)
108
-bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
86
+{
109
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
87
+ const char clocknames[] = "bus_clk\0ref_clk";
110
- bool is_secure, GetPhysAddrResult *result,
88
+ const char irq_name[] = "dwc_usb3";
111
- ARMMMUFaultInfo *fi)
89
+ const char compatVersalDWC3[] = "xlnx,versal-dwc3";
112
+bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
90
+ const char compatDWC3[] = "snps,dwc3";
113
+ MMUAccessType access_type,
91
+ char *name = g_strdup_printf("/usb@%" PRIx32, MM_USB2_CTRL_REGS);
114
+ ARMMMUIdx mmu_idx, bool is_secure,
92
+
115
+ GetPhysAddrResult *result,
93
+ qemu_fdt_add_subnode(s->fdt, name);
116
+ ARMMMUFaultInfo *fi)
94
+ qemu_fdt_setprop(s->fdt, name, "compatible",
95
+ compatVersalDWC3, sizeof(compatVersalDWC3));
96
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
97
+ 2, MM_USB2_CTRL_REGS,
98
+ 2, MM_USB2_CTRL_REGS_SIZE);
99
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
100
+ clocknames, sizeof(clocknames));
101
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
102
+ s->phandle.clk_25Mhz, s->phandle.clk_125Mhz);
103
+ qemu_fdt_setprop(s->fdt, name, "ranges", NULL, 0);
104
+ qemu_fdt_setprop_cell(s->fdt, name, "#address-cells", 2);
105
+ qemu_fdt_setprop_cell(s->fdt, name, "#size-cells", 2);
106
+ qemu_fdt_setprop_cell(s->fdt, name, "phandle", s->phandle.usb);
107
+ g_free(name);
108
+
109
+ name = g_strdup_printf("/usb@%" PRIx32 "/dwc3@%" PRIx32,
110
+ MM_USB2_CTRL_REGS, MM_USB_0);
111
+ qemu_fdt_add_subnode(s->fdt, name);
112
+ qemu_fdt_setprop(s->fdt, name, "compatible",
113
+ compatDWC3, sizeof(compatDWC3));
114
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
115
+ 2, MM_USB_0, 2, MM_USB_0_SIZE);
116
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
117
+ irq_name, sizeof(irq_name));
118
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
119
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_USB0_IRQ_0,
120
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
121
+ qemu_fdt_setprop_cell(s->fdt, name,
122
+ "snps,quirk-frame-length-adjustment", 0x20);
123
+ qemu_fdt_setprop_cells(s->fdt, name, "#stream-id-cells", 1);
124
+ qemu_fdt_setprop_string(s->fdt, name, "dr_mode", "host");
125
+ qemu_fdt_setprop_string(s->fdt, name, "phy-names", "usb3-phy");
126
+ qemu_fdt_setprop(s->fdt, name, "snps,dis_u2_susphy_quirk", NULL, 0);
127
+ qemu_fdt_setprop(s->fdt, name, "snps,dis_u3_susphy_quirk", NULL, 0);
128
+ qemu_fdt_setprop(s->fdt, name, "snps,refclk_fladj", NULL, 0);
129
+ qemu_fdt_setprop(s->fdt, name, "snps,mask_phy_reset", NULL, 0);
130
+ qemu_fdt_setprop_cell(s->fdt, name, "phandle", s->phandle.dwc);
131
+ qemu_fdt_setprop_string(s->fdt, name, "maximum-speed", "high-speed");
132
+ g_free(name);
133
+}
134
+
135
static void fdt_add_uart_nodes(VersalVirt *s)
136
{
117
{
137
uint64_t addrs[] = { MM_UART1, MM_UART0 };
118
S1Translate ptw = {
138
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
119
.in_mmu_idx = mmu_idx,
139
fdt_add_gic_nodes(s);
120
.in_space = arm_secure_to_space(is_secure),
140
fdt_add_timer_nodes(s);
121
};
141
fdt_add_zdma_nodes(s);
122
- return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
142
+ fdt_add_usb_xhci_nodes(s);
123
+ return get_phys_addr_nogpc(env, &ptw, address, access_type, result, fi);
143
fdt_add_sd_nodes(s);
144
fdt_add_rtc_node(s);
145
fdt_add_cpu_nodes(s, psci_conduit);
146
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/xlnx-versal.c
149
+++ b/hw/arm/xlnx-versal.c
150
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
151
}
152
}
124
}
153
125
154
+static void versal_create_usbs(Versal *s, qemu_irq *pic)
126
bool get_phys_addr(CPUARMState *env, target_ulong address,
155
+{
156
+ DeviceState *dev;
157
+ MemoryRegion *mr;
158
+
159
+ object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb,
160
+ TYPE_XILINX_VERSAL_USB2);
161
+ dev = DEVICE(&s->lpd.iou.usb);
162
+
163
+ object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
164
+ &error_abort);
165
+ qdev_prop_set_uint32(dev, "intrs", 1);
166
+ qdev_prop_set_uint32(dev, "slots", 2);
167
+
168
+ sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
169
+
170
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
171
+ memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr);
172
+
173
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]);
174
+
175
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
176
+ memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr);
177
+}
178
+
179
static void versal_create_gems(Versal *s, qemu_irq *pic)
180
{
181
int i;
182
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
183
versal_create_apu_cpus(s);
184
versal_create_apu_gic(s, pic);
185
versal_create_uarts(s, pic);
186
+ versal_create_usbs(s, pic);
187
versal_create_gems(s, pic);
188
versal_create_admas(s, pic);
189
versal_create_sds(s, pic);
190
--
127
--
191
2.20.1
128
2.34.1
192
193
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Malicious user can set the feedback divisor for the PLLs
3
At the moment we only handle Secure and Nonsecure security spaces for
4
to zero, triggering a floating-point exception (SIGFPE).
4
the AT instructions. Add support for Realm and Root.
5
5
6
As the datasheet [*] is not clear how hardware behaves
6
For AArch64, arm_security_space() gives the desired space. ARM DDI0487J
7
when these bits are zeroes, use the maximum divisor
7
says (R_NYXTL):
8
possible (128) to avoid the software FPE.
8
9
9
If EL3 is implemented, then when an address translation instruction
10
[*] Zynq-7000 TRM, UG585 (v1.12.2)
10
that applies to an Exception level lower than EL3 is executed, the
11
B.28 System Level Control Registers (slcr)
11
Effective value of SCR_EL3.{NSE, NS} determines the target Security
12
-> "Register (slcr) ARM_PLL_CTRL"
12
state that the instruction applies to.
13
25.10.4 PLLs
13
14
-> "Software-Controlled PLL Update"
14
For AArch32, some instructions can access NonSecure space from Secure,
15
15
so we still need to pass the state explicitly to do_ats_write().
16
Fixes: 38867cb7ec9 ("hw/misc/zynq_slcr: add clock generation for uarts")
16
17
Reported-by: Gaoning Pan <pgn@zju.edu.cn>
17
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
18
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-id: 20230809123706.1842548-5-jean-philippe@linaro.org
20
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
22
Message-id: 20201210141610.884600-1-f4bug@amsat.org
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
21
---
25
hw/misc/zynq_slcr.c | 5 +++++
22
target/arm/internals.h | 18 +++++++++---------
26
1 file changed, 5 insertions(+)
23
target/arm/helper.c | 27 ++++++++++++---------------
27
24
target/arm/ptw.c | 12 ++++++------
28
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
25
3 files changed, 27 insertions(+), 30 deletions(-)
26
27
diff --git a/target/arm/internals.h b/target/arm/internals.h
29
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/misc/zynq_slcr.c
29
--- a/target/arm/internals.h
31
+++ b/hw/misc/zynq_slcr.c
30
+++ b/target/arm/internals.h
32
@@ -XXX,XX +XXX,XX @@ static uint64_t zynq_slcr_compute_pll(uint64_t input, uint32_t ctrl_reg)
31
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
33
return 0;
32
__attribute__((nonnull));
33
34
/**
35
- * get_phys_addr_with_secure_nogpc: get the physical address for a virtual
36
- * address
37
+ * get_phys_addr_with_space_nogpc: get the physical address for a virtual
38
+ * address
39
* @env: CPUARMState
40
* @address: virtual address to get physical address for
41
* @access_type: 0 for read, 1 for write, 2 for execute
42
* @mmu_idx: MMU index indicating required translation regime
43
- * @is_secure: security state for the access
44
+ * @space: security space for the access
45
* @result: set on translation success.
46
* @fi: set to fault info if the translation fails
47
*
48
- * Similar to get_phys_addr, but use the given security regime and don't perform
49
+ * Similar to get_phys_addr, but use the given security space and don't perform
50
* a Granule Protection Check on the resulting address.
51
*/
52
-bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
53
- MMUAccessType access_type,
54
- ARMMMUIdx mmu_idx, bool is_secure,
55
- GetPhysAddrResult *result,
56
- ARMMMUFaultInfo *fi)
57
+bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
58
+ MMUAccessType access_type,
59
+ ARMMMUIdx mmu_idx, ARMSecuritySpace space,
60
+ GetPhysAddrResult *result,
61
+ ARMMMUFaultInfo *fi)
62
__attribute__((nonnull));
63
64
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ static int par_el1_shareability(GetPhysAddrResult *res)
70
71
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
72
MMUAccessType access_type, ARMMMUIdx mmu_idx,
73
- bool is_secure)
74
+ ARMSecuritySpace ss)
75
{
76
bool ret;
77
uint64_t par64;
78
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
79
* I_MXTJT: Granule protection checks are not performed on the final address
80
* of a successful translation.
81
*/
82
- ret = get_phys_addr_with_secure_nogpc(env, value, access_type, mmu_idx,
83
- is_secure, &res, &fi);
84
+ ret = get_phys_addr_with_space_nogpc(env, value, access_type, mmu_idx, ss,
85
+ &res, &fi);
86
87
/*
88
* ATS operations only do S1 or S1+S2 translations, so we never
89
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
90
uint64_t par64;
91
ARMMMUIdx mmu_idx;
92
int el = arm_current_el(env);
93
- bool secure = arm_is_secure_below_el3(env);
94
+ ARMSecuritySpace ss = arm_security_space(env);
95
96
switch (ri->opc2 & 6) {
97
case 0:
98
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
99
switch (el) {
100
case 3:
101
mmu_idx = ARMMMUIdx_E3;
102
- secure = true;
103
break;
104
case 2:
105
- g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
106
+ g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
107
/* fall through */
108
case 1:
109
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
110
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
111
switch (el) {
112
case 3:
113
mmu_idx = ARMMMUIdx_E10_0;
114
- secure = true;
115
break;
116
case 2:
117
- g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
118
+ g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
119
mmu_idx = ARMMMUIdx_Stage1_E0;
120
break;
121
case 1:
122
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
123
case 4:
124
/* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */
125
mmu_idx = ARMMMUIdx_E10_1;
126
- secure = false;
127
+ ss = ARMSS_NonSecure;
128
break;
129
case 6:
130
/* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */
131
mmu_idx = ARMMMUIdx_E10_0;
132
- secure = false;
133
+ ss = ARMSS_NonSecure;
134
break;
135
default:
136
g_assert_not_reached();
34
}
137
}
35
138
36
+ /* Consider zero feedback as maximum divide ratio possible */
139
- par64 = do_ats_write(env, value, access_type, mmu_idx, secure);
37
+ if (!mult) {
140
+ par64 = do_ats_write(env, value, access_type, mmu_idx, ss);
38
+ mult = 1 << R_xxx_PLL_CTRL_PLL_FPDIV_LENGTH;
141
39
+ }
142
A32_BANKED_CURRENT_REG_SET(env, par, par64);
40
+
143
#else
41
/* frequency multiplier -> period division */
144
@@ -XXX,XX +XXX,XX @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
42
return input / mult;
145
uint64_t par64;
146
147
/* There is no SecureEL2 for AArch32. */
148
- par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2, false);
149
+ par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2,
150
+ ARMSS_NonSecure);
151
152
A32_BANKED_CURRENT_REG_SET(env, par, par64);
153
#else
154
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
155
#ifdef CONFIG_TCG
156
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
157
ARMMMUIdx mmu_idx;
158
- int secure = arm_is_secure_below_el3(env);
159
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
160
bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE);
161
162
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
163
break;
164
case 6: /* AT S1E3R, AT S1E3W */
165
mmu_idx = ARMMMUIdx_E3;
166
- secure = true;
167
break;
168
default:
169
g_assert_not_reached();
170
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
171
}
172
173
env->cp15.par_el[1] = do_ats_write(env, value, access_type,
174
- mmu_idx, secure);
175
+ mmu_idx, arm_security_space(env));
176
#else
177
/* Handled by hardware accelerator. */
178
g_assert_not_reached();
179
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/target/arm/ptw.c
182
+++ b/target/arm/ptw.c
183
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
184
return false;
185
}
186
187
-bool get_phys_addr_with_secure_nogpc(CPUARMState *env, target_ulong address,
188
- MMUAccessType access_type,
189
- ARMMMUIdx mmu_idx, bool is_secure,
190
- GetPhysAddrResult *result,
191
- ARMMMUFaultInfo *fi)
192
+bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
193
+ MMUAccessType access_type,
194
+ ARMMMUIdx mmu_idx, ARMSecuritySpace space,
195
+ GetPhysAddrResult *result,
196
+ ARMMMUFaultInfo *fi)
197
{
198
S1Translate ptw = {
199
.in_mmu_idx = mmu_idx,
200
- .in_space = arm_secure_to_space(is_secure),
201
+ .in_space = space,
202
};
203
return get_phys_addr_nogpc(env, &ptw, address, access_type, result, fi);
43
}
204
}
44
--
205
--
45
2.20.1
206
2.34.1
46
47
diff view generated by jsdifflib
1
We're about to refactor the OpenRISC pic_cpu code in a way that means
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
that just grabbing the whole qemu_irq[] array of inbound IRQs for a
3
CPU won't be possible any more. Abstract out a function for "return
4
the qemu_irq for IRQ x input of CPU y" so we can more easily replace
5
the implementation.
6
2
3
The AT instruction is UNDEFINED if the {NSE,NS} configuration is
4
invalid. Add a function to check this on all AT instructions that apply
5
to an EL lower than 3.
6
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Message-id: 20230809123706.1842548-6-jean-philippe@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stafford Horne <shorne@gmail.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20201127225127.14770-3-peter.maydell@linaro.org
10
---
12
---
11
hw/openrisc/openrisc_sim.c | 38 +++++++++++++++++++++-----------------
13
target/arm/helper.c | 38 +++++++++++++++++++++++++++-----------
12
1 file changed, 21 insertions(+), 17 deletions(-)
14
1 file changed, 27 insertions(+), 11 deletions(-)
13
15
14
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/openrisc/openrisc_sim.c
18
--- a/target/arm/helper.c
17
+++ b/hw/openrisc/openrisc_sim.c
19
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void main_cpu_reset(void *opaque)
20
@@ -XXX,XX +XXX,XX @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
cpu_set_pc(cs, boot_info.bootstrap_pc);
21
#endif /* CONFIG_TCG */
20
}
22
}
21
23
22
+static qemu_irq get_cpu_irq(OpenRISCCPU *cpus[], int cpunum, int irq_pin)
24
+static CPAccessResult at_e012_access(CPUARMState *env, const ARMCPRegInfo *ri,
25
+ bool isread)
23
+{
26
+{
24
+ return cpus[cpunum]->env.irq[irq_pin];
27
+ /*
28
+ * R_NYXTL: instruction is UNDEFINED if it applies to an Exception level
29
+ * lower than EL3 and the combination SCR_EL3.{NSE,NS} is reserved. This can
30
+ * only happen when executing at EL3 because that combination also causes an
31
+ * illegal exception return. We don't need to check FEAT_RME either, because
32
+ * scr_write() ensures that the NSE bit is not set otherwise.
33
+ */
34
+ if ((env->cp15.scr_el3 & (SCR_NSE | SCR_NS)) == SCR_NSE) {
35
+ return CP_ACCESS_TRAP;
36
+ }
37
+ return CP_ACCESS_OK;
25
+}
38
+}
26
+
39
+
27
static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
40
static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
28
- int num_cpus, qemu_irq **cpu_irqs,
41
bool isread)
29
+ int num_cpus, OpenRISCCPU *cpus[],
30
int irq_pin, NICInfo *nd)
31
{
42
{
32
DeviceState *dev;
43
@@ -XXX,XX +XXX,XX @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
33
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
44
!(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) {
34
qdev_prop_set_uint32(splitter, "num-lines", num_cpus);
45
return CP_ACCESS_TRAP;
35
qdev_realize_and_unref(splitter, NULL, &error_fatal);
36
for (i = 0; i < num_cpus; i++) {
37
- qdev_connect_gpio_out(splitter, i, cpu_irqs[i][irq_pin]);
38
+ qdev_connect_gpio_out(splitter, i, get_cpu_irq(cpus, i, irq_pin));
39
}
40
sysbus_connect_irq(s, 0, qdev_get_gpio_in(splitter, 0));
41
} else {
42
- sysbus_connect_irq(s, 0, cpu_irqs[0][irq_pin]);
43
+ sysbus_connect_irq(s, 0, get_cpu_irq(cpus, 0, irq_pin));
44
}
46
}
45
sysbus_mmio_map(s, 0, base);
47
- return CP_ACCESS_OK;
46
sysbus_mmio_map(s, 1, descriptors);
48
+ return at_e012_access(env, ri, isread);
47
}
49
}
48
50
49
static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
51
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
50
- qemu_irq **cpu_irqs, int irq_pin)
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
51
+ OpenRISCCPU *cpus[], int irq_pin)
53
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
52
{
54
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
53
DeviceState *dev;
55
.fgt = FGT_ATS1E1R,
54
SysBusDevice *s;
56
- .writefn = ats_write64 },
55
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
57
+ .accessfn = at_e012_access, .writefn = ats_write64 },
56
s = SYS_BUS_DEVICE(dev);
58
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
57
sysbus_realize_and_unref(s, &error_fatal);
59
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
58
for (i = 0; i < num_cpus; i++) {
60
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
59
- sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
61
.fgt = FGT_ATS1E1W,
60
+ sysbus_connect_irq(s, i, get_cpu_irq(cpus, i, irq_pin));
62
- .writefn = ats_write64 },
61
}
63
+ .accessfn = at_e012_access, .writefn = ats_write64 },
62
sysbus_mmio_map(s, 0, base);
64
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
63
}
65
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
64
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
66
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
65
{
67
.fgt = FGT_ATS1E0R,
66
ram_addr_t ram_size = machine->ram_size;
68
- .writefn = ats_write64 },
67
const char *kernel_filename = machine->kernel_filename;
69
+ .accessfn = at_e012_access, .writefn = ats_write64 },
68
- OpenRISCCPU *cpu = NULL;
70
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
69
+ OpenRISCCPU *cpus[2] = {};
71
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
70
MemoryRegion *ram;
72
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
71
- qemu_irq *cpu_irqs[2];
73
.fgt = FGT_ATS1E0W,
72
qemu_irq serial_irq;
74
- .writefn = ats_write64 },
73
int n;
75
+ .accessfn = at_e012_access, .writefn = ats_write64 },
74
unsigned int smp_cpus = machine->smp.cpus;
76
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
75
77
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
76
assert(smp_cpus >= 1 && smp_cpus <= 2);
78
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
77
for (n = 0; n < smp_cpus; n++) {
79
- .writefn = ats_write64 },
78
- cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
80
+ .accessfn = at_e012_access, .writefn = ats_write64 },
79
- if (cpu == NULL) {
81
{ .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
80
+ cpus[n] = OPENRISC_CPU(cpu_create(machine->cpu_type));
82
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
81
+ if (cpus[n] == NULL) {
83
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
82
fprintf(stderr, "Unable to find CPU definition!\n");
84
- .writefn = ats_write64 },
83
exit(1);
85
+ .accessfn = at_e012_access, .writefn = ats_write64 },
84
}
86
{ .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
85
- cpu_openrisc_pic_init(cpu);
87
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
86
- cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
88
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
87
+ cpu_openrisc_pic_init(cpus[n]);
89
- .writefn = ats_write64 },
88
90
+ .accessfn = at_e012_access, .writefn = ats_write64 },
89
- cpu_openrisc_clock_init(cpu);
91
{ .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
90
+ cpu_openrisc_clock_init(cpus[n]);
92
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
91
93
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
92
- qemu_register_reset(main_cpu_reset, cpu);
94
- .writefn = ats_write64 },
93
+ qemu_register_reset(main_cpu_reset, cpus[n]);
95
+ .accessfn = at_e012_access, .writefn = ats_write64 },
94
}
96
/* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */
95
97
{ .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
96
ram = g_malloc(sizeof(*ram));
98
.opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
97
@@ -XXX,XX +XXX,XX @@ static void openrisc_sim_init(MachineState *machine)
99
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
98
100
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
99
if (nd_table[0].used) {
101
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
100
openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
102
.fgt = FGT_ATS1E1RP,
101
- cpu_irqs, 4, nd_table);
103
- .writefn = ats_write64 },
102
+ cpus, 4, nd_table);
104
+ .accessfn = at_e012_access, .writefn = ats_write64 },
103
}
105
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
104
106
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
105
if (smp_cpus > 1) {
107
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
106
- openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
108
.fgt = FGT_ATS1E1WP,
107
+ openrisc_sim_ompic_init(0x98000000, smp_cpus, cpus, 1);
109
- .writefn = ats_write64 },
108
110
+ .accessfn = at_e012_access, .writefn = ats_write64 },
109
- serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
111
};
110
+ serial_irq = qemu_irq_split(get_cpu_irq(cpus, 0, 2),
112
111
+ get_cpu_irq(cpus, 1, 2));
113
static const ARMCPRegInfo ats1cp_reginfo[] = {
112
} else {
113
- serial_irq = cpu_irqs[0][2];
114
+ serial_irq = get_cpu_irq(cpus, 0, 2);
115
}
116
117
serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
118
--
114
--
119
2.20.1
115
2.34.1
120
121
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
This module emulates control registers of versal usb2 controller, this is added
3
When FEAT_RME is implemented, these bits override the value of
4
just to make guest happy. In general this module would control the phy-reset
4
CNT[VP]_CTL_EL0.IMASK in Realm and Root state. Move the IRQ state update
5
signal from usb controller, data coherency of the transactions, signals
5
into a new gt_update_irq() function and test those bits every time we
6
the host system errors received from controller.
6
recompute the IRQ state.
7
7
8
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
8
Since we're removing the IRQ state from some trace events, add a new
9
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
9
trace event for gt_update_irq().
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
11
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
12
Message-id: 20230809123706.1842548-7-jean-philippe@linaro.org
13
[PMM: only register change hook if not USER_ONLY and if TCG]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1607023357-5096-2-git-send-email-sai.pavan.boddu@xilinx.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
16
---
15
include/hw/usb/xlnx-versal-usb2-ctrl-regs.h | 45 ++++
17
target/arm/cpu.h | 4 +++
16
hw/usb/xlnx-versal-usb2-ctrl-regs.c | 229 ++++++++++++++++++++
18
target/arm/cpu.c | 6 ++++
17
hw/usb/meson.build | 1 +
19
target/arm/helper.c | 65 ++++++++++++++++++++++++++++++++++-------
18
3 files changed, 275 insertions(+)
20
target/arm/trace-events | 7 +++--
19
create mode 100644 include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
21
4 files changed, 68 insertions(+), 14 deletions(-)
20
create mode 100644 hw/usb/xlnx-versal-usb2-ctrl-regs.c
22
21
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
24
index XXXXXXX..XXXXXXX 100644
23
new file mode 100644
25
--- a/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX
26
+++ b/target/arm/cpu.h
25
--- /dev/null
27
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
26
+++ b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h
28
};
27
@@ -XXX,XX +XXX,XX @@
29
28
+/*
30
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
29
+ * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for
31
+void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
30
+ * USB2.0 controller
32
31
+ *
33
void arm_cpu_post_init(Object *obj);
32
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com>
34
33
+ *
35
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
34
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
36
#define HSTR_TTEE (1 << 16)
35
+ * of this software and associated documentation files (the "Software"), to deal
37
#define HSTR_TJDBX (1 << 17)
36
+ * in the Software without restriction, including without limitation the rights
38
37
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
+#define CNTHCTL_CNTVMASK (1 << 18)
38
+ * copies of the Software, and to permit persons to whom the Software is
40
+#define CNTHCTL_CNTPMASK (1 << 19)
39
+ * furnished to do so, subject to the following conditions:
41
+
40
+ *
42
/* Return the current FPSCR value. */
41
+ * The above copyright notice and this permission notice shall be included in
43
uint32_t vfp_get_fpscr(CPUARMState *env);
42
+ * all copies or substantial portions of the Software.
44
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
43
+ *
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
44
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
index XXXXXXX..XXXXXXX 100644
45
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
--- a/target/arm/cpu.c
46
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
48
+++ b/target/arm/cpu.c
47
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
48
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
set_feature(env, ARM_FEATURE_VBAR);
49
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
}
50
+ * THE SOFTWARE.
52
51
+ */
53
+#ifndef CONFIG_USER_ONLY
52
+
54
+ if (tcg_enabled() && cpu_isar_feature(aa64_rme, cpu)) {
53
+#ifndef _XLNX_USB2_REGS_H_
55
+ arm_register_el_change_hook(cpu, &gt_rme_post_el_change, 0);
54
+#define _XLNX_USB2_REGS_H_
56
+ }
55
+
56
+#define TYPE_XILINX_VERSAL_USB2_CTRL_REGS "xlnx.versal-usb2-ctrl-regs"
57
+
58
+#define XILINX_VERSAL_USB2_CTRL_REGS(obj) \
59
+ OBJECT_CHECK(VersalUsb2CtrlRegs, (obj), TYPE_XILINX_VERSAL_USB2_CTRL_REGS)
60
+
61
+#define USB2_REGS_R_MAX ((0x78 / 4) + 1)
62
+
63
+typedef struct VersalUsb2CtrlRegs {
64
+ SysBusDevice parent_obj;
65
+ MemoryRegion iomem;
66
+ qemu_irq irq_ir;
67
+
68
+ uint32_t regs[USB2_REGS_R_MAX];
69
+ RegisterInfo regs_info[USB2_REGS_R_MAX];
70
+} VersalUsb2CtrlRegs;
71
+
72
+#endif
57
+#endif
73
diff --git a/hw/usb/xlnx-versal-usb2-ctrl-regs.c b/hw/usb/xlnx-versal-usb2-ctrl-regs.c
58
+
74
new file mode 100644
59
register_cp_regs_for_features(cpu);
75
index XXXXXXX..XXXXXXX
60
arm_cpu_register_gdb_regs_for_features(cpu);
76
--- /dev/null
61
77
+++ b/hw/usb/xlnx-versal-usb2-ctrl-regs.c
62
diff --git a/target/arm/helper.c b/target/arm/helper.c
78
@@ -XXX,XX +XXX,XX @@
63
index XXXXXXX..XXXXXXX 100644
79
+/*
64
--- a/target/arm/helper.c
80
+ * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for
65
+++ b/target/arm/helper.c
81
+ * USB2.0 controller
66
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_get_countervalue(CPUARMState *env)
82
+ *
67
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / gt_cntfrq_period_ns(cpu);
83
+ * This module should control phy_reset, permanent device plugs, frame length
68
}
84
+ * time adjust & setting of coherency paths. None of which are emulated in
69
85
+ * present model.
70
+static void gt_update_irq(ARMCPU *cpu, int timeridx)
86
+ *
87
+ * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com>
88
+ *
89
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
90
+ * of this software and associated documentation files (the "Software"), to deal
91
+ * in the Software without restriction, including without limitation the rights
92
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
93
+ * copies of the Software, and to permit persons to whom the Software is
94
+ * furnished to do so, subject to the following conditions:
95
+ *
96
+ * The above copyright notice and this permission notice shall be included in
97
+ * all copies or substantial portions of the Software.
98
+ *
99
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
100
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
101
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
102
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
103
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
104
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105
+ * THE SOFTWARE.
106
+ */
107
+
108
+#include "qemu/osdep.h"
109
+#include "hw/sysbus.h"
110
+#include "hw/irq.h"
111
+#include "hw/register.h"
112
+#include "qemu/bitops.h"
113
+#include "qemu/log.h"
114
+#include "qom/object.h"
115
+#include "migration/vmstate.h"
116
+#include "hw/usb/xlnx-versal-usb2-ctrl-regs.h"
117
+
118
+#ifndef XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG
119
+#define XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG 0
120
+#endif
121
+
122
+REG32(BUS_FILTER, 0x30)
123
+ FIELD(BUS_FILTER, BYPASS, 0, 4)
124
+REG32(PORT, 0x34)
125
+ FIELD(PORT, HOST_SMI_BAR_WR, 4, 1)
126
+ FIELD(PORT, HOST_SMI_PCI_CMD_REG_WR, 3, 1)
127
+ FIELD(PORT, HOST_MSI_ENABLE, 2, 1)
128
+ FIELD(PORT, PWR_CTRL_PRSNT, 1, 1)
129
+ FIELD(PORT, HUB_PERM_ATTACH, 0, 1)
130
+REG32(JITTER_ADJUST, 0x38)
131
+ FIELD(JITTER_ADJUST, FLADJ, 0, 6)
132
+REG32(BIGENDIAN, 0x40)
133
+ FIELD(BIGENDIAN, ENDIAN_GS, 0, 1)
134
+REG32(COHERENCY, 0x44)
135
+ FIELD(COHERENCY, USB_COHERENCY, 0, 1)
136
+REG32(XHC_BME, 0x48)
137
+ FIELD(XHC_BME, XHC_BME, 0, 1)
138
+REG32(REG_CTRL, 0x60)
139
+ FIELD(REG_CTRL, SLVERR_ENABLE, 0, 1)
140
+REG32(IR_STATUS, 0x64)
141
+ FIELD(IR_STATUS, HOST_SYS_ERR, 1, 1)
142
+ FIELD(IR_STATUS, ADDR_DEC_ERR, 0, 1)
143
+REG32(IR_MASK, 0x68)
144
+ FIELD(IR_MASK, HOST_SYS_ERR, 1, 1)
145
+ FIELD(IR_MASK, ADDR_DEC_ERR, 0, 1)
146
+REG32(IR_ENABLE, 0x6c)
147
+ FIELD(IR_ENABLE, HOST_SYS_ERR, 1, 1)
148
+ FIELD(IR_ENABLE, ADDR_DEC_ERR, 0, 1)
149
+REG32(IR_DISABLE, 0x70)
150
+ FIELD(IR_DISABLE, HOST_SYS_ERR, 1, 1)
151
+ FIELD(IR_DISABLE, ADDR_DEC_ERR, 0, 1)
152
+REG32(USB3, 0x78)
153
+
154
+static void ir_update_irq(VersalUsb2CtrlRegs *s)
155
+{
71
+{
156
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
72
+ CPUARMState *env = &cpu->env;
157
+ qemu_set_irq(s->irq_ir, pending);
73
+ uint64_t cnthctl = env->cp15.cnthctl_el2;
74
+ ARMSecuritySpace ss = arm_security_space(env);
75
+ /* ISTATUS && !IMASK */
76
+ int irqstate = (env->cp15.c14_timer[timeridx].ctl & 6) == 4;
77
+
78
+ /*
79
+ * If bit CNTHCTL_EL2.CNT[VP]MASK is set, it overrides IMASK.
80
+ * It is RES0 in Secure and NonSecure state.
81
+ */
82
+ if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
83
+ ((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
84
+ (timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK)))) {
85
+ irqstate = 0;
86
+ }
87
+
88
+ qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
89
+ trace_arm_gt_update_irq(timeridx, irqstate);
158
+}
90
+}
159
+
91
+
160
+static void ir_status_postw(RegisterInfo *reg, uint64_t val64)
92
+void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
161
+{
93
+{
162
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
163
+ /*
94
+ /*
164
+ * TODO: This should also clear USBSTS.HSE field in USB XHCI register.
95
+ * Changing security state between Root and Secure/NonSecure, which may
165
+ * May be combine both the modules.
96
+ * happen when switching EL, can change the effective value of CNTHCTL_EL2
97
+ * mask bits. Update the IRQ state accordingly.
166
+ */
98
+ */
167
+ ir_update_irq(s);
99
+ gt_update_irq(cpu, GTIMER_VIRT);
100
+ gt_update_irq(cpu, GTIMER_PHYS);
168
+}
101
+}
169
+
102
+
170
+static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64)
103
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
104
{
105
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
106
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
107
/* Note that this must be unsigned 64 bit arithmetic: */
108
int istatus = count - offset >= gt->cval;
109
uint64_t nexttick;
110
- int irqstate;
111
112
gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
113
114
- irqstate = (istatus && !(gt->ctl & 2));
115
- qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
116
-
117
if (istatus) {
118
/* Next transition is when count rolls back over to zero */
119
nexttick = UINT64_MAX;
120
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
121
} else {
122
timer_mod(cpu->gt_timer[timeridx], nexttick);
123
}
124
- trace_arm_gt_recalc(timeridx, irqstate, nexttick);
125
+ trace_arm_gt_recalc(timeridx, nexttick);
126
} else {
127
/* Timer disabled: ISTATUS and timer output always clear */
128
gt->ctl &= ~4;
129
- qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
130
timer_del(cpu->gt_timer[timeridx]);
131
trace_arm_gt_recalc_disabled(timeridx);
132
}
133
+ gt_update_irq(cpu, timeridx);
134
}
135
136
static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
137
@@ -XXX,XX +XXX,XX @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
138
* IMASK toggled: don't need to recalculate,
139
* just set the interrupt line based on ISTATUS
140
*/
141
- int irqstate = (oldval & 4) && !(value & 2);
142
-
143
- trace_arm_gt_imask_toggle(timeridx, irqstate);
144
- qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
145
+ trace_arm_gt_imask_toggle(timeridx);
146
+ gt_update_irq(cpu, timeridx);
147
}
148
}
149
150
@@ -XXX,XX +XXX,XX @@ static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
151
gt_ctl_write(env, ri, GTIMER_VIRT, value);
152
}
153
154
+static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
155
+ uint64_t value)
171
+{
156
+{
172
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
157
+ ARMCPU *cpu = env_archcpu(env);
173
+ uint32_t val = val64;
158
+ uint32_t oldval = env->cp15.cnthctl_el2;
174
+
159
+
175
+ s->regs[R_IR_MASK] &= ~val;
160
+ raw_write(env, ri, value);
176
+ ir_update_irq(s);
161
+
177
+ return 0;
162
+ if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
178
+}
163
+ gt_update_irq(cpu, GTIMER_VIRT);
179
+
164
+ } else if ((oldval ^ value) & CNTHCTL_CNTPMASK) {
180
+static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64)
165
+ gt_update_irq(cpu, GTIMER_PHYS);
181
+{
182
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque);
183
+ uint32_t val = val64;
184
+
185
+ s->regs[R_IR_MASK] |= val;
186
+ ir_update_irq(s);
187
+ return 0;
188
+}
189
+
190
+static const RegisterAccessInfo usb2_ctrl_regs_regs_info[] = {
191
+ { .name = "BUS_FILTER", .addr = A_BUS_FILTER,
192
+ .rsvd = 0xfffffff0,
193
+ },{ .name = "PORT", .addr = A_PORT,
194
+ .rsvd = 0xffffffe0,
195
+ },{ .name = "JITTER_ADJUST", .addr = A_JITTER_ADJUST,
196
+ .reset = 0x20,
197
+ .rsvd = 0xffffffc0,
198
+ },{ .name = "BIGENDIAN", .addr = A_BIGENDIAN,
199
+ .rsvd = 0xfffffffe,
200
+ },{ .name = "COHERENCY", .addr = A_COHERENCY,
201
+ .rsvd = 0xfffffffe,
202
+ },{ .name = "XHC_BME", .addr = A_XHC_BME,
203
+ .reset = 0x1,
204
+ .rsvd = 0xfffffffe,
205
+ },{ .name = "REG_CTRL", .addr = A_REG_CTRL,
206
+ .rsvd = 0xfffffffe,
207
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
208
+ .rsvd = 0xfffffffc,
209
+ .w1c = 0x3,
210
+ .post_write = ir_status_postw,
211
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
212
+ .reset = 0x3,
213
+ .rsvd = 0xfffffffc,
214
+ .ro = 0x3,
215
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
216
+ .rsvd = 0xfffffffc,
217
+ .pre_write = ir_enable_prew,
218
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
219
+ .rsvd = 0xfffffffc,
220
+ .pre_write = ir_disable_prew,
221
+ },{ .name = "USB3", .addr = A_USB3,
222
+ }
223
+};
224
+
225
+static void usb2_ctrl_regs_reset_init(Object *obj, ResetType type)
226
+{
227
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
228
+ unsigned int i;
229
+
230
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
231
+ register_reset(&s->regs_info[i]);
232
+ }
166
+ }
233
+}
167
+}
234
+
168
+
235
+static void usb2_ctrl_regs_reset_hold(Object *obj)
169
static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
236
+{
170
uint64_t value)
237
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
171
{
238
+
172
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
239
+ ir_update_irq(s);
173
* reset values as IMPDEF. We choose to reset to 3 to comply with
240
+}
174
* both ARMv7 and ARMv8.
241
+
175
*/
242
+static const MemoryRegionOps usb2_ctrl_regs_ops = {
176
- .access = PL2_RW, .resetvalue = 3,
243
+ .read = register_read_memory,
177
+ .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 3,
244
+ .write = register_write_memory,
178
+ .writefn = gt_cnthctl_write, .raw_writefn = raw_write,
245
+ .endianness = DEVICE_LITTLE_ENDIAN,
179
.fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) },
246
+ .valid = {
180
{ .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
247
+ .min_access_size = 4,
181
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
248
+ .max_access_size = 4,
182
diff --git a/target/arm/trace-events b/target/arm/trace-events
249
+ },
183
index XXXXXXX..XXXXXXX 100644
250
+};
184
--- a/target/arm/trace-events
251
+
185
+++ b/target/arm/trace-events
252
+static void usb2_ctrl_regs_init(Object *obj)
186
@@ -XXX,XX +XXX,XX @@
253
+{
187
# See docs/devel/tracing.rst for syntax documentation.
254
+ VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj);
188
255
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
189
# helper.c
256
+ RegisterInfoArray *reg_array;
190
-arm_gt_recalc(int timer, int irqstate, uint64_t nexttick) "gt recalc: timer %d irqstate %d next tick 0x%" PRIx64
257
+
191
-arm_gt_recalc_disabled(int timer) "gt recalc: timer %d irqstate 0 timer disabled"
258
+ memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
192
+arm_gt_recalc(int timer, uint64_t nexttick) "gt recalc: timer %d next tick 0x%" PRIx64
259
+ USB2_REGS_R_MAX * 4);
193
+arm_gt_recalc_disabled(int timer) "gt recalc: timer %d timer disabled"
260
+ reg_array =
194
arm_gt_cval_write(int timer, uint64_t value) "gt_cval_write: timer %d value 0x%" PRIx64
261
+ register_init_block32(DEVICE(obj), usb2_ctrl_regs_regs_info,
195
arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%" PRIx64
262
+ ARRAY_SIZE(usb2_ctrl_regs_regs_info),
196
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
263
+ s->regs_info, s->regs,
197
-arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
264
+ &usb2_ctrl_regs_ops,
198
+arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
265
+ XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG,
199
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
266
+ USB2_REGS_R_MAX * 4);
200
+arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
267
+ memory_region_add_subregion(&s->iomem,
201
268
+ 0x0,
202
# kvm.c
269
+ &reg_array->mem);
203
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
270
+ sysbus_init_mmio(sbd, &s->iomem);
271
+ sysbus_init_irq(sbd, &s->irq_ir);
272
+}
273
+
274
+static const VMStateDescription vmstate_usb2_ctrl_regs = {
275
+ .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
276
+ .version_id = 1,
277
+ .minimum_version_id = 1,
278
+ .fields = (VMStateField[]) {
279
+ VMSTATE_UINT32_ARRAY(regs, VersalUsb2CtrlRegs, USB2_REGS_R_MAX),
280
+ VMSTATE_END_OF_LIST(),
281
+ }
282
+};
283
+
284
+static void usb2_ctrl_regs_class_init(ObjectClass *klass, void *data)
285
+{
286
+ DeviceClass *dc = DEVICE_CLASS(klass);
287
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
288
+
289
+ rc->phases.enter = usb2_ctrl_regs_reset_init;
290
+ rc->phases.hold = usb2_ctrl_regs_reset_hold;
291
+ dc->vmsd = &vmstate_usb2_ctrl_regs;
292
+}
293
+
294
+static const TypeInfo usb2_ctrl_regs_info = {
295
+ .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS,
296
+ .parent = TYPE_SYS_BUS_DEVICE,
297
+ .instance_size = sizeof(VersalUsb2CtrlRegs),
298
+ .class_init = usb2_ctrl_regs_class_init,
299
+ .instance_init = usb2_ctrl_regs_init,
300
+};
301
+
302
+static void usb2_ctrl_regs_register_types(void)
303
+{
304
+ type_register_static(&usb2_ctrl_regs_info);
305
+}
306
+
307
+type_init(usb2_ctrl_regs_register_types)
308
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
309
index XXXXXXX..XXXXXXX 100644
310
--- a/hw/usb/meson.build
311
+++ b/hw/usb/meson.build
312
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c'))
313
softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c'))
314
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c'))
315
softmmu_ss.add(when: 'CONFIG_IMX_USBPHY', if_true: files('imx-usb-phy.c'))
316
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c'))
317
318
# emulated usb devices
319
softmmu_ss.add(when: 'CONFIG_USB', if_true: files('dev-hub.c'))
320
--
204
--
321
2.20.1
205
2.34.1
322
323
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
VCFG XIP is set (disabled) when the NVCFG XIP bits are all set (disabled).
3
A typo, noted in the bug report, resulting in an
4
incorrect write offset.
4
5
5
Signed-off-by: Joe Komlodi <komlodi@xilinx.com>
6
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
7
Fixes: 7390e0e9ab8 ("target/arm: Implement SME LD1, ST1")
7
Message-id: 1605568264-26376-3-git-send-email-komlodi@xilinx.com
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1833
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20230818214255.146905-1-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
hw/block/m25p80.c | 2 +-
14
target/arm/tcg/sme_helper.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
12
16
13
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
17
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/block/m25p80.c
19
--- a/target/arm/tcg/sme_helper.c
16
+++ b/hw/block/m25p80.c
20
+++ b/target/arm/tcg/sme_helper.c
17
@@ -XXX,XX +XXX,XX @@ static void reset_memory(Flash *s)
21
@@ -XXX,XX +XXX,XX @@ static inline void HNAME##_host(void *za, intptr_t off, void *host) \
18
s->volatile_cfg |= VCFG_DUMMY;
22
{ \
19
s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
23
uint64_t *ptr = za + off; \
20
if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK)
24
HOST(host, ptr[BE]); \
21
- != NVCFG_XIP_MODE_DISABLED) {
25
- HOST(host + 1, ptr[!BE]); \
22
+ == NVCFG_XIP_MODE_DISABLED) {
26
+ HOST(host + 8, ptr[!BE]); \
23
s->volatile_cfg |= VCFG_XIP_MODE_DISABLED;
27
} \
24
}
28
static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
25
s->volatile_cfg |= deposit32(s->volatile_cfg,
29
{ \
26
--
30
--
27
2.20.1
31
2.34.1
28
32
29
33
diff view generated by jsdifflib
1
In the vCont packet, two of the command actions (C and S) take an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
argument specifying the signal to be sent to the process/thread, which is
3
sent as an ASCII string of two hex digits which immediately follow the
4
'C' or 'S' character.
5
2
6
Our code for parsing this packet accidentally skipped the first of the
3
Typo applied byte-wise shift instead of double-word shift.
7
two bytes of the signal value, because it started parsing the hex string
8
at 'p + 1' when the preceding code had already moved past the 'C' or
9
'S' with "cur_action = *p++".
10
4
11
This meant that we would only do the right thing for signals below
5
Cc: qemu-stable@nongnu.org
12
10, and would misinterpret the rest. For instance, when the debugger
6
Fixes: 631e565450c ("target/arm: Create gen_gvec_[us]sra")
13
wants to send the process a SIGPROF (27 on x86-64) we mangle this into
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1737
14
a SIGSEGV (11).
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Remove the accidental double increment.
10
Message-id: 20230821022025.397682-1-richard.henderson@linaro.org
17
18
Fixes: https://bugs.launchpad.net/qemu/+bug/1773743
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
22
Message-id: 20201121210342.10089-1-peter.maydell@linaro.org
23
---
12
---
24
gdbstub.c | 2 +-
13
target/arm/tcg/translate.c | 2 +-
25
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
26
15
27
diff --git a/gdbstub.c b/gdbstub.c
16
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
28
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
29
--- a/gdbstub.c
18
--- a/target/arm/tcg/translate.c
30
+++ b/gdbstub.c
19
+++ b/target/arm/tcg/translate.c
31
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_vcont(const char *p)
20
@@ -XXX,XX +XXX,XX @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
32
cur_action = *p++;
21
.vece = MO_32 },
33
if (cur_action == 'C' || cur_action == 'S') {
22
{ .fni8 = gen_ssra64_i64,
34
cur_action = qemu_tolower(cur_action);
23
.fniv = gen_ssra_vec,
35
- res = qemu_strtoul(p + 1, &p, 16, &tmp);
24
- .fno = gen_helper_gvec_ssra_b,
36
+ res = qemu_strtoul(p, &p, 16, &tmp);
25
+ .fno = gen_helper_gvec_ssra_d,
37
if (res) {
26
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
38
goto out;
27
.opt_opc = vecop_list,
39
}
28
.load_dest = true,
40
--
29
--
41
2.20.1
30
2.34.1
42
31
43
32
diff view generated by jsdifflib