1
target-arm queue: Eric's SMMUv3 patchset, and an array
1
Big pullreq this week, since it's got RTH's PAN/UAO/ATS1E1
2
of minor bugfixes and improvements from various others.
2
implementation in it, and also Philippe's raspi board model
3
cleanup patchset, as well as a scattering of smaller stuff.
3
4
4
thanks
5
-- PMM
5
-- PMM
6
6
7
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:
8
7
9
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into staging (2018-05-04 14:42:46 +0100)
8
The following changes since commit 7ce9ce89930ce260af839fb3e3e5f9101f5c69a0:
9
10
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20200212-pull-request' into staging (2020-02-13 11:06:32 +0000)
10
11
11
are available in the Git repository at:
12
are available in the Git repository at:
12
13
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180504
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200213
14
15
15
for you to fetch changes up to 5680740c92993e9b3f3e011f2a2c394070e33f56:
16
for you to fetch changes up to dc7a88d0810ad272bdcd2e0869359af78fdd9114:
16
17
17
hw/arm/virt: Introduce the iommu option (2018-05-04 18:05:52 +0100)
18
target/arm: Implement ARMv8.1-VMID16 extension (2020-02-13 14:30:51 +0000)
18
19
19
----------------------------------------------------------------
20
----------------------------------------------------------------
20
target-arm queue:
21
target-arm queue:
21
* Emulate the SMMUv3 (IOMMU); one will be created in the 'virt' board
22
* i.MX: Fix inverted sense of register bits in watchdog timer
22
if the commandline includes "-machine iommu=smmuv3"
23
* i.MX: Add support for WDT on i.MX6
23
* target/arm: Implement v8M VLLDM and VLSTM
24
* arm/virt: cleanups to ACPI tables
24
* hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
25
* Implement ARMv8.1-VMID16 extension
25
* Some fixes to silence Coverity false-positives
26
* Implement ARMv8.1-PAN
26
* arm: boot: set boot_info starting from first_cpu
27
* Implement ARMv8.2-UAO
27
(fixes a technical bug not visible in practice)
28
* Implement ARMv8.2-ATS1E1
28
* hw/net/smc91c111: Convert away from old_mmio
29
* ast2400/2500/2600: Wire up EHCI controllers
29
* hw/usb/tusb6010: Convert away from old_mmio
30
* hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init
30
* hw/char/cmsdk-apb-uart.c: Accept more input after character read
31
* hw/arm/raspi: Clean up the board code
31
* target/arm: Make MPUIR write-ignored on OMAP, StrongARM
32
* hw/arm/virt: Add linux,pci-domain property
33
32
34
----------------------------------------------------------------
33
----------------------------------------------------------------
35
Eric Auger (11):
34
Chen Qun (1):
36
hw/arm/smmu-common: smmu base device and datatypes
35
hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init
37
hw/arm/smmu-common: IOMMU memory region and address space setup
38
hw/arm/smmu-common: VMSAv8-64 page table walk
39
hw/arm/smmuv3: Wired IRQ and GERROR helpers
40
hw/arm/smmuv3: Queue helpers
41
hw/arm/smmuv3: Implement MMIO write operations
42
hw/arm/smmuv3: Event queue recording helper
43
hw/arm/smmuv3: Implement translate callback
44
hw/arm/smmuv3: Abort on vfio or vhost case
45
target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route
46
hw/arm/virt: Introduce the iommu option
47
36
48
Igor Mammedov (1):
37
Guenter Roeck (2):
49
arm: boot: set boot_info starting from first_cpu
38
hw/arm: ast2400/ast2500: Wire up EHCI controllers
39
hw/arm: ast2600: Wire up EHCI controllers
50
40
51
Jan Kiszka (1):
41
Heyi Guo (7):
52
hw/arm/virt: Add linux,pci-domain property
42
bios-tables-test: prepare to change ARM virt ACPI DSDT
43
arm/virt/acpi: remove meaningless sub device "RP0" from PCI0
44
arm/virt/acpi: remove _ADR from devices identified by _HID
45
arm/acpi: fix PCI _PRT definition
46
arm/acpi: fix duplicated _UID of PCI interrupt link devices
47
arm/acpi: simplify the description of PCI _CRS
48
virt/acpi: update golden masters for DSDT update
53
49
54
Mathew Maidment (1):
50
Peter Maydell (1):
55
target/arm: Correct MPUIR privilege level in register_cp_regs_for_features() conditional case
51
target/arm: Implement ARMv8.1-VMID16 extension
56
52
57
Patrick Oppenlander (1):
53
Philippe Mathieu-Daudé (13):
58
hw/char/cmsdk-apb-uart.c: Accept more input after character read
54
hw/arm/raspi: Use BCM2708 machine type with pre Device Tree kernels
55
hw/arm/raspi: Correct the board descriptions
56
hw/arm/raspi: Extract the version from the board revision
57
hw/arm/raspi: Extract the RAM size from the board revision
58
hw/arm/raspi: Extract the processor type from the board revision
59
hw/arm/raspi: Trivial code movement
60
hw/arm/raspi: Make machines children of abstract RaspiMachineClass
61
hw/arm/raspi: Make board_rev a field of RaspiMachineClass
62
hw/arm/raspi: Let class_init() directly call raspi_machine_init()
63
hw/arm/raspi: Set default RAM size to size encoded in board revision
64
hw/arm/raspi: Extract the board model from the board revision
65
hw/arm/raspi: Use a unique raspi_machine_class_init() method
66
hw/arm/raspi: Extract the cores count from the board revision
59
67
60
Peter Maydell (3):
68
Richard Henderson (20):
61
hw/usb/tusb6010: Convert away from old_mmio
69
target/arm: Add arm_mmu_idx_is_stage1_of_2
62
hw/net/smc91c111: Convert away from old_mmio
70
target/arm: Add mmu_idx for EL1 and EL2 w/ PAN enabled
63
target/arm: Implement v8M VLLDM and VLSTM
71
target/arm: Add isar_feature tests for PAN + ATS1E1
72
target/arm: Move LOR regdefs to file scope
73
target/arm: Split out aarch32_cpsr_valid_mask
74
target/arm: Mask CPSR_J when Jazelle is not enabled
75
target/arm: Replace CPSR_ERET_MASK with aarch32_cpsr_valid_mask
76
target/arm: Use aarch32_cpsr_valid_mask in helper_exception_return
77
target/arm: Remove CPSR_RESERVED
78
target/arm: Introduce aarch64_pstate_valid_mask
79
target/arm: Update MSR access for PAN
80
target/arm: Update arm_mmu_idx_el for PAN
81
target/arm: Enforce PAN semantics in get_S1prot
82
target/arm: Set PAN bit as required on exception entry
83
target/arm: Implement ATS1E1 system registers
84
target/arm: Enable ARMv8.2-ATS1E1 in -cpu max
85
target/arm: Add ID_AA64MMFR2_EL1
86
target/arm: Update MSR access to UAO
87
target/arm: Implement UAO semantics
88
target/arm: Enable ARMv8.2-UAO in -cpu max
64
89
65
Prem Mallappa (3):
90
Roman Kapl (2):
66
hw/arm/smmuv3: Skeleton
91
i.MX: Fix inverted register bits in wdt code.
67
hw/arm/virt: Add SMMUv3 to the virt board
92
i.MX: Add support for WDT on i.MX6
68
hw/arm/virt-acpi-build: Add smmuv3 node in IORT table
69
93
70
Richard Henderson (2):
94
include/hw/arm/aspeed_soc.h | 6 +
71
target/arm: Tidy conditions in handle_vec_simd_shri
95
include/hw/arm/fsl-imx6.h | 3 +
72
target/arm: Tidy condition in disas_simd_two_reg_misc
96
target/arm/cpu-param.h | 2 +-
97
target/arm/cpu.h | 95 ++++++++---
98
target/arm/internals.h | 85 ++++++++++
99
hw/arm/aspeed_ast2600.c | 23 +++
100
hw/arm/aspeed_soc.c | 25 +++
101
hw/arm/fsl-imx6.c | 21 +++
102
hw/arm/raspi.c | 190 ++++++++++++++++------
103
hw/arm/virt-acpi-build.c | 25 +--
104
hw/char/exynos4210_uart.c | 5 +-
105
hw/misc/imx2_wdt.c | 2 +-
106
target/arm/cpu.c | 4 +
107
target/arm/cpu64.c | 10 ++
108
target/arm/helper-a64.c | 6 +-
109
target/arm/helper.c | 327 +++++++++++++++++++++++++++++---------
110
target/arm/kvm64.c | 2 +
111
target/arm/op_helper.c | 14 +-
112
target/arm/translate-a64.c | 31 ++++
113
target/arm/translate.c | 42 +++--
114
tests/data/acpi/virt/DSDT | Bin 18462 -> 5307 bytes
115
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 6644 bytes
116
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 5307 bytes
117
23 files changed, 731 insertions(+), 187 deletions(-)
73
118
74
Thomas Huth (1):
75
hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
76
77
hw/arm/Makefile.objs | 1 +
78
hw/arm/smmu-internal.h | 99 +++
79
hw/arm/smmuv3-internal.h | 621 ++++++++++++++++++
80
include/hw/acpi/acpi-defs.h | 15 +
81
include/hw/arm/smmu-common.h | 145 +++++
82
include/hw/arm/smmuv3.h | 87 +++
83
include/hw/arm/virt.h | 10 +
84
hw/arm/boot.c | 2 +-
85
hw/arm/omap1.c | 8 +-
86
hw/arm/omap2.c | 8 +-
87
hw/arm/pxa2xx.c | 15 +-
88
hw/arm/smmu-common.c | 372 +++++++++++
89
hw/arm/smmuv3.c | 1191 +++++++++++++++++++++++++++++++++++
90
hw/arm/virt-acpi-build.c | 55 +-
91
hw/arm/virt.c | 101 ++-
92
hw/char/cmsdk-apb-uart.c | 1 +
93
hw/net/smc91c111.c | 54 +-
94
hw/usb/tusb6010.c | 40 +-
95
target/arm/helper.c | 2 +-
96
target/arm/kvm.c | 38 +-
97
target/arm/translate-a64.c | 12 +-
98
target/arm/translate.c | 17 +-
99
default-configs/aarch64-softmmu.mak | 1 +
100
hw/arm/trace-events | 37 ++
101
target/arm/trace-events | 3 +
102
25 files changed, 2868 insertions(+), 67 deletions(-)
103
create mode 100644 hw/arm/smmu-internal.h
104
create mode 100644 hw/arm/smmuv3-internal.h
105
create mode 100644 include/hw/arm/smmu-common.h
106
create mode 100644 include/hw/arm/smmuv3.h
107
create mode 100644 hw/arm/smmu-common.c
108
create mode 100644 hw/arm/smmuv3.c
109
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Roman Kapl <rka@sysgo.com>
2
2
3
Even though nothing is currently broken (since all boards
3
Documentation says for WDA '0: Assert WDOG output.' and for SRS
4
use first_cpu as boot cpu), make sure that boot_info is set
4
'0: Assert system reset signal.'.
5
on all CPUs.
6
If some board would like support heterogenuos setup (i.e.
7
init boot_info on subset of CPUs) in future, it should add
8
a reasonable API to do it, instead of starting assigning
9
boot_info from some CPU and till the end of present CPUs
10
list.
11
5
12
Ref:
6
Signed-off-by: Roman Kapl <rka@sysgo.com>
13
"Message-ID: <CAFEAcA_NMWuA8WSs3cNeY6xX1kerO_uAcN_3=fK02BEhHJW86g@mail.gmail.com>"
7
Message-id: 20200207095409.11227-1-rka@sysgo.com
14
15
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 1525176522-200354-5-git-send-email-imammedo@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
10
---
20
hw/arm/boot.c | 2 +-
11
hw/misc/imx2_wdt.c | 2 +-
21
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
22
13
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
16
--- a/hw/misc/imx2_wdt.c
26
+++ b/hw/arm/boot.c
17
+++ b/hw/misc/imx2_wdt.c
27
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
18
@@ -XXX,XX +XXX,XX @@ static void imx2_wdt_write(void *opaque, hwaddr addr,
28
}
19
uint64_t value, unsigned int size)
29
info->is_linux = is_linux;
20
{
30
21
if (addr == IMX2_WDT_WCR &&
31
- for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
22
- (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
32
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
23
+ (~value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
33
ARM_CPU(cs)->env.boot_info = info;
24
watchdog_perform_action();
34
}
25
}
35
}
26
}
36
--
27
--
37
2.17.0
28
2.20.1
38
29
39
30
diff view generated by jsdifflib
New patch
1
From: Roman Kapl <rka@sysgo.com>
1
2
3
Uses the i.MX2 rudimentary watchdog driver.
4
5
Signed-off-by: Roman Kapl <rka@sysgo.com>
6
Message-id: 20200207095529.11309-1-rka@sysgo.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: removed accidental duplicate #include line]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx6.h | 3 +++
12
hw/arm/fsl-imx6.c | 21 +++++++++++++++++++++
13
2 files changed, 24 insertions(+)
14
15
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx6.h
18
+++ b/include/hw/arm/fsl-imx6.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/cpu/a9mpcore.h"
21
#include "hw/misc/imx6_ccm.h"
22
#include "hw/misc/imx6_src.h"
23
+#include "hw/misc/imx2_wdt.h"
24
#include "hw/char/imx_serial.h"
25
#include "hw/timer/imx_gpt.h"
26
#include "hw/timer/imx_epit.h"
27
@@ -XXX,XX +XXX,XX @@
28
#define FSL_IMX6_NUM_GPIOS 7
29
#define FSL_IMX6_NUM_ESDHCS 4
30
#define FSL_IMX6_NUM_ECSPIS 5
31
+#define FSL_IMX6_NUM_WDTS 2
32
33
typedef struct FslIMX6State {
34
/*< private >*/
35
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
36
IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS];
37
SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS];
38
IMXSPIState spi[FSL_IMX6_NUM_ECSPIS];
39
+ IMX2WdtState wdt[FSL_IMX6_NUM_WDTS];
40
IMXFECState eth;
41
MemoryRegion rom;
42
MemoryRegion caam;
43
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/fsl-imx6.c
46
+++ b/hw/arm/fsl-imx6.c
47
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
48
sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
49
TYPE_IMX_SPI);
50
}
51
+ for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) {
52
+ snprintf(name, NAME_SIZE, "wdt%d", i);
53
+ sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
54
+ TYPE_IMX2_WDT);
55
+ }
56
+
57
58
sysbus_init_child_obj(obj, "eth", &s->eth, sizeof(s->eth), TYPE_IMX_ENET);
59
}
60
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
61
qdev_get_gpio_in(DEVICE(&s->a9mpcore),
62
FSL_IMX6_ENET_MAC_1588_IRQ));
63
64
+ /*
65
+ * Watchdog
66
+ */
67
+ for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) {
68
+ static const hwaddr FSL_IMX6_WDOGn_ADDR[FSL_IMX6_NUM_WDTS] = {
69
+ FSL_IMX6_WDOG1_ADDR,
70
+ FSL_IMX6_WDOG2_ADDR,
71
+ };
72
+
73
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
74
+ &error_abort);
75
+
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6_WDOGn_ADDR[i]);
77
+ }
78
+
79
/* ROM memory */
80
memory_region_init_rom(&s->rom, NULL, "imx6.rom",
81
FSL_IMX6_ROM_SIZE, &err);
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
New patch
1
From: Heyi Guo <guoheyi@huawei.com>
1
2
3
We are going to change ARM virt ACPI DSDT table, which will cause make
4
check to fail, so temporarily add related golden masters to ignore
5
list.
6
7
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
8
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
9
Message-id: 20200204014325.16279-2-guoheyi@huawei.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
13
1 file changed, 3 insertions(+)
14
15
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qtest/bios-tables-test-allowed-diff.h
18
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
19
@@ -1 +1,4 @@
20
/* List of comma-separated changed AML files to ignore */
21
+"tests/data/acpi/virt/DSDT",
22
+"tests/data/acpi/virt/DSDT.memhp",
23
+"tests/data/acpi/virt/DSDT.numamem",
24
--
25
2.20.1
26
27
diff view generated by jsdifflib
New patch
1
From: Heyi Guo <guoheyi@huawei.com>
1
2
3
The sub device "RP0" under PCI0 in ACPI/DSDT does not contain any
4
method or property other than "_ADR", so it is safe to remove it.
5
6
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
7
Acked-by: "Michael S. Tsirkin" <mst@redhat.com>
8
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
9
Message-id: 20200204014325.16279-3-guoheyi@huawei.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/virt-acpi-build.c | 4 ----
13
1 file changed, 4 deletions(-)
14
15
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/virt-acpi-build.c
18
+++ b/hw/arm/virt-acpi-build.c
19
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
20
aml_append(method, aml_return(buf));
21
aml_append(dev, method);
22
23
- Aml *dev_rp0 = aml_device("%s", "RP0");
24
- aml_append(dev_rp0, aml_name_decl("_ADR", aml_int(0)));
25
- aml_append(dev, dev_rp0);
26
-
27
Aml *dev_res0 = aml_device("%s", "RES0");
28
aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
29
crs = aml_resource_template();
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
1
From: Heyi Guo <guoheyi@huawei.com>
1
2
3
According to ACPI spec, _ADR should be used for device on a bus that
4
has a standard enumeration algorithm, but not for device which is on
5
system bus and must be enumerated by OSPM. And it is not recommended
6
to contain both _HID and _ADR in a single device.
7
8
See ACPI 6.3, section 6.1, top of page 343:
9
10
A device object must contain either an _HID object or an _ADR object,
11
but should not contain both.
12
13
(https://uefi.org/sites/default/files/resources/ACPI_6_3_May16.pdf)
14
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Acked-by: Igor Mammedov <imammedo@redhat.com>
17
Acked-by: Michael S. Tsirkin <mst@redhat.com>
18
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
19
Message-id: 20200204014325.16279-4-guoheyi@huawei.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
hw/arm/virt-acpi-build.c | 8 --------
23
1 file changed, 8 deletions(-)
24
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
28
+++ b/hw/arm/virt-acpi-build.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
30
AML_EXCLUSIVE, &uart_irq, 1));
31
aml_append(dev, aml_name_decl("_CRS", crs));
32
33
- /* The _ADR entry is used to link this device to the UART described
34
- * in the SPCR table, i.e. SPCR.base_address.address == _ADR.
35
- */
36
- aml_append(dev, aml_name_decl("_ADR", aml_int(uart_memmap->base)));
37
-
38
aml_append(scope, dev);
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
42
aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
43
aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
44
aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
45
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
46
aml_append(dev, aml_name_decl("_UID", aml_string("PCI0")));
47
aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
48
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
49
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap,
50
{
51
Aml *dev = aml_device("GPO0");
52
aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061")));
53
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
54
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
55
56
Aml *crs = aml_resource_template();
57
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_power_button(Aml *scope)
58
{
59
Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE);
60
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C")));
61
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
62
aml_append(dev, aml_name_decl("_UID", aml_int(0)));
63
aml_append(scope, dev);
64
}
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
New patch
1
From: Heyi Guo <guoheyi@huawei.com>
1
2
3
The address field in each _PRT mapping package should be constructed
4
with high word for device# and low word for function#, so it is wrong
5
to use bus_no as the high word. The existing code adds a bunch useless
6
entries with device #s above 31. Enumerate all possible slots
7
(i.e. PCI_SLOT_MAX) instead.
8
9
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
10
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
11
Message-id: 20200204014325.16279-5-guoheyi@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt-acpi-build.c | 10 +++++-----
15
1 file changed, 5 insertions(+), 5 deletions(-)
16
17
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt-acpi-build.c
20
+++ b/hw/arm/virt-acpi-build.c
21
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
22
{
23
int ecam_id = VIRT_ECAM_ID(highmem_ecam);
24
Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
25
- int i, bus_no;
26
+ int i, slot_no;
27
hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base;
28
hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size;
29
hwaddr base_pio = memmap[VIRT_PCIE_PIO].base;
30
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
31
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
32
33
/* Declare the PCI Routing Table. */
34
- Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS);
35
- for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) {
36
+ Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS);
37
+ for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) {
38
for (i = 0; i < PCI_NUM_PINS; i++) {
39
- int gsi = (i + bus_no) % PCI_NUM_PINS;
40
+ int gsi = (i + slot_no) % PCI_NUM_PINS;
41
Aml *pkg = aml_package(4);
42
- aml_append(pkg, aml_int((bus_no << 16) | 0xFFFF));
43
+ aml_append(pkg, aml_int((slot_no << 16) | 0xFFFF));
44
aml_append(pkg, aml_int(i));
45
aml_append(pkg, aml_name("GSI%d", gsi));
46
aml_append(pkg, aml_int(0));
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
New patch
1
From: Heyi Guo <guoheyi@huawei.com>
1
2
3
Using _UID of 0 for all PCI interrupt link devices absolutely violates
4
the spec. Simply increase one by one.
5
6
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Message-id: 20200204014325.16279-6-guoheyi@huawei.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/virt-acpi-build.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt-acpi-build.c
17
+++ b/hw/arm/virt-acpi-build.c
18
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
19
uint32_t irqs = irq + i;
20
Aml *dev_gsi = aml_device("GSI%d", i);
21
aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
22
- aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0)));
23
+ aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i)));
24
crs = aml_resource_template();
25
aml_append(crs,
26
aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
From: Heyi Guo <guoheyi@huawei.com>
2
2
3
This patch builds the smmuv3 node in the ACPI IORT table.
3
The original code defines a named object for the resource template but
4
then returns the resource template object itself; the resulted output
5
is like below:
4
6
5
The RID space of the root complex, which spans 0x0-0x10000
7
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
6
maps to streamid space 0x0-0x10000 in smmuv3, which in turn
8
{
7
maps to deviceid space 0x0-0x10000 in the ITS group.
9
Name (RBUF, ResourceTemplate ()
10
{
11
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
12
0x0000, // Granularity
13
0x0000, // Range Minimum
14
0x00FF, // Range Maximum
15
0x0000, // Translation Offset
16
0x0100, // Length
17
,, )
18
......
19
})
20
Return (ResourceTemplate ()
21
{
22
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
23
0x0000, // Granularity
24
0x0000, // Range Minimum
25
0x00FF, // Range Maximum
26
0x0000, // Translation Offset
27
0x0100, // Length
28
,, )
29
......
30
})
31
}
8
32
9
The guest must feature the IOMMU probe deferral series
33
So the named object "RBUF" is actually useless. The more natural way
10
(https://lkml.org/lkml/2017/4/10/214) which fixes streamid
34
is to return RBUF instead, or simply drop RBUF definition.
11
multiple lookup. This bug is not related to the SMMU emulation.
12
35
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
36
Choose the latter one to simplify the code.
14
Signed-off-by: Eric Auger <eric.auger@redhat.com>
37
15
Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
38
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 1524665762-31355-14-git-send-email-eric.auger@redhat.com
39
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
40
Message-id: 20200204014325.16279-7-guoheyi@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
42
---
19
include/hw/acpi/acpi-defs.h | 15 ++++++++++
43
hw/arm/virt-acpi-build.c | 1 -
20
hw/arm/virt-acpi-build.c | 55 ++++++++++++++++++++++++++++++++-----
44
1 file changed, 1 deletion(-)
21
2 files changed, 63 insertions(+), 7 deletions(-)
22
45
23
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/acpi/acpi-defs.h
26
+++ b/include/hw/acpi/acpi-defs.h
27
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
28
} QEMU_PACKED;
29
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
30
31
+struct AcpiIortSmmu3 {
32
+ ACPI_IORT_NODE_HEADER_DEF
33
+ uint64_t base_address;
34
+ uint32_t flags;
35
+ uint32_t reserved2;
36
+ uint64_t vatos_address;
37
+ uint32_t model;
38
+ uint32_t event_gsiv;
39
+ uint32_t pri_gsiv;
40
+ uint32_t gerr_gsiv;
41
+ uint32_t sync_gsiv;
42
+ AcpiIortIdMapping id_mapping_array[0];
43
+} QEMU_PACKED;
44
+typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
45
+
46
struct AcpiIortRC {
47
ACPI_IORT_NODE_HEADER_DEF
48
AcpiIortMemoryAccess memory_properties;
49
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
46
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
50
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/virt-acpi-build.c
48
--- a/hw/arm/virt-acpi-build.c
52
+++ b/hw/arm/virt-acpi-build.c
49
+++ b/hw/arm/virt-acpi-build.c
53
@@ -XXX,XX +XXX,XX @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
50
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
}
51
size_mmio_high));
55
56
static void
57
-build_iort(GArray *table_data, BIOSLinker *linker)
58
+build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
59
{
60
- int iort_start = table_data->len;
61
+ int nb_nodes, iort_start = table_data->len;
62
AcpiIortIdMapping *idmap;
63
AcpiIortItsGroup *its;
64
AcpiIortTable *iort;
65
- size_t node_size, iort_length;
66
+ AcpiIortSmmu3 *smmu;
67
+ size_t node_size, iort_length, smmu_offset = 0;
68
AcpiIortRC *rc;
69
70
iort = acpi_data_push(table_data, sizeof(*iort));
71
72
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
73
+ nb_nodes = 3; /* RC, ITS, SMMUv3 */
74
+ } else {
75
+ nb_nodes = 2; /* RC, ITS */
76
+ }
77
+
78
iort_length = sizeof(*iort);
79
- iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
80
+ iort->node_count = cpu_to_le32(nb_nodes);
81
iort->node_offset = cpu_to_le32(sizeof(*iort));
82
83
/* ITS group node */
84
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
85
its->its_count = cpu_to_le32(1);
86
its->identifiers[0] = 0; /* MADT translation_id */
87
88
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
89
+ int irq = vms->irqmap[VIRT_SMMU];
90
+
91
+ /* SMMUv3 node */
92
+ smmu_offset = iort->node_offset + node_size;
93
+ node_size = sizeof(*smmu) + sizeof(*idmap);
94
+ iort_length += node_size;
95
+ smmu = acpi_data_push(table_data, node_size);
96
+
97
+ smmu->type = ACPI_IORT_NODE_SMMU_V3;
98
+ smmu->length = cpu_to_le16(node_size);
99
+ smmu->mapping_count = cpu_to_le32(1);
100
+ smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
101
+ smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
102
+ smmu->event_gsiv = cpu_to_le32(irq);
103
+ smmu->pri_gsiv = cpu_to_le32(irq + 1);
104
+ smmu->gerr_gsiv = cpu_to_le32(irq + 2);
105
+ smmu->sync_gsiv = cpu_to_le32(irq + 3);
106
+
107
+ /* Identity RID mapping covering the whole input RID range */
108
+ idmap = &smmu->id_mapping_array[0];
109
+ idmap->input_base = 0;
110
+ idmap->id_count = cpu_to_le32(0xFFFF);
111
+ idmap->output_base = 0;
112
+ /* output IORT node is the ITS group node (the first node) */
113
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
114
+ }
115
+
116
/* Root Complex Node */
117
node_size = sizeof(*rc) + sizeof(*idmap);
118
iort_length += node_size;
119
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
120
idmap->input_base = 0;
121
idmap->id_count = cpu_to_le32(0xFFFF);
122
idmap->output_base = 0;
123
- /* output IORT node is the ITS group node (the first node) */
124
- idmap->output_reference = cpu_to_le32(iort->node_offset);
125
+
126
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
127
+ /* output IORT node is the smmuv3 node */
128
+ idmap->output_reference = cpu_to_le32(smmu_offset);
129
+ } else {
130
+ /* output IORT node is the ITS group node (the first node) */
131
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
132
+ }
133
134
iort->length = cpu_to_le32(iort_length);
135
136
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
137
138
if (its_class_name() && !vmc->no_its) {
139
acpi_add_table(table_offsets, tables_blob);
140
- build_iort(tables_blob, tables->linker);
141
+ build_iort(tables_blob, tables->linker, vms);
142
}
52
}
143
53
144
/* XSDT is pointed to by RSDP */
54
- aml_append(method, aml_name_decl("RBUF", rbuf));
55
aml_append(method, aml_return(rbuf));
56
aml_append(dev, method);
57
145
--
58
--
146
2.17.0
59
2.20.1
147
60
148
61
diff view generated by jsdifflib
New patch
1
1
From: Heyi Guo <guoheyi@huawei.com>
2
3
Differences between disassembled ASL files:
4
5
@@ -XXX,XX +XXX,XX @@
6
*
7
* Disassembling to symbolic ASL+ operators
8
*
9
- * Disassembly of DSDT, Thu Jan 23 16:00:04 2020
10
+ * Disassembly of DSDT.new, Thu Jan 23 16:47:12 2020
11
*
12
* Original Table Header:
13
* Signature "DSDT"
14
- * Length 0x0000481E (18462)
15
+ * Length 0x000014BB (5307)
16
* Revision 0x02
17
- * Checksum 0x60
18
+ * Checksum 0xD1
19
* OEM ID "BOCHS "
20
* OEM Table ID "BXPCDSDT"
21
* OEM Revision 0x00000001 (1)
22
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
23
0x00000021,
24
}
25
})
26
- Name (_ADR, 0x09000000) // _ADR: Address
27
}
28
29
Device (FLS0)
30
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
31
Name (_CID, "PNP0A03" /* PCI Bus */) // _CID: Compatible ID
32
Name (_SEG, Zero) // _SEG: PCI Segment
33
Name (_BBN, Zero) // _BBN: BIOS Bus Number
34
- Name (_ADR, Zero) // _ADR: Address
35
Name (_UID, "PCI0") // _UID: Unique ID
36
Name (_STR, Unicode ("PCIe 0 Device")) // _STR: Description String
37
Name (_CCA, One) // _CCA: Cache Coherency Attribute
38
- Name (_PRT, Package (0x0400) // _PRT: PCI Routing Table
39
+ Name (_PRT, Package (0x80) // _PRT: PCI Routing Table
40
{
41
Package (0x04)
42
{
43
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
44
0x03,
45
GSI2,
46
Zero
47
- },
48
-
49
- Package (0x04)
50
- {
51
- 0x0020FFFF,
52
- Zero,
53
- GSI0,
54
- Zero
55
- },
56
-
57
- *Omit the other (4 * (256 - 32) - 2) packages*
58
-
59
- Package (0x04)
60
- {
61
- 0x00FFFFFF,
62
- 0x03,
63
- GSI2,
64
- Zero
65
}
66
})
67
Device (GSI0)
68
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
69
Device (GSI1)
70
{
71
Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID
72
- Name (_UID, Zero) // _UID: Unique ID
73
+ Name (_UID, One) // _UID: Unique ID
74
Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings
75
{
76
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
77
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
78
Device (GSI2)
79
{
80
Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID
81
- Name (_UID, Zero) // _UID: Unique ID
82
+ Name (_UID, 0x02) // _UID: Unique ID
83
Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings
84
{
85
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
86
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
87
Device (GSI3)
88
{
89
Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID
90
- Name (_UID, Zero) // _UID: Unique ID
91
+ Name (_UID, 0x03) // _UID: Unique ID
92
Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings
93
{
94
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
95
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
96
97
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
98
{
99
- Name (RBUF, ResourceTemplate ()
100
- {
101
- WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
102
- 0x0000, // Granularity
103
- 0x0000, // Range Minimum
104
- 0x00FF, // Range Maximum
105
- 0x0000, // Translation Offset
106
- 0x0100, // Length
107
- ,, )
108
- DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
109
- 0x00000000, // Granularity
110
- 0x10000000, // Range Minimum
111
- 0x3EFEFFFF, // Range Maximum
112
- 0x00000000, // Translation Offset
113
- 0x2EFF0000, // Length
114
- ,, , AddressRangeMemory, TypeStatic)
115
- DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
116
- 0x00000000, // Granularity
117
- 0x00000000, // Range Minimum
118
- 0x0000FFFF, // Range Maximum
119
- 0x3EFF0000, // Translation Offset
120
- 0x00010000, // Length
121
- ,, , TypeStatic, DenseTranslation)
122
- QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
123
- 0x0000000000000000, // Granularity
124
- 0x0000008000000000, // Range Minimum
125
- 0x000000FFFFFFFFFF, // Range Maximum
126
- 0x0000000000000000, // Translation Offset
127
- 0x0000008000000000, // Length
128
- ,, , AddressRangeMemory, TypeStatic)
129
- })
130
Return (ResourceTemplate ()
131
{
132
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
133
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
134
})
135
}
136
137
- Device (RP0)
138
- {
139
- Name (_ADR, Zero) // _ADR: Address
140
- }
141
-
142
Device (RES0)
143
{
144
Name (_HID, "PNP0C02" /* PNP Motherboard Resources */) // _HID: Hardware ID
145
@@ -XXX,XX +XXX,XX @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001)
146
Device (PWRB)
147
{
148
Name (_HID, "PNP0C0C" /* Power Button Device */) // _HID: Hardware ID
149
- Name (_ADR, Zero) // _ADR: Address
150
Name (_UID, Zero) // _UID: Unique ID
151
}
152
}
153
154
The differences between the two versions of DSDT.memhp are almost the
155
same as the above, except for total length and checksum.
156
157
DSDT.numamem binary is just the same with DSDT on virt machine, so we
158
don't show the differences again.
159
160
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
161
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
162
Message-id: 20200204014325.16279-8-guoheyi@huawei.com
163
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
164
---
165
tests/qtest/bios-tables-test-allowed-diff.h | 3 ---
166
tests/data/acpi/virt/DSDT | Bin 18462 -> 5307 bytes
167
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 6644 bytes
168
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 5307 bytes
169
4 files changed, 3 deletions(-)
170
171
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
172
index XXXXXXX..XXXXXXX 100644
173
--- a/tests/qtest/bios-tables-test-allowed-diff.h
174
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
175
@@ -1,4 +1 @@
176
/* List of comma-separated changed AML files to ignore */
177
-"tests/data/acpi/virt/DSDT",
178
-"tests/data/acpi/virt/DSDT.memhp",
179
-"tests/data/acpi/virt/DSDT.numamem",
180
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
181
index XXXXXXX..XXXXXXX 100644
182
GIT binary patch
183
delta 156
184
zcmbO?fpNDcmrJlq$Zin^2BwP>xulufJQ*iyC^K43^tIeLL4lLWeZ}O>oO+X=b6T<Z
185
z6mvCfR_C%{pDgc^#>hCi&BajKi^V<I(}*M9!_$Q~z%RhS*}#o~BR<sAg^OwOMVP!X
186
lHhJdBGOmtnjvVpMLBX3Jy81CrwsAkqC^^YPgaxRb0RT`TDiQzy
187
188
literal 18462
189
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
265
A00000
266
267
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
268
index XXXXXXX..XXXXXXX 100644
269
GIT binary patch
270
delta 173
271
zcmcaUi}8ywmrJlq$QMZl2ByY|T++<_a~LOTC^K43^tIeLL4lLWeZ}O>oO+X=b6T<Z
272
z6mvCfR_C%{pDgc^#>hCi&BajKi^V<I(}*M9!_$Q~z%RhS*}#o~BR<sAg^OwOMVP!X
273
pHhJdBGOmtnjvVpMLBX3Jy81D0wsHT%Dk&Kd9^{0q-Wg&Z0|3#tFC_o~
274
275
literal 19799
276
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
365
DDbP3`
366
367
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
368
index XXXXXXX..XXXXXXX 100644
369
GIT binary patch
370
delta 156
371
zcmbO?fpNDcmrJlq$Zin^2BwP>xulufJQ*iyC^K43^tIeLL4lLWeZ}O>oO+X=b6T<Z
372
z6mvCfR_C%{pDgc^#>hCi&BajKi^V<I(}*M9!_$Q~z%RhS*}#o~BR<sAg^OwOMVP!X
373
lHhJdBGOmtnjvVpMLBX3Jy81CrwsAkqC^^YPgaxRb0RT`TDiQzy
374
375
literal 18462
376
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
452
A00000
453
454
--
455
2.20.1
456
457
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The patch introduces the smmu base device and class for the ARM
3
Use a common predicate for querying stage1-ness.
4
smmu. Devices for specific versions will be derived from this
5
base device.
6
4
7
We also introduce some important datatypes.
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
Message-id: 20200208125816.14954-2-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-2-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
hw/arm/Makefile.objs | 1 +
11
target/arm/internals.h | 18 ++++++++++++++++++
16
include/hw/arm/smmu-common.h | 123 ++++++++++++++++++++++++++++
12
target/arm/helper.c | 8 +++-----
17
hw/arm/smmu-common.c | 81 ++++++++++++++++++
13
2 files changed, 21 insertions(+), 5 deletions(-)
18
default-configs/aarch64-softmmu.mak | 1 +
19
4 files changed, 206 insertions(+)
20
create mode 100644 include/hw/arm/smmu-common.h
21
create mode 100644 hw/arm/smmu-common.c
22
14
23
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/Makefile.objs
17
--- a/target/arm/internals.h
26
+++ b/hw/arm/Makefile.objs
18
+++ b/target/arm/internals.h
27
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
19
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
28
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
20
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
29
obj-$(CONFIG_IOTKIT) += iotkit.o
21
#endif
30
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
22
31
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
23
+/**
32
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
24
+ * arm_mmu_idx_is_stage1_of_2:
33
new file mode 100644
25
+ * @mmu_idx: The ARMMMUIdx to test
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/arm/smmu-common.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * ARM SMMU Support
40
+ *
26
+ *
41
+ * Copyright (C) 2015-2016 Broadcom Corporation
27
+ * Return true if @mmu_idx is a NOTLB mmu_idx that is the
42
+ * Copyright (c) 2017 Red Hat, Inc.
28
+ * first stage of a two stage regime.
43
+ * Written by Prem Mallappa, Eric Auger
44
+ *
45
+ * This program is free software; you can redistribute it and/or modify
46
+ * it under the terms of the GNU General Public License version 2 as
47
+ * published by the Free Software Foundation.
48
+ *
49
+ * This program is distributed in the hope that it will be useful,
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52
+ * GNU General Public License for more details.
53
+ *
54
+ */
29
+ */
55
+
30
+static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
56
+#ifndef HW_ARM_SMMU_COMMON_H
57
+#define HW_ARM_SMMU_COMMON_H
58
+
59
+#include "hw/sysbus.h"
60
+#include "hw/pci/pci.h"
61
+
62
+#define SMMU_PCI_BUS_MAX 256
63
+#define SMMU_PCI_DEVFN_MAX 256
64
+
65
+#define SMMU_MAX_VA_BITS 48
66
+
67
+/*
68
+ * Page table walk error types
69
+ */
70
+typedef enum {
71
+ SMMU_PTW_ERR_NONE,
72
+ SMMU_PTW_ERR_WALK_EABT, /* Translation walk external abort */
73
+ SMMU_PTW_ERR_TRANSLATION, /* Translation fault */
74
+ SMMU_PTW_ERR_ADDR_SIZE, /* Address Size fault */
75
+ SMMU_PTW_ERR_ACCESS, /* Access fault */
76
+ SMMU_PTW_ERR_PERMISSION, /* Permission fault */
77
+} SMMUPTWEventType;
78
+
79
+typedef struct SMMUPTWEventInfo {
80
+ SMMUPTWEventType type;
81
+ dma_addr_t addr; /* fetched address that induced an abort, if any */
82
+} SMMUPTWEventInfo;
83
+
84
+typedef struct SMMUTransTableInfo {
85
+ bool disabled; /* is the translation table disabled? */
86
+ uint64_t ttb; /* TT base address */
87
+ uint8_t tsz; /* input range, ie. 2^(64 -tsz)*/
88
+ uint8_t granule_sz; /* granule page shift */
89
+} SMMUTransTableInfo;
90
+
91
+/*
92
+ * Generic structure populated by derived SMMU devices
93
+ * after decoding the configuration information and used as
94
+ * input to the page table walk
95
+ */
96
+typedef struct SMMUTransCfg {
97
+ int stage; /* translation stage */
98
+ bool aa64; /* arch64 or aarch32 translation table */
99
+ bool disabled; /* smmu is disabled */
100
+ bool bypassed; /* translation is bypassed */
101
+ bool aborted; /* translation is aborted */
102
+ uint64_t ttb; /* TT base address */
103
+ uint8_t oas; /* output address width */
104
+ uint8_t tbi; /* Top Byte Ignore */
105
+ uint16_t asid;
106
+ SMMUTransTableInfo tt[2];
107
+} SMMUTransCfg;
108
+
109
+typedef struct SMMUDevice {
110
+ void *smmu;
111
+ PCIBus *bus;
112
+ int devfn;
113
+ IOMMUMemoryRegion iommu;
114
+ AddressSpace as;
115
+} SMMUDevice;
116
+
117
+typedef struct SMMUNotifierNode {
118
+ SMMUDevice *sdev;
119
+ QLIST_ENTRY(SMMUNotifierNode) next;
120
+} SMMUNotifierNode;
121
+
122
+typedef struct SMMUPciBus {
123
+ PCIBus *bus;
124
+ SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
125
+} SMMUPciBus;
126
+
127
+typedef struct SMMUState {
128
+ /* <private> */
129
+ SysBusDevice dev;
130
+ const char *mrtypename;
131
+ MemoryRegion iomem;
132
+
133
+ GHashTable *smmu_pcibus_by_busptr;
134
+ GHashTable *configs; /* cache for configuration data */
135
+ GHashTable *iotlb;
136
+ SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
137
+ PCIBus *pci_bus;
138
+ QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
139
+ uint8_t bus_num;
140
+ PCIBus *primary_bus;
141
+} SMMUState;
142
+
143
+typedef struct {
144
+ /* <private> */
145
+ SysBusDeviceClass parent_class;
146
+
147
+ /*< public >*/
148
+
149
+ DeviceRealize parent_realize;
150
+
151
+} SMMUBaseClass;
152
+
153
+#define TYPE_ARM_SMMU "arm-smmu"
154
+#define ARM_SMMU(obj) OBJECT_CHECK(SMMUState, (obj), TYPE_ARM_SMMU)
155
+#define ARM_SMMU_CLASS(klass) \
156
+ OBJECT_CLASS_CHECK(SMMUBaseClass, (klass), TYPE_ARM_SMMU)
157
+#define ARM_SMMU_GET_CLASS(obj) \
158
+ OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
159
+
160
+#endif /* HW_ARM_SMMU_COMMON */
161
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
162
new file mode 100644
163
index XXXXXXX..XXXXXXX
164
--- /dev/null
165
+++ b/hw/arm/smmu-common.c
166
@@ -XXX,XX +XXX,XX @@
167
+/*
168
+ * Copyright (C) 2014-2016 Broadcom Corporation
169
+ * Copyright (c) 2017 Red Hat, Inc.
170
+ * Written by Prem Mallappa, Eric Auger
171
+ *
172
+ * This program is free software; you can redistribute it and/or modify
173
+ * it under the terms of the GNU General Public License version 2 as
174
+ * published by the Free Software Foundation.
175
+ *
176
+ * This program is distributed in the hope that it will be useful,
177
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
178
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
179
+ * GNU General Public License for more details.
180
+ *
181
+ * Author: Prem Mallappa <pmallapp@broadcom.com>
182
+ *
183
+ */
184
+
185
+#include "qemu/osdep.h"
186
+#include "sysemu/sysemu.h"
187
+#include "exec/address-spaces.h"
188
+#include "trace.h"
189
+#include "exec/target_page.h"
190
+#include "qom/cpu.h"
191
+#include "hw/qdev-properties.h"
192
+#include "qapi/error.h"
193
+
194
+#include "qemu/error-report.h"
195
+#include "hw/arm/smmu-common.h"
196
+
197
+static void smmu_base_realize(DeviceState *dev, Error **errp)
198
+{
31
+{
199
+ SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
32
+ switch (mmu_idx) {
200
+ Error *local_err = NULL;
33
+ case ARMMMUIdx_Stage1_E0:
201
+
34
+ case ARMMMUIdx_Stage1_E1:
202
+ sbc->parent_realize(dev, &local_err);
35
+ return true;
203
+ if (local_err) {
36
+ default:
204
+ error_propagate(errp, local_err);
37
+ return false;
205
+ return;
206
+ }
38
+ }
207
+}
39
+}
208
+
40
+
209
+static void smmu_base_reset(DeviceState *dev)
41
/*
210
+{
42
* Parameters of a given virtual address, as extracted from the
211
+ /* will be filled later on */
43
* translation control register (TCR) for a given regime.
212
+}
44
diff --git a/target/arm/helper.c b/target/arm/helper.c
213
+
214
+static Property smmu_dev_properties[] = {
215
+ DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0),
216
+ DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus, "PCI", PCIBus *),
217
+ DEFINE_PROP_END_OF_LIST(),
218
+};
219
+
220
+static void smmu_base_class_init(ObjectClass *klass, void *data)
221
+{
222
+ DeviceClass *dc = DEVICE_CLASS(klass);
223
+ SMMUBaseClass *sbc = ARM_SMMU_CLASS(klass);
224
+
225
+ dc->props = smmu_dev_properties;
226
+ device_class_set_parent_realize(dc, smmu_base_realize,
227
+ &sbc->parent_realize);
228
+ dc->reset = smmu_base_reset;
229
+}
230
+
231
+static const TypeInfo smmu_base_info = {
232
+ .name = TYPE_ARM_SMMU,
233
+ .parent = TYPE_SYS_BUS_DEVICE,
234
+ .instance_size = sizeof(SMMUState),
235
+ .class_data = NULL,
236
+ .class_size = sizeof(SMMUBaseClass),
237
+ .class_init = smmu_base_class_init,
238
+ .abstract = true,
239
+};
240
+
241
+static void smmu_base_register_types(void)
242
+{
243
+ type_register_static(&smmu_base_info);
244
+}
245
+
246
+type_init(smmu_base_register_types)
247
+
248
diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
249
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
250
--- a/default-configs/aarch64-softmmu.mak
46
--- a/target/arm/helper.c
251
+++ b/default-configs/aarch64-softmmu.mak
47
+++ b/target/arm/helper.c
252
@@ -XXX,XX +XXX,XX @@ CONFIG_DDC=y
48
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
253
CONFIG_DPCD=y
49
bool take_exc = false;
254
CONFIG_XLNX_ZYNQMP=y
50
255
CONFIG_XLNX_ZYNQMP_ARM=y
51
if (fi.s1ptw && current_el == 1 && !arm_is_secure(env)
256
+CONFIG_ARM_SMMUV3=y
52
- && (mmu_idx == ARMMMUIdx_Stage1_E1 ||
53
- mmu_idx == ARMMMUIdx_Stage1_E0)) {
54
+ && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
55
/*
56
* Synchronous stage 2 fault on an access made as part of the
57
* translation table walk for AT S1E0* or AT S1E1* insn
58
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
59
}
60
}
61
62
- if ((env->cp15.hcr_el2 & HCR_DC) &&
63
- (mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1)) {
64
+ if ((env->cp15.hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
65
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
66
return true;
67
}
68
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
69
hwaddr addr, MemTxAttrs txattrs,
70
ARMMMUFaultInfo *fi)
71
{
72
- if ((mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1) &&
73
+ if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
74
!regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
75
target_ulong s2size;
76
hwaddr s2pa;
257
--
77
--
258
2.17.0
78
2.20.1
259
79
260
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Path analysis shows that size == 3 && !is_q has been eliminated.
3
To implement PAN, we will want to swap, for short periods
4
4
of time, to a different privileged mmu_idx. In addition,
5
Fixes: Coverity CID1385853
5
we cannot do this with flushing alone, because the AT*
6
instructions have both PAN and PAN-less versions.
7
8
Add the ARMMMUIdx*_PAN constants where necessary next to
9
the corresponding ARMMMUIdx* constant.
10
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20200208125816.14954-3-richard.henderson@linaro.org
8
Message-id: 20180501180455.11214-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/translate-a64.c | 6 +++++-
17
target/arm/cpu-param.h | 2 +-
12
1 file changed, 5 insertions(+), 1 deletion(-)
18
target/arm/cpu.h | 33 ++++++++++++++-------
13
19
target/arm/internals.h | 9 ++++++
20
target/arm/helper.c | 60 +++++++++++++++++++++++++++++++-------
21
target/arm/translate-a64.c | 3 ++
22
target/arm/translate.c | 2 ++
23
6 files changed, 87 insertions(+), 22 deletions(-)
24
25
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu-param.h
28
+++ b/target/arm/cpu-param.h
29
@@ -XXX,XX +XXX,XX @@
30
# define TARGET_PAGE_BITS_MIN 10
31
#endif
32
33
-#define NB_MMU_MODES 9
34
+#define NB_MMU_MODES 12
35
36
#endif
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 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
42
* 5. we want to be able to use the TLB for accesses done as part of a
43
* stage1 page table walk, rather than having to walk the stage2 page
44
* table over and over.
45
+ * 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
46
+ * Never (PAN) bit within PSTATE.
47
*
48
* This gives us the following list of cases:
49
*
50
* NS EL0 EL1&0 stage 1+2 (aka NS PL0)
51
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
52
+ * NS EL1 EL1&0 stage 1+2 +PAN
53
* NS EL0 EL2&0
54
- * NS EL2 EL2&0
55
+ * NS EL2 EL2&0 +PAN
56
* NS EL2 (aka NS PL2)
57
* S EL0 EL1&0 (aka S PL0)
58
* S EL1 EL1&0 (not used if EL3 is 32 bit)
59
+ * S EL1 EL1&0 +PAN
60
* S EL3 (aka S PL1)
61
* NS EL1&0 stage 2
62
*
63
- * for a total of 9 different mmu_idx.
64
+ * for a total of 12 different mmu_idx.
65
*
66
* R profile CPUs have an MPU, but can use the same set of MMU indexes
67
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
68
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
69
/*
70
* A-profile.
71
*/
72
- ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
73
- ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
74
+ ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
75
+ ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
76
77
- ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
78
+ ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
79
+ ARMMMUIdx_E10_1_PAN = 3 | ARM_MMU_IDX_A,
80
81
- ARMMMUIdx_E2 = 3 | ARM_MMU_IDX_A,
82
- ARMMMUIdx_E20_2 = 4 | ARM_MMU_IDX_A,
83
+ ARMMMUIdx_E2 = 4 | ARM_MMU_IDX_A,
84
+ ARMMMUIdx_E20_2 = 5 | ARM_MMU_IDX_A,
85
+ ARMMMUIdx_E20_2_PAN = 6 | ARM_MMU_IDX_A,
86
87
- ARMMMUIdx_SE10_0 = 5 | ARM_MMU_IDX_A,
88
- ARMMMUIdx_SE10_1 = 6 | ARM_MMU_IDX_A,
89
- ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
90
+ ARMMMUIdx_SE10_0 = 7 | ARM_MMU_IDX_A,
91
+ ARMMMUIdx_SE10_1 = 8 | ARM_MMU_IDX_A,
92
+ ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
93
+ ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
94
95
- ARMMMUIdx_Stage2 = 8 | ARM_MMU_IDX_A,
96
+ ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
97
98
/*
99
* These are not allocated TLBs and are used only for AT system
100
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
101
*/
102
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
103
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
104
+ ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
105
106
/*
107
* M-profile.
108
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
109
TO_CORE_BIT(E10_0),
110
TO_CORE_BIT(E20_0),
111
TO_CORE_BIT(E10_1),
112
+ TO_CORE_BIT(E10_1_PAN),
113
TO_CORE_BIT(E2),
114
TO_CORE_BIT(E20_2),
115
+ TO_CORE_BIT(E20_2_PAN),
116
TO_CORE_BIT(SE10_0),
117
TO_CORE_BIT(SE10_1),
118
+ TO_CORE_BIT(SE10_1_PAN),
119
TO_CORE_BIT(SE3),
120
TO_CORE_BIT(Stage2),
121
122
diff --git a/target/arm/internals.h b/target/arm/internals.h
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/internals.h
125
+++ b/target/arm/internals.h
126
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
127
switch (mmu_idx) {
128
case ARMMMUIdx_Stage1_E0:
129
case ARMMMUIdx_Stage1_E1:
130
+ case ARMMMUIdx_Stage1_E1_PAN:
131
case ARMMMUIdx_E10_0:
132
case ARMMMUIdx_E10_1:
133
+ case ARMMMUIdx_E10_1_PAN:
134
case ARMMMUIdx_E20_0:
135
case ARMMMUIdx_E20_2:
136
+ case ARMMMUIdx_E20_2_PAN:
137
case ARMMMUIdx_SE10_0:
138
case ARMMMUIdx_SE10_1:
139
+ case ARMMMUIdx_SE10_1_PAN:
140
return true;
141
default:
142
return false;
143
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
144
switch (mmu_idx) {
145
case ARMMMUIdx_E10_0:
146
case ARMMMUIdx_E10_1:
147
+ case ARMMMUIdx_E10_1_PAN:
148
case ARMMMUIdx_E20_0:
149
case ARMMMUIdx_E20_2:
150
+ case ARMMMUIdx_E20_2_PAN:
151
case ARMMMUIdx_Stage1_E0:
152
case ARMMMUIdx_Stage1_E1:
153
+ case ARMMMUIdx_Stage1_E1_PAN:
154
case ARMMMUIdx_E2:
155
case ARMMMUIdx_Stage2:
156
case ARMMMUIdx_MPrivNegPri:
157
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
158
case ARMMMUIdx_SE3:
159
case ARMMMUIdx_SE10_0:
160
case ARMMMUIdx_SE10_1:
161
+ case ARMMMUIdx_SE10_1_PAN:
162
case ARMMMUIdx_MSPrivNegPri:
163
case ARMMMUIdx_MSUserNegPri:
164
case ARMMMUIdx_MSPriv:
165
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
166
switch (mmu_idx) {
167
case ARMMMUIdx_Stage1_E0:
168
case ARMMMUIdx_Stage1_E1:
169
+ case ARMMMUIdx_Stage1_E1_PAN:
170
return true;
171
default:
172
return false;
173
diff --git a/target/arm/helper.c b/target/arm/helper.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/arm/helper.c
176
+++ b/target/arm/helper.c
177
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
178
179
tlb_flush_by_mmuidx(cs,
180
ARMMMUIdxBit_E10_1 |
181
+ ARMMMUIdxBit_E10_1_PAN |
182
ARMMMUIdxBit_E10_0 |
183
ARMMMUIdxBit_Stage2);
184
}
185
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
186
187
tlb_flush_by_mmuidx_all_cpus_synced(cs,
188
ARMMMUIdxBit_E10_1 |
189
+ ARMMMUIdxBit_E10_1_PAN |
190
ARMMMUIdxBit_E10_0 |
191
ARMMMUIdxBit_Stage2);
192
}
193
@@ -XXX,XX +XXX,XX @@ static int gt_phys_redir_timeridx(CPUARMState *env)
194
switch (arm_mmu_idx(env)) {
195
case ARMMMUIdx_E20_0:
196
case ARMMMUIdx_E20_2:
197
+ case ARMMMUIdx_E20_2_PAN:
198
return GTIMER_HYP;
199
default:
200
return GTIMER_PHYS;
201
@@ -XXX,XX +XXX,XX @@ static int gt_virt_redir_timeridx(CPUARMState *env)
202
switch (arm_mmu_idx(env)) {
203
case ARMMMUIdx_E20_0:
204
case ARMMMUIdx_E20_2:
205
+ case ARMMMUIdx_E20_2_PAN:
206
return GTIMER_HYPVIRT;
207
default:
208
return GTIMER_VIRT;
209
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
210
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
211
212
if (arm_feature(env, ARM_FEATURE_EL2)) {
213
- if (mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_E10_1) {
214
+ if (mmu_idx == ARMMMUIdx_E10_0 ||
215
+ mmu_idx == ARMMMUIdx_E10_1 ||
216
+ mmu_idx == ARMMMUIdx_E10_1_PAN) {
217
format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
218
} else {
219
format64 |= arm_current_el(env) == 2;
220
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
221
if (extract64(raw_read(env, ri) ^ value, 48, 16) &&
222
(arm_hcr_el2_eff(env) & HCR_E2H)) {
223
tlb_flush_by_mmuidx(env_cpu(env),
224
- ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E20_0);
225
+ ARMMMUIdxBit_E20_2 |
226
+ ARMMMUIdxBit_E20_2_PAN |
227
+ ARMMMUIdxBit_E20_0);
228
}
229
raw_write(env, ri, value);
230
}
231
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
232
if (raw_read(env, ri) != value) {
233
tlb_flush_by_mmuidx(cs,
234
ARMMMUIdxBit_E10_1 |
235
+ ARMMMUIdxBit_E10_1_PAN |
236
ARMMMUIdxBit_E10_0 |
237
ARMMMUIdxBit_Stage2);
238
raw_write(env, ri, value);
239
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
240
{
241
/* Since we exclude secure first, we may read HCR_EL2 directly. */
242
if (arm_is_secure_below_el3(env)) {
243
- return ARMMMUIdxBit_SE10_1 | ARMMMUIdxBit_SE10_0;
244
+ return ARMMMUIdxBit_SE10_1 |
245
+ ARMMMUIdxBit_SE10_1_PAN |
246
+ ARMMMUIdxBit_SE10_0;
247
} else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE))
248
== (HCR_E2H | HCR_TGE)) {
249
- return ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E20_0;
250
+ return ARMMMUIdxBit_E20_2 |
251
+ ARMMMUIdxBit_E20_2_PAN |
252
+ ARMMMUIdxBit_E20_0;
253
} else {
254
- return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0;
255
+ return ARMMMUIdxBit_E10_1 |
256
+ ARMMMUIdxBit_E10_1_PAN |
257
+ ARMMMUIdxBit_E10_0;
258
}
259
}
260
261
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
262
* stage 1 translations.
263
*/
264
if (arm_is_secure_below_el3(env)) {
265
- return ARMMMUIdxBit_SE10_1 | ARMMMUIdxBit_SE10_0;
266
+ return ARMMMUIdxBit_SE10_1 |
267
+ ARMMMUIdxBit_SE10_1_PAN |
268
+ ARMMMUIdxBit_SE10_0;
269
} else if (arm_feature(env, ARM_FEATURE_EL2)) {
270
- return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0 | ARMMMUIdxBit_Stage2;
271
+ return ARMMMUIdxBit_E10_1 |
272
+ ARMMMUIdxBit_E10_1_PAN |
273
+ ARMMMUIdxBit_E10_0 |
274
+ ARMMMUIdxBit_Stage2;
275
} else {
276
- return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0;
277
+ return ARMMMUIdxBit_E10_1 |
278
+ ARMMMUIdxBit_E10_1_PAN |
279
+ ARMMMUIdxBit_E10_0;
280
}
281
}
282
283
static int e2_tlbmask(CPUARMState *env)
284
{
285
/* TODO: ARMv8.4-SecEL2 */
286
- return ARMMMUIdxBit_E20_0 | ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E2;
287
+ return ARMMMUIdxBit_E20_0 |
288
+ ARMMMUIdxBit_E20_2 |
289
+ ARMMMUIdxBit_E20_2_PAN |
290
+ ARMMMUIdxBit_E2;
291
}
292
293
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
294
@@ -XXX,XX +XXX,XX @@ static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
295
switch (mmu_idx) {
296
case ARMMMUIdx_E20_0:
297
case ARMMMUIdx_E20_2:
298
+ case ARMMMUIdx_E20_2_PAN:
299
case ARMMMUIdx_Stage2:
300
case ARMMMUIdx_E2:
301
return 2;
302
@@ -XXX,XX +XXX,XX @@ static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
303
case ARMMMUIdx_SE10_0:
304
return arm_el_is_aa64(env, 3) ? 1 : 3;
305
case ARMMMUIdx_SE10_1:
306
+ case ARMMMUIdx_SE10_1_PAN:
307
case ARMMMUIdx_Stage1_E0:
308
case ARMMMUIdx_Stage1_E1:
309
+ case ARMMMUIdx_Stage1_E1_PAN:
310
case ARMMMUIdx_E10_0:
311
case ARMMMUIdx_E10_1:
312
+ case ARMMMUIdx_E10_1_PAN:
313
case ARMMMUIdx_MPrivNegPri:
314
case ARMMMUIdx_MUserNegPri:
315
case ARMMMUIdx_MPriv:
316
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
317
return ARMMMUIdx_Stage1_E0;
318
case ARMMMUIdx_E10_1:
319
return ARMMMUIdx_Stage1_E1;
320
+ case ARMMMUIdx_E10_1_PAN:
321
+ return ARMMMUIdx_Stage1_E1_PAN;
322
default:
323
return mmu_idx;
324
}
325
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
326
return false;
327
case ARMMMUIdx_E10_0:
328
case ARMMMUIdx_E10_1:
329
+ case ARMMMUIdx_E10_1_PAN:
330
g_assert_not_reached();
331
}
332
}
333
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
334
target_ulong *page_size,
335
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
336
{
337
- if (mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_E10_1) {
338
+ if (mmu_idx == ARMMMUIdx_E10_0 ||
339
+ mmu_idx == ARMMMUIdx_E10_1 ||
340
+ mmu_idx == ARMMMUIdx_E10_1_PAN) {
341
/* Call ourselves recursively to do the stage 1 and then stage 2
342
* translations.
343
*/
344
@@ -XXX,XX +XXX,XX @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
345
case ARMMMUIdx_SE10_0:
346
return 0;
347
case ARMMMUIdx_E10_1:
348
+ case ARMMMUIdx_E10_1_PAN:
349
case ARMMMUIdx_SE10_1:
350
+ case ARMMMUIdx_SE10_1_PAN:
351
return 1;
352
case ARMMMUIdx_E2:
353
case ARMMMUIdx_E20_2:
354
+ case ARMMMUIdx_E20_2_PAN:
355
return 2;
356
case ARMMMUIdx_SE3:
357
return 3;
358
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
359
/* TODO: ARMv8.2-UAO */
360
switch (mmu_idx) {
361
case ARMMMUIdx_E10_1:
362
+ case ARMMMUIdx_E10_1_PAN:
363
case ARMMMUIdx_SE10_1:
364
+ case ARMMMUIdx_SE10_1_PAN:
365
/* TODO: ARMv8.3-NV */
366
flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
367
break;
368
case ARMMMUIdx_E20_2:
369
+ case ARMMMUIdx_E20_2_PAN:
370
/* TODO: ARMv8.4-SecEL2 */
371
/*
372
* Note that E20_2 is gated by HCR_EL2.E2H == 1, but E20_0 is
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
373
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
374
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
375
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
376
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
377
@@ -XXX,XX +XXX,XX @@ static int get_a64_user_mem_index(DisasContext *s)
19
/* All 64-bit element operations can be shared with scalar 2misc */
378
*/
20
int pass;
379
switch (useridx) {
21
380
case ARMMMUIdx_E10_1:
22
- for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
381
+ case ARMMMUIdx_E10_1_PAN:
23
+ /* Coverity claims (size == 3 && !is_q) has been eliminated
382
useridx = ARMMMUIdx_E10_0;
24
+ * from all paths leading to here.
383
break;
25
+ */
384
case ARMMMUIdx_E20_2:
26
+ tcg_debug_assert(is_q);
385
+ case ARMMMUIdx_E20_2_PAN:
27
+ for (pass = 0; pass < 2; pass++) {
386
useridx = ARMMMUIdx_E20_0;
28
TCGv_i64 tcg_op = tcg_temp_new_i64();
387
break;
29
TCGv_i64 tcg_res = tcg_temp_new_i64();
388
case ARMMMUIdx_SE10_1:
30
389
+ case ARMMMUIdx_SE10_1_PAN:
390
useridx = ARMMMUIdx_SE10_0;
391
break;
392
default:
393
diff --git a/target/arm/translate.c b/target/arm/translate.c
394
index XXXXXXX..XXXXXXX 100644
395
--- a/target/arm/translate.c
396
+++ b/target/arm/translate.c
397
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
398
case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
399
case ARMMMUIdx_E10_0:
400
case ARMMMUIdx_E10_1:
401
+ case ARMMMUIdx_E10_1_PAN:
402
return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
403
case ARMMMUIdx_SE3:
404
case ARMMMUIdx_SE10_0:
405
case ARMMMUIdx_SE10_1:
406
+ case ARMMMUIdx_SE10_1_PAN:
407
return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
408
case ARMMMUIdx_MUser:
409
case ARMMMUIdx_MPriv:
31
--
410
--
32
2.17.0
411
2.20.1
33
412
34
413
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We introduce some helpers to handle wired IRQs and especially
3
Include definitions for all of the bits in ID_MMFR3.
4
GERROR interrupt. SMMU writes GERROR register on GERROR event
4
We already have a definition for ID_AA64MMFR1.PAN.
5
and SW acks GERROR interrupts by setting GERRORn.
6
5
7
The Wired interrupts are edge sensitive hence the pulse usage.
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-6-git-send-email-eric.auger@redhat.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200208125816.14954-4-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/arm/smmuv3-internal.h | 14 +++++++++
12
target/arm/cpu.h | 29 +++++++++++++++++++++++++++++
16
hw/arm/smmuv3.c | 64 ++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 29 insertions(+)
17
hw/arm/trace-events | 3 ++
18
3 files changed, 81 insertions(+)
19
14
20
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/smmuv3-internal.h
17
--- a/target/arm/cpu.h
23
+++ b/hw/arm/smmuv3-internal.h
18
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static inline uint32_t smmuv3_idreg(int regoffset)
19
@@ -XXX,XX +XXX,XX @@ FIELD(ID_ISAR6, FHM, 8, 4)
25
return smmuv3_ids[regoffset / 4];
20
FIELD(ID_ISAR6, SB, 12, 4)
21
FIELD(ID_ISAR6, SPECRES, 16, 4)
22
23
+FIELD(ID_MMFR3, CMAINTVA, 0, 4)
24
+FIELD(ID_MMFR3, CMAINTSW, 4, 4)
25
+FIELD(ID_MMFR3, BPMAINT, 8, 4)
26
+FIELD(ID_MMFR3, MAINTBCST, 12, 4)
27
+FIELD(ID_MMFR3, PAN, 16, 4)
28
+FIELD(ID_MMFR3, COHWALK, 20, 4)
29
+FIELD(ID_MMFR3, CMEMSZ, 24, 4)
30
+FIELD(ID_MMFR3, SUPERSEC, 28, 4)
31
+
32
FIELD(ID_MMFR4, SPECSEI, 0, 4)
33
FIELD(ID_MMFR4, AC2, 4, 4)
34
FIELD(ID_MMFR4, XNX, 8, 4)
35
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
36
return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
26
}
37
}
27
38
28
+static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
39
+static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
29
+{
40
+{
30
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
41
+ return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0;
31
+}
42
+}
32
+
43
+
33
+static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
44
+static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
34
+{
45
+{
35
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
46
+ return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2;
36
+}
47
+}
37
+
48
+
38
+/* public until callers get introduced */
49
/*
39
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
50
* 64-bit feature tests via id registers.
40
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
51
*/
41
+
52
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
42
#endif
53
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
43
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
54
}
44
index XXXXXXX..XXXXXXX 100644
55
45
--- a/hw/arm/smmuv3.c
56
+static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
46
+++ b/hw/arm/smmuv3.c
47
@@ -XXX,XX +XXX,XX @@
48
#include "hw/arm/smmuv3.h"
49
#include "smmuv3-internal.h"
50
51
+/**
52
+ * smmuv3_trigger_irq - pulse @irq if enabled and update
53
+ * GERROR register in case of GERROR interrupt
54
+ *
55
+ * @irq: irq type
56
+ * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
57
+ */
58
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
59
+{
57
+{
60
+
58
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0;
61
+ bool pulse = false;
62
+
63
+ switch (irq) {
64
+ case SMMU_IRQ_EVTQ:
65
+ pulse = smmuv3_eventq_irq_enabled(s);
66
+ break;
67
+ case SMMU_IRQ_PRIQ:
68
+ qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n");
69
+ break;
70
+ case SMMU_IRQ_CMD_SYNC:
71
+ pulse = true;
72
+ break;
73
+ case SMMU_IRQ_GERROR:
74
+ {
75
+ uint32_t pending = s->gerror ^ s->gerrorn;
76
+ uint32_t new_gerrors = ~pending & gerror_mask;
77
+
78
+ if (!new_gerrors) {
79
+ /* only toggle non pending errors */
80
+ return;
81
+ }
82
+ s->gerror ^= new_gerrors;
83
+ trace_smmuv3_write_gerror(new_gerrors, s->gerror);
84
+
85
+ pulse = smmuv3_gerror_irq_enabled(s);
86
+ break;
87
+ }
88
+ }
89
+ if (pulse) {
90
+ trace_smmuv3_trigger_irq(irq);
91
+ qemu_irq_pulse(s->irq[irq]);
92
+ }
93
+}
59
+}
94
+
60
+
95
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
61
+static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
96
+{
62
+{
97
+ uint32_t pending = s->gerror ^ s->gerrorn;
63
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
98
+ uint32_t toggled = s->gerrorn ^ new_gerrorn;
99
+
100
+ if (toggled & ~pending) {
101
+ qemu_log_mask(LOG_GUEST_ERROR,
102
+ "guest toggles non pending errors = 0x%x\n",
103
+ toggled & ~pending);
104
+ }
105
+
106
+ /*
107
+ * We do not raise any error in case guest toggles bits corresponding
108
+ * to not active IRQs (CONSTRAINED UNPREDICTABLE)
109
+ */
110
+ s->gerrorn = new_gerrorn;
111
+
112
+ trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
113
+}
64
+}
114
+
65
+
115
static void smmuv3_init_regs(SMMUv3State *s)
66
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
116
{
67
{
117
/**
68
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
118
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
119
index XXXXXXX..XXXXXXX 100644
120
--- a/hw/arm/trace-events
121
+++ b/hw/arm/trace-events
122
@@ -XXX,XX +XXX,XX @@ smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "base
123
124
#hw/arm/smmuv3.c
125
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
126
+smmuv3_trigger_irq(int irq) "irq=%d"
127
+smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
128
+smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
129
--
69
--
130
2.17.0
70
2.20.1
131
71
132
72
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Let's introduce a helper function aiming at recording an
3
For static const regdefs, file scope is preferred.
4
event in the event queue.
5
4
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1524665762-31355-9-git-send-email-eric.auger@redhat.com
7
Message-id: 20200208125816.14954-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/smmuv3-internal.h | 148 ++++++++++++++++++++++++++++++++++++++-
10
target/arm/helper.c | 57 +++++++++++++++++++++++----------------------
12
hw/arm/smmuv3.c | 108 ++++++++++++++++++++++++++--
11
1 file changed, 29 insertions(+), 28 deletions(-)
13
hw/arm/trace-events | 1 +
14
3 files changed, 249 insertions(+), 8 deletions(-)
15
12
16
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/smmuv3-internal.h
15
--- a/target/arm/helper.c
19
+++ b/hw/arm/smmuv3-internal.h
16
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
17
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
21
s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
18
return access_lor_ns(env);
22
}
19
}
23
20
24
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
21
+/*
25
-
22
+ * A trivial implementation of ARMv8.1-LOR leaves all of these
26
/* Commands */
23
+ * registers fixed at 0, which indicates that there are zero
27
24
+ * supported Limited Ordering regions.
28
typedef enum SMMUCommandType {
25
+ */
29
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
26
+static const ARMCPRegInfo lor_reginfo[] = {
30
27
+ { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
31
#define SMMU_FEATURE_2LVL_STE (1 << 0)
28
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
32
29
+ .access = PL1_RW, .accessfn = access_lor_other,
33
+/* Events */
30
+ .type = ARM_CP_CONST, .resetvalue = 0 },
34
+
31
+ { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
35
+typedef enum SMMUEventType {
32
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
36
+ SMMU_EVT_OK = 0x00,
33
+ .access = PL1_RW, .accessfn = access_lor_other,
37
+ SMMU_EVT_F_UUT ,
34
+ .type = ARM_CP_CONST, .resetvalue = 0 },
38
+ SMMU_EVT_C_BAD_STREAMID ,
35
+ { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
39
+ SMMU_EVT_F_STE_FETCH ,
36
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
40
+ SMMU_EVT_C_BAD_STE ,
37
+ .access = PL1_RW, .accessfn = access_lor_other,
41
+ SMMU_EVT_F_BAD_ATS_TREQ ,
38
+ .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ SMMU_EVT_F_STREAM_DISABLED ,
39
+ { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
43
+ SMMU_EVT_F_TRANS_FORBIDDEN ,
40
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
44
+ SMMU_EVT_C_BAD_SUBSTREAMID ,
41
+ .access = PL1_RW, .accessfn = access_lor_other,
45
+ SMMU_EVT_F_CD_FETCH ,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ SMMU_EVT_C_BAD_CD ,
43
+ { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
47
+ SMMU_EVT_F_WALK_EABT ,
44
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
48
+ SMMU_EVT_F_TRANSLATION = 0x10,
45
+ .access = PL1_R, .accessfn = access_lorid,
49
+ SMMU_EVT_F_ADDR_SIZE ,
46
+ .type = ARM_CP_CONST, .resetvalue = 0 },
50
+ SMMU_EVT_F_ACCESS ,
47
+ REGINFO_SENTINEL
51
+ SMMU_EVT_F_PERMISSION ,
52
+ SMMU_EVT_F_TLB_CONFLICT = 0x20,
53
+ SMMU_EVT_F_CFG_CONFLICT ,
54
+ SMMU_EVT_E_PAGE_REQ = 0x24,
55
+} SMMUEventType;
56
+
57
+static const char *event_stringify[] = {
58
+ [SMMU_EVT_OK] = "SMMU_EVT_OK",
59
+ [SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
60
+ [SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
61
+ [SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
62
+ [SMMU_EVT_C_BAD_STE] = "SMMU_EVT_C_BAD_STE",
63
+ [SMMU_EVT_F_BAD_ATS_TREQ] = "SMMU_EVT_F_BAD_ATS_TREQ",
64
+ [SMMU_EVT_F_STREAM_DISABLED] = "SMMU_EVT_F_STREAM_DISABLED",
65
+ [SMMU_EVT_F_TRANS_FORBIDDEN] = "SMMU_EVT_F_TRANS_FORBIDDEN",
66
+ [SMMU_EVT_C_BAD_SUBSTREAMID] = "SMMU_EVT_C_BAD_SUBSTREAMID",
67
+ [SMMU_EVT_F_CD_FETCH] = "SMMU_EVT_F_CD_FETCH",
68
+ [SMMU_EVT_C_BAD_CD] = "SMMU_EVT_C_BAD_CD",
69
+ [SMMU_EVT_F_WALK_EABT] = "SMMU_EVT_F_WALK_EABT",
70
+ [SMMU_EVT_F_TRANSLATION] = "SMMU_EVT_F_TRANSLATION",
71
+ [SMMU_EVT_F_ADDR_SIZE] = "SMMU_EVT_F_ADDR_SIZE",
72
+ [SMMU_EVT_F_ACCESS] = "SMMU_EVT_F_ACCESS",
73
+ [SMMU_EVT_F_PERMISSION] = "SMMU_EVT_F_PERMISSION",
74
+ [SMMU_EVT_F_TLB_CONFLICT] = "SMMU_EVT_F_TLB_CONFLICT",
75
+ [SMMU_EVT_F_CFG_CONFLICT] = "SMMU_EVT_F_CFG_CONFLICT",
76
+ [SMMU_EVT_E_PAGE_REQ] = "SMMU_EVT_E_PAGE_REQ",
77
+};
48
+};
78
+
49
+
79
+static inline const char *smmu_event_string(SMMUEventType type)
50
#ifdef TARGET_AARCH64
80
+{
51
static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
81
+ if (type < ARRAY_SIZE(event_stringify)) {
52
bool isread)
82
+ return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
53
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
83
+ } else {
84
+ return "INVALID";
85
+ }
86
+}
87
+
88
+/* Encode an event record */
89
+typedef struct SMMUEventInfo {
90
+ SMMUEventType type;
91
+ uint32_t sid;
92
+ bool recorded;
93
+ bool record_trans_faults;
94
+ union {
95
+ struct {
96
+ uint32_t ssid;
97
+ bool ssv;
98
+ dma_addr_t addr;
99
+ bool rnw;
100
+ bool pnu;
101
+ bool ind;
102
+ } f_uut;
103
+ struct SSIDInfo {
104
+ uint32_t ssid;
105
+ bool ssv;
106
+ } c_bad_streamid;
107
+ struct SSIDAddrInfo {
108
+ uint32_t ssid;
109
+ bool ssv;
110
+ dma_addr_t addr;
111
+ } f_ste_fetch;
112
+ struct SSIDInfo c_bad_ste;
113
+ struct {
114
+ dma_addr_t addr;
115
+ bool rnw;
116
+ } f_transl_forbidden;
117
+ struct {
118
+ uint32_t ssid;
119
+ } c_bad_substream;
120
+ struct SSIDAddrInfo f_cd_fetch;
121
+ struct SSIDInfo c_bad_cd;
122
+ struct FullInfo {
123
+ bool stall;
124
+ uint16_t stag;
125
+ uint32_t ssid;
126
+ bool ssv;
127
+ bool s2;
128
+ dma_addr_t addr;
129
+ bool rnw;
130
+ bool pnu;
131
+ bool ind;
132
+ uint8_t class;
133
+ dma_addr_t addr2;
134
+ } f_walk_eabt;
135
+ struct FullInfo f_translation;
136
+ struct FullInfo f_addr_size;
137
+ struct FullInfo f_access;
138
+ struct FullInfo f_permission;
139
+ struct SSIDInfo f_cfg_conflict;
140
+ /**
141
+ * not supported yet:
142
+ * F_BAD_ATS_TREQ
143
+ * F_BAD_ATS_TREQ
144
+ * F_TLB_CONFLICT
145
+ * E_PAGE_REQUEST
146
+ * IMPDEF_EVENTn
147
+ */
148
+ } u;
149
+} SMMUEventInfo;
150
+
151
+/* EVTQ fields */
152
+
153
+#define EVT_Q_OVERFLOW (1 << 31)
154
+
155
+#define EVT_SET_TYPE(x, v) deposit32((x)->word[0], 0 , 8 , v)
156
+#define EVT_SET_SSV(x, v) deposit32((x)->word[0], 11, 1 , v)
157
+#define EVT_SET_SSID(x, v) deposit32((x)->word[0], 12, 20, v)
158
+#define EVT_SET_SID(x, v) ((x)->word[1] = v)
159
+#define EVT_SET_STAG(x, v) deposit32((x)->word[2], 0 , 16, v)
160
+#define EVT_SET_STALL(x, v) deposit32((x)->word[2], 31, 1 , v)
161
+#define EVT_SET_PNU(x, v) deposit32((x)->word[3], 1 , 1 , v)
162
+#define EVT_SET_IND(x, v) deposit32((x)->word[3], 2 , 1 , v)
163
+#define EVT_SET_RNW(x, v) deposit32((x)->word[3], 3 , 1 , v)
164
+#define EVT_SET_S2(x, v) deposit32((x)->word[3], 7 , 1 , v)
165
+#define EVT_SET_CLASS(x, v) deposit32((x)->word[3], 8 , 2 , v)
166
+#define EVT_SET_ADDR(x, addr) \
167
+ do { \
168
+ (x)->word[5] = (uint32_t)(addr >> 32); \
169
+ (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
170
+ } while (0)
171
+#define EVT_SET_ADDR2(x, addr) \
172
+ do { \
173
+ deposit32((x)->word[7], 3, 29, addr >> 16); \
174
+ deposit32((x)->word[7], 0, 16, addr & 0xffff);\
175
+ } while (0)
176
+
177
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
178
+
179
#endif
180
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/hw/arm/smmuv3.c
183
+++ b/hw/arm/smmuv3.c
184
@@ -XXX,XX +XXX,XX @@ static MemTxResult queue_write(SMMUQueue *q, void *data)
185
return MEMTX_OK;
186
}
187
188
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
189
+static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
190
{
191
SMMUQueue *q = &s->eventq;
192
+ MemTxResult r;
193
+
194
+ if (!smmuv3_eventq_enabled(s)) {
195
+ return MEMTX_ERROR;
196
+ }
197
+
198
+ if (smmuv3_q_full(q)) {
199
+ return MEMTX_ERROR;
200
+ }
201
+
202
+ r = queue_write(q, evt);
203
+ if (r != MEMTX_OK) {
204
+ return r;
205
+ }
206
+
207
+ if (smmuv3_q_empty(q)) {
208
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
209
+ }
210
+ return MEMTX_OK;
211
+}
212
+
213
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
214
+{
215
+ Evt evt;
216
+ MemTxResult r;
217
218
if (!smmuv3_eventq_enabled(s)) {
219
return;
220
}
54
}
221
55
222
- if (smmuv3_q_full(q)) {
56
if (cpu_isar_feature(aa64_lor, cpu)) {
223
+ EVT_SET_TYPE(&evt, info->type);
57
- /*
224
+ EVT_SET_SID(&evt, info->sid);
58
- * A trivial implementation of ARMv8.1-LOR leaves all of these
225
+
59
- * registers fixed at 0, which indicates that there are zero
226
+ switch (info->type) {
60
- * supported Limited Ordering regions.
227
+ case SMMU_EVT_OK:
61
- */
228
return;
62
- static const ARMCPRegInfo lor_reginfo[] = {
229
+ case SMMU_EVT_F_UUT:
63
- { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
230
+ EVT_SET_SSID(&evt, info->u.f_uut.ssid);
64
- .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
231
+ EVT_SET_SSV(&evt, info->u.f_uut.ssv);
65
- .access = PL1_RW, .accessfn = access_lor_other,
232
+ EVT_SET_ADDR(&evt, info->u.f_uut.addr);
66
- .type = ARM_CP_CONST, .resetvalue = 0 },
233
+ EVT_SET_RNW(&evt, info->u.f_uut.rnw);
67
- { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
234
+ EVT_SET_PNU(&evt, info->u.f_uut.pnu);
68
- .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
235
+ EVT_SET_IND(&evt, info->u.f_uut.ind);
69
- .access = PL1_RW, .accessfn = access_lor_other,
236
+ break;
70
- .type = ARM_CP_CONST, .resetvalue = 0 },
237
+ case SMMU_EVT_C_BAD_STREAMID:
71
- { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
238
+ EVT_SET_SSID(&evt, info->u.c_bad_streamid.ssid);
72
- .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
239
+ EVT_SET_SSV(&evt, info->u.c_bad_streamid.ssv);
73
- .access = PL1_RW, .accessfn = access_lor_other,
240
+ break;
74
- .type = ARM_CP_CONST, .resetvalue = 0 },
241
+ case SMMU_EVT_F_STE_FETCH:
75
- { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
242
+ EVT_SET_SSID(&evt, info->u.f_ste_fetch.ssid);
76
- .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
243
+ EVT_SET_SSV(&evt, info->u.f_ste_fetch.ssv);
77
- .access = PL1_RW, .accessfn = access_lor_other,
244
+ EVT_SET_ADDR(&evt, info->u.f_ste_fetch.addr);
78
- .type = ARM_CP_CONST, .resetvalue = 0 },
245
+ break;
79
- { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
246
+ case SMMU_EVT_C_BAD_STE:
80
- .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
247
+ EVT_SET_SSID(&evt, info->u.c_bad_ste.ssid);
81
- .access = PL1_R, .accessfn = access_lorid,
248
+ EVT_SET_SSV(&evt, info->u.c_bad_ste.ssv);
82
- .type = ARM_CP_CONST, .resetvalue = 0 },
249
+ break;
83
- REGINFO_SENTINEL
250
+ case SMMU_EVT_F_STREAM_DISABLED:
84
- };
251
+ break;
85
define_arm_cp_regs(cpu, lor_reginfo);
252
+ case SMMU_EVT_F_TRANS_FORBIDDEN:
253
+ EVT_SET_ADDR(&evt, info->u.f_transl_forbidden.addr);
254
+ EVT_SET_RNW(&evt, info->u.f_transl_forbidden.rnw);
255
+ break;
256
+ case SMMU_EVT_C_BAD_SUBSTREAMID:
257
+ EVT_SET_SSID(&evt, info->u.c_bad_substream.ssid);
258
+ break;
259
+ case SMMU_EVT_F_CD_FETCH:
260
+ EVT_SET_SSID(&evt, info->u.f_cd_fetch.ssid);
261
+ EVT_SET_SSV(&evt, info->u.f_cd_fetch.ssv);
262
+ EVT_SET_ADDR(&evt, info->u.f_cd_fetch.addr);
263
+ break;
264
+ case SMMU_EVT_C_BAD_CD:
265
+ EVT_SET_SSID(&evt, info->u.c_bad_cd.ssid);
266
+ EVT_SET_SSV(&evt, info->u.c_bad_cd.ssv);
267
+ break;
268
+ case SMMU_EVT_F_WALK_EABT:
269
+ case SMMU_EVT_F_TRANSLATION:
270
+ case SMMU_EVT_F_ADDR_SIZE:
271
+ case SMMU_EVT_F_ACCESS:
272
+ case SMMU_EVT_F_PERMISSION:
273
+ EVT_SET_STALL(&evt, info->u.f_walk_eabt.stall);
274
+ EVT_SET_STAG(&evt, info->u.f_walk_eabt.stag);
275
+ EVT_SET_SSID(&evt, info->u.f_walk_eabt.ssid);
276
+ EVT_SET_SSV(&evt, info->u.f_walk_eabt.ssv);
277
+ EVT_SET_S2(&evt, info->u.f_walk_eabt.s2);
278
+ EVT_SET_ADDR(&evt, info->u.f_walk_eabt.addr);
279
+ EVT_SET_RNW(&evt, info->u.f_walk_eabt.rnw);
280
+ EVT_SET_PNU(&evt, info->u.f_walk_eabt.pnu);
281
+ EVT_SET_IND(&evt, info->u.f_walk_eabt.ind);
282
+ EVT_SET_CLASS(&evt, info->u.f_walk_eabt.class);
283
+ EVT_SET_ADDR2(&evt, info->u.f_walk_eabt.addr2);
284
+ break;
285
+ case SMMU_EVT_F_CFG_CONFLICT:
286
+ EVT_SET_SSID(&evt, info->u.f_cfg_conflict.ssid);
287
+ EVT_SET_SSV(&evt, info->u.f_cfg_conflict.ssv);
288
+ break;
289
+ /* rest is not implemented */
290
+ case SMMU_EVT_F_BAD_ATS_TREQ:
291
+ case SMMU_EVT_F_TLB_CONFLICT:
292
+ case SMMU_EVT_E_PAGE_REQ:
293
+ default:
294
+ g_assert_not_reached();
295
}
86
}
296
87
297
- queue_write(q, evt);
298
-
299
- if (smmuv3_q_empty(q)) {
300
- smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
301
+ trace_smmuv3_record_event(smmu_event_string(info->type), info->sid);
302
+ r = smmuv3_write_eventq(s, &evt);
303
+ if (r != MEMTX_OK) {
304
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
305
}
306
+ info->recorded = true;
307
}
308
309
static void smmuv3_init_regs(SMMUv3State *s)
310
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
311
index XXXXXXX..XXXXXXX 100644
312
--- a/hw/arm/trace-events
313
+++ b/hw/arm/trace-events
314
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
315
smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
316
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
317
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
318
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
319
--
88
--
320
2.17.0
89
2.20.1
321
90
322
91
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now we have relevant helpers for queue and irq
3
Split this helper out of msr_mask in translate.c. At the same time,
4
management, let's implement MMIO write operations.
4
transform the negative reductive logic to positive accumulative logic.
5
It will be usable along the exception paths.
5
6
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
While touching msr_mask, fix up formatting.
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-8-git-send-email-eric.auger@redhat.com
11
Message-id: 20200208125816.14954-6-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/smmuv3-internal.h | 8 +-
14
target/arm/internals.h | 21 +++++++++++++++++++++
13
hw/arm/smmuv3.c | 170 +++++++++++++++++++++++++++++++++++++--
15
target/arm/translate.c | 40 +++++++++++++++++-----------------------
14
hw/arm/trace-events | 6 ++
16
2 files changed, 38 insertions(+), 23 deletions(-)
15
3 files changed, 174 insertions(+), 10 deletions(-)
16
17
17
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/smmuv3-internal.h
20
--- a/target/arm/internals.h
20
+++ b/hw/arm/smmuv3-internal.h
21
+++ b/target/arm/internals.h
21
@@ -XXX,XX +XXX,XX @@ REG32(CR0, 0x20)
22
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
22
FIELD(CR0, EVENTQEN, 2, 1)
23
FIELD(CR0, CMDQEN, 3, 1)
24
25
+#define SMMU_CR0_RESERVED 0xFFFFFC20
26
+
27
REG32(CR0ACK, 0x24)
28
REG32(CR1, 0x28)
29
REG32(CR2, 0x2c)
30
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
31
return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
32
}
33
34
-/* public until callers get introduced */
35
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
36
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
37
-
38
/* Queue Handling */
39
40
#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
41
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
42
addr; \
43
})
44
45
-int smmuv3_cmdq_consume(SMMUv3State *s);
46
+#define SMMU_FEATURE_2LVL_STE (1 << 0)
47
48
#endif
49
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmuv3.c
52
+++ b/hw/arm/smmuv3.c
53
@@ -XXX,XX +XXX,XX @@
54
* @irq: irq type
55
* @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
56
*/
57
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
58
+static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq,
59
+ uint32_t gerror_mask)
60
{
61
62
bool pulse = false;
63
@@ -XXX,XX +XXX,XX @@ void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
64
}
23
}
65
}
24
}
66
25
67
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
26
+static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
68
+static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
27
+ const ARMISARegisters *id)
69
{
70
uint32_t pending = s->gerror ^ s->gerrorn;
71
uint32_t toggled = s->gerrorn ^ new_gerrorn;
72
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
73
s->sid_split = 0;
74
}
75
76
-int smmuv3_cmdq_consume(SMMUv3State *s)
77
+static int smmuv3_cmdq_consume(SMMUv3State *s)
78
{
79
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
80
SMMUQueue *q = &s->cmdq;
81
@@ -XXX,XX +XXX,XX @@ int smmuv3_cmdq_consume(SMMUv3State *s)
82
return 0;
83
}
84
85
+static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset,
86
+ uint64_t data, MemTxAttrs attrs)
87
+{
28
+{
88
+ switch (offset) {
29
+ uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J;
89
+ case A_GERROR_IRQ_CFG0:
30
+
90
+ s->gerror_irq_cfg0 = data;
31
+ if ((features >> ARM_FEATURE_V4T) & 1) {
91
+ return MEMTX_OK;
32
+ valid |= CPSR_T;
92
+ case A_STRTAB_BASE:
93
+ s->strtab_base = data;
94
+ return MEMTX_OK;
95
+ case A_CMDQ_BASE:
96
+ s->cmdq.base = data;
97
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
98
+ if (s->cmdq.log2size > SMMU_CMDQS) {
99
+ s->cmdq.log2size = SMMU_CMDQS;
100
+ }
101
+ return MEMTX_OK;
102
+ case A_EVENTQ_BASE:
103
+ s->eventq.base = data;
104
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
105
+ if (s->eventq.log2size > SMMU_EVENTQS) {
106
+ s->eventq.log2size = SMMU_EVENTQS;
107
+ }
108
+ return MEMTX_OK;
109
+ case A_EVENTQ_IRQ_CFG0:
110
+ s->eventq_irq_cfg0 = data;
111
+ return MEMTX_OK;
112
+ default:
113
+ qemu_log_mask(LOG_UNIMP,
114
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (WI)\n",
115
+ __func__, offset);
116
+ return MEMTX_OK;
117
+ }
33
+ }
34
+ if ((features >> ARM_FEATURE_V5) & 1) {
35
+ valid |= CPSR_Q; /* V5TE in reality*/
36
+ }
37
+ if ((features >> ARM_FEATURE_V6) & 1) {
38
+ valid |= CPSR_E | CPSR_GE;
39
+ }
40
+ if ((features >> ARM_FEATURE_THUMB2) & 1) {
41
+ valid |= CPSR_IT;
42
+ }
43
+
44
+ return valid;
118
+}
45
+}
119
+
46
+
120
+static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
47
/*
121
+ uint64_t data, MemTxAttrs attrs)
48
* Parameters of a given virtual address, as extracted from the
122
+{
49
* translation control register (TCR) for a given regime.
123
+ switch (offset) {
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
124
+ case A_CR0:
51
index XXXXXXX..XXXXXXX 100644
125
+ s->cr[0] = data;
52
--- a/target/arm/translate.c
126
+ s->cr0ack = data & ~SMMU_CR0_RESERVED;
53
+++ b/target/arm/translate.c
127
+ /* in case the command queue has been enabled */
54
@@ -XXX,XX +XXX,XX @@ static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
128
+ smmuv3_cmdq_consume(s);
55
/* Return the mask of PSR bits set by a MSR instruction. */
129
+ return MEMTX_OK;
56
static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
130
+ case A_CR1:
57
{
131
+ s->cr[1] = data;
58
- uint32_t mask;
132
+ return MEMTX_OK;
59
+ uint32_t mask = 0;
133
+ case A_CR2:
60
134
+ s->cr[2] = data;
61
- mask = 0;
135
+ return MEMTX_OK;
62
- if (flags & (1 << 0))
136
+ case A_IRQ_CTRL:
63
+ if (flags & (1 << 0)) {
137
+ s->irq_ctrl = data;
64
mask |= 0xff;
138
+ return MEMTX_OK;
65
- if (flags & (1 << 1))
139
+ case A_GERRORN:
140
+ smmuv3_write_gerrorn(s, data);
141
+ /*
142
+ * By acknowledging the CMDQ_ERR, SW may notify cmds can
143
+ * be processed again
144
+ */
145
+ smmuv3_cmdq_consume(s);
146
+ return MEMTX_OK;
147
+ case A_GERROR_IRQ_CFG0: /* 64b */
148
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 0, 32, data);
149
+ return MEMTX_OK;
150
+ case A_GERROR_IRQ_CFG0 + 4:
151
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 32, 32, data);
152
+ return MEMTX_OK;
153
+ case A_GERROR_IRQ_CFG1:
154
+ s->gerror_irq_cfg1 = data;
155
+ return MEMTX_OK;
156
+ case A_GERROR_IRQ_CFG2:
157
+ s->gerror_irq_cfg2 = data;
158
+ return MEMTX_OK;
159
+ case A_STRTAB_BASE: /* 64b */
160
+ s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
161
+ return MEMTX_OK;
162
+ case A_STRTAB_BASE + 4:
163
+ s->strtab_base = deposit64(s->strtab_base, 32, 32, data);
164
+ return MEMTX_OK;
165
+ case A_STRTAB_BASE_CFG:
166
+ s->strtab_base_cfg = data;
167
+ if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) == 1) {
168
+ s->sid_split = FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT);
169
+ s->features |= SMMU_FEATURE_2LVL_STE;
170
+ }
171
+ return MEMTX_OK;
172
+ case A_CMDQ_BASE: /* 64b */
173
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 32, data);
174
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
175
+ if (s->cmdq.log2size > SMMU_CMDQS) {
176
+ s->cmdq.log2size = SMMU_CMDQS;
177
+ }
178
+ return MEMTX_OK;
179
+ case A_CMDQ_BASE + 4: /* 64b */
180
+ s->cmdq.base = deposit64(s->cmdq.base, 32, 32, data);
181
+ return MEMTX_OK;
182
+ case A_CMDQ_PROD:
183
+ s->cmdq.prod = data;
184
+ smmuv3_cmdq_consume(s);
185
+ return MEMTX_OK;
186
+ case A_CMDQ_CONS:
187
+ s->cmdq.cons = data;
188
+ return MEMTX_OK;
189
+ case A_EVENTQ_BASE: /* 64b */
190
+ s->eventq.base = deposit64(s->eventq.base, 0, 32, data);
191
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
192
+ if (s->eventq.log2size > SMMU_EVENTQS) {
193
+ s->eventq.log2size = SMMU_EVENTQS;
194
+ }
195
+ return MEMTX_OK;
196
+ case A_EVENTQ_BASE + 4:
197
+ s->eventq.base = deposit64(s->eventq.base, 32, 32, data);
198
+ return MEMTX_OK;
199
+ case A_EVENTQ_PROD:
200
+ s->eventq.prod = data;
201
+ return MEMTX_OK;
202
+ case A_EVENTQ_CONS:
203
+ s->eventq.cons = data;
204
+ return MEMTX_OK;
205
+ case A_EVENTQ_IRQ_CFG0: /* 64b */
206
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 0, 32, data);
207
+ return MEMTX_OK;
208
+ case A_EVENTQ_IRQ_CFG0 + 4:
209
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 32, 32, data);
210
+ return MEMTX_OK;
211
+ case A_EVENTQ_IRQ_CFG1:
212
+ s->eventq_irq_cfg1 = data;
213
+ return MEMTX_OK;
214
+ case A_EVENTQ_IRQ_CFG2:
215
+ s->eventq_irq_cfg2 = data;
216
+ return MEMTX_OK;
217
+ default:
218
+ qemu_log_mask(LOG_UNIMP,
219
+ "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n",
220
+ __func__, offset);
221
+ return MEMTX_OK;
222
+ }
66
+ }
223
+}
67
+ if (flags & (1 << 1)) {
68
mask |= 0xff00;
69
- if (flags & (1 << 2))
70
+ }
71
+ if (flags & (1 << 2)) {
72
mask |= 0xff0000;
73
- if (flags & (1 << 3))
74
+ }
75
+ if (flags & (1 << 3)) {
76
mask |= 0xff000000;
77
+ }
78
79
- /* Mask out undefined bits. */
80
- mask &= ~CPSR_RESERVED;
81
- if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
82
- mask &= ~CPSR_T;
83
- }
84
- if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
85
- mask &= ~CPSR_Q; /* V5TE in reality*/
86
- }
87
- if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
88
- mask &= ~(CPSR_E | CPSR_GE);
89
- }
90
- if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
91
- mask &= ~CPSR_IT;
92
- }
93
- /* Mask out execution state and reserved bits. */
94
+ /* Mask out undefined and reserved bits. */
95
+ mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
224
+
96
+
225
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
97
+ /* Mask out execution state. */
226
unsigned size, MemTxAttrs attrs)
98
if (!spsr) {
227
{
99
- mask &= ~(CPSR_EXEC | CPSR_RESERVED);
228
- /* not yet implemented */
100
+ mask &= ~CPSR_EXEC;
229
- return MEMTX_ERROR;
101
}
230
+ SMMUState *sys = opaque;
231
+ SMMUv3State *s = ARM_SMMUV3(sys);
232
+ MemTxResult r;
233
+
102
+
234
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
103
/* Mask out privileged bits. */
235
+ offset &= ~0x10000;
104
- if (IS_USER(s))
236
+
105
+ if (IS_USER(s)) {
237
+ switch (size) {
106
mask &= CPSR_USER;
238
+ case 8:
239
+ r = smmu_writell(s, offset, data, attrs);
240
+ break;
241
+ case 4:
242
+ r = smmu_writel(s, offset, data, attrs);
243
+ break;
244
+ default:
245
+ r = MEMTX_ERROR;
246
+ break;
247
+ }
107
+ }
248
+
108
return mask;
249
+ trace_smmuv3_write_mmio(offset, data, size, r);
250
+ return r;
251
}
109
}
252
110
253
static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
254
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
255
index XXXXXXX..XXXXXXX 100644
256
--- a/hw/arm/trace-events
257
+++ b/hw/arm/trace-events
258
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t con
259
smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
260
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
261
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
262
+smmuv3_update(bool is_empty, uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "q empty:%d prod:%d cons:%d p.wrap:%d p.cons:%d"
263
+smmuv3_update_check_cmd(int error) "cmdq not enabled or error :0x%x"
264
+smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
265
+smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
266
+smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
267
+smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
268
--
111
--
269
2.17.0
112
2.20.1
270
113
271
114
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The J bit signals Jazelle mode, and so of course is RES0
4
when the feature is not enabled.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200208125816.14954-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 5 ++++-
12
1 file changed, 4 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
19
static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
20
const ARMISARegisters *id)
21
{
22
- uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J;
23
+ uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV;
24
25
if ((features >> ARM_FEATURE_V4T) & 1) {
26
valid |= CPSR_T;
27
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
28
if ((features >> ARM_FEATURE_THUMB2) & 1) {
29
valid |= CPSR_IT;
30
}
31
+ if (isar_feature_jazelle(id)) {
32
+ valid |= CPSR_J;
33
+ }
34
35
return valid;
36
}
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
CPSR_ERET_MASK was a useless renaming of CPSR_RESERVED.
4
The function also takes into account bits that the cpu
5
does not support.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200208125816.14954-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 2 --
13
target/arm/op_helper.c | 5 ++++-
14
2 files changed, 4 insertions(+), 3 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
21
#define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE)
22
/* Execution state bits. MRS read as zero, MSR writes ignored. */
23
#define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL)
24
-/* Mask of bits which may be set by exception return copying them from SPSR */
25
-#define CPSR_ERET_MASK (~CPSR_RESERVED)
26
27
/* Bit definitions for M profile XPSR. Most are the same as CPSR. */
28
#define XPSR_EXCP 0x1ffU
29
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/op_helper.c
32
+++ b/target/arm/op_helper.c
33
@@ -XXX,XX +XXX,XX @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
34
/* Write the CPSR for a 32-bit exception return */
35
void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
36
{
37
+ uint32_t mask;
38
+
39
qemu_mutex_lock_iothread();
40
arm_call_pre_el_change_hook(env_archcpu(env));
41
qemu_mutex_unlock_iothread();
42
43
- cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
44
+ mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
45
+ cpsr_write(env, val, mask, CPSRWriteExceptionReturn);
46
47
/* Generated code has already stored the new PC value, but
48
* without masking out its low bits, because which bits need
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Using ~0 as the mask on the aarch64->aarch32 exception return
4
was not even as correct as the CPSR_ERET_MASK that we had used
5
on the aarch32->aarch32 exception return.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200208125816.14954-9-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper-a64.c | 5 +++--
13
1 file changed, 3 insertions(+), 2 deletions(-)
14
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.c
18
+++ b/target/arm/helper-a64.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
20
{
21
int cur_el = arm_current_el(env);
22
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
23
- uint32_t spsr = env->banked_spsr[spsr_idx];
24
+ uint32_t mask, spsr = env->banked_spsr[spsr_idx];
25
int new_el;
26
bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
27
28
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
29
* will sort the register banks out for us, and we've already
30
* caught all the bad-mode cases in el_from_spsr().
31
*/
32
- cpsr_write(env, spsr, ~0, CPSRWriteRaw);
33
+ mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
34
+ cpsr_write(env, spsr, mask, CPSRWriteRaw);
35
if (!arm_singlestep_active(env)) {
36
env->uncached_cpsr &= ~PSTATE_SS;
37
}
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The only remaining use was in op_helper.c. Use PSTATE_SS
4
directly, and move the commentary so that it is more obvious
5
what is going on.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200208125816.14954-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 6 ------
13
target/arm/op_helper.c | 9 ++++++++-
14
2 files changed, 8 insertions(+), 7 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
21
#define CPSR_IT_2_7 (0xfc00U)
22
#define CPSR_GE (0xfU << 16)
23
#define CPSR_IL (1U << 20)
24
-/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in
25
- * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use
26
- * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32,
27
- * where it is live state but not accessible to the AArch32 code.
28
- */
29
-#define CPSR_RESERVED (0x7U << 21)
30
#define CPSR_J (1U << 24)
31
#define CPSR_IT_0_1 (3U << 25)
32
#define CPSR_Q (1U << 27)
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
38
39
uint32_t HELPER(cpsr_read)(CPUARMState *env)
40
{
41
- return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED);
42
+ /*
43
+ * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr.
44
+ * This is convenient for populating SPSR_ELx, but must be
45
+ * hidden from aarch32 mode, where it is not visible.
46
+ *
47
+ * TODO: ARMv8.4-DIT -- need to move SS somewhere else.
48
+ */
49
+ return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS);
50
}
51
52
void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Use this along the exception return path, where we previously
4
accepted any values.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200208125816.14954-11-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 12 ++++++++++++
12
target/arm/helper-a64.c | 1 +
13
2 files changed, 13 insertions(+)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
20
return valid;
21
}
22
23
+static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
24
+{
25
+ uint32_t valid;
26
+
27
+ valid = PSTATE_M | PSTATE_DAIF | PSTATE_IL | PSTATE_SS | PSTATE_NZCV;
28
+ if (isar_feature_aa64_bti(id)) {
29
+ valid |= PSTATE_BTYPE;
30
+ }
31
+
32
+ return valid;
33
+}
34
+
35
/*
36
* Parameters of a given virtual address, as extracted from the
37
* translation control register (TCR) for a given regime.
38
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/helper-a64.c
41
+++ b/target/arm/helper-a64.c
42
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
43
cur_el, new_el, env->regs[15]);
44
} else {
45
env->aarch64 = 1;
46
+ spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
47
pstate_write(env, spsr);
48
if (!arm_singlestep_active(env)) {
49
env->pstate &= ~PSTATE_SS;
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The (size > 3 && !is_q) condition is identical to the preceeding test
3
For aarch64, there's a dedicated msr (imm, reg) insn.
4
of bit 3 in immh; eliminate it. For the benefit of Coverity, assert
4
For aarch32, this is done via msr to cpsr. Writes from el0
5
that size is within the bounds we expect.
5
are ignored, which is already handled by the CPSR_USER mask.
6
6
7
Fixes: Coverity CID1385846
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Fixes: Coverity CID1385849
9
Fixes: Coverity CID1385852
10
Fixes: Coverity CID1385857
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20200208125816.14954-12-richard.henderson@linaro.org
13
Message-id: 20180501180455.11214-2-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
target/arm/translate-a64.c | 6 +-----
12
target/arm/cpu.h | 2 ++
17
1 file changed, 1 insertion(+), 5 deletions(-)
13
target/arm/internals.h | 6 ++++++
14
target/arm/helper.c | 21 +++++++++++++++++++++
15
target/arm/translate-a64.c | 14 ++++++++++++++
16
4 files changed, 43 insertions(+)
18
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
23
#define CPSR_IT_2_7 (0xfc00U)
24
#define CPSR_GE (0xfU << 16)
25
#define CPSR_IL (1U << 20)
26
+#define CPSR_PAN (1U << 22)
27
#define CPSR_J (1U << 24)
28
#define CPSR_IT_0_1 (3U << 25)
29
#define CPSR_Q (1U << 27)
30
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
31
#define PSTATE_BTYPE (3U << 10)
32
#define PSTATE_IL (1U << 20)
33
#define PSTATE_SS (1U << 21)
34
+#define PSTATE_PAN (1U << 22)
35
#define PSTATE_V (1U << 28)
36
#define PSTATE_C (1U << 29)
37
#define PSTATE_Z (1U << 30)
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
43
if (isar_feature_jazelle(id)) {
44
valid |= CPSR_J;
45
}
46
+ if (isar_feature_aa32_pan(id)) {
47
+ valid |= CPSR_PAN;
48
+ }
49
50
return valid;
51
}
52
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
53
if (isar_feature_aa64_bti(id)) {
54
valid |= PSTATE_BTYPE;
55
}
56
+ if (isar_feature_aa64_pan(id)) {
57
+ valid |= PSTATE_PAN;
58
+ }
59
60
return valid;
61
}
62
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/helper.c
65
+++ b/target/arm/helper.c
66
@@ -XXX,XX +XXX,XX @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
env->daif = value & PSTATE_DAIF;
68
}
69
70
+static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri)
71
+{
72
+ return env->pstate & PSTATE_PAN;
73
+}
74
+
75
+static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
+ uint64_t value)
77
+{
78
+ env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
79
+}
80
+
81
+static const ARMCPRegInfo pan_reginfo = {
82
+ .name = "PAN", .state = ARM_CP_STATE_AA64,
83
+ .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3,
84
+ .type = ARM_CP_NO_RAW, .access = PL1_RW,
85
+ .readfn = aa64_pan_read, .writefn = aa64_pan_write
86
+};
87
+
88
static CPAccessResult aa64_cacheop_access(CPUARMState *env,
89
const ARMCPRegInfo *ri,
90
bool isread)
91
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
92
if (cpu_isar_feature(aa64_lor, cpu)) {
93
define_arm_cp_regs(cpu, lor_reginfo);
94
}
95
+ if (cpu_isar_feature(aa64_pan, cpu)) {
96
+ define_one_arm_cp_reg(cpu, &pan_reginfo);
97
+ }
98
99
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
100
define_arm_cp_regs(cpu, vhe_reginfo);
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
101
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
index XXXXXXX..XXXXXXX 100644
102
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
103
--- a/target/arm/translate-a64.c
22
+++ b/target/arm/translate-a64.c
104
+++ b/target/arm/translate-a64.c
23
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
105
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
24
unallocated_encoding(s);
106
s->base.is_jmp = DISAS_NEXT;
25
return;
107
break;
26
}
108
27
-
109
+ case 0x04: /* PAN */
28
- if (size > 3 && !is_q) {
110
+ if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
29
- unallocated_encoding(s);
111
+ goto do_unallocated;
30
- return;
112
+ }
31
- }
113
+ if (crm & 1) {
32
+ tcg_debug_assert(size <= 3);
114
+ set_pstate_bits(PSTATE_PAN);
33
115
+ } else {
34
if (!fp_access_check(s)) {
116
+ clear_pstate_bits(PSTATE_PAN);
35
return;
117
+ }
118
+ t1 = tcg_const_i32(s->current_el);
119
+ gen_helper_rebuild_hflags_a64(cpu_env, t1);
120
+ tcg_temp_free_i32(t1);
121
+ break;
122
+
123
case 0x05: /* SPSel */
124
if (s->current_el == 0) {
125
goto do_unallocated;
36
--
126
--
37
2.17.0
127
2.20.1
38
128
39
129
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Examine the PAN bit for EL1, EL2, and Secure EL1 to
4
determine if it applies.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200208125816.14954-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.c | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
20
return ARMMMUIdx_E10_0;
21
case 1:
22
if (arm_is_secure_below_el3(env)) {
23
+ if (env->pstate & PSTATE_PAN) {
24
+ return ARMMMUIdx_SE10_1_PAN;
25
+ }
26
return ARMMMUIdx_SE10_1;
27
}
28
+ if (env->pstate & PSTATE_PAN) {
29
+ return ARMMMUIdx_E10_1_PAN;
30
+ }
31
return ARMMMUIdx_E10_1;
32
case 2:
33
/* TODO: ARMv8.4-SecEL2 */
34
/* Note that TGE does not apply at EL2. */
35
if ((env->cp15.hcr_el2 & HCR_E2H) && arm_el_is_aa64(env, 2)) {
36
+ if (env->pstate & PSTATE_PAN) {
37
+ return ARMMMUIdx_E20_2_PAN;
38
+ }
39
return ARMMMUIdx_E20_2;
40
}
41
return ARMMMUIdx_E2;
42
--
43
2.20.1
44
45
diff view generated by jsdifflib
1
Convert the tusb6010 device away from using the old_mmio field
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of MemoryRegionOps. This device is used only in the n800 and n810
3
boards.
4
2
3
If we have a PAN-enforcing mmu_idx, set prot == 0 if user_rw != 0.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200208125816.14954-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180427173611.10281-2-peter.maydell@linaro.org
8
---
10
---
9
hw/usb/tusb6010.c | 40 ++++++++++++++++++++++++++++++++++++----
11
target/arm/internals.h | 13 +++++++++++++
10
1 file changed, 36 insertions(+), 4 deletions(-)
12
target/arm/helper.c | 3 +++
13
2 files changed, 16 insertions(+)
11
14
12
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/usb/tusb6010.c
17
--- a/target/arm/internals.h
15
+++ b/hw/usb/tusb6010.c
18
+++ b/target/arm/internals.h
16
@@ -XXX,XX +XXX,XX @@ static void tusb_async_writew(void *opaque, hwaddr addr,
19
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
17
}
20
}
18
}
21
}
19
22
20
+static uint64_t tusb_async_readfn(void *opaque, hwaddr addr, unsigned size)
23
+static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
21
+{
24
+{
22
+ switch (size) {
25
+ switch (mmu_idx) {
23
+ case 1:
26
+ case ARMMMUIdx_Stage1_E1_PAN:
24
+ return tusb_async_readb(opaque, addr);
27
+ case ARMMMUIdx_E10_1_PAN:
25
+ case 2:
28
+ case ARMMMUIdx_E20_2_PAN:
26
+ return tusb_async_readh(opaque, addr);
29
+ case ARMMMUIdx_SE10_1_PAN:
27
+ case 4:
30
+ return true;
28
+ return tusb_async_readw(opaque, addr);
29
+ default:
31
+ default:
30
+ g_assert_not_reached();
32
+ return false;
31
+ }
33
+ }
32
+}
34
+}
33
+
35
+
34
+static void tusb_async_writefn(void *opaque, hwaddr addr,
36
/* Return the FSR value for a debug exception (watchpoint, hardware
35
+ uint64_t value, unsigned size)
37
* breakpoint or BKPT insn) targeting the specified exception level.
36
+{
38
*/
37
+ switch (size) {
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
+ case 1:
40
index XXXXXXX..XXXXXXX 100644
39
+ tusb_async_writeb(opaque, addr, value);
41
--- a/target/arm/helper.c
40
+ break;
42
+++ b/target/arm/helper.c
41
+ case 2:
43
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
42
+ tusb_async_writeh(opaque, addr, value);
44
if (is_user) {
43
+ break;
45
prot_rw = user_rw;
44
+ case 4:
46
} else {
45
+ tusb_async_writew(opaque, addr, value);
47
+ if (user_rw && regime_is_pan(env, mmu_idx)) {
46
+ break;
48
+ return 0;
47
+ default:
49
+ }
48
+ g_assert_not_reached();
50
prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
49
+ }
51
}
50
+}
51
+
52
static const MemoryRegionOps tusb_async_ops = {
53
- .old_mmio = {
54
- .read = { tusb_async_readb, tusb_async_readh, tusb_async_readw, },
55
- .write = { tusb_async_writeb, tusb_async_writeh, tusb_async_writew, },
56
- },
57
+ .read = tusb_async_readfn,
58
+ .write = tusb_async_writefn,
59
+ .valid.min_access_size = 1,
60
+ .valid.max_access_size = 4,
61
.endianness = DEVICE_NATIVE_ENDIAN,
62
};
63
52
64
--
53
--
65
2.17.0
54
2.20.1
66
55
67
56
diff view generated by jsdifflib
1
For v8M the instructions VLLDM and VLSTM support lazy saving
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and restoring of the secure floating-point registers. Even
3
if the floating point extension is not implemented, these
4
instructions must act as NOPs in Secure state, so they can
5
be used as part of the secure-to-nonsecure call sequence.
6
2
7
Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
3
The PAN bit is preserved, or set as per SCTLR_ELx.SPAN,
8
Cc: qemu-stable@nongnu.org
4
plus several other conditions listed in the ARM ARM.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200208125816.14954-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180503105730.5958-1-peter.maydell@linaro.org
12
---
10
---
13
target/arm/translate.c | 17 ++++++++++++++++-
11
target/arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++++++++---
14
1 file changed, 16 insertions(+), 1 deletion(-)
12
1 file changed, 50 insertions(+), 3 deletions(-)
15
13
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
16
--- a/target/arm/helper.c
19
+++ b/target/arm/translate.c
17
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
21
/* Coprocessor. */
19
uint32_t mask, uint32_t offset,
22
if (arm_dc_feature(s, ARM_FEATURE_M)) {
20
uint32_t newpc)
23
/* We don't currently implement M profile FP support,
21
{
24
- * so this entire space should give a NOCP fault.
22
+ int new_el;
25
+ * so this entire space should give a NOCP fault, with
23
+
26
+ * the exception of the v8M VLLDM and VLSTM insns, which
24
/* Change the CPU state so as to actually take the exception. */
27
+ * must be NOPs in Secure state and UNDEF in Nonsecure state.
25
switch_mode(env, new_mode);
28
*/
26
+ new_el = arm_current_el(env);
29
+ if (arm_dc_feature(s, ARM_FEATURE_V8) &&
27
+
30
+ (insn & 0xffa00f00) == 0xec200a00) {
28
/*
31
+ /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
29
* For exceptions taken to AArch32 we must clear the SS bit in both
32
+ * - VLLDM, VLSTM
30
* PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now.
33
+ * We choose to UNDEF if the RAZ bits are non-zero.
31
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
34
+ */
32
env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
35
+ if (!s->v8m_secure || (insn & 0x0040f0ff)) {
33
/* Set new mode endianness */
36
+ goto illegal_op;
34
env->uncached_cpsr &= ~CPSR_E;
35
- if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
36
+ if (env->cp15.sctlr_el[new_el] & SCTLR_EE) {
37
env->uncached_cpsr |= CPSR_E;
38
}
39
/* J and IL must always be cleared for exception entry */
40
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
41
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
42
env->elr_el[2] = env->regs[15];
43
} else {
44
+ /* CPSR.PAN is normally preserved preserved unless... */
45
+ if (cpu_isar_feature(aa64_pan, env_archcpu(env))) {
46
+ switch (new_el) {
47
+ case 3:
48
+ if (!arm_is_secure_below_el3(env)) {
49
+ /* ... the target is EL3, from non-secure state. */
50
+ env->uncached_cpsr &= ~CPSR_PAN;
51
+ break;
37
+ }
52
+ }
38
+ /* Just NOP since FP support is not implemented */
53
+ /* ... the target is EL3, from secure state ... */
54
+ /* fall through */
55
+ case 1:
56
+ /* ... the target is EL1 and SCTLR.SPAN is 0. */
57
+ if (!(env->cp15.sctlr_el[new_el] & SCTLR_SPAN)) {
58
+ env->uncached_cpsr |= CPSR_PAN;
59
+ }
39
+ break;
60
+ break;
40
+ }
61
+ }
41
+ /* All other insns: NOCP */
62
+ }
42
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
63
/*
43
default_exception_el(s));
64
* this is a lie, as there was no c1_sys on V4T/V5, but who cares
44
break;
65
* and we should just guard the thumb mode on V4
66
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
67
unsigned int new_el = env->exception.target_el;
68
target_ulong addr = env->cp15.vbar_el[new_el];
69
unsigned int new_mode = aarch64_pstate_mode(new_el, true);
70
+ unsigned int old_mode;
71
unsigned int cur_el = arm_current_el(env);
72
73
/*
74
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
75
}
76
77
if (is_a64(env)) {
78
- env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env);
79
+ old_mode = pstate_read(env);
80
aarch64_save_sp(env, arm_current_el(env));
81
env->elr_el[new_el] = env->pc;
82
} else {
83
- env->banked_spsr[aarch64_banked_spsr_index(new_el)] = cpsr_read(env);
84
+ old_mode = cpsr_read(env);
85
env->elr_el[new_el] = env->regs[15];
86
87
aarch64_sync_32_to_64(env);
88
89
env->condexec_bits = 0;
90
}
91
+ env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode;
92
+
93
qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
94
env->elr_el[new_el]);
95
96
+ if (cpu_isar_feature(aa64_pan, cpu)) {
97
+ /* The value of PSTATE.PAN is normally preserved, except when ... */
98
+ new_mode |= old_mode & PSTATE_PAN;
99
+ switch (new_el) {
100
+ case 2:
101
+ /* ... the target is EL2 with HCR_EL2.{E2H,TGE} == '11' ... */
102
+ if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE))
103
+ != (HCR_E2H | HCR_TGE)) {
104
+ break;
105
+ }
106
+ /* fall through */
107
+ case 1:
108
+ /* ... the target is EL1 ... */
109
+ /* ... and SCTLR_ELx.SPAN == 0, then set to 1. */
110
+ if ((env->cp15.sctlr_el[new_el] & SCTLR_SPAN) == 0) {
111
+ new_mode |= PSTATE_PAN;
112
+ }
113
+ break;
114
+ }
115
+ }
116
+
117
pstate_write(env, PSTATE_DAIF | new_mode);
118
env->aarch64 = 1;
119
aarch64_restore_sp(env, new_el);
45
--
120
--
46
2.17.0
121
2.20.1
47
122
48
123
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This is a minor enhancement over ARMv8.1-PAN.
4
The *_PAN mmu_idx are used with the existing do_ats_write.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200208125816.14954-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++-----
12
1 file changed, 50 insertions(+), 6 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
20
switch (ri->opc2 & 6) {
21
case 0:
22
- /* stage 1 current state PL1: ATS1CPR, ATS1CPW */
23
+ /* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */
24
switch (el) {
25
case 3:
26
mmu_idx = ARMMMUIdx_SE3;
27
break;
28
case 2:
29
- mmu_idx = ARMMMUIdx_Stage1_E1;
30
- break;
31
+ g_assert(!secure); /* TODO: ARMv8.4-SecEL2 */
32
+ /* fall through */
33
case 1:
34
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
35
+ if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
36
+ mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN
37
+ : ARMMMUIdx_Stage1_E1_PAN);
38
+ } else {
39
+ mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
40
+ }
41
break;
42
default:
43
g_assert_not_reached();
44
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
45
switch (ri->opc2 & 6) {
46
case 0:
47
switch (ri->opc1) {
48
- case 0: /* AT S1E1R, AT S1E1W */
49
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
50
+ case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
51
+ if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
52
+ mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN
53
+ : ARMMMUIdx_Stage1_E1_PAN);
54
+ } else {
55
+ mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1;
56
+ }
57
break;
58
case 4: /* AT S1E2R, AT S1E2W */
59
mmu_idx = ARMMMUIdx_E2;
60
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
61
REGINFO_SENTINEL
62
};
63
64
+#ifndef CONFIG_USER_ONLY
65
+static const ARMCPRegInfo ats1e1_reginfo[] = {
66
+ { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
67
+ .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
68
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
69
+ .writefn = ats_write64 },
70
+ { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
71
+ .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
72
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
73
+ .writefn = ats_write64 },
74
+ REGINFO_SENTINEL
75
+};
76
+
77
+static const ARMCPRegInfo ats1cp_reginfo[] = {
78
+ { .name = "ATS1CPRP",
79
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
80
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
81
+ .writefn = ats_write },
82
+ { .name = "ATS1CPWP",
83
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
84
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
85
+ .writefn = ats_write },
86
+ REGINFO_SENTINEL
87
+};
88
+#endif
89
+
90
void register_cp_regs_for_features(ARMCPU *cpu)
91
{
92
/* Register all the coprocessor registers based on feature bits */
93
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
94
if (cpu_isar_feature(aa64_pan, cpu)) {
95
define_one_arm_cp_reg(cpu, &pan_reginfo);
96
}
97
+#ifndef CONFIG_USER_ONLY
98
+ if (cpu_isar_feature(aa64_ats1e1, cpu)) {
99
+ define_arm_cp_regs(cpu, ats1e1_reginfo);
100
+ }
101
+ if (cpu_isar_feature(aa32_ats1e1, cpu)) {
102
+ define_arm_cp_regs(cpu, ats1cp_reginfo);
103
+ }
104
+#endif
105
106
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
107
define_arm_cp_regs(cpu, vhe_reginfo);
108
--
109
2.20.1
110
111
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This includes enablement of ARMv8.1-PAN.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200208125816.14954-17-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.c | 4 ++++
11
target/arm/cpu64.c | 5 +++++
12
2 files changed, 9 insertions(+)
13
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
19
t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
20
cpu->isar.mvfr2 = t;
21
22
+ t = cpu->id_mmfr3;
23
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
24
+ cpu->id_mmfr3 = t;
25
+
26
t = cpu->id_mmfr4;
27
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
28
cpu->id_mmfr4 = t;
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu64.c
32
+++ b/target/arm/cpu64.c
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
34
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
35
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
36
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
37
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
38
cpu->isar.id_aa64mmfr1 = t;
39
40
/* Replicate the same data to the 32-bit id registers. */
41
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
42
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
43
cpu->isar.id_isar6 = u;
44
45
+ u = cpu->id_mmfr3;
46
+ u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
47
+ cpu->id_mmfr3 = u;
48
+
49
/*
50
* FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
51
* so do not set MVFR1.FPHP. Strictly speaking this is not legal,
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Add definitions for all of the fields, up to ARMv8.5.
4
Convert the existing RESERVED register to a full register.
5
Query KVM for the value of the register for the host.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200208125816.14954-18-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 17 +++++++++++++++++
13
target/arm/helper.c | 4 ++--
14
target/arm/kvm64.c | 2 ++
15
3 files changed, 21 insertions(+), 2 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
22
uint64_t id_aa64pfr1;
23
uint64_t id_aa64mmfr0;
24
uint64_t id_aa64mmfr1;
25
+ uint64_t id_aa64mmfr2;
26
} isar;
27
uint32_t midr;
28
uint32_t revidr;
29
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
30
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
31
FIELD(ID_AA64MMFR1, XNX, 28, 4)
32
33
+FIELD(ID_AA64MMFR2, CNP, 0, 4)
34
+FIELD(ID_AA64MMFR2, UAO, 4, 4)
35
+FIELD(ID_AA64MMFR2, LSM, 8, 4)
36
+FIELD(ID_AA64MMFR2, IESB, 12, 4)
37
+FIELD(ID_AA64MMFR2, VARANGE, 16, 4)
38
+FIELD(ID_AA64MMFR2, CCIDX, 20, 4)
39
+FIELD(ID_AA64MMFR2, NV, 24, 4)
40
+FIELD(ID_AA64MMFR2, ST, 28, 4)
41
+FIELD(ID_AA64MMFR2, AT, 32, 4)
42
+FIELD(ID_AA64MMFR2, IDS, 36, 4)
43
+FIELD(ID_AA64MMFR2, FWB, 40, 4)
44
+FIELD(ID_AA64MMFR2, TTL, 48, 4)
45
+FIELD(ID_AA64MMFR2, BBM, 52, 4)
46
+FIELD(ID_AA64MMFR2, EVT, 56, 4)
47
+FIELD(ID_AA64MMFR2, E0PD, 60, 4)
48
+
49
FIELD(ID_DFR0, COPDBG, 0, 4)
50
FIELD(ID_DFR0, COPSDBG, 4, 4)
51
FIELD(ID_DFR0, MMAPDBG, 8, 4)
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.c
55
+++ b/target/arm/helper.c
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
57
.access = PL1_R, .type = ARM_CP_CONST,
58
.accessfn = access_aa64_tid3,
59
.resetvalue = cpu->isar.id_aa64mmfr1 },
60
- { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
61
+ { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
62
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
63
.access = PL1_R, .type = ARM_CP_CONST,
64
.accessfn = access_aa64_tid3,
65
- .resetvalue = 0 },
66
+ .resetvalue = cpu->isar.id_aa64mmfr2 },
67
{ .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
68
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
69
.access = PL1_R, .type = ARM_CP_CONST,
70
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/kvm64.c
73
+++ b/target/arm/kvm64.c
74
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
75
ARM64_SYS_REG(3, 0, 0, 7, 0));
76
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
77
ARM64_SYS_REG(3, 0, 0, 7, 1));
78
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2,
79
+ ARM64_SYS_REG(3, 0, 0, 7, 2));
80
81
/*
82
* Note that if AArch32 support is not present in the host,
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We introduce helpers to read/write into the command and event
4
circular queues.
5
6
smmuv3_write_eventq and smmuv3_cmq_consume will become static
7
in subsequent patches.
8
9
Invalidation commands are not yet dealt with. We do not cache
10
data that need to be invalidated. This will change with vhost
11
integration.
12
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 1524665762-31355-7-git-send-email-eric.auger@redhat.com
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200208125816.14954-19-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
7
---
19
hw/arm/smmuv3-internal.h | 163 +++++++++++++++++++++++++++++++++++++++
8
target/arm/cpu.h | 6 ++++++
20
hw/arm/smmuv3.c | 136 ++++++++++++++++++++++++++++++++
9
target/arm/internals.h | 3 +++
21
hw/arm/trace-events | 5 ++
10
target/arm/helper.c | 21 +++++++++++++++++++++
22
3 files changed, 304 insertions(+)
11
target/arm/translate-a64.c | 14 ++++++++++++++
12
4 files changed, 44 insertions(+)
23
13
24
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/smmuv3-internal.h
16
--- a/target/arm/cpu.h
27
+++ b/hw/arm/smmuv3-internal.h
17
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
18
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
29
void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
19
#define PSTATE_IL (1U << 20)
30
void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
20
#define PSTATE_SS (1U << 21)
31
21
#define PSTATE_PAN (1U << 22)
32
+/* Queue Handling */
22
+#define PSTATE_UAO (1U << 23)
33
+
23
#define PSTATE_V (1U << 28)
34
+#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
24
#define PSTATE_C (1U << 29)
35
+#define WRAP_MASK(q) (1 << (q)->log2size)
25
#define PSTATE_Z (1U << 30)
36
+#define INDEX_MASK(q) (((1 << (q)->log2size)) - 1)
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
37
+#define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
27
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
38
+
28
}
39
+#define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
29
40
+#define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
30
+static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
41
+
42
+#define Q_CONS_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
43
+#define Q_PROD_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
44
+
45
+#define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
46
+#define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
47
+
48
+static inline bool smmuv3_q_full(SMMUQueue *q)
49
+{
31
+{
50
+ return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
32
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
51
+}
33
+}
52
+
34
+
53
+static inline bool smmuv3_q_empty(SMMUQueue *q)
35
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
36
{
37
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
43
if (isar_feature_aa64_pan(id)) {
44
valid |= PSTATE_PAN;
45
}
46
+ if (isar_feature_aa64_uao(id)) {
47
+ valid |= PSTATE_UAO;
48
+ }
49
50
return valid;
51
}
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.c
55
+++ b/target/arm/helper.c
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pan_reginfo = {
57
.readfn = aa64_pan_read, .writefn = aa64_pan_write
58
};
59
60
+static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri)
54
+{
61
+{
55
+ return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
62
+ return env->pstate & PSTATE_UAO;
56
+}
63
+}
57
+
64
+
58
+static inline void queue_prod_incr(SMMUQueue *q)
65
+static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
+ uint64_t value)
59
+{
67
+{
60
+ q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
68
+ env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO);
61
+}
69
+}
62
+
70
+
63
+static inline void queue_cons_incr(SMMUQueue *q)
71
+static const ARMCPRegInfo uao_reginfo = {
64
+{
72
+ .name = "UAO", .state = ARM_CP_STATE_AA64,
65
+ /*
73
+ .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
66
+ * We have to use deposit for the CONS registers to preserve
74
+ .type = ARM_CP_NO_RAW, .access = PL1_RW,
67
+ * the ERR field in the high bits.
75
+ .readfn = aa64_uao_read, .writefn = aa64_uao_write
68
+ */
69
+ q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
70
+}
71
+
72
+static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
73
+{
74
+ return FIELD_EX32(s->cr[0], CR0, CMDQEN);
75
+}
76
+
77
+static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
78
+{
79
+ return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
80
+}
81
+
82
+static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
83
+{
84
+ s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
85
+}
86
+
87
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
88
+
89
+/* Commands */
90
+
91
+typedef enum SMMUCommandType {
92
+ SMMU_CMD_NONE = 0x00,
93
+ SMMU_CMD_PREFETCH_CONFIG ,
94
+ SMMU_CMD_PREFETCH_ADDR,
95
+ SMMU_CMD_CFGI_STE,
96
+ SMMU_CMD_CFGI_STE_RANGE,
97
+ SMMU_CMD_CFGI_CD,
98
+ SMMU_CMD_CFGI_CD_ALL,
99
+ SMMU_CMD_CFGI_ALL,
100
+ SMMU_CMD_TLBI_NH_ALL = 0x10,
101
+ SMMU_CMD_TLBI_NH_ASID,
102
+ SMMU_CMD_TLBI_NH_VA,
103
+ SMMU_CMD_TLBI_NH_VAA,
104
+ SMMU_CMD_TLBI_EL3_ALL = 0x18,
105
+ SMMU_CMD_TLBI_EL3_VA = 0x1a,
106
+ SMMU_CMD_TLBI_EL2_ALL = 0x20,
107
+ SMMU_CMD_TLBI_EL2_ASID,
108
+ SMMU_CMD_TLBI_EL2_VA,
109
+ SMMU_CMD_TLBI_EL2_VAA,
110
+ SMMU_CMD_TLBI_S12_VMALL = 0x28,
111
+ SMMU_CMD_TLBI_S2_IPA = 0x2a,
112
+ SMMU_CMD_TLBI_NSNH_ALL = 0x30,
113
+ SMMU_CMD_ATC_INV = 0x40,
114
+ SMMU_CMD_PRI_RESP,
115
+ SMMU_CMD_RESUME = 0x44,
116
+ SMMU_CMD_STALL_TERM,
117
+ SMMU_CMD_SYNC,
118
+} SMMUCommandType;
119
+
120
+static const char *cmd_stringify[] = {
121
+ [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
122
+ [SMMU_CMD_PREFETCH_ADDR] = "SMMU_CMD_PREFETCH_ADDR",
123
+ [SMMU_CMD_CFGI_STE] = "SMMU_CMD_CFGI_STE",
124
+ [SMMU_CMD_CFGI_STE_RANGE] = "SMMU_CMD_CFGI_STE_RANGE",
125
+ [SMMU_CMD_CFGI_CD] = "SMMU_CMD_CFGI_CD",
126
+ [SMMU_CMD_CFGI_CD_ALL] = "SMMU_CMD_CFGI_CD_ALL",
127
+ [SMMU_CMD_CFGI_ALL] = "SMMU_CMD_CFGI_ALL",
128
+ [SMMU_CMD_TLBI_NH_ALL] = "SMMU_CMD_TLBI_NH_ALL",
129
+ [SMMU_CMD_TLBI_NH_ASID] = "SMMU_CMD_TLBI_NH_ASID",
130
+ [SMMU_CMD_TLBI_NH_VA] = "SMMU_CMD_TLBI_NH_VA",
131
+ [SMMU_CMD_TLBI_NH_VAA] = "SMMU_CMD_TLBI_NH_VAA",
132
+ [SMMU_CMD_TLBI_EL3_ALL] = "SMMU_CMD_TLBI_EL3_ALL",
133
+ [SMMU_CMD_TLBI_EL3_VA] = "SMMU_CMD_TLBI_EL3_VA",
134
+ [SMMU_CMD_TLBI_EL2_ALL] = "SMMU_CMD_TLBI_EL2_ALL",
135
+ [SMMU_CMD_TLBI_EL2_ASID] = "SMMU_CMD_TLBI_EL2_ASID",
136
+ [SMMU_CMD_TLBI_EL2_VA] = "SMMU_CMD_TLBI_EL2_VA",
137
+ [SMMU_CMD_TLBI_EL2_VAA] = "SMMU_CMD_TLBI_EL2_VAA",
138
+ [SMMU_CMD_TLBI_S12_VMALL] = "SMMU_CMD_TLBI_S12_VMALL",
139
+ [SMMU_CMD_TLBI_S2_IPA] = "SMMU_CMD_TLBI_S2_IPA",
140
+ [SMMU_CMD_TLBI_NSNH_ALL] = "SMMU_CMD_TLBI_NSNH_ALL",
141
+ [SMMU_CMD_ATC_INV] = "SMMU_CMD_ATC_INV",
142
+ [SMMU_CMD_PRI_RESP] = "SMMU_CMD_PRI_RESP",
143
+ [SMMU_CMD_RESUME] = "SMMU_CMD_RESUME",
144
+ [SMMU_CMD_STALL_TERM] = "SMMU_CMD_STALL_TERM",
145
+ [SMMU_CMD_SYNC] = "SMMU_CMD_SYNC",
146
+};
76
+};
147
+
77
+
148
+static inline const char *smmu_cmd_string(SMMUCommandType type)
78
static CPAccessResult aa64_cacheop_access(CPUARMState *env,
149
+{
79
const ARMCPRegInfo *ri,
150
+ if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
80
bool isread)
151
+ return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
152
+ } else {
82
define_arm_cp_regs(cpu, ats1cp_reginfo);
153
+ return "INVALID";
83
}
84
#endif
85
+ if (cpu_isar_feature(aa64_uao, cpu)) {
86
+ define_one_arm_cp_reg(cpu, &uao_reginfo);
154
+ }
87
+ }
155
+}
88
89
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
90
define_arm_cp_regs(cpu, vhe_reginfo);
91
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/translate-a64.c
94
+++ b/target/arm/translate-a64.c
95
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
96
s->base.is_jmp = DISAS_NEXT;
97
break;
98
99
+ case 0x03: /* UAO */
100
+ if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
101
+ goto do_unallocated;
102
+ }
103
+ if (crm & 1) {
104
+ set_pstate_bits(PSTATE_UAO);
105
+ } else {
106
+ clear_pstate_bits(PSTATE_UAO);
107
+ }
108
+ t1 = tcg_const_i32(s->current_el);
109
+ gen_helper_rebuild_hflags_a64(cpu_env, t1);
110
+ tcg_temp_free_i32(t1);
111
+ break;
156
+
112
+
157
+/* CMDQ fields */
113
case 0x04: /* PAN */
158
+
114
if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
159
+typedef enum {
115
goto do_unallocated;
160
+ SMMU_CERROR_NONE = 0,
161
+ SMMU_CERROR_ILL,
162
+ SMMU_CERROR_ABT,
163
+ SMMU_CERROR_ATC_INV_SYNC,
164
+} SMMUCmdError;
165
+
166
+enum { /* Command completion notification */
167
+ CMD_SYNC_SIG_NONE,
168
+ CMD_SYNC_SIG_IRQ,
169
+ CMD_SYNC_SIG_SEV,
170
+};
171
+
172
+#define CMD_TYPE(x) extract32((x)->word[0], 0 , 8)
173
+#define CMD_SSEC(x) extract32((x)->word[0], 10, 1)
174
+#define CMD_SSV(x) extract32((x)->word[0], 11, 1)
175
+#define CMD_RESUME_AC(x) extract32((x)->word[0], 12, 1)
176
+#define CMD_RESUME_AB(x) extract32((x)->word[0], 13, 1)
177
+#define CMD_SYNC_CS(x) extract32((x)->word[0], 12, 2)
178
+#define CMD_SSID(x) extract32((x)->word[0], 12, 20)
179
+#define CMD_SID(x) ((x)->word[1])
180
+#define CMD_VMID(x) extract32((x)->word[1], 0 , 16)
181
+#define CMD_ASID(x) extract32((x)->word[1], 16, 16)
182
+#define CMD_RESUME_STAG(x) extract32((x)->word[2], 0 , 16)
183
+#define CMD_RESP(x) extract32((x)->word[2], 11, 2)
184
+#define CMD_LEAF(x) extract32((x)->word[2], 0 , 1)
185
+#define CMD_STE_RANGE(x) extract32((x)->word[2], 0 , 5)
186
+#define CMD_ADDR(x) ({ \
187
+ uint64_t high = (uint64_t)(x)->word[3]; \
188
+ uint64_t low = extract32((x)->word[2], 12, 20); \
189
+ uint64_t addr = high << 32 | (low << 12); \
190
+ addr; \
191
+ })
192
+
193
+int smmuv3_cmdq_consume(SMMUv3State *s);
194
+
195
#endif
196
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/arm/smmuv3.c
199
+++ b/hw/arm/smmuv3.c
200
@@ -XXX,XX +XXX,XX @@ void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
201
trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
202
}
203
204
+static inline MemTxResult queue_read(SMMUQueue *q, void *data)
205
+{
206
+ dma_addr_t addr = Q_CONS_ENTRY(q);
207
+
208
+ return dma_memory_read(&address_space_memory, addr, data, q->entry_size);
209
+}
210
+
211
+static MemTxResult queue_write(SMMUQueue *q, void *data)
212
+{
213
+ dma_addr_t addr = Q_PROD_ENTRY(q);
214
+ MemTxResult ret;
215
+
216
+ ret = dma_memory_write(&address_space_memory, addr, data, q->entry_size);
217
+ if (ret != MEMTX_OK) {
218
+ return ret;
219
+ }
220
+
221
+ queue_prod_incr(q);
222
+ return MEMTX_OK;
223
+}
224
+
225
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
226
+{
227
+ SMMUQueue *q = &s->eventq;
228
+
229
+ if (!smmuv3_eventq_enabled(s)) {
230
+ return;
231
+ }
232
+
233
+ if (smmuv3_q_full(q)) {
234
+ return;
235
+ }
236
+
237
+ queue_write(q, evt);
238
+
239
+ if (smmuv3_q_empty(q)) {
240
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
241
+ }
242
+}
243
+
244
static void smmuv3_init_regs(SMMUv3State *s)
245
{
246
/**
247
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
248
s->sid_split = 0;
249
}
250
251
+int smmuv3_cmdq_consume(SMMUv3State *s)
252
+{
253
+ SMMUCmdError cmd_error = SMMU_CERROR_NONE;
254
+ SMMUQueue *q = &s->cmdq;
255
+ SMMUCommandType type = 0;
256
+
257
+ if (!smmuv3_cmdq_enabled(s)) {
258
+ return 0;
259
+ }
260
+ /*
261
+ * some commands depend on register values, typically CR0. In case those
262
+ * register values change while handling the command, spec says it
263
+ * is UNPREDICTABLE whether the command is interpreted under the new
264
+ * or old value.
265
+ */
266
+
267
+ while (!smmuv3_q_empty(q)) {
268
+ uint32_t pending = s->gerror ^ s->gerrorn;
269
+ Cmd cmd;
270
+
271
+ trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q),
272
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
273
+
274
+ if (FIELD_EX32(pending, GERROR, CMDQ_ERR)) {
275
+ break;
276
+ }
277
+
278
+ if (queue_read(q, &cmd) != MEMTX_OK) {
279
+ cmd_error = SMMU_CERROR_ABT;
280
+ break;
281
+ }
282
+
283
+ type = CMD_TYPE(&cmd);
284
+
285
+ trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
286
+
287
+ switch (type) {
288
+ case SMMU_CMD_SYNC:
289
+ if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
290
+ smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0);
291
+ }
292
+ break;
293
+ case SMMU_CMD_PREFETCH_CONFIG:
294
+ case SMMU_CMD_PREFETCH_ADDR:
295
+ case SMMU_CMD_CFGI_STE:
296
+ case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
297
+ case SMMU_CMD_CFGI_CD:
298
+ case SMMU_CMD_CFGI_CD_ALL:
299
+ case SMMU_CMD_TLBI_NH_ALL:
300
+ case SMMU_CMD_TLBI_NH_ASID:
301
+ case SMMU_CMD_TLBI_NH_VA:
302
+ case SMMU_CMD_TLBI_NH_VAA:
303
+ case SMMU_CMD_TLBI_EL3_ALL:
304
+ case SMMU_CMD_TLBI_EL3_VA:
305
+ case SMMU_CMD_TLBI_EL2_ALL:
306
+ case SMMU_CMD_TLBI_EL2_ASID:
307
+ case SMMU_CMD_TLBI_EL2_VA:
308
+ case SMMU_CMD_TLBI_EL2_VAA:
309
+ case SMMU_CMD_TLBI_S12_VMALL:
310
+ case SMMU_CMD_TLBI_S2_IPA:
311
+ case SMMU_CMD_TLBI_NSNH_ALL:
312
+ case SMMU_CMD_ATC_INV:
313
+ case SMMU_CMD_PRI_RESP:
314
+ case SMMU_CMD_RESUME:
315
+ case SMMU_CMD_STALL_TERM:
316
+ trace_smmuv3_unhandled_cmd(type);
317
+ break;
318
+ default:
319
+ cmd_error = SMMU_CERROR_ILL;
320
+ qemu_log_mask(LOG_GUEST_ERROR,
321
+ "Illegal command type: %d\n", CMD_TYPE(&cmd));
322
+ break;
323
+ }
324
+ if (cmd_error) {
325
+ break;
326
+ }
327
+ /*
328
+ * We only increment the cons index after the completion of
329
+ * the command. We do that because the SYNC returns immediately
330
+ * and does not check the completion of previous commands
331
+ */
332
+ queue_cons_incr(q);
333
+ }
334
+
335
+ if (cmd_error) {
336
+ trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error);
337
+ smmu_write_cmdq_err(s, cmd_error);
338
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK);
339
+ }
340
+
341
+ trace_smmuv3_cmdq_consume_out(Q_PROD(q), Q_CONS(q),
342
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
343
+
344
+ return 0;
345
+}
346
+
347
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
348
unsigned size, MemTxAttrs attrs)
349
{
350
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
351
index XXXXXXX..XXXXXXX 100644
352
--- a/hw/arm/trace-events
353
+++ b/hw/arm/trace-events
354
@@ -XXX,XX +XXX,XX @@ smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
355
smmuv3_trigger_irq(int irq) "irq=%d"
356
smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
357
smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
358
+smmuv3_unhandled_cmd(uint32_t type) "Unhandled command type=%d"
359
+smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod=%d cons=%d prod.wrap=%d cons.wrap=%d"
360
+smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
361
+smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
362
+smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
363
--
116
--
364
2.17.0
117
2.20.1
365
118
366
119
diff view generated by jsdifflib
1
From: Mathew Maidment <mathew1800@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The duplication of id_tlbtr_reginfo was unintentionally added within
3
We need only override the current condition under which
4
3281af8114c6b8ead02f08b58e3c36895c1ea047 which should have been
4
TBFLAG_A64.UNPRIV is set.
5
id_mpuir_reginfo.
6
5
7
The effect was that for OMAP and StrongARM CPUs we would
8
incorrectly UNDEF writes to MPUIR rather than NOPing them.
9
10
Signed-off-by: Mathew Maidment <mathew1800@gmail.com>
11
Message-id: 20180501184933.37609-2-mathew1800@gmail.com
12
[PMM: tweak commit message]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200208125816.14954-20-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/helper.c | 2 +-
11
target/arm/helper.c | 41 +++++++++++++++++++++--------------------
17
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 21 insertions(+), 20 deletions(-)
18
13
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
18
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
24
for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
19
}
25
r->access = PL1_RW;
20
26
}
21
/* Compute the condition for using AccType_UNPRIV for LDTR et al. */
27
- id_tlbtr_reginfo.access = PL1_RW;
22
- /* TODO: ARMv8.2-UAO */
28
+ id_mpuir_reginfo.access = PL1_RW;
23
- switch (mmu_idx) {
29
id_tlbtr_reginfo.access = PL1_RW;
24
- case ARMMMUIdx_E10_1:
25
- case ARMMMUIdx_E10_1_PAN:
26
- case ARMMMUIdx_SE10_1:
27
- case ARMMMUIdx_SE10_1_PAN:
28
- /* TODO: ARMv8.3-NV */
29
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
30
- break;
31
- case ARMMMUIdx_E20_2:
32
- case ARMMMUIdx_E20_2_PAN:
33
- /* TODO: ARMv8.4-SecEL2 */
34
- /*
35
- * Note that E20_2 is gated by HCR_EL2.E2H == 1, but E20_0 is
36
- * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
37
- */
38
- if (env->cp15.hcr_el2 & HCR_TGE) {
39
+ if (!(env->pstate & PSTATE_UAO)) {
40
+ switch (mmu_idx) {
41
+ case ARMMMUIdx_E10_1:
42
+ case ARMMMUIdx_E10_1_PAN:
43
+ case ARMMMUIdx_SE10_1:
44
+ case ARMMMUIdx_SE10_1_PAN:
45
+ /* TODO: ARMv8.3-NV */
46
flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
47
+ break;
48
+ case ARMMMUIdx_E20_2:
49
+ case ARMMMUIdx_E20_2_PAN:
50
+ /* TODO: ARMv8.4-SecEL2 */
51
+ /*
52
+ * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
53
+ * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
54
+ */
55
+ if (env->cp15.hcr_el2 & HCR_TGE) {
56
+ flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
57
+ }
58
+ break;
59
+ default:
60
+ break;
30
}
61
}
31
if (arm_feature(env, ARM_FEATURE_V8)) {
62
- break;
63
- default:
64
- break;
65
}
66
67
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
32
--
68
--
33
2.17.0
69
2.20.1
34
70
35
71
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200208125816.14954-21-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu64.c | 4 ++++
9
1 file changed, 4 insertions(+)
10
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
17
cpu->isar.id_aa64mmfr1 = t;
18
19
+ t = cpu->isar.id_aa64mmfr2;
20
+ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
21
+ cpu->isar.id_aa64mmfr2 = t;
22
+
23
/* Replicate the same data to the 32-bit id registers. */
24
u = cpu->isar.id_isar5;
25
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
We set up the infrastructure to enumerate all the PCI devices
3
Initialize EHCI controllers on AST2400 and AST2500 using the existing
4
attached to the SMMU and create an associated IOMMU memory
4
TYPE_PLATFORM_EHCI. After this change, booting ast2500-evb into Linux
5
region and address space.
5
successfully instantiates a USB interface.
6
6
7
Those info are stored in SMMUDevice objects. The devices are
7
ehci-platform 1e6a3000.usb: EHCI Host Controller
8
grouped according to the PCIBus they belong to. A hash table
8
ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1
9
indexed by the PCIBus pointer is used. Also an array indexed by
9
ehci-platform 1e6a3000.usb: irq 21, io mem 0x1e6a3000
10
the bus number allows to find the list of SMMUDevices.
10
ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00
11
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.05
12
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
13
usb usb1: Product: EHCI Host Controller
11
14
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
16
Reviewed-by: Cédric Le Goater <clg@kaod.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Joel Stanley <joel@jms.id.au>
15
Message-id: 1524665762-31355-3-git-send-email-eric.auger@redhat.com
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20200206183437.3979-1-linux@roeck-us.net
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
21
---
18
include/hw/arm/smmu-common.h | 8 +++++
22
include/hw/arm/aspeed_soc.h | 6 ++++++
19
hw/arm/smmu-common.c | 69 ++++++++++++++++++++++++++++++++++++
23
hw/arm/aspeed_soc.c | 25 +++++++++++++++++++++++++
20
hw/arm/trace-events | 3 ++
24
2 files changed, 31 insertions(+)
21
3 files changed, 80 insertions(+)
22
25
23
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
26
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
24
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/smmu-common.h
28
--- a/include/hw/arm/aspeed_soc.h
26
+++ b/include/hw/arm/smmu-common.h
29
+++ b/include/hw/arm/aspeed_soc.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
@@ -XXX,XX +XXX,XX @@
28
#define ARM_SMMU_GET_CLASS(obj) \
31
#include "target/arm/cpu.h"
29
OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
32
#include "hw/gpio/aspeed_gpio.h"
30
33
#include "hw/sd/aspeed_sdhci.h"
31
+/* Return the SMMUPciBus handle associated to a PCI bus number */
34
+#include "hw/usb/hcd-ehci.h"
32
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num);
35
33
+
36
#define ASPEED_SPIS_NUM 2
34
+/* Return the stream ID of an SMMU device */
37
+#define ASPEED_EHCIS_NUM 2
35
+static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
38
#define ASPEED_WDTS_NUM 4
36
+{
39
#define ASPEED_CPUS_NUM 2
37
+ return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
40
#define ASPEED_MACS_NUM 4
38
+}
41
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
39
#endif /* HW_ARM_SMMU_COMMON */
42
AspeedXDMAState xdma;
40
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
43
AspeedSMCState fmc;
44
AspeedSMCState spi[ASPEED_SPIS_NUM];
45
+ EHCISysBusState ehci[ASPEED_EHCIS_NUM];
46
AspeedSDMCState sdmc;
47
AspeedWDTState wdt[ASPEED_WDTS_NUM];
48
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
49
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCClass {
50
uint32_t silicon_rev;
51
uint64_t sram_size;
52
int spis_num;
53
+ int ehcis_num;
54
int wdts_num;
55
int macs_num;
56
const int *irqmap;
57
@@ -XXX,XX +XXX,XX @@ enum {
58
ASPEED_FMC,
59
ASPEED_SPI1,
60
ASPEED_SPI2,
61
+ ASPEED_EHCI1,
62
+ ASPEED_EHCI2,
63
ASPEED_VIC,
64
ASPEED_SDMC,
65
ASPEED_SCU,
66
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
41
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/smmu-common.c
68
--- a/hw/arm/aspeed_soc.c
43
+++ b/hw/arm/smmu-common.c
69
+++ b/hw/arm/aspeed_soc.c
44
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
45
#include "qemu/error-report.h"
71
[ASPEED_IOMEM] = 0x1E600000,
46
#include "hw/arm/smmu-common.h"
72
[ASPEED_FMC] = 0x1E620000,
47
73
[ASPEED_SPI1] = 0x1E630000,
48
+/**
74
+ [ASPEED_EHCI1] = 0x1E6A1000,
49
+ * The bus number is used for lookup when SID based invalidation occurs.
75
[ASPEED_VIC] = 0x1E6C0000,
50
+ * In that case we lazily populate the SMMUPciBus array from the bus hash
76
[ASPEED_SDMC] = 0x1E6E0000,
51
+ * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus
77
[ASPEED_SCU] = 0x1E6E2000,
52
+ * numbers may not be always initialized yet.
78
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
53
+ */
79
[ASPEED_FMC] = 0x1E620000,
54
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
80
[ASPEED_SPI1] = 0x1E630000,
55
+{
81
[ASPEED_SPI2] = 0x1E631000,
56
+ SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
82
+ [ASPEED_EHCI1] = 0x1E6A1000,
57
+
83
+ [ASPEED_EHCI2] = 0x1E6A3000,
58
+ if (!smmu_pci_bus) {
84
[ASPEED_VIC] = 0x1E6C0000,
59
+ GHashTableIter iter;
85
[ASPEED_SDMC] = 0x1E6E0000,
60
+
86
[ASPEED_SCU] = 0x1E6E2000,
61
+ g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
87
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2400_irqmap[] = {
62
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
88
[ASPEED_UART5] = 10,
63
+ if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
89
[ASPEED_VUART] = 8,
64
+ s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
90
[ASPEED_FMC] = 19,
65
+ return smmu_pci_bus;
91
+ [ASPEED_EHCI1] = 5,
66
+ }
92
+ [ASPEED_EHCI2] = 13,
67
+ }
93
[ASPEED_SDMC] = 0,
68
+ }
94
[ASPEED_SCU] = 21,
69
+ return smmu_pci_bus;
95
[ASPEED_ADC] = 31,
70
+}
96
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
71
+
97
sizeof(s->spi[i]), typename);
72
+static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
98
}
73
+{
99
74
+ SMMUState *s = opaque;
100
+ for (i = 0; i < sc->ehcis_num; i++) {
75
+ SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
101
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
76
+ SMMUDevice *sdev;
102
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
77
+
78
+ if (!sbus) {
79
+ sbus = g_malloc0(sizeof(SMMUPciBus) +
80
+ sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX);
81
+ sbus->bus = bus;
82
+ g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
83
+ }
103
+ }
84
+
104
+
85
+ sdev = sbus->pbdev[devfn];
105
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
86
+ if (!sdev) {
106
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
87
+ char *name = g_strdup_printf("%s-%d-%d",
107
typename);
88
+ s->mrtypename,
108
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
89
+ pci_bus_num(bus), devfn);
109
s->spi[i].ctrl->flash_window_base);
90
+ sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);
110
}
91
+
111
92
+ sdev->smmu = s;
112
+ /* EHCI */
93
+ sdev->bus = bus;
113
+ for (i = 0; i < sc->ehcis_num; i++) {
94
+ sdev->devfn = devfn;
114
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err);
95
+
115
+ if (err) {
96
+ memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
116
+ error_propagate(errp, err);
97
+ s->mrtypename,
117
+ return;
98
+ OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
118
+ }
99
+ address_space_init(&sdev->as,
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
100
+ MEMORY_REGION(&sdev->iommu), name);
120
+ sc->memmap[ASPEED_EHCI1 + i]);
101
+ trace_smmu_add_mr(name);
121
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
102
+ g_free(name);
122
+ aspeed_soc_get_irq(s, ASPEED_EHCI1 + i));
103
+ }
123
+ }
104
+
124
+
105
+ return &sdev->as;
125
/* SDMC - SDRAM Memory Controller */
106
+}
126
object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
107
+
127
if (err) {
108
static void smmu_base_realize(DeviceState *dev, Error **errp)
128
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
109
{
129
sc->silicon_rev = AST2400_A1_SILICON_REV;
110
+ SMMUState *s = ARM_SMMU(dev);
130
sc->sram_size = 0x8000;
111
SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
131
sc->spis_num = 1;
112
Error *local_err = NULL;
132
+ sc->ehcis_num = 1;
113
133
sc->wdts_num = 2;
114
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
134
sc->macs_num = 2;
115
error_propagate(errp, local_err);
135
sc->irqmap = aspeed_soc_ast2400_irqmap;
116
return;
136
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
117
}
137
sc->silicon_rev = AST2500_A1_SILICON_REV;
118
+
138
sc->sram_size = 0x9000;
119
+ s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
139
sc->spis_num = 2;
120
+
140
+ sc->ehcis_num = 2;
121
+ if (s->primary_bus) {
141
sc->wdts_num = 3;
122
+ pci_setup_iommu(s->primary_bus, smmu_find_add_as, s);
142
sc->macs_num = 2;
123
+ } else {
143
sc->irqmap = aspeed_soc_ast2500_irqmap;
124
+ error_setg(errp, "SMMU is not attached to any PCI bus!");
125
+ }
126
}
127
128
static void smmu_base_reset(DeviceState *dev)
129
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/trace-events
132
+++ b/hw/arm/trace-events
133
@@ -XXX,XX +XXX,XX @@
134
135
# hw/arm/virt-acpi-build.c
136
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
137
+
138
+# hw/arm/smmu-common.c
139
+smmu_add_mr(const char *name) "%s"
140
\ No newline at end of file
141
--
144
--
142
2.17.0
145
2.20.1
143
146
144
147
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
From: Guenter Roeck <linux@roeck-us.net>
2
2
3
This patch implements a skeleton for the smmuv3 device.
3
Initialize EHCI controllers on AST2600 using the existing
4
Datatypes and register definitions are introduced. The MMIO
4
TYPE_PLATFORM_EHCI. After this change, booting ast2600-evb
5
region, the interrupts and the queue are initialized.
5
into Linux successfully instantiates a USB interface after
6
the necessary changes are made to its devicetree files.
6
7
7
Only the MMIO read operation is implemented here.
8
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
9
ehci-platform: EHCI generic platform driver
10
ehci-platform 1e6a3000.usb: EHCI Host Controller
11
ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1
12
ehci-platform 1e6a3000.usb: irq 25, io mem 0x1e6a3000
13
ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00
14
usb usb1: Manufacturer: Linux 5.5.0-09825-ga0802f2d0ef5-dirty ehci_hcd
15
usb 1-1: new high-speed USB device number 2 using ehci-platform
8
16
9
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
17
Reviewed-by: Cédric Le Goater <clg@kaod.org>
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
12
Message-id: 1524665762-31355-5-git-send-email-eric.auger@redhat.com
20
Message-id: 20200207174548.9087-1-linux@roeck-us.net
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
22
---
15
hw/arm/Makefile.objs | 2 +-
23
hw/arm/aspeed_ast2600.c | 23 +++++++++++++++++++++++
16
hw/arm/smmuv3-internal.h | 142 +++++++++++++++
24
1 file changed, 23 insertions(+)
17
include/hw/arm/smmuv3.h | 87 ++++++++++
18
hw/arm/smmuv3.c | 366 +++++++++++++++++++++++++++++++++++++++
19
hw/arm/trace-events | 3 +
20
5 files changed, 599 insertions(+), 1 deletion(-)
21
create mode 100644 hw/arm/smmuv3-internal.h
22
create mode 100644 include/hw/arm/smmuv3.h
23
create mode 100644 hw/arm/smmuv3.c
24
25
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
26
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
26
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
28
--- a/hw/arm/aspeed_ast2600.c
28
+++ b/hw/arm/Makefile.objs
29
+++ b/hw/arm/aspeed_ast2600.c
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
30
@@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
30
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
31
[ASPEED_FMC] = 0x1E620000,
31
obj-$(CONFIG_IOTKIT) += iotkit.o
32
[ASPEED_SPI1] = 0x1E630000,
32
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
33
[ASPEED_SPI2] = 0x1E641000,
33
-obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
34
+ [ASPEED_EHCI1] = 0x1E6A1000,
34
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
35
+ [ASPEED_EHCI2] = 0x1E6A3000,
35
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
36
[ASPEED_MII1] = 0x1E650000,
36
new file mode 100644
37
[ASPEED_MII2] = 0x1E650008,
37
index XXXXXXX..XXXXXXX
38
[ASPEED_MII3] = 0x1E650010,
38
--- /dev/null
39
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2600_irqmap[] = {
39
+++ b/hw/arm/smmuv3-internal.h
40
[ASPEED_ADC] = 78,
40
@@ -XXX,XX +XXX,XX @@
41
[ASPEED_XDMA] = 6,
41
+/*
42
[ASPEED_SDHCI] = 43,
42
+ * ARM SMMUv3 support - Internal API
43
+ [ASPEED_EHCI1] = 5,
43
+ *
44
+ [ASPEED_EHCI2] = 9,
44
+ * Copyright (C) 2014-2016 Broadcom Corporation
45
[ASPEED_EMMC] = 15,
45
+ * Copyright (c) 2017 Red Hat, Inc.
46
[ASPEED_GPIO] = 40,
46
+ * Written by Prem Mallappa, Eric Auger
47
[ASPEED_GPIO_1_8V] = 11,
47
+ *
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
48
+ * This program is free software; you can redistribute it and/or modify
49
sizeof(s->spi[i]), typename);
49
+ * it under the terms of the GNU General Public License version 2 as
50
}
50
+ * published by the Free Software Foundation.
51
51
+ *
52
+ for (i = 0; i < sc->ehcis_num; i++) {
52
+ * This program is distributed in the hope that it will be useful,
53
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
53
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
54
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55
+ * GNU General Public License for more details.
56
+ *
57
+ * You should have received a copy of the GNU General Public License along
58
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
59
+ */
60
+
61
+#ifndef HW_ARM_SMMU_V3_INTERNAL_H
62
+#define HW_ARM_SMMU_V3_INTERNAL_H
63
+
64
+#include "hw/arm/smmu-common.h"
65
+
66
+/* MMIO Registers */
67
+
68
+REG32(IDR0, 0x0)
69
+ FIELD(IDR0, S1P, 1 , 1)
70
+ FIELD(IDR0, TTF, 2 , 2)
71
+ FIELD(IDR0, COHACC, 4 , 1)
72
+ FIELD(IDR0, ASID16, 12, 1)
73
+ FIELD(IDR0, TTENDIAN, 21, 2)
74
+ FIELD(IDR0, STALL_MODEL, 24, 2)
75
+ FIELD(IDR0, TERM_MODEL, 26, 1)
76
+ FIELD(IDR0, STLEVEL, 27, 2)
77
+
78
+REG32(IDR1, 0x4)
79
+ FIELD(IDR1, SIDSIZE, 0 , 6)
80
+ FIELD(IDR1, EVENTQS, 16, 5)
81
+ FIELD(IDR1, CMDQS, 21, 5)
82
+
83
+#define SMMU_IDR1_SIDSIZE 16
84
+#define SMMU_CMDQS 19
85
+#define SMMU_EVENTQS 19
86
+
87
+REG32(IDR2, 0x8)
88
+REG32(IDR3, 0xc)
89
+REG32(IDR4, 0x10)
90
+REG32(IDR5, 0x14)
91
+ FIELD(IDR5, OAS, 0, 3);
92
+ FIELD(IDR5, GRAN4K, 4, 1);
93
+ FIELD(IDR5, GRAN16K, 5, 1);
94
+ FIELD(IDR5, GRAN64K, 6, 1);
95
+
96
+#define SMMU_IDR5_OAS 4
97
+
98
+REG32(IIDR, 0x1c)
99
+REG32(CR0, 0x20)
100
+ FIELD(CR0, SMMU_ENABLE, 0, 1)
101
+ FIELD(CR0, EVENTQEN, 2, 1)
102
+ FIELD(CR0, CMDQEN, 3, 1)
103
+
104
+REG32(CR0ACK, 0x24)
105
+REG32(CR1, 0x28)
106
+REG32(CR2, 0x2c)
107
+REG32(STATUSR, 0x40)
108
+REG32(IRQ_CTRL, 0x50)
109
+ FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
110
+ FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
111
+ FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1)
112
+
113
+REG32(IRQ_CTRL_ACK, 0x54)
114
+REG32(GERROR, 0x60)
115
+ FIELD(GERROR, CMDQ_ERR, 0, 1)
116
+ FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
117
+ FIELD(GERROR, PRIQ_ABT_ERR, 3, 1)
118
+ FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1)
119
+ FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
120
+ FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1)
121
+ FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
122
+ FIELD(GERROR, MSI_SFM_ERR, 8, 1)
123
+
124
+REG32(GERRORN, 0x64)
125
+
126
+#define A_GERROR_IRQ_CFG0 0x68 /* 64b */
127
+REG32(GERROR_IRQ_CFG1, 0x70)
128
+REG32(GERROR_IRQ_CFG2, 0x74)
129
+
130
+#define A_STRTAB_BASE 0x80 /* 64b */
131
+
132
+#define SMMU_BASE_ADDR_MASK 0xffffffffffe0
133
+
134
+REG32(STRTAB_BASE_CFG, 0x88)
135
+ FIELD(STRTAB_BASE_CFG, FMT, 16, 2)
136
+ FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5)
137
+ FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
138
+
139
+#define A_CMDQ_BASE 0x90 /* 64b */
140
+REG32(CMDQ_PROD, 0x98)
141
+REG32(CMDQ_CONS, 0x9c)
142
+ FIELD(CMDQ_CONS, ERR, 24, 7)
143
+
144
+#define A_EVENTQ_BASE 0xa0 /* 64b */
145
+REG32(EVENTQ_PROD, 0xa8)
146
+REG32(EVENTQ_CONS, 0xac)
147
+
148
+#define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */
149
+REG32(EVENTQ_IRQ_CFG1, 0xb8)
150
+REG32(EVENTQ_IRQ_CFG2, 0xbc)
151
+
152
+#define A_IDREGS 0xfd0
153
+
154
+static inline int smmu_enabled(SMMUv3State *s)
155
+{
156
+ return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
157
+}
158
+
159
+/* Command Queue Entry */
160
+typedef struct Cmd {
161
+ uint32_t word[4];
162
+} Cmd;
163
+
164
+/* Event Queue Entry */
165
+typedef struct Evt {
166
+ uint32_t word[8];
167
+} Evt;
168
+
169
+static inline uint32_t smmuv3_idreg(int regoffset)
170
+{
171
+ /*
172
+ * Return the value of the Primecell/Corelink ID registers at the
173
+ * specified offset from the first ID register.
174
+ * These value indicate an ARM implementation of MMU600 p1
175
+ */
176
+ static const uint8_t smmuv3_ids[] = {
177
+ 0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
178
+ };
179
+ return smmuv3_ids[regoffset / 4];
180
+}
181
+
182
+#endif
183
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
184
new file mode 100644
185
index XXXXXXX..XXXXXXX
186
--- /dev/null
187
+++ b/include/hw/arm/smmuv3.h
188
@@ -XXX,XX +XXX,XX @@
189
+/*
190
+ * Copyright (C) 2014-2016 Broadcom Corporation
191
+ * Copyright (c) 2017 Red Hat, Inc.
192
+ * Written by Prem Mallappa, Eric Auger
193
+ *
194
+ * This program is free software; you can redistribute it and/or modify
195
+ * it under the terms of the GNU General Public License version 2 as
196
+ * published by the Free Software Foundation.
197
+ *
198
+ * This program is distributed in the hope that it will be useful,
199
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
200
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201
+ * GNU General Public License for more details.
202
+ *
203
+ * You should have received a copy of the GNU General Public License along
204
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
205
+ */
206
+
207
+#ifndef HW_ARM_SMMUV3_H
208
+#define HW_ARM_SMMUV3_H
209
+
210
+#include "hw/arm/smmu-common.h"
211
+#include "hw/registerfields.h"
212
+
213
+#define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
214
+
215
+typedef struct SMMUQueue {
216
+ uint64_t base; /* base register */
217
+ uint32_t prod;
218
+ uint32_t cons;
219
+ uint8_t entry_size;
220
+ uint8_t log2size;
221
+} SMMUQueue;
222
+
223
+typedef struct SMMUv3State {
224
+ SMMUState smmu_state;
225
+
226
+ uint32_t features;
227
+ uint8_t sid_size;
228
+ uint8_t sid_split;
229
+
230
+ uint32_t idr[6];
231
+ uint32_t iidr;
232
+ uint32_t cr[3];
233
+ uint32_t cr0ack;
234
+ uint32_t statusr;
235
+ uint32_t irq_ctrl;
236
+ uint32_t gerror;
237
+ uint32_t gerrorn;
238
+ uint64_t gerror_irq_cfg0;
239
+ uint32_t gerror_irq_cfg1;
240
+ uint32_t gerror_irq_cfg2;
241
+ uint64_t strtab_base;
242
+ uint32_t strtab_base_cfg;
243
+ uint64_t eventq_irq_cfg0;
244
+ uint32_t eventq_irq_cfg1;
245
+ uint32_t eventq_irq_cfg2;
246
+
247
+ SMMUQueue eventq, cmdq;
248
+
249
+ qemu_irq irq[4];
250
+} SMMUv3State;
251
+
252
+typedef enum {
253
+ SMMU_IRQ_EVTQ,
254
+ SMMU_IRQ_PRIQ,
255
+ SMMU_IRQ_CMD_SYNC,
256
+ SMMU_IRQ_GERROR,
257
+} SMMUIrq;
258
+
259
+typedef struct {
260
+ /*< private >*/
261
+ SMMUBaseClass smmu_base_class;
262
+ /*< public >*/
263
+
264
+ DeviceRealize parent_realize;
265
+ DeviceReset parent_reset;
266
+} SMMUv3Class;
267
+
268
+#define TYPE_ARM_SMMUV3 "arm-smmuv3"
269
+#define ARM_SMMUV3(obj) OBJECT_CHECK(SMMUv3State, (obj), TYPE_ARM_SMMUV3)
270
+#define ARM_SMMUV3_CLASS(klass) \
271
+ OBJECT_CLASS_CHECK(SMMUv3Class, (klass), TYPE_ARM_SMMUV3)
272
+#define ARM_SMMUV3_GET_CLASS(obj) \
273
+ OBJECT_GET_CLASS(SMMUv3Class, (obj), TYPE_ARM_SMMUV3)
274
+
275
+#endif
276
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
277
new file mode 100644
278
index XXXXXXX..XXXXXXX
279
--- /dev/null
280
+++ b/hw/arm/smmuv3.c
281
@@ -XXX,XX +XXX,XX @@
282
+/*
283
+ * Copyright (C) 2014-2016 Broadcom Corporation
284
+ * Copyright (c) 2017 Red Hat, Inc.
285
+ * Written by Prem Mallappa, Eric Auger
286
+ *
287
+ * This program is free software; you can redistribute it and/or modify
288
+ * it under the terms of the GNU General Public License version 2 as
289
+ * published by the Free Software Foundation.
290
+ *
291
+ * This program is distributed in the hope that it will be useful,
292
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
293
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
294
+ * GNU General Public License for more details.
295
+ *
296
+ * You should have received a copy of the GNU General Public License along
297
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
298
+ */
299
+
300
+#include "qemu/osdep.h"
301
+#include "hw/boards.h"
302
+#include "sysemu/sysemu.h"
303
+#include "hw/sysbus.h"
304
+#include "hw/qdev-core.h"
305
+#include "hw/pci/pci.h"
306
+#include "exec/address-spaces.h"
307
+#include "trace.h"
308
+#include "qemu/log.h"
309
+#include "qemu/error-report.h"
310
+#include "qapi/error.h"
311
+
312
+#include "hw/arm/smmuv3.h"
313
+#include "smmuv3-internal.h"
314
+
315
+static void smmuv3_init_regs(SMMUv3State *s)
316
+{
317
+ /**
318
+ * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
319
+ * multi-level stream table
320
+ */
321
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
322
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
323
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
324
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
325
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
326
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
327
+ /* terminated transaction will always be aborted/error returned */
328
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1);
329
+ /* 2-level stream table supported */
330
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1);
331
+
332
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE);
333
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS);
334
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS);
335
+
336
+ /* 4K and 64K granule support */
337
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
338
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
339
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
340
+
341
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
342
+ s->cmdq.prod = 0;
343
+ s->cmdq.cons = 0;
344
+ s->cmdq.entry_size = sizeof(struct Cmd);
345
+ s->eventq.base = deposit64(s->eventq.base, 0, 5, SMMU_EVENTQS);
346
+ s->eventq.prod = 0;
347
+ s->eventq.cons = 0;
348
+ s->eventq.entry_size = sizeof(struct Evt);
349
+
350
+ s->features = 0;
351
+ s->sid_split = 0;
352
+}
353
+
354
+static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
355
+ unsigned size, MemTxAttrs attrs)
356
+{
357
+ /* not yet implemented */
358
+ return MEMTX_ERROR;
359
+}
360
+
361
+static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
362
+ uint64_t *data, MemTxAttrs attrs)
363
+{
364
+ switch (offset) {
365
+ case A_GERROR_IRQ_CFG0:
366
+ *data = s->gerror_irq_cfg0;
367
+ return MEMTX_OK;
368
+ case A_STRTAB_BASE:
369
+ *data = s->strtab_base;
370
+ return MEMTX_OK;
371
+ case A_CMDQ_BASE:
372
+ *data = s->cmdq.base;
373
+ return MEMTX_OK;
374
+ case A_EVENTQ_BASE:
375
+ *data = s->eventq.base;
376
+ return MEMTX_OK;
377
+ default:
378
+ *data = 0;
379
+ qemu_log_mask(LOG_UNIMP,
380
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (RAZ)\n",
381
+ __func__, offset);
382
+ return MEMTX_OK;
383
+ }
384
+}
385
+
386
+static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
387
+ uint64_t *data, MemTxAttrs attrs)
388
+{
389
+ switch (offset) {
390
+ case A_IDREGS ... A_IDREGS + 0x1f:
391
+ *data = smmuv3_idreg(offset - A_IDREGS);
392
+ return MEMTX_OK;
393
+ case A_IDR0 ... A_IDR5:
394
+ *data = s->idr[(offset - A_IDR0) / 4];
395
+ return MEMTX_OK;
396
+ case A_IIDR:
397
+ *data = s->iidr;
398
+ return MEMTX_OK;
399
+ case A_CR0:
400
+ *data = s->cr[0];
401
+ return MEMTX_OK;
402
+ case A_CR0ACK:
403
+ *data = s->cr0ack;
404
+ return MEMTX_OK;
405
+ case A_CR1:
406
+ *data = s->cr[1];
407
+ return MEMTX_OK;
408
+ case A_CR2:
409
+ *data = s->cr[2];
410
+ return MEMTX_OK;
411
+ case A_STATUSR:
412
+ *data = s->statusr;
413
+ return MEMTX_OK;
414
+ case A_IRQ_CTRL:
415
+ case A_IRQ_CTRL_ACK:
416
+ *data = s->irq_ctrl;
417
+ return MEMTX_OK;
418
+ case A_GERROR:
419
+ *data = s->gerror;
420
+ return MEMTX_OK;
421
+ case A_GERRORN:
422
+ *data = s->gerrorn;
423
+ return MEMTX_OK;
424
+ case A_GERROR_IRQ_CFG0: /* 64b */
425
+ *data = extract64(s->gerror_irq_cfg0, 0, 32);
426
+ return MEMTX_OK;
427
+ case A_GERROR_IRQ_CFG0 + 4:
428
+ *data = extract64(s->gerror_irq_cfg0, 32, 32);
429
+ return MEMTX_OK;
430
+ case A_GERROR_IRQ_CFG1:
431
+ *data = s->gerror_irq_cfg1;
432
+ return MEMTX_OK;
433
+ case A_GERROR_IRQ_CFG2:
434
+ *data = s->gerror_irq_cfg2;
435
+ return MEMTX_OK;
436
+ case A_STRTAB_BASE: /* 64b */
437
+ *data = extract64(s->strtab_base, 0, 32);
438
+ return MEMTX_OK;
439
+ case A_STRTAB_BASE + 4: /* 64b */
440
+ *data = extract64(s->strtab_base, 32, 32);
441
+ return MEMTX_OK;
442
+ case A_STRTAB_BASE_CFG:
443
+ *data = s->strtab_base_cfg;
444
+ return MEMTX_OK;
445
+ case A_CMDQ_BASE: /* 64b */
446
+ *data = extract64(s->cmdq.base, 0, 32);
447
+ return MEMTX_OK;
448
+ case A_CMDQ_BASE + 4:
449
+ *data = extract64(s->cmdq.base, 32, 32);
450
+ return MEMTX_OK;
451
+ case A_CMDQ_PROD:
452
+ *data = s->cmdq.prod;
453
+ return MEMTX_OK;
454
+ case A_CMDQ_CONS:
455
+ *data = s->cmdq.cons;
456
+ return MEMTX_OK;
457
+ case A_EVENTQ_BASE: /* 64b */
458
+ *data = extract64(s->eventq.base, 0, 32);
459
+ return MEMTX_OK;
460
+ case A_EVENTQ_BASE + 4: /* 64b */
461
+ *data = extract64(s->eventq.base, 32, 32);
462
+ return MEMTX_OK;
463
+ case A_EVENTQ_PROD:
464
+ *data = s->eventq.prod;
465
+ return MEMTX_OK;
466
+ case A_EVENTQ_CONS:
467
+ *data = s->eventq.cons;
468
+ return MEMTX_OK;
469
+ default:
470
+ *data = 0;
471
+ qemu_log_mask(LOG_UNIMP,
472
+ "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n",
473
+ __func__, offset);
474
+ return MEMTX_OK;
475
+ }
476
+}
477
+
478
+static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data,
479
+ unsigned size, MemTxAttrs attrs)
480
+{
481
+ SMMUState *sys = opaque;
482
+ SMMUv3State *s = ARM_SMMUV3(sys);
483
+ MemTxResult r;
484
+
485
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
486
+ offset &= ~0x10000;
487
+
488
+ switch (size) {
489
+ case 8:
490
+ r = smmu_readll(s, offset, data, attrs);
491
+ break;
492
+ case 4:
493
+ r = smmu_readl(s, offset, data, attrs);
494
+ break;
495
+ default:
496
+ r = MEMTX_ERROR;
497
+ break;
498
+ }
55
+ }
499
+
56
+
500
+ trace_smmuv3_read_mmio(offset, *data, size, r);
57
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
501
+ return r;
58
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
502
+}
59
typename);
503
+
60
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
504
+static const MemoryRegionOps smmu_mem_ops = {
61
s->spi[i].ctrl->flash_window_base);
505
+ .read_with_attrs = smmu_read_mmio,
62
}
506
+ .write_with_attrs = smmu_write_mmio,
63
507
+ .endianness = DEVICE_LITTLE_ENDIAN,
64
+ /* EHCI */
508
+ .valid = {
65
+ for (i = 0; i < sc->ehcis_num; i++) {
509
+ .min_access_size = 4,
66
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err);
510
+ .max_access_size = 8,
67
+ if (err) {
511
+ },
68
+ error_propagate(errp, err);
512
+ .impl = {
69
+ return;
513
+ .min_access_size = 4,
70
+ }
514
+ .max_access_size = 8,
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
515
+ },
72
+ sc->memmap[ASPEED_EHCI1 + i]);
516
+};
73
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
517
+
74
+ aspeed_soc_get_irq(s, ASPEED_EHCI1 + i));
518
+static void smmu_init_irq(SMMUv3State *s, SysBusDevice *dev)
519
+{
520
+ int i;
521
+
522
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
523
+ sysbus_init_irq(dev, &s->irq[i]);
524
+ }
525
+}
526
+
527
+static void smmu_reset(DeviceState *dev)
528
+{
529
+ SMMUv3State *s = ARM_SMMUV3(dev);
530
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
531
+
532
+ c->parent_reset(dev);
533
+
534
+ smmuv3_init_regs(s);
535
+}
536
+
537
+static void smmu_realize(DeviceState *d, Error **errp)
538
+{
539
+ SMMUState *sys = ARM_SMMU(d);
540
+ SMMUv3State *s = ARM_SMMUV3(sys);
541
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
542
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
543
+ Error *local_err = NULL;
544
+
545
+ c->parent_realize(d, &local_err);
546
+ if (local_err) {
547
+ error_propagate(errp, local_err);
548
+ return;
549
+ }
75
+ }
550
+
76
+
551
+ memory_region_init_io(&sys->iomem, OBJECT(s),
77
/* SDMC - SDRAM Memory Controller */
552
+ &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
78
object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
553
+
79
if (err) {
554
+ sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION;
80
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
555
+
81
sc->silicon_rev = AST2600_A0_SILICON_REV;
556
+ sysbus_init_mmio(dev, &sys->iomem);
82
sc->sram_size = 0x10000;
557
+
83
sc->spis_num = 2;
558
+ smmu_init_irq(s, dev);
84
+ sc->ehcis_num = 2;
559
+}
85
sc->wdts_num = 4;
560
+
86
sc->macs_num = 4;
561
+static const VMStateDescription vmstate_smmuv3_queue = {
87
sc->irqmap = aspeed_soc_ast2600_irqmap;
562
+ .name = "smmuv3_queue",
563
+ .version_id = 1,
564
+ .minimum_version_id = 1,
565
+ .fields = (VMStateField[]) {
566
+ VMSTATE_UINT64(base, SMMUQueue),
567
+ VMSTATE_UINT32(prod, SMMUQueue),
568
+ VMSTATE_UINT32(cons, SMMUQueue),
569
+ VMSTATE_UINT8(log2size, SMMUQueue),
570
+ },
571
+};
572
+
573
+static const VMStateDescription vmstate_smmuv3 = {
574
+ .name = "smmuv3",
575
+ .version_id = 1,
576
+ .minimum_version_id = 1,
577
+ .fields = (VMStateField[]) {
578
+ VMSTATE_UINT32(features, SMMUv3State),
579
+ VMSTATE_UINT8(sid_size, SMMUv3State),
580
+ VMSTATE_UINT8(sid_split, SMMUv3State),
581
+
582
+ VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3),
583
+ VMSTATE_UINT32(cr0ack, SMMUv3State),
584
+ VMSTATE_UINT32(statusr, SMMUv3State),
585
+ VMSTATE_UINT32(irq_ctrl, SMMUv3State),
586
+ VMSTATE_UINT32(gerror, SMMUv3State),
587
+ VMSTATE_UINT32(gerrorn, SMMUv3State),
588
+ VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3State),
589
+ VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3State),
590
+ VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3State),
591
+ VMSTATE_UINT64(strtab_base, SMMUv3State),
592
+ VMSTATE_UINT32(strtab_base_cfg, SMMUv3State),
593
+ VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3State),
594
+ VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3State),
595
+ VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3State),
596
+
597
+ VMSTATE_STRUCT(cmdq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
598
+ VMSTATE_STRUCT(eventq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
599
+
600
+ VMSTATE_END_OF_LIST(),
601
+ },
602
+};
603
+
604
+static void smmuv3_instance_init(Object *obj)
605
+{
606
+ /* Nothing much to do here as of now */
607
+}
608
+
609
+static void smmuv3_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+ SMMUv3Class *c = ARM_SMMUV3_CLASS(klass);
613
+
614
+ dc->vmsd = &vmstate_smmuv3;
615
+ device_class_set_parent_reset(dc, smmu_reset, &c->parent_reset);
616
+ c->parent_realize = dc->realize;
617
+ dc->realize = smmu_realize;
618
+}
619
+
620
+static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
621
+ void *data)
622
+{
623
+}
624
+
625
+static const TypeInfo smmuv3_type_info = {
626
+ .name = TYPE_ARM_SMMUV3,
627
+ .parent = TYPE_ARM_SMMU,
628
+ .instance_size = sizeof(SMMUv3State),
629
+ .instance_init = smmuv3_instance_init,
630
+ .class_size = sizeof(SMMUv3Class),
631
+ .class_init = smmuv3_class_init,
632
+};
633
+
634
+static const TypeInfo smmuv3_iommu_memory_region_info = {
635
+ .parent = TYPE_IOMMU_MEMORY_REGION,
636
+ .name = TYPE_SMMUV3_IOMMU_MEMORY_REGION,
637
+ .class_init = smmuv3_iommu_memory_region_class_init,
638
+};
639
+
640
+static void smmuv3_register_types(void)
641
+{
642
+ type_register(&smmuv3_type_info);
643
+ type_register(&smmuv3_iommu_memory_region_info);
644
+}
645
+
646
+type_init(smmuv3_register_types)
647
+
648
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
649
index XXXXXXX..XXXXXXX 100644
650
--- a/hw/arm/trace-events
651
+++ b/hw/arm/trace-events
652
@@ -XXX,XX +XXX,XX @@ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr,
653
smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
654
smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
655
smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
656
+
657
+#hw/arm/smmuv3.c
658
+smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
659
--
88
--
660
2.17.0
89
2.20.1
661
90
662
91
diff view generated by jsdifflib
New patch
1
From: Chen Qun <kuhn.chenqun@huawei.com>
1
2
3
It's easy to reproduce as follow:
4
virsh qemu-monitor-command vm1 --pretty '{"execute": "device-list-properties",
5
"arguments":{"typename":"exynos4210.uart"}}'
6
7
ASAN shows memory leak stack:
8
#1 0xfffd896d71cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb)
9
#2 0xaaad270beee3 in timer_new_full /qemu/include/qemu/timer.h:530
10
#3 0xaaad270beee3 in timer_new /qemu/include/qemu/timer.h:551
11
#4 0xaaad270beee3 in timer_new_ns /qemu/include/qemu/timer.h:569
12
#5 0xaaad270beee3 in exynos4210_uart_init /qemu/hw/char/exynos4210_uart.c:677
13
#6 0xaaad275c8f4f in object_initialize_with_type /qemu/qom/object.c:516
14
#7 0xaaad275c91bb in object_new_with_type /qemu/qom/object.c:684
15
#8 0xaaad2755df2f in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:152
16
17
Reported-by: Euler Robot <euler.robot@huawei.com>
18
Signed-off-by: Chen Qun <kuhn.chenqun@huawei.com>
19
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
20
Message-id: 20200213025603.149432-1-kuhn.chenqun@huawei.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/char/exynos4210_uart.c | 5 +++--
24
1 file changed, 3 insertions(+), 2 deletions(-)
25
26
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/char/exynos4210_uart.c
29
+++ b/hw/char/exynos4210_uart.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_init(Object *obj)
31
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
32
Exynos4210UartState *s = EXYNOS4210_UART(dev);
33
34
- s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
35
- exynos4210_uart_timeout_int, s);
36
s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600;
37
38
/* memory mapping */
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
40
{
41
Exynos4210UartState *s = EXYNOS4210_UART(dev);
42
43
+ s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
44
+ exynos4210_uart_timeout_int, s);
45
+
46
qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
47
exynos4210_uart_receive, exynos4210_uart_event,
48
NULL, s, NULL, true);
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
When booting without device tree, the Linux kernels uses the $R1
4
register to determine the machine type. The list of values is
5
registered at [1].
6
7
There are two entries for the Raspberry Pi:
8
9
- https://www.arm.linux.org.uk/developer/machines/list.php?mid=3138
10
name: MACH_TYPE_BCM2708
11
value: 0xc42 (3138)
12
status: Active, not mainlined
13
date: 15 Oct 2010
14
15
- https://www.arm.linux.org.uk/developer/machines/list.php?mid=4828
16
name: MACH_TYPE_BCM2835
17
value: 4828
18
status: Active, mainlined
19
date: 6 Dec 2013
20
21
QEMU always used the non-mainlined type MACH_TYPE_BCM2708.
22
The value 0xc43 is registered to 'MX51_GGC' (processor i.MX51), and
23
0xc44 to 'Western Digital Sharespace NAS' (processor Marvell 88F5182).
24
25
The Raspberry Pi foundation bootloader only sets the BCM2708 machine
26
type, see [2] or [3]:
27
28
133 9:
29
134 mov r0, #0
30
135 ldr r1, =3138 @ BCM2708 machine id
31
136 ldr r2, atags @ ATAGS
32
137 bx r4
33
34
U-Boot only uses MACH_TYPE_BCM2708 (see [4]):
35
36
25 /*
37
26 * 2835 is a SKU in a series for which the 2708 is the first or primary SoC,
38
27 * so 2708 has historically been used rather than a dedicated 2835 ID.
39
28 *
40
29 * We don't define a machine type for bcm2709/bcm2836 since the RPi Foundation
41
30 * chose to use someone else's previously registered machine ID (3139, MX51_GGC)
42
31 * rather than obtaining a valid ID:-/
43
32 *
44
33 * For the bcm2837, hopefully a machine type is not needed, since everything
45
34 * is DT.
46
35 */
47
48
While the definition MACH_BCM2709 with value 0xc43 was introduced in
49
a commit described "Add 2709 platform for Raspberry Pi 2" out of the
50
mainline Linux kernel, it does not seem used, and the platform is
51
introduced with Device Tree support anyway (see [5] and [6]).
52
53
Remove the unused values (0xc43 introduced in commit 1df7d1f9303aef
54
"raspi: add raspberry pi 2 machine" and 0xc44 in commit bade58166f4
55
"raspi: Raspberry Pi 3 support"), keeping only MACH_TYPE_BCM2708.
56
57
[1] https://www.arm.linux.org.uk/developer/machines/
58
[2] https://github.com/raspberrypi/tools/blob/920c7ed2e/armstubs/armstub7.S#L135
59
[3] https://github.com/raspberrypi/tools/blob/49719d554/armstubs/armstub7.S#L64
60
[4] https://gitlab.denx.de/u-boot/u-boot/blob/v2015.04/include/configs/rpi-common.h#L18
61
[5] https://github.com/raspberrypi/linux/commit/d9fac63adac#diff-6722037d79570df5b392a49e0e006573R526
62
[6] http://lists.infradead.org/pipermail/linux-rpi-kernel/2015-February/001268.html
63
64
Cc: Zoltán Baldaszti <bztemail@gmail.com>
65
Cc: Pekka Enberg <penberg@iki.fi>
66
Cc: Stephen Warren <swarren@nvidia.com>
67
Cc: Kshitij Soni <kshitij.soni@broadcom.com>
68
Cc: Michael Chan <michael.chan@broadcom.com>
69
Cc: Andrew Baumann <Andrew.Baumann@microsoft.com>
70
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
71
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
72
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
73
Message-id: 20200208165645.15657-2-f4bug@amsat.org
74
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
75
---
76
hw/arm/raspi.c | 6 +++---
77
1 file changed, 3 insertions(+), 3 deletions(-)
78
79
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/arm/raspi.c
82
+++ b/hw/arm/raspi.c
83
@@ -XXX,XX +XXX,XX @@
84
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
85
#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
86
87
-/* Table of Linux board IDs for different Pi versions */
88
-static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
89
+/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
90
+#define MACH_TYPE_BCM2708 3138
91
92
typedef struct RasPiState {
93
BCM283XState soc;
94
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
95
static struct arm_boot_info binfo;
96
int r;
97
98
- binfo.board_id = raspi_boardid[version];
99
+ binfo.board_id = MACH_TYPE_BCM2708;
100
binfo.ram_size = ram_size;
101
binfo.nb_cpus = machine->smp.cpus;
102
103
--
104
2.20.1
105
106
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
We hardcode the board revision as 0xa21041 for the raspi2, and
4
0xa02082 for the raspi3:
5
6
166 static void raspi_init(MachineState *machine, int version)
7
167 {
8
...
9
194 int board_rev = version == 3 ? 0xa02082 : 0xa21041;
10
11
These revision codes are for the 2B and 3B models, see:
12
https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
13
14
Correct the board description.
15
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20200208165645.15657-3-f4bug@amsat.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/arm/raspi.c | 4 ++--
22
1 file changed, 2 insertions(+), 2 deletions(-)
23
24
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/raspi.c
27
+++ b/hw/arm/raspi.c
28
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
29
30
static void raspi2_machine_init(MachineClass *mc)
31
{
32
- mc->desc = "Raspberry Pi 2";
33
+ mc->desc = "Raspberry Pi 2B";
34
mc->init = raspi2_init;
35
mc->block_default_type = IF_SD;
36
mc->no_parallel = 1;
37
@@ -XXX,XX +XXX,XX @@ static void raspi3_init(MachineState *machine)
38
39
static void raspi3_machine_init(MachineClass *mc)
40
{
41
- mc->desc = "Raspberry Pi 3";
42
+ mc->desc = "Raspberry Pi 3B";
43
mc->init = raspi3_init;
44
mc->block_default_type = IF_SD;
45
mc->no_parallel = 1;
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This patch implements the IOMMU Memory Region translate()
3
The board revision encode the board version. Add a helper
4
callback. Most of the code relates to the translation
4
to extract the version, and use it.
5
configuration decoding and check (STE, CD).
6
5
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
7
Message-id: 20200208165645.15657-4-f4bug@amsat.org
9
Message-id: 1524665762-31355-10-git-send-email-eric.auger@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/arm/smmuv3-internal.h | 160 +++++++++++++++++
11
hw/arm/raspi.c | 31 +++++++++++++++++++++++++++----
14
hw/arm/smmuv3.c | 358 +++++++++++++++++++++++++++++++++++++++
12
1 file changed, 27 insertions(+), 4 deletions(-)
15
hw/arm/trace-events | 9 +
16
3 files changed, 527 insertions(+)
17
13
18
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/smmuv3-internal.h
16
--- a/hw/arm/raspi.c
21
+++ b/hw/arm/smmuv3-internal.h
17
+++ b/hw/arm/raspi.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUEventInfo {
18
@@ -XXX,XX +XXX,XX @@
23
19
#include "qapi/error.h"
24
void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
20
#include "cpu.h"
25
21
#include "hw/arm/bcm2836.h"
26
+/* Configuration Data */
22
+#include "hw/registerfields.h"
23
#include "qemu/error-report.h"
24
#include "hw/boards.h"
25
#include "hw/loader.h"
26
@@ -XXX,XX +XXX,XX @@ typedef struct RasPiState {
27
MemoryRegion ram;
28
} RasPiState;
29
30
+/*
31
+ * Board revision codes:
32
+ * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/
33
+ */
34
+FIELD(REV_CODE, REVISION, 0, 4);
35
+FIELD(REV_CODE, TYPE, 4, 8);
36
+FIELD(REV_CODE, PROCESSOR, 12, 4);
37
+FIELD(REV_CODE, MANUFACTURER, 16, 4);
38
+FIELD(REV_CODE, MEMORY_SIZE, 20, 3);
39
+FIELD(REV_CODE, STYLE, 23, 1);
27
+
40
+
28
+/* STE Level 1 Descriptor */
41
+static int board_processor_id(uint32_t board_rev)
29
+typedef struct STEDesc {
30
+ uint32_t word[2];
31
+} STEDesc;
32
+
33
+/* CD Level 1 Descriptor */
34
+typedef struct CDDesc {
35
+ uint32_t word[2];
36
+} CDDesc;
37
+
38
+/* Stream Table Entry(STE) */
39
+typedef struct STE {
40
+ uint32_t word[16];
41
+} STE;
42
+
43
+/* Context Descriptor(CD) */
44
+typedef struct CD {
45
+ uint32_t word[16];
46
+} CD;
47
+
48
+/* STE fields */
49
+
50
+#define STE_VALID(x) extract32((x)->word[0], 0, 1)
51
+
52
+#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
53
+#define STE_CFG_S1_ENABLED(config) (config & 0x1)
54
+#define STE_CFG_S2_ENABLED(config) (config & 0x2)
55
+#define STE_CFG_ABORT(config) (!(config & 0x4))
56
+#define STE_CFG_BYPASS(config) (config == 0x4)
57
+
58
+#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
59
+#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
60
+#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
61
+#define STE_EATS(x) extract32((x)->word[2], 28, 2)
62
+#define STE_STRW(x) extract32((x)->word[2], 30, 2)
63
+#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
64
+#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
65
+#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
66
+#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
67
+#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
68
+#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
69
+#define STE_S2HD(x) extract32((x)->word[5], 24, 1)
70
+#define STE_S2HA(x) extract32((x)->word[5], 25, 1)
71
+#define STE_S2S(x) extract32((x)->word[5], 26, 1)
72
+#define STE_CTXPTR(x) \
73
+ ({ \
74
+ unsigned long addr; \
75
+ addr = (uint64_t)extract32((x)->word[1], 0, 16) << 32; \
76
+ addr |= (uint64_t)((x)->word[0] & 0xffffffc0); \
77
+ addr; \
78
+ })
79
+
80
+#define STE_S2TTB(x) \
81
+ ({ \
82
+ unsigned long addr; \
83
+ addr = (uint64_t)extract32((x)->word[7], 0, 16) << 32; \
84
+ addr |= (uint64_t)((x)->word[6] & 0xfffffff0); \
85
+ addr; \
86
+ })
87
+
88
+static inline int oas2bits(int oas_field)
89
+{
42
+{
90
+ switch (oas_field) {
43
+ assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
91
+ case 0:
44
+ return FIELD_EX32(board_rev, REV_CODE, PROCESSOR);
92
+ return 32;
93
+ case 1:
94
+ return 36;
95
+ case 2:
96
+ return 40;
97
+ case 3:
98
+ return 42;
99
+ case 4:
100
+ return 44;
101
+ case 5:
102
+ return 48;
103
+ }
104
+ return -1;
105
+}
45
+}
106
+
46
+
107
+static inline int pa_range(STE *ste)
47
+static int board_version(uint32_t board_rev)
108
+{
48
+{
109
+ int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
49
+ return board_processor_id(board_rev) + 1;
110
+
111
+ if (!STE_S2AA64(ste)) {
112
+ return 40;
113
+ }
114
+
115
+ return oas2bits(oas_field);
116
+}
50
+}
117
+
51
+
118
+#define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
52
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
119
+
53
{
120
+/* CD fields */
54
static const uint32_t smpboot[] = {
121
+
55
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
122
+#define CD_VALID(x) extract32((x)->word[0], 30, 1)
56
arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo);
123
+#define CD_ASID(x) extract32((x)->word[1], 16, 16)
124
+#define CD_TTB(x, sel) \
125
+ ({ \
126
+ uint64_t hi, lo; \
127
+ hi = extract32((x)->word[(sel) * 2 + 3], 0, 19); \
128
+ hi <<= 32; \
129
+ lo = (x)->word[(sel) * 2 + 2] & ~0xfULL; \
130
+ hi | lo; \
131
+ })
132
+
133
+#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
134
+#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
135
+#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
136
+#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
137
+#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
138
+#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
139
+#define CD_HD(x) extract32((x)->word[1], 10 , 1)
140
+#define CD_HA(x) extract32((x)->word[1], 11 , 1)
141
+#define CD_S(x) extract32((x)->word[1], 12, 1)
142
+#define CD_R(x) extract32((x)->word[1], 13, 1)
143
+#define CD_A(x) extract32((x)->word[1], 14, 1)
144
+#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
145
+
146
+#define CDM_VALID(x) ((x)->word[0] & 0x1)
147
+
148
+static inline int is_cd_valid(SMMUv3State *s, STE *ste, CD *cd)
149
+{
150
+ return CD_VALID(cd);
151
+}
152
+
153
+/**
154
+ * tg2granule - Decodes the CD translation granule size field according
155
+ * to the ttbr in use
156
+ * @bits: TG0/1 fields
157
+ * @ttbr: ttbr index in use
158
+ */
159
+static inline int tg2granule(int bits, int ttbr)
160
+{
161
+ switch (bits) {
162
+ case 0:
163
+ return ttbr ? 0 : 12;
164
+ case 1:
165
+ return ttbr ? 14 : 16;
166
+ case 2:
167
+ return ttbr ? 12 : 14;
168
+ case 3:
169
+ return ttbr ? 16 : 0;
170
+ default:
171
+ return 0;
172
+ }
173
+}
174
+
175
+static inline uint64_t l1std_l2ptr(STEDesc *desc)
176
+{
177
+ uint64_t hi, lo;
178
+
179
+ hi = desc->word[1];
180
+ lo = desc->word[0] & ~0x1fULL;
181
+ return hi << 32 | lo;
182
+}
183
+
184
+#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 4))
185
+
186
#endif
187
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/arm/smmuv3.c
190
+++ b/hw/arm/smmuv3.c
191
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
192
s->sid_split = 0;
193
}
57
}
194
58
195
+static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
59
-static void raspi_init(MachineState *machine, int version)
196
+ SMMUEventInfo *event)
60
+static void raspi_init(MachineState *machine, uint32_t board_rev)
197
+{
198
+ int ret;
199
+
200
+ trace_smmuv3_get_ste(addr);
201
+ /* TODO: guarantee 64-bit single-copy atomicity */
202
+ ret = dma_memory_read(&address_space_memory, addr,
203
+ (void *)buf, sizeof(*buf));
204
+ if (ret != MEMTX_OK) {
205
+ qemu_log_mask(LOG_GUEST_ERROR,
206
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
207
+ event->type = SMMU_EVT_F_STE_FETCH;
208
+ event->u.f_ste_fetch.addr = addr;
209
+ return -EINVAL;
210
+ }
211
+ return 0;
212
+
213
+}
214
+
215
+/* @ssid > 0 not supported yet */
216
+static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
217
+ CD *buf, SMMUEventInfo *event)
218
+{
219
+ dma_addr_t addr = STE_CTXPTR(ste);
220
+ int ret;
221
+
222
+ trace_smmuv3_get_cd(addr);
223
+ /* TODO: guarantee 64-bit single-copy atomicity */
224
+ ret = dma_memory_read(&address_space_memory, addr,
225
+ (void *)buf, sizeof(*buf));
226
+ if (ret != MEMTX_OK) {
227
+ qemu_log_mask(LOG_GUEST_ERROR,
228
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
229
+ event->type = SMMU_EVT_F_CD_FETCH;
230
+ event->u.f_ste_fetch.addr = addr;
231
+ return -EINVAL;
232
+ }
233
+ return 0;
234
+}
235
+
236
+/* Returns <0 if the caller has no need to continue the translation */
237
+static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
238
+ STE *ste, SMMUEventInfo *event)
239
+{
240
+ uint32_t config;
241
+ int ret = -EINVAL;
242
+
243
+ if (!STE_VALID(ste)) {
244
+ goto bad_ste;
245
+ }
246
+
247
+ config = STE_CONFIG(ste);
248
+
249
+ if (STE_CFG_ABORT(config)) {
250
+ cfg->aborted = true; /* abort but don't record any event */
251
+ return ret;
252
+ }
253
+
254
+ if (STE_CFG_BYPASS(config)) {
255
+ cfg->bypassed = true;
256
+ return ret;
257
+ }
258
+
259
+ if (STE_CFG_S2_ENABLED(config)) {
260
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
261
+ goto bad_ste;
262
+ }
263
+
264
+ if (STE_S1CDMAX(ste) != 0) {
265
+ qemu_log_mask(LOG_UNIMP,
266
+ "SMMUv3 does not support multiple context descriptors yet\n");
267
+ goto bad_ste;
268
+ }
269
+
270
+ if (STE_S1STALLD(ste)) {
271
+ qemu_log_mask(LOG_UNIMP,
272
+ "SMMUv3 S1 stalling fault model not allowed yet\n");
273
+ goto bad_ste;
274
+ }
275
+ return 0;
276
+
277
+bad_ste:
278
+ event->type = SMMU_EVT_C_BAD_STE;
279
+ return -EINVAL;
280
+}
281
+
282
+/**
283
+ * smmu_find_ste - Return the stream table entry associated
284
+ * to the sid
285
+ *
286
+ * @s: smmuv3 handle
287
+ * @sid: stream ID
288
+ * @ste: returned stream table entry
289
+ * @event: handle to an event info
290
+ *
291
+ * Supports linear and 2-level stream table
292
+ * Return 0 on success, -EINVAL otherwise
293
+ */
294
+static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
295
+ SMMUEventInfo *event)
296
+{
297
+ dma_addr_t addr;
298
+ int ret;
299
+
300
+ trace_smmuv3_find_ste(sid, s->features, s->sid_split);
301
+ /* Check SID range */
302
+ if (sid > (1 << SMMU_IDR1_SIDSIZE)) {
303
+ event->type = SMMU_EVT_C_BAD_STREAMID;
304
+ return -EINVAL;
305
+ }
306
+ if (s->features & SMMU_FEATURE_2LVL_STE) {
307
+ int l1_ste_offset, l2_ste_offset, max_l2_ste, span;
308
+ dma_addr_t strtab_base, l1ptr, l2ptr;
309
+ STEDesc l1std;
310
+
311
+ strtab_base = s->strtab_base & SMMU_BASE_ADDR_MASK;
312
+ l1_ste_offset = sid >> s->sid_split;
313
+ l2_ste_offset = sid & ((1 << s->sid_split) - 1);
314
+ l1ptr = (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std));
315
+ /* TODO: guarantee 64-bit single-copy atomicity */
316
+ ret = dma_memory_read(&address_space_memory, l1ptr,
317
+ (uint8_t *)&l1std, sizeof(l1std));
318
+ if (ret != MEMTX_OK) {
319
+ qemu_log_mask(LOG_GUEST_ERROR,
320
+ "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr);
321
+ event->type = SMMU_EVT_F_STE_FETCH;
322
+ event->u.f_ste_fetch.addr = l1ptr;
323
+ return -EINVAL;
324
+ }
325
+
326
+ span = L1STD_SPAN(&l1std);
327
+
328
+ if (!span) {
329
+ /* l2ptr is not valid */
330
+ qemu_log_mask(LOG_GUEST_ERROR,
331
+ "invalid sid=%d (L1STD span=0)\n", sid);
332
+ event->type = SMMU_EVT_C_BAD_STREAMID;
333
+ return -EINVAL;
334
+ }
335
+ max_l2_ste = (1 << span) - 1;
336
+ l2ptr = l1std_l2ptr(&l1std);
337
+ trace_smmuv3_find_ste_2lvl(s->strtab_base, l1ptr, l1_ste_offset,
338
+ l2ptr, l2_ste_offset, max_l2_ste);
339
+ if (l2_ste_offset > max_l2_ste) {
340
+ qemu_log_mask(LOG_GUEST_ERROR,
341
+ "l2_ste_offset=%d > max_l2_ste=%d\n",
342
+ l2_ste_offset, max_l2_ste);
343
+ event->type = SMMU_EVT_C_BAD_STE;
344
+ return -EINVAL;
345
+ }
346
+ addr = l2ptr + l2_ste_offset * sizeof(*ste);
347
+ } else {
348
+ addr = s->strtab_base + sid * sizeof(*ste);
349
+ }
350
+
351
+ if (smmu_get_ste(s, addr, ste, event)) {
352
+ return -EINVAL;
353
+ }
354
+
355
+ return 0;
356
+}
357
+
358
+static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
359
+{
360
+ int ret = -EINVAL;
361
+ int i;
362
+
363
+ if (!CD_VALID(cd) || !CD_AARCH64(cd)) {
364
+ goto bad_cd;
365
+ }
366
+ if (!CD_A(cd)) {
367
+ goto bad_cd; /* SMMU_IDR0.TERM_MODEL == 1 */
368
+ }
369
+ if (CD_S(cd)) {
370
+ goto bad_cd; /* !STE_SECURE && SMMU_IDR0.STALL_MODEL == 1 */
371
+ }
372
+ if (CD_HA(cd) || CD_HD(cd)) {
373
+ goto bad_cd; /* HTTU = 0 */
374
+ }
375
+
376
+ /* we support only those at the moment */
377
+ cfg->aa64 = true;
378
+ cfg->stage = 1;
379
+
380
+ cfg->oas = oas2bits(CD_IPS(cd));
381
+ cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
382
+ cfg->tbi = CD_TBI(cd);
383
+ cfg->asid = CD_ASID(cd);
384
+
385
+ trace_smmuv3_decode_cd(cfg->oas);
386
+
387
+ /* decode data dependent on TT */
388
+ for (i = 0; i <= 1; i++) {
389
+ int tg, tsz;
390
+ SMMUTransTableInfo *tt = &cfg->tt[i];
391
+
392
+ cfg->tt[i].disabled = CD_EPD(cd, i);
393
+ if (cfg->tt[i].disabled) {
394
+ continue;
395
+ }
396
+
397
+ tsz = CD_TSZ(cd, i);
398
+ if (tsz < 16 || tsz > 39) {
399
+ goto bad_cd;
400
+ }
401
+
402
+ tg = CD_TG(cd, i);
403
+ tt->granule_sz = tg2granule(tg, i);
404
+ if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
405
+ goto bad_cd;
406
+ }
407
+
408
+ tt->tsz = tsz;
409
+ tt->ttb = CD_TTB(cd, i);
410
+ if (tt->ttb & ~(MAKE_64BIT_MASK(0, cfg->oas))) {
411
+ goto bad_cd;
412
+ }
413
+ trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz);
414
+ }
415
+
416
+ event->record_trans_faults = CD_R(cd);
417
+
418
+ return 0;
419
+
420
+bad_cd:
421
+ event->type = SMMU_EVT_C_BAD_CD;
422
+ return ret;
423
+}
424
+
425
+/**
426
+ * smmuv3_decode_config - Prepare the translation configuration
427
+ * for the @mr iommu region
428
+ * @mr: iommu memory region the translation config must be prepared for
429
+ * @cfg: output translation configuration which is populated through
430
+ * the different configuration decoding steps
431
+ * @event: must be zero'ed by the caller
432
+ *
433
+ * return < 0 if the translation needs to be aborted (@event is filled
434
+ * accordingly). Return 0 otherwise.
435
+ */
436
+static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
437
+ SMMUEventInfo *event)
438
+{
439
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
440
+ uint32_t sid = smmu_get_sid(sdev);
441
+ SMMUv3State *s = sdev->smmu;
442
+ int ret = -EINVAL;
443
+ STE ste;
444
+ CD cd;
445
+
446
+ if (smmu_find_ste(s, sid, &ste, event)) {
447
+ return ret;
448
+ }
449
+
450
+ if (decode_ste(s, cfg, &ste, event)) {
451
+ return ret;
452
+ }
453
+
454
+ if (smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event)) {
455
+ return ret;
456
+ }
457
+
458
+ return decode_cd(cfg, &cd, event);
459
+}
460
+
461
+static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
462
+ IOMMUAccessFlags flag)
463
+{
464
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
465
+ SMMUv3State *s = sdev->smmu;
466
+ uint32_t sid = smmu_get_sid(sdev);
467
+ SMMUEventInfo event = {.type = SMMU_EVT_OK, .sid = sid};
468
+ SMMUPTWEventInfo ptw_info = {};
469
+ SMMUTransCfg cfg = {};
470
+ IOMMUTLBEntry entry = {
471
+ .target_as = &address_space_memory,
472
+ .iova = addr,
473
+ .translated_addr = addr,
474
+ .addr_mask = ~(hwaddr)0,
475
+ .perm = IOMMU_NONE,
476
+ };
477
+ int ret = 0;
478
+
479
+ if (!smmu_enabled(s)) {
480
+ goto out;
481
+ }
482
+
483
+ ret = smmuv3_decode_config(mr, &cfg, &event);
484
+ if (ret) {
485
+ goto out;
486
+ }
487
+
488
+ if (cfg.aborted) {
489
+ goto out;
490
+ }
491
+
492
+ ret = smmu_ptw(&cfg, addr, flag, &entry, &ptw_info);
493
+ if (ret) {
494
+ switch (ptw_info.type) {
495
+ case SMMU_PTW_ERR_WALK_EABT:
496
+ event.type = SMMU_EVT_F_WALK_EABT;
497
+ event.u.f_walk_eabt.addr = addr;
498
+ event.u.f_walk_eabt.rnw = flag & 0x1;
499
+ event.u.f_walk_eabt.class = 0x1;
500
+ event.u.f_walk_eabt.addr2 = ptw_info.addr;
501
+ break;
502
+ case SMMU_PTW_ERR_TRANSLATION:
503
+ if (event.record_trans_faults) {
504
+ event.type = SMMU_EVT_F_TRANSLATION;
505
+ event.u.f_translation.addr = addr;
506
+ event.u.f_translation.rnw = flag & 0x1;
507
+ }
508
+ break;
509
+ case SMMU_PTW_ERR_ADDR_SIZE:
510
+ if (event.record_trans_faults) {
511
+ event.type = SMMU_EVT_F_ADDR_SIZE;
512
+ event.u.f_addr_size.addr = addr;
513
+ event.u.f_addr_size.rnw = flag & 0x1;
514
+ }
515
+ break;
516
+ case SMMU_PTW_ERR_ACCESS:
517
+ if (event.record_trans_faults) {
518
+ event.type = SMMU_EVT_F_ACCESS;
519
+ event.u.f_access.addr = addr;
520
+ event.u.f_access.rnw = flag & 0x1;
521
+ }
522
+ break;
523
+ case SMMU_PTW_ERR_PERMISSION:
524
+ if (event.record_trans_faults) {
525
+ event.type = SMMU_EVT_F_PERMISSION;
526
+ event.u.f_permission.addr = addr;
527
+ event.u.f_permission.rnw = flag & 0x1;
528
+ }
529
+ break;
530
+ default:
531
+ g_assert_not_reached();
532
+ }
533
+ }
534
+out:
535
+ if (ret) {
536
+ qemu_log_mask(LOG_GUEST_ERROR,
537
+ "%s translation failed for iova=0x%"PRIx64"(%d)\n",
538
+ mr->parent_obj.name, addr, ret);
539
+ entry.perm = IOMMU_NONE;
540
+ smmuv3_record_event(s, &event);
541
+ } else if (!cfg.aborted) {
542
+ entry.perm = flag;
543
+ trace_smmuv3_translate(mr->parent_obj.name, sid, addr,
544
+ entry.translated_addr, entry.perm);
545
+ }
546
+
547
+ return entry;
548
+}
549
+
550
static int smmuv3_cmdq_consume(SMMUv3State *s)
551
{
61
{
552
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
62
RasPiState *s = g_new0(RasPiState, 1);
553
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
63
+ int version = board_version(board_rev);
554
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
64
uint32_t vcram_size;
555
void *data)
65
DriveInfo *di;
66
BlockBackend *blk;
67
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
68
/* Setup the SOC */
69
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
70
&error_abort);
71
- int board_rev = version == 3 ? 0xa02082 : 0xa21041;
72
object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
73
&error_abort);
74
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
75
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
76
77
static void raspi2_init(MachineState *machine)
556
{
78
{
557
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
79
- raspi_init(machine, 2);
558
+
80
+ raspi_init(machine, 0xa21041);
559
+ imrc->translate = smmuv3_translate;
560
}
81
}
561
82
562
static const TypeInfo smmuv3_type_info = {
83
static void raspi2_machine_init(MachineClass *mc)
563
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
84
@@ -XXX,XX +XXX,XX @@ DEFINE_MACHINE("raspi2", raspi2_machine_init)
564
index XXXXXXX..XXXXXXX 100644
85
#ifdef TARGET_AARCH64
565
--- a/hw/arm/trace-events
86
static void raspi3_init(MachineState *machine)
566
+++ b/hw/arm/trace-events
87
{
567
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx
88
- raspi_init(machine, 3);
568
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
89
+ raspi_init(machine, 0xa02082);
569
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
90
}
570
smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
91
571
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
92
static void raspi3_machine_init(MachineClass *mc)
572
+smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%lx l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
573
+smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
574
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass iova:0x%"PRIx64" is_write=%d"
575
+smmuv3_translate_in(uint16_t sid, int pci_bus_num, uint64_t strtab_base) "SID:0x%x bus:%d strtab_base:0x%"PRIx64
576
+smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
577
+smmuv3_translate(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
578
+smmuv3_decode_cd(uint32_t oas) "oas=%d"
579
+smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d"
580
--
93
--
581
2.17.0
94
2.20.1
582
95
583
96
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add code to instantiate an smmuv3 in virt machine. A new iommu
3
The board revision encode the amount of RAM. Add a helper
4
integer member is introduced in VirtMachineState to store the type
4
to extract the RAM size, and use it.
5
of the iommu in use.
5
Since the amount of RAM is fixed (it is impossible to physically
6
modify to have more or less RAM), do not allow sizes different
7
than the one anounced by the manufacturer.
6
8
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
9
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200208165645.15657-5-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 1524665762-31355-13-git-send-email-eric.auger@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
include/hw/arm/virt.h | 10 +++++++
15
hw/arm/raspi.c | 15 ++++++++++++---
14
hw/arm/virt.c | 64 ++++++++++++++++++++++++++++++++++++++++++-
16
1 file changed, 12 insertions(+), 3 deletions(-)
15
2 files changed, 73 insertions(+), 1 deletion(-)
16
17
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
20
--- a/hw/arm/raspi.c
20
+++ b/include/hw/arm/virt.h
21
+++ b/hw/arm/raspi.c
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
22
23
23
#define NUM_GICV2M_SPIS 64
24
#include "qemu/osdep.h"
24
#define NUM_VIRTIO_TRANSPORTS 32
25
#include "qemu/units.h"
25
+#define NUM_SMMU_IRQS 4
26
+#include "qemu/cutils.h"
26
27
#include "qapi/error.h"
27
#define ARCH_GICV3_MAINT_IRQ 9
28
#include "cpu.h"
28
29
#include "hw/arm/bcm2836.h"
29
@@ -XXX,XX +XXX,XX @@ enum {
30
@@ -XXX,XX +XXX,XX @@ FIELD(REV_CODE, MANUFACTURER, 16, 4);
30
VIRT_GIC_V2M,
31
FIELD(REV_CODE, MEMORY_SIZE, 20, 3);
31
VIRT_GIC_ITS,
32
FIELD(REV_CODE, STYLE, 23, 1);
32
VIRT_GIC_REDIST,
33
33
+ VIRT_SMMU,
34
+static uint64_t board_ram_size(uint32_t board_rev)
34
VIRT_UART,
35
VIRT_MMIO,
36
VIRT_RTC,
37
@@ -XXX,XX +XXX,XX @@ enum {
38
VIRT_SECURE_MEM,
39
};
40
41
+typedef enum VirtIOMMUType {
42
+ VIRT_IOMMU_NONE,
43
+ VIRT_IOMMU_SMMUV3,
44
+ VIRT_IOMMU_VIRTIO,
45
+} VirtIOMMUType;
46
+
47
typedef struct MemMapEntry {
48
hwaddr base;
49
hwaddr size;
50
@@ -XXX,XX +XXX,XX @@ typedef struct {
51
bool its;
52
bool virt;
53
int32_t gic_version;
54
+ VirtIOMMUType iommu;
55
struct arm_boot_info bootinfo;
56
const MemMapEntry *memmap;
57
const int *irqmap;
58
@@ -XXX,XX +XXX,XX @@ typedef struct {
59
uint32_t clock_phandle;
60
uint32_t gic_phandle;
61
uint32_t msi_phandle;
62
+ uint32_t iommu_phandle;
63
int psci_conduit;
64
} VirtMachineState;
65
66
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/virt.c
69
+++ b/hw/arm/virt.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "hw/smbios/smbios.h"
72
#include "qapi/visitor.h"
73
#include "standard-headers/linux/input.h"
74
+#include "hw/arm/smmuv3.h"
75
76
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
77
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
78
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
79
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
80
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
81
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
82
+ [VIRT_SMMU] = { 0x09050000, 0x00020000 },
83
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
84
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
85
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
86
@@ -XXX,XX +XXX,XX @@ static const int a15irqmap[] = {
87
[VIRT_SECURE_UART] = 8,
88
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
89
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
90
+ [VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
91
[VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
92
};
93
94
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
95
0x7 /* PCI irq */);
96
}
97
98
-static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
99
+static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
100
+ PCIBus *bus)
101
+{
35
+{
102
+ char *node;
36
+ assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
103
+ const char compat[] = "arm,smmu-v3";
37
+ return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE);
104
+ int irq = vms->irqmap[VIRT_SMMU];
105
+ int i;
106
+ hwaddr base = vms->memmap[VIRT_SMMU].base;
107
+ hwaddr size = vms->memmap[VIRT_SMMU].size;
108
+ const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
109
+ DeviceState *dev;
110
+
111
+ if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) {
112
+ return;
113
+ }
114
+
115
+ dev = qdev_create(NULL, "arm-smmuv3");
116
+
117
+ object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
118
+ &error_abort);
119
+ qdev_init_nofail(dev);
120
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
121
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
122
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
123
+ }
124
+
125
+ node = g_strdup_printf("/smmuv3@%" PRIx64, base);
126
+ qemu_fdt_add_subnode(vms->fdt, node);
127
+ qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat));
128
+ qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", 2, base, 2, size);
129
+
130
+ qemu_fdt_setprop_cells(vms->fdt, node, "interrupts",
131
+ GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
132
+ GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
133
+ GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
134
+ GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
135
+
136
+ qemu_fdt_setprop(vms->fdt, node, "interrupt-names", irq_names,
137
+ sizeof(irq_names));
138
+
139
+ qemu_fdt_setprop_cell(vms->fdt, node, "clocks", vms->clock_phandle);
140
+ qemu_fdt_setprop_string(vms->fdt, node, "clock-names", "apb_pclk");
141
+ qemu_fdt_setprop(vms->fdt, node, "dma-coherent", NULL, 0);
142
+
143
+ qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1);
144
+
145
+ qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle);
146
+ g_free(node);
147
+}
38
+}
148
+
39
+
149
+static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
40
static int board_processor_id(uint32_t board_rev)
150
{
41
{
151
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
42
assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
152
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
43
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, uint32_t board_rev)
153
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
44
{
154
qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 1);
45
RasPiState *s = g_new0(RasPiState, 1);
155
create_pcie_irq_map(vms, vms->gic_phandle, irq, nodename);
46
int version = board_version(board_rev);
156
47
+ uint64_t ram_size = board_ram_size(board_rev);
157
+ if (vms->iommu) {
48
uint32_t vcram_size;
158
+ vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
49
DriveInfo *di;
159
+
50
BlockBackend *blk;
160
+ create_smmu(vms, pic, pci->bus);
51
BusState *bus;
161
+
52
DeviceState *carddev;
162
+ qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
53
163
+ 0x0, vms->iommu_phandle, 0x0, 0x10000);
54
- if (machine->ram_size > 1 * GiB) {
164
+ }
55
- error_report("Requested ram size is too large for this machine: "
165
+
56
- "maximum is 1GB");
166
g_free(nodename);
57
+ if (machine->ram_size != ram_size) {
167
}
58
+ char *size_str = size_to_str(ram_size);
59
+ error_report("Invalid RAM size, should be %s", size_str);
60
+ g_free(size_str);
61
exit(1);
62
}
168
63
169
--
64
--
170
2.17.0
65
2.20.1
171
66
172
67
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
ARM virt machine now exposes a new "iommu" option.
3
The board revision encode the processor type. Add a helper
4
The SMMUv3 IOMMU is instantiated using -machine virt,iommu=smmuv3.
4
to extract the type, and use it.
5
5
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
7
Message-id: 20200208165645.15657-6-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-15-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/virt.c | 36 ++++++++++++++++++++++++++++++++++++
11
hw/arm/raspi.c | 18 ++++++++++++++++--
13
1 file changed, 36 insertions(+)
12
1 file changed, 16 insertions(+), 2 deletions(-)
14
13
15
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/virt.c
16
--- a/hw/arm/raspi.c
18
+++ b/hw/arm/virt.c
17
+++ b/hw/arm/raspi.c
19
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static int board_version(uint32_t board_rev)
20
}
19
return board_processor_id(board_rev) + 1;
21
}
20
}
22
21
23
+static char *virt_get_iommu(Object *obj, Error **errp)
22
+static const char *board_soc_type(uint32_t board_rev)
24
+{
23
+{
25
+ VirtMachineState *vms = VIRT_MACHINE(obj);
24
+ static const char *soc_types[] = {
25
+ NULL, TYPE_BCM2836, TYPE_BCM2837,
26
+ };
27
+ int proc_id = board_processor_id(board_rev);
26
+
28
+
27
+ switch (vms->iommu) {
29
+ if (proc_id >= ARRAY_SIZE(soc_types) || !soc_types[proc_id]) {
28
+ case VIRT_IOMMU_NONE:
30
+ error_report("Unsupported processor id '%d' (board revision: 0x%x)",
29
+ return g_strdup("none");
31
+ proc_id, board_rev);
30
+ case VIRT_IOMMU_SMMUV3:
32
+ exit(1);
31
+ return g_strdup("smmuv3");
32
+ default:
33
+ g_assert_not_reached();
34
+ }
33
+ }
34
+ return soc_types[proc_id];
35
+}
35
+}
36
+
36
+
37
+static void virt_set_iommu(Object *obj, const char *value, Error **errp)
37
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
38
+{
39
+ VirtMachineState *vms = VIRT_MACHINE(obj);
40
+
41
+ if (!strcmp(value, "smmuv3")) {
42
+ vms->iommu = VIRT_IOMMU_SMMUV3;
43
+ } else if (!strcmp(value, "none")) {
44
+ vms->iommu = VIRT_IOMMU_NONE;
45
+ } else {
46
+ error_setg(errp, "Invalid iommu value");
47
+ error_append_hint(errp, "Valid values are none, smmuv3.\n");
48
+ }
49
+}
50
+
51
static CpuInstanceProperties
52
virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
53
{
38
{
54
@@ -XXX,XX +XXX,XX @@ static void virt_2_12_instance_init(Object *obj)
39
static const uint32_t smpboot[] = {
55
NULL);
40
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, uint32_t board_rev)
56
}
41
}
57
42
58
+ /* Default disallows iommu instantiation */
43
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
59
+ vms->iommu = VIRT_IOMMU_NONE;
44
- version == 3 ? TYPE_BCM2837 : TYPE_BCM2836,
60
+ object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, NULL);
45
- &error_abort, NULL);
61
+ object_property_set_description(obj, "iommu",
46
+ board_soc_type(board_rev), &error_abort, NULL);
62
+ "Set the IOMMU type. "
47
63
+ "Valid values are none and smmuv3",
48
/* Allocate and map RAM */
64
+ NULL);
49
memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
65
+
66
vms->memmap = a15memmap;
67
vms->irqmap = a15irqmap;
68
}
69
--
50
--
70
2.17.0
51
2.20.1
71
52
72
53
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
When running omap1/2 or pxa2xx based ARM machines with -nodefaults,
3
There is no point in creating the SoC object before allocating the RAM.
4
they bail out immediately complaining about a "missing SecureDigital
4
Move the call to keep all the SoC-related calls together.
5
device". That's not how the "default" devices in vl.c are meant to
6
work - it should be possible for a board to also start up without
7
default devices. So let's turn the error message and exit() into
8
a warning instead.
9
5
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 1525326811-3233-1-git-send-email-thuth@redhat.com
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200208165645.15657-7-f4bug@amsat.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
hw/arm/omap1.c | 8 ++++----
12
hw/arm/raspi.c | 5 ++---
17
hw/arm/omap2.c | 8 ++++----
13
1 file changed, 2 insertions(+), 3 deletions(-)
18
hw/arm/pxa2xx.c | 15 +++++++--------
19
3 files changed, 15 insertions(+), 16 deletions(-)
20
14
21
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
15
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/omap1.c
17
--- a/hw/arm/raspi.c
24
+++ b/hw/arm/omap1.c
18
+++ b/hw/arm/raspi.c
25
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, uint32_t board_rev)
26
#include "hw/arm/soc_dma.h"
20
exit(1);
27
#include "sysemu/block-backend.h"
28
#include "sysemu/blockdev.h"
29
+#include "sysemu/qtest.h"
30
#include "qemu/range.h"
31
#include "hw/sysbus.h"
32
#include "qemu/cutils.h"
33
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
34
omap_findclk(s, "dpll3"));
35
36
dinfo = drive_get(IF_SD, 0, 0);
37
- if (!dinfo) {
38
- error_report("missing SecureDigital device");
39
- exit(1);
40
+ if (!dinfo && !qtest_enabled()) {
41
+ warn_report("missing SecureDigital device");
42
}
21
}
43
s->mmc = omap_mmc_init(0xfffb7800, system_memory,
22
44
- blk_by_legacy_dinfo(dinfo),
23
- object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
45
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
24
- board_soc_type(board_rev), &error_abort, NULL);
46
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
25
-
47
&s->drq[OMAP_DMA_MMC_TX],
26
/* Allocate and map RAM */
48
omap_findclk(s, "mmc_ck"));
27
memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
49
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
28
machine->ram_size);
50
index XXXXXXX..XXXXXXX 100644
29
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, uint32_t board_rev)
51
--- a/hw/arm/omap2.c
30
memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0);
52
+++ b/hw/arm/omap2.c
31
53
@@ -XXX,XX +XXX,XX @@
32
/* Setup the SOC */
54
#include "cpu.h"
33
+ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
55
#include "sysemu/block-backend.h"
34
+ board_soc_type(board_rev), &error_abort, NULL);
56
#include "sysemu/blockdev.h"
35
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
57
+#include "sysemu/qtest.h"
36
&error_abort);
58
#include "hw/boards.h"
37
object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev",
59
#include "hw/hw.h"
60
#include "hw/arm/arm.h"
61
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
62
s->drq[OMAP24XX_DMA_GPMC]);
63
64
dinfo = drive_get(IF_SD, 0, 0);
65
- if (!dinfo) {
66
- error_report("missing SecureDigital device");
67
- exit(1);
68
+ if (!dinfo && !qtest_enabled()) {
69
+ warn_report("missing SecureDigital device");
70
}
71
s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
72
- blk_by_legacy_dinfo(dinfo),
73
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
74
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
75
&s->drq[OMAP24XX_DMA_MMC1_TX],
76
omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
77
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/pxa2xx.c
80
+++ b/hw/arm/pxa2xx.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "chardev/char-fe.h"
83
#include "sysemu/block-backend.h"
84
#include "sysemu/blockdev.h"
85
+#include "sysemu/qtest.h"
86
#include "qemu/cutils.h"
87
88
static struct {
89
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
90
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
91
92
dinfo = drive_get(IF_SD, 0, 0);
93
- if (!dinfo) {
94
- error_report("missing SecureDigital device");
95
- exit(1);
96
+ if (!dinfo && !qtest_enabled()) {
97
+ warn_report("missing SecureDigital device");
98
}
99
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
100
- blk_by_legacy_dinfo(dinfo),
101
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
102
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
103
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
104
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
105
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
106
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
107
108
dinfo = drive_get(IF_SD, 0, 0);
109
- if (!dinfo) {
110
- error_report("missing SecureDigital device");
111
- exit(1);
112
+ if (!dinfo && !qtest_enabled()) {
113
+ warn_report("missing SecureDigital device");
114
}
115
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
116
- blk_by_legacy_dinfo(dinfo),
117
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
118
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
119
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
120
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
121
--
38
--
122
2.17.0
39
2.20.1
123
40
124
41
diff view generated by jsdifflib
1
From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The character frontend needs to be notified that the uart receive buffer
3
QOM'ify RaspiMachineState. Now machines inherit of RaspiMachineClass.
4
is empty and ready to handle another character.
5
4
6
Previously, the uart only worked correctly when receiving one character
5
Cc: Igor Mammedov <imammedo@redhat.com>
7
at a time.
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
9
Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
8
Message-id: 20200208165645.15657-8-f4bug@amsat.org
10
Message-id: CAEg67GkRTw=cXei3o9hvpxG_L4zSrNzR0bFyAgny+sSEUb_kPw@mail.gmail.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/char/cmsdk-apb-uart.c | 1 +
12
hw/arm/raspi.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------
15
1 file changed, 1 insertion(+)
13
1 file changed, 49 insertions(+), 7 deletions(-)
16
14
17
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
15
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/char/cmsdk-apb-uart.c
17
--- a/hw/arm/raspi.c
20
+++ b/hw/char/cmsdk-apb-uart.c
18
+++ b/hw/arm/raspi.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
19
@@ -XXX,XX +XXX,XX @@
22
r = s->rxbuf;
20
/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */
23
s->state &= ~R_STATE_RXFULL_MASK;
21
#define MACH_TYPE_BCM2708 3138
24
cmsdk_apb_uart_update(s);
22
25
+ qemu_chr_fe_accept_input(&s->chr);
23
-typedef struct RasPiState {
26
break;
24
+typedef struct RaspiMachineState {
27
case A_STATE:
25
+ /*< private >*/
28
r = s->state;
26
+ MachineState parent_obj;
27
+ /*< public >*/
28
BCM283XState soc;
29
MemoryRegion ram;
30
-} RasPiState;
31
+} RaspiMachineState;
32
+
33
+typedef struct RaspiMachineClass {
34
+ /*< private >*/
35
+ MachineClass parent_obj;
36
+ /*< public >*/
37
+} RaspiMachineClass;
38
+
39
+#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common")
40
+#define RASPI_MACHINE(obj) \
41
+ OBJECT_CHECK(RaspiMachineState, (obj), TYPE_RASPI_MACHINE)
42
+
43
+#define RASPI_MACHINE_CLASS(klass) \
44
+ OBJECT_CLASS_CHECK(RaspiMachineClass, (klass), TYPE_RASPI_MACHINE)
45
+#define RASPI_MACHINE_GET_CLASS(obj) \
46
+ OBJECT_GET_CLASS(RaspiMachineClass, (obj), TYPE_RASPI_MACHINE)
47
48
/*
49
* Board revision codes:
50
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
51
52
static void raspi_init(MachineState *machine, uint32_t board_rev)
53
{
54
- RasPiState *s = g_new0(RasPiState, 1);
55
+ RaspiMachineState *s = RASPI_MACHINE(machine);
56
int version = board_version(board_rev);
57
uint64_t ram_size = board_ram_size(board_rev);
58
uint32_t vcram_size;
59
@@ -XXX,XX +XXX,XX @@ static void raspi2_init(MachineState *machine)
60
raspi_init(machine, 0xa21041);
61
}
62
63
-static void raspi2_machine_init(MachineClass *mc)
64
+static void raspi2_machine_class_init(ObjectClass *oc, void *data)
65
{
66
+ MachineClass *mc = MACHINE_CLASS(oc);
67
+
68
mc->desc = "Raspberry Pi 2B";
69
mc->init = raspi2_init;
70
mc->block_default_type = IF_SD;
71
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
72
mc->default_ram_size = 1 * GiB;
73
mc->ignore_memory_transaction_failures = true;
74
};
75
-DEFINE_MACHINE("raspi2", raspi2_machine_init)
76
77
#ifdef TARGET_AARCH64
78
static void raspi3_init(MachineState *machine)
79
@@ -XXX,XX +XXX,XX @@ static void raspi3_init(MachineState *machine)
80
raspi_init(machine, 0xa02082);
81
}
82
83
-static void raspi3_machine_init(MachineClass *mc)
84
+static void raspi3_machine_class_init(ObjectClass *oc, void *data)
85
{
86
+ MachineClass *mc = MACHINE_CLASS(oc);
87
+
88
mc->desc = "Raspberry Pi 3B";
89
mc->init = raspi3_init;
90
mc->block_default_type = IF_SD;
91
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
92
mc->default_cpus = BCM283X_NCPUS;
93
mc->default_ram_size = 1 * GiB;
94
}
95
-DEFINE_MACHINE("raspi3", raspi3_machine_init)
96
#endif
97
+
98
+static const TypeInfo raspi_machine_types[] = {
99
+ {
100
+ .name = MACHINE_TYPE_NAME("raspi2"),
101
+ .parent = TYPE_RASPI_MACHINE,
102
+ .class_init = raspi2_machine_class_init,
103
+#ifdef TARGET_AARCH64
104
+ }, {
105
+ .name = MACHINE_TYPE_NAME("raspi3"),
106
+ .parent = TYPE_RASPI_MACHINE,
107
+ .class_init = raspi3_machine_class_init,
108
+#endif
109
+ }, {
110
+ .name = TYPE_RASPI_MACHINE,
111
+ .parent = TYPE_MACHINE,
112
+ .instance_size = sizeof(RaspiMachineState),
113
+ .class_size = sizeof(RaspiMachineClass),
114
+ .abstract = true,
115
+ }
116
+};
117
+
118
+DEFINE_TYPES(raspi_machine_types)
29
--
119
--
30
2.17.0
120
2.20.1
31
121
32
122
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
In case the MSI is translated by an IOMMU we need to fixup the
3
We want to have a common class_init(). The only value that
4
MSI route with the translated address.
4
matters (and changes) is the board revision.
5
Pass the board_rev as class_data to class_init().
5
6
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
8
Message-id: 20200208165645.15657-9-f4bug@amsat.org
8
Message-id: 1524665762-31355-12-git-send-email-eric.auger@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/kvm.c | 38 +++++++++++++++++++++++++++++++++++++-
12
hw/arm/raspi.c | 17 ++++++++++++++---
13
target/arm/trace-events | 3 +++
13
1 file changed, 14 insertions(+), 3 deletions(-)
14
2 files changed, 40 insertions(+), 1 deletion(-)
15
14
16
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
15
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm.c
17
--- a/hw/arm/raspi.c
19
+++ b/target/arm/kvm.c
18
+++ b/hw/arm/raspi.c
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct RaspiMachineClass {
21
#include "sysemu/kvm.h"
20
/*< private >*/
22
#include "kvm_arm.h"
21
MachineClass parent_obj;
23
#include "cpu.h"
22
/*< public >*/
24
+#include "trace.h"
23
+ uint32_t board_rev;
25
#include "internals.h"
24
} RaspiMachineClass;
26
#include "hw/arm/arm.h"
25
27
+#include "hw/pci/pci.h"
26
#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common")
28
#include "exec/memattrs.h"
27
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
29
#include "exec/address-spaces.h"
28
arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo);
30
#include "hw/boards.h"
29
}
31
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vgic_probe(void)
30
32
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
31
-static void raspi_init(MachineState *machine, uint32_t board_rev)
33
uint64_t address, uint32_t data, PCIDevice *dev)
32
+static void raspi_init(MachineState *machine)
34
{
33
{
35
- return 0;
34
+ RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine);
36
+ AddressSpace *as = pci_device_iommu_address_space(dev);
35
RaspiMachineState *s = RASPI_MACHINE(machine);
37
+ hwaddr xlat, len, doorbell_gpa;
36
+ uint32_t board_rev = mc->board_rev;
38
+ MemoryRegionSection mrs;
37
int version = board_version(board_rev);
39
+ MemoryRegion *mr;
38
uint64_t ram_size = board_ram_size(board_rev);
40
+ int ret = 1;
39
uint32_t vcram_size;
41
+
40
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, uint32_t board_rev)
42
+ if (as == &address_space_memory) {
41
43
+ return 0;
42
static void raspi2_init(MachineState *machine)
44
+ }
43
{
45
+
44
- raspi_init(machine, 0xa21041);
46
+ /* MSI doorbell address is translated by an IOMMU */
45
+ raspi_init(machine);
47
+
48
+ rcu_read_lock();
49
+ mr = address_space_translate(as, address, &xlat, &len, true);
50
+ if (!mr) {
51
+ goto unlock;
52
+ }
53
+ mrs = memory_region_find(mr, xlat, 1);
54
+ if (!mrs.mr) {
55
+ goto unlock;
56
+ }
57
+
58
+ doorbell_gpa = mrs.offset_within_address_space;
59
+ memory_region_unref(mrs.mr);
60
+
61
+ route->u.msi.address_lo = doorbell_gpa;
62
+ route->u.msi.address_hi = doorbell_gpa >> 32;
63
+
64
+ trace_kvm_arm_fixup_msi_route(address, doorbell_gpa);
65
+
66
+ ret = 0;
67
+
68
+unlock:
69
+ rcu_read_unlock();
70
+ return ret;
71
}
46
}
72
47
73
int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
48
static void raspi2_machine_class_init(ObjectClass *oc, void *data)
74
diff --git a/target/arm/trace-events b/target/arm/trace-events
49
{
75
index XXXXXXX..XXXXXXX 100644
50
MachineClass *mc = MACHINE_CLASS(oc);
76
--- a/target/arm/trace-events
51
+ RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
77
+++ b/target/arm/trace-events
52
+ uint32_t board_rev = (uint32_t)(uintptr_t)data;
78
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
53
79
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
54
+ rmc->board_rev = board_rev;
80
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
55
mc->desc = "Raspberry Pi 2B";
81
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
56
mc->init = raspi2_init;
82
+
57
mc->block_default_type = IF_SD;
83
+# target/arm/kvm.c
58
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
84
+kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
59
#ifdef TARGET_AARCH64
60
static void raspi3_init(MachineState *machine)
61
{
62
- raspi_init(machine, 0xa02082);
63
+ raspi_init(machine);
64
}
65
66
static void raspi3_machine_class_init(ObjectClass *oc, void *data)
67
{
68
MachineClass *mc = MACHINE_CLASS(oc);
69
+ RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
70
+ uint32_t board_rev = (uint32_t)(uintptr_t)data;
71
72
+ rmc->board_rev = board_rev;
73
mc->desc = "Raspberry Pi 3B";
74
mc->init = raspi3_init;
75
mc->block_default_type = IF_SD;
76
@@ -XXX,XX +XXX,XX @@ static const TypeInfo raspi_machine_types[] = {
77
.name = MACHINE_TYPE_NAME("raspi2"),
78
.parent = TYPE_RASPI_MACHINE,
79
.class_init = raspi2_machine_class_init,
80
+ .class_data = (void *)0xa21041,
81
#ifdef TARGET_AARCH64
82
}, {
83
.name = MACHINE_TYPE_NAME("raspi3"),
84
.parent = TYPE_RASPI_MACHINE,
85
.class_init = raspi3_machine_class_init,
86
+ .class_data = (void *)0xa02082,
87
#endif
88
}, {
89
.name = TYPE_RASPI_MACHINE,
85
--
90
--
86
2.17.0
91
2.20.1
87
92
88
93
diff view generated by jsdifflib
1
Convert the smc91c111 device away from using the old_mmio field of
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
MemoryRegionOps. This device is used by several Arm board models.
3
2
3
raspi_machine_init() access to board_rev via RaspiMachineClass.
4
raspi2_init() and raspi3_init() do nothing. Call raspi_machine_init
5
directly.
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20200208165645.15657-10-f4bug@amsat.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180427173611.10281-3-peter.maydell@linaro.org
7
---
11
---
8
hw/net/smc91c111.c | 54 +++++++++++++++++++++-------------------------
12
hw/arm/raspi.c | 16 +++-------------
9
1 file changed, 25 insertions(+), 29 deletions(-)
13
1 file changed, 3 insertions(+), 13 deletions(-)
10
14
11
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
15
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/smc91c111.c
17
--- a/hw/arm/raspi.c
14
+++ b/hw/net/smc91c111.c
18
+++ b/hw/arm/raspi.c
15
@@ -XXX,XX +XXX,XX @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
19
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
16
return 0;
20
arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo);
17
}
21
}
18
22
19
-static void smc91c111_writew(void *opaque, hwaddr offset,
23
-static void raspi_init(MachineState *machine)
20
- uint32_t value)
24
+static void raspi_machine_init(MachineState *machine)
21
+static uint64_t smc91c111_readfn(void *opaque, hwaddr addr, unsigned size)
22
{
25
{
23
- smc91c111_writeb(opaque, offset, value & 0xff);
26
RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine);
24
- smc91c111_writeb(opaque, offset + 1, value >> 8);
27
RaspiMachineState *s = RASPI_MACHINE(machine);
25
+ int i;
28
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine)
26
+ uint32_t val = 0;
29
setup_boot(machine, version, machine->ram_size - vcram_size);
27
+
28
+ for (i = 0; i < size; i++) {
29
+ val |= smc91c111_readb(opaque, addr + i) << (i * 8);
30
+ }
31
+ return val;
32
}
30
}
33
31
34
-static void smc91c111_writel(void *opaque, hwaddr offset,
32
-static void raspi2_init(MachineState *machine)
35
- uint32_t value)
36
+static void smc91c111_writefn(void *opaque, hwaddr addr,
37
+ uint64_t value, unsigned size)
38
{
39
+ int i = 0;
40
+
41
/* 32-bit writes to offset 0xc only actually write to the bank select
42
- register (offset 0xe) */
43
- if (offset != 0xc)
44
- smc91c111_writew(opaque, offset, value & 0xffff);
45
- smc91c111_writew(opaque, offset + 2, value >> 16);
46
-}
47
+ * register (offset 0xe), so skip the first two bytes we would write.
48
+ */
49
+ if (addr == 0xc && size == 4) {
50
+ i += 2;
51
+ }
52
53
-static uint32_t smc91c111_readw(void *opaque, hwaddr offset)
54
-{
33
-{
55
- uint32_t val;
34
- raspi_init(machine);
56
- val = smc91c111_readb(opaque, offset);
57
- val |= smc91c111_readb(opaque, offset + 1) << 8;
58
- return val;
59
-}
35
-}
60
-
36
-
61
-static uint32_t smc91c111_readl(void *opaque, hwaddr offset)
37
static void raspi2_machine_class_init(ObjectClass *oc, void *data)
38
{
39
MachineClass *mc = MACHINE_CLASS(oc);
40
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
41
42
rmc->board_rev = board_rev;
43
mc->desc = "Raspberry Pi 2B";
44
- mc->init = raspi2_init;
45
+ mc->init = raspi_machine_init;
46
mc->block_default_type = IF_SD;
47
mc->no_parallel = 1;
48
mc->no_floppy = 1;
49
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
50
};
51
52
#ifdef TARGET_AARCH64
53
-static void raspi3_init(MachineState *machine)
62
-{
54
-{
63
- uint32_t val;
55
- raspi_init(machine);
64
- val = smc91c111_readw(opaque, offset);
56
-}
65
- val |= smc91c111_readw(opaque, offset + 2) << 16;
57
-
66
- return val;
58
static void raspi3_machine_class_init(ObjectClass *oc, void *data)
67
+ for (; i < size; i++) {
59
{
68
+ smc91c111_writeb(opaque, addr + i,
60
MachineClass *mc = MACHINE_CLASS(oc);
69
+ extract32(value, i * 8, 8));
61
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data)
70
+ }
62
71
}
63
rmc->board_rev = board_rev;
72
64
mc->desc = "Raspberry Pi 3B";
73
static int smc91c111_can_receive_nc(NetClientState *nc)
65
- mc->init = raspi3_init;
74
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps smc91c111_mem_ops = {
66
+ mc->init = raspi_machine_init;
75
/* The special case for 32 bit writes to 0xc means we can't just
67
mc->block_default_type = IF_SD;
76
* set .impl.min/max_access_size to 1, unfortunately
68
mc->no_parallel = 1;
77
*/
69
mc->no_floppy = 1;
78
- .old_mmio = {
79
- .read = { smc91c111_readb, smc91c111_readw, smc91c111_readl, },
80
- .write = { smc91c111_writeb, smc91c111_writew, smc91c111_writel, },
81
- },
82
+ .read = smc91c111_readfn,
83
+ .write = smc91c111_writefn,
84
+ .valid.min_access_size = 1,
85
+ .valid.max_access_size = 4,
86
.endianness = DEVICE_NATIVE_ENDIAN,
87
};
88
89
--
70
--
90
2.17.0
71
2.20.1
91
72
92
73
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This allows to pin the host controller in the Linux PCI domain space.
3
We added a helper to extract the RAM size from the board
4
Linux requires that property to be available consistently or not at all,
4
revision, and made board_rev a field of RaspiMachineClass.
5
in which case the domain number becomes unstable on additions/removals.
5
The class_init() can now use the helper to extract from the
6
Adding it here won't make a difference in practice for most setups as we
6
board revision the board-specific amount of RAM.
7
only expose one controller.
8
7
9
However, enabling Jailhouse on top may introduce another controller, and
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
that one would like to have stable address as well. So the property is
9
Message-id: 20200208165645.15657-11-f4bug@amsat.org
11
needed for the first controller as well.
12
13
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
14
Message-id: 3301c5bc-7b47-1b0e-8ce4-30435057a276@web.de
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
12
---
18
hw/arm/virt.c | 1 +
13
hw/arm/raspi.c | 4 ++--
19
1 file changed, 1 insertion(+)
14
1 file changed, 2 insertions(+), 2 deletions(-)
20
15
21
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/virt.c
18
--- a/hw/arm/raspi.c
24
+++ b/hw/arm/virt.c
19
+++ b/hw/arm/raspi.c
25
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
20
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
26
qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "pci");
21
mc->max_cpus = BCM283X_NCPUS;
27
qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 3);
22
mc->min_cpus = BCM283X_NCPUS;
28
qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 2);
23
mc->default_cpus = BCM283X_NCPUS;
29
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "linux,pci-domain", 0);
24
- mc->default_ram_size = 1 * GiB;
30
qemu_fdt_setprop_cells(vms->fdt, nodename, "bus-range", 0,
25
+ mc->default_ram_size = board_ram_size(board_rev);
31
nr_pcie_buses - 1);
26
mc->ignore_memory_transaction_failures = true;
32
qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0);
27
};
28
29
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data)
30
mc->max_cpus = BCM283X_NCPUS;
31
mc->min_cpus = BCM283X_NCPUS;
32
mc->default_cpus = BCM283X_NCPUS;
33
- mc->default_ram_size = 1 * GiB;
34
+ mc->default_ram_size = board_ram_size(board_rev);
35
}
36
#endif
37
33
--
38
--
34
2.17.0
39
2.20.1
35
40
36
41
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This patch implements the page table walk for VMSAv8-64.
3
The board revision encode the model type. Add a helper
4
to extract the model, and use it.
4
5
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
7
Message-id: 20200208165645.15657-12-f4bug@amsat.org
7
Message-id: 1524665762-31355-4-git-send-email-eric.auger@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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/arm/smmu-internal.h | 99 ++++++++++++++++
11
hw/arm/raspi.c | 18 ++++++++++++++++--
12
include/hw/arm/smmu-common.h | 14 +++
12
1 file changed, 16 insertions(+), 2 deletions(-)
13
hw/arm/smmu-common.c | 222 +++++++++++++++++++++++++++++++++++
14
hw/arm/trace-events | 9 +-
15
4 files changed, 343 insertions(+), 1 deletion(-)
16
create mode 100644 hw/arm/smmu-internal.h
17
13
18
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
19
new file mode 100644
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX
16
--- a/hw/arm/raspi.c
21
--- /dev/null
17
+++ b/hw/arm/raspi.c
22
+++ b/hw/arm/smmu-internal.h
18
@@ -XXX,XX +XXX,XX @@ static const char *board_soc_type(uint32_t board_rev)
23
@@ -XXX,XX +XXX,XX @@
19
return soc_types[proc_id];
24
+/*
20
}
25
+ * ARM SMMU support - Internal API
21
26
+ *
22
+static const char *board_type(uint32_t board_rev)
27
+ * Copyright (c) 2017 Red Hat, Inc.
28
+ * Copyright (C) 2014-2016 Broadcom Corporation
29
+ * Written by Prem Mallappa, Eric Auger
30
+ *
31
+ * This program is free software; you can redistribute it and/or modify
32
+ * it under the terms of the GNU General Public License version 2 as
33
+ * published by the Free Software Foundation.
34
+ *
35
+ * This program is distributed in the hope that it will be useful,
36
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
+ * General Public License for more details.
39
+ *
40
+ * You should have received a copy of the GNU General Public License along
41
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
42
+ */
43
+
44
+#ifndef HW_ARM_SMMU_INTERNAL_H
45
+#define HW_ARM_SMMU_INTERNAL_H
46
+
47
+#define TBI0(tbi) ((tbi) & 0x1)
48
+#define TBI1(tbi) ((tbi) & 0x2 >> 1)
49
+
50
+/* PTE Manipulation */
51
+
52
+#define ARM_LPAE_PTE_TYPE_SHIFT 0
53
+#define ARM_LPAE_PTE_TYPE_MASK 0x3
54
+
55
+#define ARM_LPAE_PTE_TYPE_BLOCK 1
56
+#define ARM_LPAE_PTE_TYPE_TABLE 3
57
+
58
+#define ARM_LPAE_L3_PTE_TYPE_RESERVED 1
59
+#define ARM_LPAE_L3_PTE_TYPE_PAGE 3
60
+
61
+#define ARM_LPAE_PTE_VALID (1 << 0)
62
+
63
+#define PTE_ADDRESS(pte, shift) \
64
+ (extract64(pte, shift, 47 - shift + 1) << shift)
65
+
66
+#define is_invalid_pte(pte) (!(pte & ARM_LPAE_PTE_VALID))
67
+
68
+#define is_reserved_pte(pte, level) \
69
+ ((level == 3) && \
70
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_RESERVED))
71
+
72
+#define is_block_pte(pte, level) \
73
+ ((level < 3) && \
74
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_BLOCK))
75
+
76
+#define is_table_pte(pte, level) \
77
+ ((level < 3) && \
78
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_TABLE))
79
+
80
+#define is_page_pte(pte, level) \
81
+ ((level == 3) && \
82
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_PAGE))
83
+
84
+/* access permissions */
85
+
86
+#define PTE_AP(pte) \
87
+ (extract64(pte, 6, 2))
88
+
89
+#define PTE_APTABLE(pte) \
90
+ (extract64(pte, 61, 2))
91
+
92
+/*
93
+ * TODO: At the moment all transactions are considered as privileged (EL1)
94
+ * as IOMMU translation callback does not pass user/priv attributes.
95
+ */
96
+#define is_permission_fault(ap, perm) \
97
+ (((perm) & IOMMU_WO) && ((ap) & 0x2))
98
+
99
+#define PTE_AP_TO_PERM(ap) \
100
+ (IOMMU_ACCESS_FLAG(true, !((ap) & 0x2)))
101
+
102
+/* Level Indexing */
103
+
104
+static inline int level_shift(int level, int granule_sz)
105
+{
23
+{
106
+ return granule_sz + (3 - level) * (granule_sz - 3);
24
+ static const char *types[] = {
25
+ "A", "B", "A+", "B+", "2B", "Alpha", "CM1", NULL, "3B", "Zero",
26
+ "CM3", NULL, "Zero W", "3B+", "3A+", NULL, "CM3+", "4B",
27
+ };
28
+ assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */
29
+ int bt = FIELD_EX32(board_rev, REV_CODE, TYPE);
30
+ if (bt >= ARRAY_SIZE(types) || !types[bt]) {
31
+ return "Unknown";
32
+ }
33
+ return types[bt];
107
+}
34
+}
108
+
35
+
109
+static inline uint64_t level_page_mask(int level, int granule_sz)
36
static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
110
+{
111
+ return ~(MAKE_64BIT_MASK(0, level_shift(level, granule_sz)));
112
+}
113
+
114
+static inline
115
+uint64_t iova_level_offset(uint64_t iova, int inputsize,
116
+ int level, int gsz)
117
+{
118
+ return ((iova & MAKE_64BIT_MASK(0, inputsize)) >> level_shift(level, gsz)) &
119
+ MAKE_64BIT_MASK(0, gsz - 3);
120
+}
121
+
122
+#endif
123
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
124
index XXXXXXX..XXXXXXX 100644
125
--- a/include/hw/arm/smmu-common.h
126
+++ b/include/hw/arm/smmu-common.h
127
@@ -XXX,XX +XXX,XX @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
128
{
37
{
129
return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
38
static const uint32_t smpboot[] = {
130
}
39
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
131
+
40
uint32_t board_rev = (uint32_t)(uintptr_t)data;
132
+/**
41
133
+ * smmu_ptw - Perform the page table walk for a given iova / access flags
42
rmc->board_rev = board_rev;
134
+ * pair, according to @cfg translation config
43
- mc->desc = "Raspberry Pi 2B";
135
+ */
44
+ mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev));
136
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
45
mc->init = raspi_machine_init;
137
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
46
mc->block_default_type = IF_SD;
138
+
47
mc->no_parallel = 1;
139
+/**
48
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data)
140
+ * select_tt - compute which translation table shall be used according to
49
uint32_t board_rev = (uint32_t)(uintptr_t)data;
141
+ * the input iova and translation config and return the TT specific info
50
142
+ */
51
rmc->board_rev = board_rev;
143
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
52
- mc->desc = "Raspberry Pi 3B";
144
+
53
+ mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev));
145
#endif /* HW_ARM_SMMU_COMMON */
54
mc->init = raspi_machine_init;
146
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
55
mc->block_default_type = IF_SD;
147
index XXXXXXX..XXXXXXX 100644
56
mc->no_parallel = 1;
148
--- a/hw/arm/smmu-common.c
149
+++ b/hw/arm/smmu-common.c
150
@@ -XXX,XX +XXX,XX @@
151
152
#include "qemu/error-report.h"
153
#include "hw/arm/smmu-common.h"
154
+#include "smmu-internal.h"
155
+
156
+/* VMSAv8-64 Translation */
157
+
158
+/**
159
+ * get_pte - Get the content of a page table entry located at
160
+ * @base_addr[@index]
161
+ */
162
+static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte,
163
+ SMMUPTWEventInfo *info)
164
+{
165
+ int ret;
166
+ dma_addr_t addr = baseaddr + index * sizeof(*pte);
167
+
168
+ /* TODO: guarantee 64-bit single-copy atomicity */
169
+ ret = dma_memory_read(&address_space_memory, addr,
170
+ (uint8_t *)pte, sizeof(*pte));
171
+
172
+ if (ret != MEMTX_OK) {
173
+ info->type = SMMU_PTW_ERR_WALK_EABT;
174
+ info->addr = addr;
175
+ return -EINVAL;
176
+ }
177
+ trace_smmu_get_pte(baseaddr, index, addr, *pte);
178
+ return 0;
179
+}
180
+
181
+/* VMSAv8-64 Translation Table Format Descriptor Decoding */
182
+
183
+/**
184
+ * get_page_pte_address - returns the L3 descriptor output address,
185
+ * ie. the page frame
186
+ * ARM ARM spec: Figure D4-17 VMSAv8-64 level 3 descriptor format
187
+ */
188
+static inline hwaddr get_page_pte_address(uint64_t pte, int granule_sz)
189
+{
190
+ return PTE_ADDRESS(pte, granule_sz);
191
+}
192
+
193
+/**
194
+ * get_table_pte_address - return table descriptor output address,
195
+ * ie. address of next level table
196
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
197
+ */
198
+static inline hwaddr get_table_pte_address(uint64_t pte, int granule_sz)
199
+{
200
+ return PTE_ADDRESS(pte, granule_sz);
201
+}
202
+
203
+/**
204
+ * get_block_pte_address - return block descriptor output address and block size
205
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
206
+ */
207
+static inline hwaddr get_block_pte_address(uint64_t pte, int level,
208
+ int granule_sz, uint64_t *bsz)
209
+{
210
+ int n = (granule_sz - 3) * (4 - level) + 3;
211
+
212
+ *bsz = 1 << n;
213
+ return PTE_ADDRESS(pte, n);
214
+}
215
+
216
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
217
+{
218
+ bool tbi = extract64(iova, 55, 1) ? TBI1(cfg->tbi) : TBI0(cfg->tbi);
219
+ uint8_t tbi_byte = tbi * 8;
220
+
221
+ if (cfg->tt[0].tsz &&
222
+ !extract64(iova, 64 - cfg->tt[0].tsz, cfg->tt[0].tsz - tbi_byte)) {
223
+ /* there is a ttbr0 region and we are in it (high bits all zero) */
224
+ return &cfg->tt[0];
225
+ } else if (cfg->tt[1].tsz &&
226
+ !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
227
+ /* there is a ttbr1 region and we are in it (high bits all one) */
228
+ return &cfg->tt[1];
229
+ } else if (!cfg->tt[0].tsz) {
230
+ /* ttbr0 region is "everything not in the ttbr1 region" */
231
+ return &cfg->tt[0];
232
+ } else if (!cfg->tt[1].tsz) {
233
+ /* ttbr1 region is "everything not in the ttbr0 region" */
234
+ return &cfg->tt[1];
235
+ }
236
+ /* in the gap between the two regions, this is a Translation fault */
237
+ return NULL;
238
+}
239
+
240
+/**
241
+ * smmu_ptw_64 - VMSAv8-64 Walk of the page tables for a given IOVA
242
+ * @cfg: translation config
243
+ * @iova: iova to translate
244
+ * @perm: access type
245
+ * @tlbe: IOMMUTLBEntry (out)
246
+ * @info: handle to an error info
247
+ *
248
+ * Return 0 on success, < 0 on error. In case of error, @info is filled
249
+ * and tlbe->perm is set to IOMMU_NONE.
250
+ * Upon success, @tlbe is filled with translated_addr and entry
251
+ * permission rights.
252
+ */
253
+static int smmu_ptw_64(SMMUTransCfg *cfg,
254
+ dma_addr_t iova, IOMMUAccessFlags perm,
255
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
256
+{
257
+ dma_addr_t baseaddr, indexmask;
258
+ int stage = cfg->stage;
259
+ SMMUTransTableInfo *tt = select_tt(cfg, iova);
260
+ uint8_t level, granule_sz, inputsize, stride;
261
+
262
+ if (!tt || tt->disabled) {
263
+ info->type = SMMU_PTW_ERR_TRANSLATION;
264
+ goto error;
265
+ }
266
+
267
+ granule_sz = tt->granule_sz;
268
+ stride = granule_sz - 3;
269
+ inputsize = 64 - tt->tsz;
270
+ level = 4 - (inputsize - 4) / stride;
271
+ indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
272
+ baseaddr = extract64(tt->ttb, 0, 48);
273
+ baseaddr &= ~indexmask;
274
+
275
+ tlbe->iova = iova;
276
+ tlbe->addr_mask = (1 << granule_sz) - 1;
277
+
278
+ while (level <= 3) {
279
+ uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
280
+ uint64_t mask = subpage_size - 1;
281
+ uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
282
+ uint64_t pte;
283
+ dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
284
+ uint8_t ap;
285
+
286
+ if (get_pte(baseaddr, offset, &pte, info)) {
287
+ goto error;
288
+ }
289
+ trace_smmu_ptw_level(level, iova, subpage_size,
290
+ baseaddr, offset, pte);
291
+
292
+ if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
293
+ trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
294
+ pte_addr, offset, pte);
295
+ info->type = SMMU_PTW_ERR_TRANSLATION;
296
+ goto error;
297
+ }
298
+
299
+ if (is_page_pte(pte, level)) {
300
+ uint64_t gpa = get_page_pte_address(pte, granule_sz);
301
+
302
+ ap = PTE_AP(pte);
303
+ if (is_permission_fault(ap, perm)) {
304
+ info->type = SMMU_PTW_ERR_PERMISSION;
305
+ goto error;
306
+ }
307
+
308
+ tlbe->translated_addr = gpa + (iova & mask);
309
+ tlbe->perm = PTE_AP_TO_PERM(ap);
310
+ trace_smmu_ptw_page_pte(stage, level, iova,
311
+ baseaddr, pte_addr, pte, gpa);
312
+ return 0;
313
+ }
314
+ if (is_block_pte(pte, level)) {
315
+ uint64_t block_size;
316
+ hwaddr gpa = get_block_pte_address(pte, level, granule_sz,
317
+ &block_size);
318
+
319
+ ap = PTE_AP(pte);
320
+ if (is_permission_fault(ap, perm)) {
321
+ info->type = SMMU_PTW_ERR_PERMISSION;
322
+ goto error;
323
+ }
324
+
325
+ trace_smmu_ptw_block_pte(stage, level, baseaddr,
326
+ pte_addr, pte, iova, gpa,
327
+ block_size >> 20);
328
+
329
+ tlbe->translated_addr = gpa + (iova & mask);
330
+ tlbe->perm = PTE_AP_TO_PERM(ap);
331
+ return 0;
332
+ }
333
+
334
+ /* table pte */
335
+ ap = PTE_APTABLE(pte);
336
+
337
+ if (is_permission_fault(ap, perm)) {
338
+ info->type = SMMU_PTW_ERR_PERMISSION;
339
+ goto error;
340
+ }
341
+ baseaddr = get_table_pte_address(pte, granule_sz);
342
+ level++;
343
+ }
344
+
345
+ info->type = SMMU_PTW_ERR_TRANSLATION;
346
+
347
+error:
348
+ tlbe->perm = IOMMU_NONE;
349
+ return -EINVAL;
350
+}
351
+
352
+/**
353
+ * smmu_ptw - Walk the page tables for an IOVA, according to @cfg
354
+ *
355
+ * @cfg: translation configuration
356
+ * @iova: iova to translate
357
+ * @perm: tentative access type
358
+ * @tlbe: returned entry
359
+ * @info: ptw event handle
360
+ *
361
+ * return 0 on success
362
+ */
363
+inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
364
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
365
+{
366
+ if (!cfg->aa64) {
367
+ /*
368
+ * This code path is not entered as we check this while decoding
369
+ * the configuration data in the derived SMMU model.
370
+ */
371
+ g_assert_not_reached();
372
+ }
373
+
374
+ return smmu_ptw_64(cfg, iova, perm, tlbe, info);
375
+}
376
377
/**
378
* The bus number is used for lookup when SID based invalidation occurs.
379
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
380
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/arm/trace-events
382
+++ b/hw/arm/trace-events
383
@@ -XXX,XX +XXX,XX @@
384
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
385
386
# hw/arm/smmu-common.c
387
-smmu_add_mr(const char *name) "%s"
388
\ No newline at end of file
389
+smmu_add_mr(const char *name) "%s"
390
+smmu_page_walk(int stage, uint64_t baseaddr, int first_level, uint64_t start, uint64_t end) "stage=%d, baseaddr=0x%"PRIx64", first level=%d, start=0x%"PRIx64", end=0x%"PRIx64
391
+smmu_lookup_table(int level, uint64_t baseaddr, int granule_sz, uint64_t start, uint64_t end, int flags, uint64_t subpage_size) "level=%d baseaddr=0x%"PRIx64" granule=%d, start=0x%"PRIx64" end=0x%"PRIx64" flags=%d subpage_size=0x%"PRIx64
392
+smmu_ptw_level(int level, uint64_t iova, size_t subpage_size, uint64_t baseaddr, uint32_t offset, uint64_t pte) "level=%d iova=0x%"PRIx64" subpage_sz=0x%lx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
393
+smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" offset=%d pte=0x%"PRIx64
394
+smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
395
+smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
396
+smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
397
--
57
--
398
2.17.0
58
2.20.1
399
59
400
60
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
With the exception of the ignore_memory_transaction_failures
4
flag set for the raspi2, both machine_class_init() methods
5
are now identical. Merge them to keep a unique method.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20200208165645.15657-13-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/raspi.c | 31 ++++++-------------------------
13
1 file changed, 6 insertions(+), 25 deletions(-)
14
15
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/raspi.c
18
+++ b/hw/arm/raspi.c
19
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_init(MachineState *machine)
20
setup_boot(machine, version, machine->ram_size - vcram_size);
21
}
22
23
-static void raspi2_machine_class_init(ObjectClass *oc, void *data)
24
+static void raspi_machine_class_init(ObjectClass *oc, void *data)
25
{
26
MachineClass *mc = MACHINE_CLASS(oc);
27
RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
28
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data)
29
mc->min_cpus = BCM283X_NCPUS;
30
mc->default_cpus = BCM283X_NCPUS;
31
mc->default_ram_size = board_ram_size(board_rev);
32
- mc->ignore_memory_transaction_failures = true;
33
+ if (board_version(board_rev) == 2) {
34
+ mc->ignore_memory_transaction_failures = true;
35
+ }
36
};
37
38
-#ifdef TARGET_AARCH64
39
-static void raspi3_machine_class_init(ObjectClass *oc, void *data)
40
-{
41
- MachineClass *mc = MACHINE_CLASS(oc);
42
- RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc);
43
- uint32_t board_rev = (uint32_t)(uintptr_t)data;
44
-
45
- rmc->board_rev = board_rev;
46
- mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev));
47
- mc->init = raspi_machine_init;
48
- mc->block_default_type = IF_SD;
49
- mc->no_parallel = 1;
50
- mc->no_floppy = 1;
51
- mc->no_cdrom = 1;
52
- mc->max_cpus = BCM283X_NCPUS;
53
- mc->min_cpus = BCM283X_NCPUS;
54
- mc->default_cpus = BCM283X_NCPUS;
55
- mc->default_ram_size = board_ram_size(board_rev);
56
-}
57
-#endif
58
-
59
static const TypeInfo raspi_machine_types[] = {
60
{
61
.name = MACHINE_TYPE_NAME("raspi2"),
62
.parent = TYPE_RASPI_MACHINE,
63
- .class_init = raspi2_machine_class_init,
64
+ .class_init = raspi_machine_class_init,
65
.class_data = (void *)0xa21041,
66
#ifdef TARGET_AARCH64
67
}, {
68
.name = MACHINE_TYPE_NAME("raspi3"),
69
.parent = TYPE_RASPI_MACHINE,
70
- .class_init = raspi3_machine_class_init,
71
+ .class_init = raspi_machine_class_init,
72
.class_data = (void *)0xa02082,
73
#endif
74
}, {
75
--
76
2.20.1
77
78
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
At the moment, the SMMUv3 does not support notification on
3
The count of ARM cores is encoded in the board revision. Add a
4
TLB invalidation. So let's log an error as soon as such notifier
4
helper to extract the number of cores, and use it. This will be
5
gets enabled.
5
helpful when we add the Raspi0/1 that have a single core.
6
6
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200208165645.15657-14-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-11-git-send-email-eric.auger@redhat.com
10
[PMM: tweaked commit message as suggested by Igor]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/arm/smmuv3.c | 11 +++++++++++
13
hw/arm/raspi.c | 19 ++++++++++++++++---
13
1 file changed, 11 insertions(+)
14
1 file changed, 16 insertions(+), 3 deletions(-)
14
15
15
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/smmuv3.c
18
--- a/hw/arm/raspi.c
18
+++ b/hw/arm/smmuv3.c
19
+++ b/hw/arm/raspi.c
19
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
20
@@ -XXX,XX +XXX,XX @@ static const char *board_soc_type(uint32_t board_rev)
20
dc->realize = smmu_realize;
21
return soc_types[proc_id];
21
}
22
}
22
23
23
+static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
24
+static int cores_count(uint32_t board_rev)
24
+ IOMMUNotifierFlag old,
25
+ IOMMUNotifierFlag new)
26
+{
25
+{
27
+ if (old == IOMMU_NOTIFIER_NONE) {
26
+ static const int soc_cores_count[] = {
28
+ warn_report("SMMUV3 does not support vhost/vfio integration yet: "
27
+ 0, BCM283X_NCPUS, BCM283X_NCPUS,
29
+ "devices of those types will not function properly");
28
+ };
29
+ int proc_id = board_processor_id(board_rev);
30
+
31
+ if (proc_id >= ARRAY_SIZE(soc_cores_count) || !soc_cores_count[proc_id]) {
32
+ error_report("Unsupported processor id '%d' (board revision: 0x%x)",
33
+ proc_id, board_rev);
34
+ exit(1);
30
+ }
35
+ }
36
+ return soc_cores_count[proc_id];
31
+}
37
+}
32
+
38
+
33
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
39
static const char *board_type(uint32_t board_rev)
34
void *data)
35
{
40
{
36
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
41
static const char *types[] = {
37
42
@@ -XXX,XX +XXX,XX @@ static void raspi_machine_class_init(ObjectClass *oc, void *data)
38
imrc->translate = smmuv3_translate;
43
mc->no_parallel = 1;
39
+ imrc->notify_flag_changed = smmuv3_notify_flag_changed;
44
mc->no_floppy = 1;
40
}
45
mc->no_cdrom = 1;
41
46
- mc->max_cpus = BCM283X_NCPUS;
42
static const TypeInfo smmuv3_type_info = {
47
- mc->min_cpus = BCM283X_NCPUS;
48
- mc->default_cpus = BCM283X_NCPUS;
49
+ mc->default_cpus = mc->min_cpus = mc->max_cpus = cores_count(board_rev);
50
mc->default_ram_size = board_ram_size(board_rev);
51
if (board_version(board_rev) == 2) {
52
mc->ignore_memory_transaction_failures = true;
43
--
53
--
44
2.17.0
54
2.20.1
45
55
46
56
diff view generated by jsdifflib
New patch
1
The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits:
1
2
3
* the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is
4
8 or 16 bits
5
* the VMID field in VTTBR_EL2 is extended to 16 bits
6
* VTCR_EL2.VS lets the guest specify whether to use the full 16 bits,
7
or use the backwards-compatible 8 bits
8
9
For QEMU implementing this is trivial:
10
* we do not track VMIDs in TLB entries, so we never use the VMID field
11
* we treat any write to VTTBR_EL2, not just a change to the VMID field
12
bits, as a "possible VMID change" that causes us to throw away TLB
13
entries, so that code doesn't need changing
14
* we allow the guest to read/write the VTCR_EL2.VS bit already
15
16
So all that's missing is the ID register part: report that we support
17
VMID16 in our 'max' CPU.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20200210120146.17631-1-peter.maydell@linaro.org
23
---
24
target/arm/cpu64.c | 1 +
25
1 file changed, 1 insertion(+)
26
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu64.c
30
+++ b/target/arm/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
32
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
33
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
34
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
35
+ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
36
cpu->isar.id_aa64mmfr1 = t;
37
38
t = cpu->isar.id_aa64mmfr2;
39
--
40
2.20.1
41
42
diff view generated by jsdifflib