From 0e7bb14b564b6eef9aa0eed45df47babcdcaba12 Mon Sep 17 00:00:00 2001 From: Roman Kapl Date: Fri, 7 Feb 2020 10:54:09 +0100 Subject: [PATCH 01/46] i.MX: Fix inverted register bits in wdt code. Documentation says for WDA '0: Assert WDOG output.' and for SRS '0: Assert system reset signal.'. Signed-off-by: Roman Kapl Message-id: 20200207095409.11227-1-rka@sysgo.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/misc/imx2_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c index 5576778a32..2aedfe803a 100644 --- a/hw/misc/imx2_wdt.c +++ b/hw/misc/imx2_wdt.c @@ -29,7 +29,7 @@ static void imx2_wdt_write(void *opaque, hwaddr addr, uint64_t value, unsigned int size) { if (addr == IMX2_WDT_WCR && - (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) { + (~value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) { watchdog_perform_action(); } } From 5fecbf0f0cc9168da1b003a115ac18fe722f293a Mon Sep 17 00:00:00 2001 From: Roman Kapl Date: Fri, 7 Feb 2020 10:55:29 +0100 Subject: [PATCH 02/46] i.MX: Add support for WDT on i.MX6 Uses the i.MX2 rudimentary watchdog driver. Signed-off-by: Roman Kapl Message-id: 20200207095529.11309-1-rka@sysgo.com Reviewed-by: Peter Maydell [PMM: removed accidental duplicate #include line] Signed-off-by: Peter Maydell --- hw/arm/fsl-imx6.c | 21 +++++++++++++++++++++ include/hw/arm/fsl-imx6.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index 552145b24e..ecc62855f2 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -91,6 +91,12 @@ static void fsl_imx6_init(Object *obj) sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI); } + for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) { + snprintf(name, NAME_SIZE, "wdt%d", i); + sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]), + TYPE_IMX2_WDT); + } + sysbus_init_child_obj(obj, "eth", &s->eth, sizeof(s->eth), TYPE_IMX_ENET); } @@ -383,6 +389,21 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_ENET_MAC_1588_IRQ)); + /* + * Watchdog + */ + for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) { + static const hwaddr FSL_IMX6_WDOGn_ADDR[FSL_IMX6_NUM_WDTS] = { + FSL_IMX6_WDOG1_ADDR, + FSL_IMX6_WDOG2_ADDR, + }; + + object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", + &error_abort); + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX6_WDOGn_ADDR[i]); + } + /* ROM memory */ memory_region_init_rom(&s->rom, NULL, "imx6.rom", FSL_IMX6_ROM_SIZE, &err); diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h index 1265a55c3b..60eadccb42 100644 --- a/include/hw/arm/fsl-imx6.h +++ b/include/hw/arm/fsl-imx6.h @@ -21,6 +21,7 @@ #include "hw/cpu/a9mpcore.h" #include "hw/misc/imx6_ccm.h" #include "hw/misc/imx6_src.h" +#include "hw/misc/imx2_wdt.h" #include "hw/char/imx_serial.h" #include "hw/timer/imx_gpt.h" #include "hw/timer/imx_epit.h" @@ -42,6 +43,7 @@ #define FSL_IMX6_NUM_GPIOS 7 #define FSL_IMX6_NUM_ESDHCS 4 #define FSL_IMX6_NUM_ECSPIS 5 +#define FSL_IMX6_NUM_WDTS 2 typedef struct FslIMX6State { /*< private >*/ @@ -59,6 +61,7 @@ typedef struct FslIMX6State { IMXGPIOState gpio[FSL_IMX6_NUM_GPIOS]; SDHCIState esdhc[FSL_IMX6_NUM_ESDHCS]; IMXSPIState spi[FSL_IMX6_NUM_ECSPIS]; + IMX2WdtState wdt[FSL_IMX6_NUM_WDTS]; IMXFECState eth; MemoryRegion rom; MemoryRegion caam; From 4ac637ef8439827d8db4a807c81df978a8c772c4 Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:19 +0800 Subject: [PATCH 03/46] bios-tables-test: prepare to change ARM virt ACPI DSDT We are going to change ARM virt ACPI DSDT table, which will cause make check to fail, so temporarily add related golden masters to ignore list. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-2-guoheyi@huawei.com Signed-off-by: Peter Maydell --- tests/qtest/bios-tables-test-allowed-diff.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..32a401ae35 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,4 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/virt/DSDT", +"tests/data/acpi/virt/DSDT.memhp", +"tests/data/acpi/virt/DSDT.numamem", From cf48a9052e82b8fff57c2f2e2d53dee6496ee133 Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:20 +0800 Subject: [PATCH 04/46] arm/virt/acpi: remove meaningless sub device "RP0" from PCI0 The sub device "RP0" under PCI0 in ACPI/DSDT does not contain any method or property other than "_ADR", so it is safe to remove it. Signed-off-by: Heyi Guo Acked-by: "Michael S. Tsirkin" Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-3-guoheyi@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index bd5f771e9b..9f4c7d1889 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -317,10 +317,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(method, aml_return(buf)); aml_append(dev, method); - Aml *dev_rp0 = aml_device("%s", "RP0"); - aml_append(dev_rp0, aml_name_decl("_ADR", aml_int(0))); - aml_append(dev, dev_rp0); - Aml *dev_res0 = aml_device("%s", "RES0"); aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02"))); crs = aml_resource_template(); From 93e41700012525ca198d10c586e024b925779e6d Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:21 +0800 Subject: [PATCH 05/46] arm/virt/acpi: remove _ADR from devices identified by _HID According to ACPI spec, _ADR should be used for device on a bus that has a standard enumeration algorithm, but not for device which is on system bus and must be enumerated by OSPM. And it is not recommended to contain both _HID and _ADR in a single device. See ACPI 6.3, section 6.1, top of page 343: A device object must contain either an _HID object or an _ADR object, but should not contain both. (https://uefi.org/sites/default/files/resources/ACPI_6_3_May16.pdf) Signed-off-by: Heyi Guo Acked-by: Igor Mammedov Acked-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-4-guoheyi@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 9f4c7d1889..be752c0ad8 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -78,11 +78,6 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, AML_EXCLUSIVE, &uart_irq, 1)); aml_append(dev, aml_name_decl("_CRS", crs)); - /* The _ADR entry is used to link this device to the UART described - * in the SPCR table, i.e. SPCR.base_address.address == _ADR. - */ - aml_append(dev, aml_name_decl("_ADR", aml_int(uart_memmap->base))); - aml_append(scope, dev); } @@ -170,7 +165,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03"))); aml_append(dev, aml_name_decl("_SEG", aml_int(0))); aml_append(dev, aml_name_decl("_BBN", aml_int(0))); - aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_string("PCI0"))); aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device"))); aml_append(dev, aml_name_decl("_CCA", aml_int(1))); @@ -334,7 +328,6 @@ static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, { Aml *dev = aml_device("GPO0"); aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061"))); - aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_int(0))); Aml *crs = aml_resource_template(); @@ -364,7 +357,6 @@ static void acpi_dsdt_add_power_button(Aml *scope) { Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE); aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C"))); - aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(dev, aml_name_decl("_UID", aml_int(0))); aml_append(scope, dev); } From c77b25315941250163d3c226266db584ebf7f3e8 Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:22 +0800 Subject: [PATCH 06/46] arm/acpi: fix PCI _PRT definition The address field in each _PRT mapping package should be constructed with high word for device# and low word for function#, so it is wrong to use bus_no as the high word. The existing code adds a bunch useless entries with device #s above 31. Enumerate all possible slots (i.e. PCI_SLOT_MAX) instead. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-5-guoheyi@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index be752c0ad8..5d157a9dd5 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -151,7 +151,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, { int ecam_id = VIRT_ECAM_ID(highmem_ecam); Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; - int i, bus_no; + int i, slot_no; hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base; hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size; hwaddr base_pio = memmap[VIRT_PCIE_PIO].base; @@ -170,12 +170,12 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, aml_append(dev, aml_name_decl("_CCA", aml_int(1))); /* Declare the PCI Routing Table. */ - Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS); - for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) { + Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS); + for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) { for (i = 0; i < PCI_NUM_PINS; i++) { - int gsi = (i + bus_no) % PCI_NUM_PINS; + int gsi = (i + slot_no) % PCI_NUM_PINS; Aml *pkg = aml_package(4); - aml_append(pkg, aml_int((bus_no << 16) | 0xFFFF)); + aml_append(pkg, aml_int((slot_no << 16) | 0xFFFF)); aml_append(pkg, aml_int(i)); aml_append(pkg, aml_name("GSI%d", gsi)); aml_append(pkg, aml_int(0)); From f0ca15ad8954bad5baf8a7d5f625dd810616b53c Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:23 +0800 Subject: [PATCH 07/46] arm/acpi: fix duplicated _UID of PCI interrupt link devices Using _UID of 0 for all PCI interrupt link devices absolutely violates the spec. Simply increase one by one. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-6-guoheyi@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 5d157a9dd5..f3e340b172 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -189,7 +189,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, uint32_t irqs = irq + i; Aml *dev_gsi = aml_device("GSI%d", i); aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F"))); - aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0))); + aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i))); crs = aml_resource_template(); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, From b43bd40ba27c3a9ebd246f7294dc8983d96fe7e4 Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:24 +0800 Subject: [PATCH 08/46] arm/acpi: simplify the description of PCI _CRS The original code defines a named object for the resource template but then returns the resource template object itself; the resulted output is like below: Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, // Granularity 0x0000, // Range Minimum 0x00FF, // Range Maximum 0x0000, // Translation Offset 0x0100, // Length ,, ) ...... }) Return (ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, // Granularity 0x0000, // Range Minimum 0x00FF, // Range Maximum 0x0000, // Translation Offset 0x0100, // Length ,, ) ...... }) } So the named object "RBUF" is actually useless. The more natural way is to return RBUF instead, or simply drop RBUF definition. Choose the latter one to simplify the code. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-7-guoheyi@huawei.com Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index f3e340b172..fb4b166f82 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -236,7 +236,6 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, size_mmio_high)); } - aml_append(method, aml_name_decl("RBUF", rbuf)); aml_append(method, aml_return(rbuf)); aml_append(dev, method); From 979a89023f40a89c67f68566c26b22b0e903b95e Mon Sep 17 00:00:00 2001 From: Heyi Guo Date: Tue, 4 Feb 2020 09:43:25 +0800 Subject: [PATCH 09/46] virt/acpi: update golden masters for DSDT update Differences between disassembled ASL files: @@ -5,13 +5,13 @@ * * Disassembling to symbolic ASL+ operators * - * Disassembly of DSDT, Thu Jan 23 16:00:04 2020 + * Disassembly of DSDT.new, Thu Jan 23 16:47:12 2020 * * Original Table Header: * Signature "DSDT" - * Length 0x0000481E (18462) + * Length 0x000014BB (5307) * Revision 0x02 - * Checksum 0x60 + * Checksum 0xD1 * OEM ID "BOCHS " * OEM Table ID "BXPCDSDT" * OEM Revision 0x00000001 (1) @@ -43,7 +43,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) 0x00000021, } }) - Name (_ADR, 0x09000000) // _ADR: Address } Device (FLS0) @@ -668,11 +667,10 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Name (_CID, "PNP0A03" /* PCI Bus */) // _CID: Compatible ID Name (_SEG, Zero) // _SEG: PCI Segment Name (_BBN, Zero) // _BBN: BIOS Bus Number - Name (_ADR, Zero) // _ADR: Address Name (_UID, "PCI0") // _UID: Unique ID Name (_STR, Unicode ("PCIe 0 Device")) // _STR: Description String Name (_CCA, One) // _CCA: Cache Coherency Attribute - Name (_PRT, Package (0x0400) // _PRT: PCI Routing Table + Name (_PRT, Package (0x80) // _PRT: PCI Routing Table { Package (0x04) { @@ -1696,7174 +1694,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) 0x03, GSI2, Zero - }, - - Package (0x04) - { - 0x0020FFFF, - Zero, - GSI0, - Zero - }, - - *Omit the other (4 * (256 - 32) - 2) packages* - - Package (0x04) - { - 0x00FFFFFF, - 0x03, - GSI2, - Zero } }) Device (GSI0) @@ -8892,7 +1722,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Device (GSI1) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID - Name (_UID, Zero) // _UID: Unique ID + Name (_UID, One) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8915,7 +1745,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Device (GSI2) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID - Name (_UID, Zero) // _UID: Unique ID + Name (_UID, 0x02) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8938,7 +1768,7 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Device (GSI3) { Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */) // _HID: Hardware ID - Name (_UID, Zero) // _UID: Unique ID + Name (_UID, 0x03) // _UID: Unique ID Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) @@ -8965,37 +1795,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { - Name (RBUF, ResourceTemplate () - { - WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, - 0x0000, // Granularity - 0x0000, // Range Minimum - 0x00FF, // Range Maximum - 0x0000, // Translation Offset - 0x0100, // Length - ,, ) - DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, - 0x00000000, // Granularity - 0x10000000, // Range Minimum - 0x3EFEFFFF, // Range Maximum - 0x00000000, // Translation Offset - 0x2EFF0000, // Length - ,, , AddressRangeMemory, TypeStatic) - DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, - 0x00000000, // Granularity - 0x00000000, // Range Minimum - 0x0000FFFF, // Range Maximum - 0x3EFF0000, // Translation Offset - 0x00010000, // Length - ,, , TypeStatic, DenseTranslation) - QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, - 0x0000000000000000, // Granularity - 0x0000008000000000, // Range Minimum - 0x000000FFFFFFFFFF, // Range Maximum - 0x0000000000000000, // Translation Offset - 0x0000008000000000, // Length - ,, , AddressRangeMemory, TypeStatic) - }) Return (ResourceTemplate () { WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, @@ -9080,11 +1879,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) }) } - Device (RP0) - { - Name (_ADR, Zero) // _ADR: Address - } - Device (RES0) { Name (_HID, "PNP0C02" /* PNP Motherboard Resources */) // _HID: Hardware ID @@ -9131,7 +1925,6 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPCDSDT", 0x00000001) Device (PWRB) { Name (_HID, "PNP0C0C" /* Power Button Device */) // _HID: Hardware ID - Name (_ADR, Zero) // _ADR: Address Name (_UID, Zero) // _UID: Unique ID } } The differences between the two versions of DSDT.memhp are almost the same as the above, except for total length and checksum. DSDT.numamem binary is just the same with DSDT on virt machine, so we don't show the differences again. Signed-off-by: Heyi Guo Reviewed-by: Michael S. Tsirkin Message-id: 20200204014325.16279-8-guoheyi@huawei.com Signed-off-by: Peter Maydell --- tests/data/acpi/virt/DSDT | Bin 18462 -> 5307 bytes tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 6644 bytes tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 5307 bytes tests/qtest/bios-tables-test-allowed-diff.h | 3 --- 4 files changed, 3 deletions(-) diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT index d0f3afeb134fdf1c11f64cd06dbcdd30be603b80..d6f5c617881c4247f55d4dcd06581f9693916b2f 100644 GIT binary patch delta 156 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 A00000 diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp index 41ccc6431b917252bcbaac86c33b340c796be5ce..c527ac4739af3df3c3e042bf91c412033a2b73c3 100644 GIT binary patch delta 173 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 DDbP3` diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem index d0f3afeb134fdf1c11f64cd06dbcdd30be603b80..d6f5c617881c4247f55d4dcd06581f9693916b2f 100644 GIT binary patch delta 156 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 A00000 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 32a401ae35..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,4 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/virt/DSDT", -"tests/data/acpi/virt/DSDT.memhp", -"tests/data/acpi/virt/DSDT.numamem", From fee7aa46edd76f06c3dc176abb8fd05b365efce6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:57:57 +0000 Subject: [PATCH 10/46] target/arm: Add arm_mmu_idx_is_stage1_of_2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a common predicate for querying stage1-ness. Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-2-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 8 +++----- target/arm/internals.h | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 7d15d5c933..57dc7a307c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3261,8 +3261,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, bool take_exc = false; if (fi.s1ptw && current_el == 1 && !arm_is_secure(env) - && (mmu_idx == ARMMMUIdx_Stage1_E1 || - mmu_idx == ARMMMUIdx_Stage1_E0)) { + && arm_mmu_idx_is_stage1_of_2(mmu_idx)) { /* * Synchronous stage 2 fault on an access made as part of the * translation table walk for AT S1E0* or AT S1E1* insn @@ -9285,8 +9284,7 @@ static inline bool regime_translation_disabled(CPUARMState *env, } } - if ((env->cp15.hcr_el2 & HCR_DC) && - (mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1)) { + if ((env->cp15.hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) { /* HCR.DC means SCTLR_EL1.M behaves as 0 */ return true; } @@ -9595,7 +9593,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, hwaddr addr, MemTxAttrs txattrs, ARMMMUFaultInfo *fi) { - if ((mmu_idx == ARMMMUIdx_Stage1_E0 || mmu_idx == ARMMMUIdx_Stage1_E1) && + if (arm_mmu_idx_is_stage1_of_2(mmu_idx) && !regime_translation_disabled(env, ARMMMUIdx_Stage2)) { target_ulong s2size; hwaddr s2pa; diff --git a/target/arm/internals.h b/target/arm/internals.h index 6d4a942bde..1f8ee5f573 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1034,6 +1034,24 @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env) ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env); #endif +/** + * arm_mmu_idx_is_stage1_of_2: + * @mmu_idx: The ARMMMUIdx to test + * + * Return true if @mmu_idx is a NOTLB mmu_idx that is the + * first stage of a two stage regime. + */ +static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_Stage1_E0: + case ARMMMUIdx_Stage1_E1: + return true; + default: + return false; + } +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. From 452ef8cb8c7b06f44a30a3c3a54d3be82c4aef59 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:57:58 +0000 Subject: [PATCH 11/46] target/arm: Add mmu_idx for EL1 and EL2 w/ PAN enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To implement PAN, we will want to swap, for short periods of time, to a different privileged mmu_idx. In addition, we cannot do this with flushing alone, because the AT* instructions have both PAN and PAN-less versions. Add the ARMMMUIdx*_PAN constants where necessary next to the corresponding ARMMMUIdx* constant. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 2 +- target/arm/cpu.h | 33 ++++++++++++++------- target/arm/helper.c | 60 +++++++++++++++++++++++++++++++------- target/arm/internals.h | 9 ++++++ target/arm/translate-a64.c | 3 ++ target/arm/translate.c | 2 ++ 6 files changed, 87 insertions(+), 22 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index 18ac562346..d593b60b28 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -29,6 +29,6 @@ # define TARGET_PAGE_BITS_MIN 10 #endif -#define NB_MMU_MODES 9 +#define NB_MMU_MODES 12 #endif diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0b3036c484..c63bceaaa5 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2751,20 +2751,24 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync); * 5. we want to be able to use the TLB for accesses done as part of a * stage1 page table walk, rather than having to walk the stage2 page * table over and over. + * 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access + * Never (PAN) bit within PSTATE. * * This gives us the following list of cases: * * NS EL0 EL1&0 stage 1+2 (aka NS PL0) * NS EL1 EL1&0 stage 1+2 (aka NS PL1) + * NS EL1 EL1&0 stage 1+2 +PAN * NS EL0 EL2&0 - * NS EL2 EL2&0 + * NS EL2 EL2&0 +PAN * NS EL2 (aka NS PL2) * S EL0 EL1&0 (aka S PL0) * S EL1 EL1&0 (not used if EL3 is 32 bit) + * S EL1 EL1&0 +PAN * S EL3 (aka S PL1) * NS EL1&0 stage 2 * - * for a total of 9 different mmu_idx. + * for a total of 12 different mmu_idx. * * R profile CPUs have an MPU, but can use the same set of MMU indexes * as A profile. They only need to distinguish NS EL0 and NS EL1 (and @@ -2819,19 +2823,22 @@ typedef enum ARMMMUIdx { /* * A-profile. */ - ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A, - ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A, + ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A, + ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A, - ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A, + ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A, + ARMMMUIdx_E10_1_PAN = 3 | ARM_MMU_IDX_A, - ARMMMUIdx_E2 = 3 | ARM_MMU_IDX_A, - ARMMMUIdx_E20_2 = 4 | ARM_MMU_IDX_A, + ARMMMUIdx_E2 = 4 | ARM_MMU_IDX_A, + ARMMMUIdx_E20_2 = 5 | ARM_MMU_IDX_A, + ARMMMUIdx_E20_2_PAN = 6 | ARM_MMU_IDX_A, - ARMMMUIdx_SE10_0 = 5 | ARM_MMU_IDX_A, - ARMMMUIdx_SE10_1 = 6 | ARM_MMU_IDX_A, - ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A, + ARMMMUIdx_SE10_0 = 7 | ARM_MMU_IDX_A, + ARMMMUIdx_SE10_1 = 8 | ARM_MMU_IDX_A, + ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A, + ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A, - ARMMMUIdx_Stage2 = 8 | ARM_MMU_IDX_A, + ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A, /* * These are not allocated TLBs and are used only for AT system @@ -2839,6 +2846,7 @@ typedef enum ARMMMUIdx { */ ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB, ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB, + ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB, /* * M-profile. @@ -2864,10 +2872,13 @@ typedef enum ARMMMUIdxBit { TO_CORE_BIT(E10_0), TO_CORE_BIT(E20_0), TO_CORE_BIT(E10_1), + TO_CORE_BIT(E10_1_PAN), TO_CORE_BIT(E2), TO_CORE_BIT(E20_2), + TO_CORE_BIT(E20_2_PAN), TO_CORE_BIT(SE10_0), TO_CORE_BIT(SE10_1), + TO_CORE_BIT(SE10_1_PAN), TO_CORE_BIT(SE3), TO_CORE_BIT(Stage2), diff --git a/target/arm/helper.c b/target/arm/helper.c index 57dc7a307c..bfd6c0d04b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -671,6 +671,7 @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | ARMMMUIdxBit_E10_0 | ARMMMUIdxBit_Stage2); } @@ -682,6 +683,7 @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | ARMMMUIdxBit_E10_0 | ARMMMUIdxBit_Stage2); } @@ -2700,6 +2702,7 @@ static int gt_phys_redir_timeridx(CPUARMState *env) switch (arm_mmu_idx(env)) { case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: return GTIMER_HYP; default: return GTIMER_PHYS; @@ -2711,6 +2714,7 @@ static int gt_virt_redir_timeridx(CPUARMState *env) switch (arm_mmu_idx(env)) { case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: return GTIMER_HYPVIRT; default: return GTIMER_VIRT; @@ -3337,7 +3341,9 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, format64 = arm_s1_regime_using_lpae_format(env, mmu_idx); if (arm_feature(env, ARM_FEATURE_EL2)) { - if (mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_E10_1) { + if (mmu_idx == ARMMMUIdx_E10_0 || + mmu_idx == ARMMMUIdx_E10_1 || + mmu_idx == ARMMMUIdx_E10_1_PAN) { format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC); } else { format64 |= arm_current_el(env) == 2; @@ -3797,7 +3803,9 @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri, if (extract64(raw_read(env, ri) ^ value, 48, 16) && (arm_hcr_el2_eff(env) & HCR_E2H)) { tlb_flush_by_mmuidx(env_cpu(env), - ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E20_0); + ARMMMUIdxBit_E20_2 | + ARMMMUIdxBit_E20_2_PAN | + ARMMMUIdxBit_E20_0); } raw_write(env, ri, value); } @@ -3815,6 +3823,7 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, if (raw_read(env, ri) != value) { tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | ARMMMUIdxBit_E10_0 | ARMMMUIdxBit_Stage2); raw_write(env, ri, value); @@ -4175,12 +4184,18 @@ static int vae1_tlbmask(CPUARMState *env) { /* Since we exclude secure first, we may read HCR_EL2 directly. */ if (arm_is_secure_below_el3(env)) { - return ARMMMUIdxBit_SE10_1 | ARMMMUIdxBit_SE10_0; + return ARMMMUIdxBit_SE10_1 | + ARMMMUIdxBit_SE10_1_PAN | + ARMMMUIdxBit_SE10_0; } else if ((env->cp15.hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) { - return ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E20_0; + return ARMMMUIdxBit_E20_2 | + ARMMMUIdxBit_E20_2_PAN | + ARMMMUIdxBit_E20_0; } else { - return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0; + return ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | + ARMMMUIdxBit_E10_0; } } @@ -4214,18 +4229,28 @@ static int alle1_tlbmask(CPUARMState *env) * stage 1 translations. */ if (arm_is_secure_below_el3(env)) { - return ARMMMUIdxBit_SE10_1 | ARMMMUIdxBit_SE10_0; + return ARMMMUIdxBit_SE10_1 | + ARMMMUIdxBit_SE10_1_PAN | + ARMMMUIdxBit_SE10_0; } else if (arm_feature(env, ARM_FEATURE_EL2)) { - return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0 | ARMMMUIdxBit_Stage2; + return ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | + ARMMMUIdxBit_E10_0 | + ARMMMUIdxBit_Stage2; } else { - return ARMMMUIdxBit_E10_1 | ARMMMUIdxBit_E10_0; + return ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | + ARMMMUIdxBit_E10_0; } } static int e2_tlbmask(CPUARMState *env) { /* TODO: ARMv8.4-SecEL2 */ - return ARMMMUIdxBit_E20_0 | ARMMMUIdxBit_E20_2 | ARMMMUIdxBit_E2; + return ARMMMUIdxBit_E20_0 | + ARMMMUIdxBit_E20_2 | + ARMMMUIdxBit_E20_2_PAN | + ARMMMUIdxBit_E2; } static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -9206,6 +9231,7 @@ static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: case ARMMMUIdx_Stage2: case ARMMMUIdx_E2: return 2; @@ -9214,10 +9240,13 @@ static uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) case ARMMMUIdx_SE10_0: return arm_el_is_aa64(env, 3) ? 1 : 3; case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: case ARMMMUIdx_Stage1_E0: case ARMMMUIdx_Stage1_E1: + case ARMMMUIdx_Stage1_E1_PAN: case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_MPrivNegPri: case ARMMMUIdx_MUserNegPri: case ARMMMUIdx_MPriv: @@ -9333,6 +9362,8 @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx) return ARMMMUIdx_Stage1_E0; case ARMMMUIdx_E10_1: return ARMMMUIdx_Stage1_E1; + case ARMMMUIdx_E10_1_PAN: + return ARMMMUIdx_Stage1_E1_PAN; default: return mmu_idx; } @@ -9379,6 +9410,7 @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) return false; case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: g_assert_not_reached(); } } @@ -11271,7 +11303,9 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, target_ulong *page_size, ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs) { - if (mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_E10_1) { + if (mmu_idx == ARMMMUIdx_E10_0 || + mmu_idx == ARMMMUIdx_E10_1 || + mmu_idx == ARMMMUIdx_E10_1_PAN) { /* Call ourselves recursively to do the stage 1 and then stage 2 * translations. */ @@ -11798,10 +11832,13 @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) case ARMMMUIdx_SE10_0: return 0; case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: return 1; case ARMMMUIdx_E2: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: return 2; case ARMMMUIdx_SE3: return 3; @@ -12018,11 +12055,14 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, /* TODO: ARMv8.2-UAO */ switch (mmu_idx) { case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: /* TODO: ARMv8.3-NV */ flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); break; case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: /* TODO: ARMv8.4-SecEL2 */ /* * Note that E20_2 is gated by HCR_EL2.E2H == 1, but E20_0 is diff --git a/target/arm/internals.h b/target/arm/internals.h index 1f8ee5f573..6be8b2d1a9 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -843,12 +843,16 @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_Stage1_E0: case ARMMMUIdx_Stage1_E1: + case ARMMMUIdx_Stage1_E1_PAN: case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: case ARMMMUIdx_SE10_0: case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: return true; default: return false; @@ -861,10 +865,13 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: case ARMMMUIdx_E20_0: case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: case ARMMMUIdx_Stage1_E0: case ARMMMUIdx_Stage1_E1: + case ARMMMUIdx_Stage1_E1_PAN: case ARMMMUIdx_E2: case ARMMMUIdx_Stage2: case ARMMMUIdx_MPrivNegPri: @@ -875,6 +882,7 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) case ARMMMUIdx_SE3: case ARMMMUIdx_SE10_0: case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: case ARMMMUIdx_MSPrivNegPri: case ARMMMUIdx_MSUserNegPri: case ARMMMUIdx_MSPriv: @@ -1046,6 +1054,7 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) switch (mmu_idx) { case ARMMMUIdx_Stage1_E0: case ARMMMUIdx_Stage1_E1: + case ARMMMUIdx_Stage1_E1_PAN: return true; default: return false; diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 6e82486884..49631c2340 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -124,12 +124,15 @@ static int get_a64_user_mem_index(DisasContext *s) */ switch (useridx) { case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: useridx = ARMMMUIdx_E10_0; break; case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: useridx = ARMMMUIdx_E20_0; break; case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: useridx = ARMMMUIdx_SE10_0; break; default: diff --git a/target/arm/translate.c b/target/arm/translate.c index e11a5871d0..d58c328e08 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -155,10 +155,12 @@ static inline int get_a32_user_mem_index(DisasContext *s) case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */ case ARMMMUIdx_E10_0: case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: return arm_to_core_mmu_idx(ARMMMUIdx_E10_0); case ARMMMUIdx_SE3: case ARMMMUIdx_SE10_0: case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0); case ARMMMUIdx_MUser: case ARMMMUIdx_MPriv: From 3d6ad6bb466f487bcc861f99e2c9054230df1076 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:57:59 +0000 Subject: [PATCH 12/46] target/arm: Add isar_feature tests for PAN + ATS1E1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include definitions for all of the bits in ID_MMFR3. We already have a definition for ID_AA64MMFR1.PAN. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c63bceaaa5..08b2f5d73e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1727,6 +1727,15 @@ FIELD(ID_ISAR6, FHM, 8, 4) FIELD(ID_ISAR6, SB, 12, 4) FIELD(ID_ISAR6, SPECRES, 16, 4) +FIELD(ID_MMFR3, CMAINTVA, 0, 4) +FIELD(ID_MMFR3, CMAINTSW, 4, 4) +FIELD(ID_MMFR3, BPMAINT, 8, 4) +FIELD(ID_MMFR3, MAINTBCST, 12, 4) +FIELD(ID_MMFR3, PAN, 16, 4) +FIELD(ID_MMFR3, COHWALK, 20, 4) +FIELD(ID_MMFR3, CMEMSZ, 24, 4) +FIELD(ID_MMFR3, SUPERSEC, 28, 4) + FIELD(ID_MMFR4, SPECSEI, 0, 4) FIELD(ID_MMFR4, AC2, 4, 4) FIELD(ID_MMFR4, XNX, 8, 4) @@ -3443,6 +3452,16 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id) return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4; } +static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) +{ + return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) != 0; +} + +static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) +{ + return FIELD_EX64(id->mvfr0, ID_MMFR3, PAN) >= 2; +} + /* * 64-bit feature tests via id registers. */ @@ -3602,6 +3621,16 @@ static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; } +static inline bool isar_feature_aa64_pan(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0; +} + +static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; +} + static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; From d8564ee4e5bce87ec1fdf23656df9367eb1bc571 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:00 +0000 Subject: [PATCH 13/46] target/arm: Move LOR regdefs to file scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For static const regdefs, file scope is preferred. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 57 +++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index bfd6c0d04b..e4f17c7e83 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6334,6 +6334,35 @@ static CPAccessResult access_lor_other(CPUARMState *env, return access_lor_ns(env); } +/* + * A trivial implementation of ARMv8.1-LOR leaves all of these + * registers fixed at 0, which indicates that there are zero + * supported Limited Ordering regions. + */ +static const ARMCPRegInfo lor_reginfo[] = { + { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, + .access = PL1_R, .accessfn = access_lorid, + .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL +}; + #ifdef TARGET_AARCH64 static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7568,34 +7597,6 @@ void register_cp_regs_for_features(ARMCPU *cpu) } if (cpu_isar_feature(aa64_lor, cpu)) { - /* - * A trivial implementation of ARMv8.1-LOR leaves all of these - * registers fixed at 0, which indicates that there are zero - * supported Limited Ordering regions. - */ - static const ARMCPRegInfo lor_reginfo[] = { - { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, - .access = PL1_RW, .accessfn = access_lor_other, - .type = ARM_CP_CONST, .resetvalue = 0 }, - { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, - .access = PL1_R, .accessfn = access_lorid, - .type = ARM_CP_CONST, .resetvalue = 0 }, - REGINFO_SENTINEL - }; define_arm_cp_regs(cpu, lor_reginfo); } From 4f9584ed4bba8a57a3cb2fa48a682725005d530a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:01 +0000 Subject: [PATCH 14/46] target/arm: Split out aarch32_cpsr_valid_mask Split this helper out of msr_mask in translate.c. At the same time, transform the negative reductive logic to positive accumulative logic. It will be usable along the exception paths. While touching msr_mask, fix up formatting. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 21 +++++++++++++++++++++ target/arm/translate.c | 40 +++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 6be8b2d1a9..4d4896fcdc 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1061,6 +1061,27 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) } } +static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, + const ARMISARegisters *id) +{ + uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J; + + if ((features >> ARM_FEATURE_V4T) & 1) { + valid |= CPSR_T; + } + if ((features >> ARM_FEATURE_V5) & 1) { + valid |= CPSR_Q; /* V5TE in reality*/ + } + if ((features >> ARM_FEATURE_V6) & 1) { + valid |= CPSR_E | CPSR_GE; + } + if ((features >> ARM_FEATURE_THUMB2) & 1) { + valid |= CPSR_IT; + } + + return valid; +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. diff --git a/target/arm/translate.c b/target/arm/translate.c index d58c328e08..20f89ace2f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -2734,39 +2734,33 @@ static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) /* Return the mask of PSR bits set by a MSR instruction. */ static uint32_t msr_mask(DisasContext *s, int flags, int spsr) { - uint32_t mask; + uint32_t mask = 0; - mask = 0; - if (flags & (1 << 0)) + if (flags & (1 << 0)) { mask |= 0xff; - if (flags & (1 << 1)) + } + if (flags & (1 << 1)) { mask |= 0xff00; - if (flags & (1 << 2)) + } + if (flags & (1 << 2)) { mask |= 0xff0000; - if (flags & (1 << 3)) + } + if (flags & (1 << 3)) { mask |= 0xff000000; + } - /* Mask out undefined bits. */ - mask &= ~CPSR_RESERVED; - if (!arm_dc_feature(s, ARM_FEATURE_V4T)) { - mask &= ~CPSR_T; - } - if (!arm_dc_feature(s, ARM_FEATURE_V5)) { - mask &= ~CPSR_Q; /* V5TE in reality*/ - } - if (!arm_dc_feature(s, ARM_FEATURE_V6)) { - mask &= ~(CPSR_E | CPSR_GE); - } - if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) { - mask &= ~CPSR_IT; - } - /* Mask out execution state and reserved bits. */ + /* Mask out undefined and reserved bits. */ + mask &= aarch32_cpsr_valid_mask(s->features, s->isar); + + /* Mask out execution state. */ if (!spsr) { - mask &= ~(CPSR_EXEC | CPSR_RESERVED); + mask &= ~CPSR_EXEC; } + /* Mask out privileged bits. */ - if (IS_USER(s)) + if (IS_USER(s)) { mask &= CPSR_USER; + } return mask; } From f062d1447f2a80e7a5f593b8cb5ac7cab5e16eb0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:02 +0000 Subject: [PATCH 15/46] target/arm: Mask CPSR_J when Jazelle is not enabled The J bit signals Jazelle mode, and so of course is RES0 when the feature is not enabled. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/arm/internals.h b/target/arm/internals.h index 4d4896fcdc..0569c96fd9 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1064,7 +1064,7 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, const ARMISARegisters *id) { - uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J; + uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV; if ((features >> ARM_FEATURE_V4T) & 1) { valid |= CPSR_T; @@ -1078,6 +1078,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, if ((features >> ARM_FEATURE_THUMB2) & 1) { valid |= CPSR_IT; } + if (isar_feature_jazelle(id)) { + valid |= CPSR_J; + } return valid; } From 437864216d63f052f3cd06ec8861d0e432496424 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:03 +0000 Subject: [PATCH 16/46] target/arm: Replace CPSR_ERET_MASK with aarch32_cpsr_valid_mask CPSR_ERET_MASK was a useless renaming of CPSR_RESERVED. The function also takes into account bits that the cpu does not support. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 -- target/arm/op_helper.c | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 08b2f5d73e..694b074298 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1209,8 +1209,6 @@ void pmu_init(ARMCPU *cpu); #define CPSR_USER (CPSR_NZCV | CPSR_Q | CPSR_GE) /* Execution state bits. MRS read as zero, MSR writes ignored. */ #define CPSR_EXEC (CPSR_T | CPSR_IT | CPSR_J | CPSR_IL) -/* Mask of bits which may be set by exception return copying them from SPSR */ -#define CPSR_ERET_MASK (~CPSR_RESERVED) /* Bit definitions for M profile XPSR. Most are the same as CPSR. */ #define XPSR_EXCP 0x1ffU diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 27d16ad9ad..acf1815ea3 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -400,11 +400,14 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) /* Write the CPSR for a 32-bit exception return */ void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val) { + uint32_t mask; + qemu_mutex_lock_iothread(); arm_call_pre_el_change_hook(env_archcpu(env)); qemu_mutex_unlock_iothread(); - cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn); + mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar); + cpsr_write(env, val, mask, CPSRWriteExceptionReturn); /* Generated code has already stored the new PC value, but * without masking out its low bits, because which bits need From d203cabd1bd12f31c9df0b5737421ba67b96857b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:04 +0000 Subject: [PATCH 17/46] target/arm: Use aarch32_cpsr_valid_mask in helper_exception_return Using ~0 as the mask on the aarch64->aarch32 exception return was not even as correct as the CPSR_ERET_MASK that we had used on the aarch32->aarch32 exception return. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper-a64.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index bf45f8a785..0c9feba392 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -959,7 +959,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) { int cur_el = arm_current_el(env); unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el); - uint32_t spsr = env->banked_spsr[spsr_idx]; + uint32_t mask, spsr = env->banked_spsr[spsr_idx]; int new_el; bool return_to_aa64 = (spsr & PSTATE_nRW) == 0; @@ -1014,7 +1014,8 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) * will sort the register banks out for us, and we've already * caught all the bad-mode cases in el_from_spsr(). */ - cpsr_write(env, spsr, ~0, CPSRWriteRaw); + mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar); + cpsr_write(env, spsr, mask, CPSRWriteRaw); if (!arm_singlestep_active(env)) { env->uncached_cpsr &= ~PSTATE_SS; } From 70dae0d069c45250bbefd9424089383a8ac239de Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:05 +0000 Subject: [PATCH 18/46] target/arm: Remove CPSR_RESERVED The only remaining use was in op_helper.c. Use PSTATE_SS directly, and move the commentary so that it is more obvious what is going on. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-10-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 6 ------ target/arm/op_helper.c | 9 ++++++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 694b074298..c6dff1d55b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1186,12 +1186,6 @@ void pmu_init(ARMCPU *cpu); #define CPSR_IT_2_7 (0xfc00U) #define CPSR_GE (0xfU << 16) #define CPSR_IL (1U << 20) -/* Note that the RESERVED bits include bit 21, which is PSTATE_SS in - * an AArch64 SPSR but RES0 in AArch32 SPSR and CPSR. In QEMU we use - * env->uncached_cpsr bit 21 to store PSTATE.SS when executing in AArch32, - * where it is live state but not accessible to the AArch32 code. - */ -#define CPSR_RESERVED (0x7U << 21) #define CPSR_J (1U << 24) #define CPSR_IT_0_1 (3U << 25) #define CPSR_Q (1U << 27) diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index acf1815ea3..af3020b78f 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -387,7 +387,14 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) uint32_t HELPER(cpsr_read)(CPUARMState *env) { - return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); + /* + * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr. + * This is convenient for populating SPSR_ELx, but must be + * hidden from aarch32 mode, where it is not visible. + * + * TODO: ARMv8.4-DIT -- need to move SS somewhere else. + */ + return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS); } void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask) From 140845111809cd6fd57ccde93867b48cc56ffc74 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:06 +0000 Subject: [PATCH 19/46] target/arm: Introduce aarch64_pstate_valid_mask Use this along the exception return path, where we previously accepted any values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper-a64.c | 1 + target/arm/internals.h | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 0c9feba392..509ae93069 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -1032,6 +1032,7 @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc) cur_el, new_el, env->regs[15]); } else { env->aarch64 = 1; + spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar); pstate_write(env, spsr); if (!arm_singlestep_active(env)) { env->pstate &= ~PSTATE_SS; diff --git a/target/arm/internals.h b/target/arm/internals.h index 0569c96fd9..034d98ad53 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1085,6 +1085,18 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, return valid; } +static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) +{ + uint32_t valid; + + valid = PSTATE_M | PSTATE_DAIF | PSTATE_IL | PSTATE_SS | PSTATE_NZCV; + if (isar_feature_aa64_bti(id)) { + valid |= PSTATE_BTYPE; + } + + return valid; +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. From 220f508f49c5f49fb771d5105f991c19ffede3f7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:07 +0000 Subject: [PATCH 20/46] target/arm: Update MSR access for PAN For aarch64, there's a dedicated msr (imm, reg) insn. For aarch32, this is done via msr to cpsr. Writes from el0 are ignored, which is already handled by the CPSR_USER mask. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 ++ target/arm/helper.c | 21 +++++++++++++++++++++ target/arm/internals.h | 6 ++++++ target/arm/translate-a64.c | 14 ++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c6dff1d55b..65a0ef8cd6 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1186,6 +1186,7 @@ void pmu_init(ARMCPU *cpu); #define CPSR_IT_2_7 (0xfc00U) #define CPSR_GE (0xfU << 16) #define CPSR_IL (1U << 20) +#define CPSR_PAN (1U << 22) #define CPSR_J (1U << 24) #define CPSR_IT_0_1 (3U << 25) #define CPSR_Q (1U << 27) @@ -1250,6 +1251,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_BTYPE (3U << 10) #define PSTATE_IL (1U << 20) #define PSTATE_SS (1U << 21) +#define PSTATE_PAN (1U << 22) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) diff --git a/target/arm/helper.c b/target/arm/helper.c index e4f17c7e83..058fb23959 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4163,6 +4163,24 @@ static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri, env->daif = value & PSTATE_DAIF; } +static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pstate & PSTATE_PAN; +} + +static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN); +} + +static const ARMCPRegInfo pan_reginfo = { + .name = "PAN", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3, + .type = ARM_CP_NO_RAW, .access = PL1_RW, + .readfn = aa64_pan_read, .writefn = aa64_pan_write +}; + static CPAccessResult aa64_cacheop_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7599,6 +7617,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (cpu_isar_feature(aa64_lor, cpu)) { define_arm_cp_regs(cpu, lor_reginfo); } + if (cpu_isar_feature(aa64_pan, cpu)) { + define_one_arm_cp_reg(cpu, &pan_reginfo); + } if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); diff --git a/target/arm/internals.h b/target/arm/internals.h index 034d98ad53..f6709a2b08 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1081,6 +1081,9 @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, if (isar_feature_jazelle(id)) { valid |= CPSR_J; } + if (isar_feature_aa32_pan(id)) { + valid |= CPSR_PAN; + } return valid; } @@ -1093,6 +1096,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_bti(id)) { valid |= PSTATE_BTYPE; } + if (isar_feature_aa64_pan(id)) { + valid |= PSTATE_PAN; + } return valid; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 49631c2340..d8ba240a15 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1602,6 +1602,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, s->base.is_jmp = DISAS_NEXT; break; + case 0x04: /* PAN */ + if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) { + goto do_unallocated; + } + if (crm & 1) { + set_pstate_bits(PSTATE_PAN); + } else { + clear_pstate_bits(PSTATE_PAN); + } + t1 = tcg_const_i32(s->current_el); + gen_helper_rebuild_hflags_a64(cpu_env, t1); + tcg_temp_free_i32(t1); + break; + case 0x05: /* SPSel */ if (s->current_el == 0) { goto do_unallocated; From 66412260cc1bee60a22d96e4ad8569b85745fea4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:08 +0000 Subject: [PATCH 21/46] target/arm: Update arm_mmu_idx_el for PAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Examine the PAN bit for EL1, EL2, and Secure EL1 to determine if it applies. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index 058fb23959..f6a600aa00 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11895,13 +11895,22 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el) return ARMMMUIdx_E10_0; case 1: if (arm_is_secure_below_el3(env)) { + if (env->pstate & PSTATE_PAN) { + return ARMMMUIdx_SE10_1_PAN; + } return ARMMMUIdx_SE10_1; } + if (env->pstate & PSTATE_PAN) { + return ARMMMUIdx_E10_1_PAN; + } return ARMMMUIdx_E10_1; case 2: /* TODO: ARMv8.4-SecEL2 */ /* Note that TGE does not apply at EL2. */ if ((env->cp15.hcr_el2 & HCR_E2H) && arm_el_is_aa64(env, 2)) { + if (env->pstate & PSTATE_PAN) { + return ARMMMUIdx_E20_2_PAN; + } return ARMMMUIdx_E20_2; } return ARMMMUIdx_E2; From 81636b70c226dc27d7ebc8dedbcec26166d23085 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:09 +0000 Subject: [PATCH 22/46] target/arm: Enforce PAN semantics in get_S1prot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we have a PAN-enforcing mmu_idx, set prot == 0 if user_rw != 0. Reviewed-by: Alex Bennée Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-14-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 3 +++ target/arm/internals.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index f6a600aa00..178757d271 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9569,6 +9569,9 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, if (is_user) { prot_rw = user_rw; } else { + if (user_rw && regime_is_pan(env, mmu_idx)) { + return 0; + } prot_rw = simple_ap_to_rw_prot_is_user(ap, false); } diff --git a/target/arm/internals.h b/target/arm/internals.h index f6709a2b08..4a139644b5 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -893,6 +893,19 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) } } +static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_Stage1_E1_PAN: + case ARMMMUIdx_E10_1_PAN: + case ARMMMUIdx_E20_2_PAN: + case ARMMMUIdx_SE10_1_PAN: + return true; + default: + return false; + } +} + /* Return the FSR value for a debug exception (watchpoint, hardware * breakpoint or BKPT insn) targeting the specified exception level. */ From 4a2696c0d4d80e14a192b28148c6167bc5056f94 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:10 +0000 Subject: [PATCH 23/46] target/arm: Set PAN bit as required on exception entry The PAN bit is preserved, or set as per SCTLR_ELx.SPAN, plus several other conditions listed in the ARM ARM. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20200208125816.14954-15-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 178757d271..de16ce79ad 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8763,8 +8763,12 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, uint32_t mask, uint32_t offset, uint32_t newpc) { + int new_el; + /* Change the CPU state so as to actually take the exception. */ switch_mode(env, new_mode); + new_el = arm_current_el(env); + /* * For exceptions taken to AArch32 we must clear the SS bit in both * PSTATE and in the old-state value we save to SPSR_, so zero it now. @@ -8777,7 +8781,7 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; /* Set new mode endianness */ env->uncached_cpsr &= ~CPSR_E; - if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) { + if (env->cp15.sctlr_el[new_el] & SCTLR_EE) { env->uncached_cpsr |= CPSR_E; } /* J and IL must always be cleared for exception entry */ @@ -8788,6 +8792,25 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode, env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0; env->elr_el[2] = env->regs[15]; } else { + /* CPSR.PAN is normally preserved preserved unless... */ + if (cpu_isar_feature(aa64_pan, env_archcpu(env))) { + switch (new_el) { + case 3: + if (!arm_is_secure_below_el3(env)) { + /* ... the target is EL3, from non-secure state. */ + env->uncached_cpsr &= ~CPSR_PAN; + break; + } + /* ... the target is EL3, from secure state ... */ + /* fall through */ + case 1: + /* ... the target is EL1 and SCTLR.SPAN is 0. */ + if (!(env->cp15.sctlr_el[new_el] & SCTLR_SPAN)) { + env->uncached_cpsr |= CPSR_PAN; + } + break; + } + } /* * this is a lie, as there was no c1_sys on V4T/V5, but who cares * and we should just guard the thumb mode on V4 @@ -9050,6 +9073,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) unsigned int new_el = env->exception.target_el; target_ulong addr = env->cp15.vbar_el[new_el]; unsigned int new_mode = aarch64_pstate_mode(new_el, true); + unsigned int old_mode; unsigned int cur_el = arm_current_el(env); /* @@ -9129,20 +9153,43 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs) } if (is_a64(env)) { - env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env); + old_mode = pstate_read(env); aarch64_save_sp(env, arm_current_el(env)); env->elr_el[new_el] = env->pc; } else { - env->banked_spsr[aarch64_banked_spsr_index(new_el)] = cpsr_read(env); + old_mode = cpsr_read(env); env->elr_el[new_el] = env->regs[15]; aarch64_sync_32_to_64(env); env->condexec_bits = 0; } + env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode; + qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n", env->elr_el[new_el]); + if (cpu_isar_feature(aa64_pan, cpu)) { + /* The value of PSTATE.PAN is normally preserved, except when ... */ + new_mode |= old_mode & PSTATE_PAN; + switch (new_el) { + case 2: + /* ... the target is EL2 with HCR_EL2.{E2H,TGE} == '11' ... */ + if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) + != (HCR_E2H | HCR_TGE)) { + break; + } + /* fall through */ + case 1: + /* ... the target is EL1 ... */ + /* ... and SCTLR_ELx.SPAN == 0, then set to 1. */ + if ((env->cp15.sctlr_el[new_el] & SCTLR_SPAN) == 0) { + new_mode |= PSTATE_PAN; + } + break; + } + } + pstate_write(env, PSTATE_DAIF | new_mode); env->aarch64 = 1; aarch64_restore_sp(env, new_el); From 04b07d29722192926f467ea5fedf2c3b0996a2a5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:11 +0000 Subject: [PATCH 24/46] target/arm: Implement ATS1E1 system registers This is a minor enhancement over ARMv8.1-PAN. The *_PAN mmu_idx are used with the existing do_ats_write. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-16-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index de16ce79ad..d99661d4ea 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3409,16 +3409,21 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) switch (ri->opc2 & 6) { case 0: - /* stage 1 current state PL1: ATS1CPR, ATS1CPW */ + /* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */ switch (el) { case 3: mmu_idx = ARMMMUIdx_SE3; break; case 2: - mmu_idx = ARMMMUIdx_Stage1_E1; - break; + g_assert(!secure); /* TODO: ARMv8.4-SecEL2 */ + /* fall through */ case 1: - mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; + if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) { + mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN + : ARMMMUIdx_Stage1_E1_PAN); + } else { + mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; + } break; default: g_assert_not_reached(); @@ -3487,8 +3492,13 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, switch (ri->opc2 & 6) { case 0: switch (ri->opc1) { - case 0: /* AT S1E1R, AT S1E1W */ - mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; + case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */ + if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) { + mmu_idx = (secure ? ARMMMUIdx_SE10_1_PAN + : ARMMMUIdx_Stage1_E1_PAN); + } else { + mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_Stage1_E1; + } break; case 4: /* AT S1E2R, AT S1E2W */ mmu_idx = ARMMMUIdx_E2; @@ -6683,6 +6693,32 @@ static const ARMCPRegInfo vhe_reginfo[] = { REGINFO_SENTINEL }; +#ifndef CONFIG_USER_ONLY +static const ARMCPRegInfo ats1e1_reginfo[] = { + { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, + { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write64 }, + REGINFO_SENTINEL +}; + +static const ARMCPRegInfo ats1cp_reginfo[] = { + { .name = "ATS1CPRP", + .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write }, + { .name = "ATS1CPWP", + .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, + .writefn = ats_write }, + REGINFO_SENTINEL +}; +#endif + void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ @@ -7620,6 +7656,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) if (cpu_isar_feature(aa64_pan, cpu)) { define_one_arm_cp_reg(cpu, &pan_reginfo); } +#ifndef CONFIG_USER_ONLY + if (cpu_isar_feature(aa64_ats1e1, cpu)) { + define_arm_cp_regs(cpu, ats1e1_reginfo); + } + if (cpu_isar_feature(aa32_ats1e1, cpu)) { + define_arm_cp_regs(cpu, ats1cp_reginfo); + } +#endif if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); From e0fe7309a7c21ef2386de50d37c86aea0d671c08 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:12 +0000 Subject: [PATCH 25/46] target/arm: Enable ARMv8.2-ATS1E1 in -cpu max This includes enablement of ARMv8.1-PAN. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-17-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.c | 4 ++++ target/arm/cpu64.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index b0762a76c4..de733aceeb 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2709,6 +2709,10 @@ static void arm_max_initfn(Object *obj) t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ cpu->isar.mvfr2 = t; + t = cpu->id_mmfr3; + t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */ + cpu->id_mmfr3 = t; + t = cpu->id_mmfr4; t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ cpu->id_mmfr4 = t; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index c80fb5fd43..57fbc5eade 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -673,6 +673,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); + t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ cpu->isar.id_aa64mmfr1 = t; /* Replicate the same data to the 32-bit id registers. */ @@ -693,6 +694,10 @@ static void aarch64_max_initfn(Object *obj) u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1); cpu->isar.id_isar6 = u; + u = cpu->id_mmfr3; + u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ + cpu->id_mmfr3 = u; + /* * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet, * so do not set MVFR1.FPHP. Strictly speaking this is not legal, From 64761e10af2742a916c08271828890274137b9e8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:13 +0000 Subject: [PATCH 26/46] target/arm: Add ID_AA64MMFR2_EL1 Add definitions for all of the fields, up to ARMv8.5. Convert the existing RESERVED register to a full register. Query KVM for the value of the register for the host. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-18-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 17 +++++++++++++++++ target/arm/helper.c | 4 ++-- target/arm/kvm64.c | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 65a0ef8cd6..71879393c2 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -871,6 +871,7 @@ struct ARMCPU { uint64_t id_aa64pfr1; uint64_t id_aa64mmfr0; uint64_t id_aa64mmfr1; + uint64_t id_aa64mmfr2; } isar; uint32_t midr; uint32_t revidr; @@ -1803,6 +1804,22 @@ FIELD(ID_AA64MMFR1, PAN, 20, 4) FIELD(ID_AA64MMFR1, SPECSEI, 24, 4) FIELD(ID_AA64MMFR1, XNX, 28, 4) +FIELD(ID_AA64MMFR2, CNP, 0, 4) +FIELD(ID_AA64MMFR2, UAO, 4, 4) +FIELD(ID_AA64MMFR2, LSM, 8, 4) +FIELD(ID_AA64MMFR2, IESB, 12, 4) +FIELD(ID_AA64MMFR2, VARANGE, 16, 4) +FIELD(ID_AA64MMFR2, CCIDX, 20, 4) +FIELD(ID_AA64MMFR2, NV, 24, 4) +FIELD(ID_AA64MMFR2, ST, 28, 4) +FIELD(ID_AA64MMFR2, AT, 32, 4) +FIELD(ID_AA64MMFR2, IDS, 36, 4) +FIELD(ID_AA64MMFR2, FWB, 40, 4) +FIELD(ID_AA64MMFR2, TTL, 48, 4) +FIELD(ID_AA64MMFR2, BBM, 52, 4) +FIELD(ID_AA64MMFR2, EVT, 56, 4) +FIELD(ID_AA64MMFR2, E0PD, 60, 4) + FIELD(ID_DFR0, COPDBG, 0, 4) FIELD(ID_DFR0, COPSDBG, 4, 4) FIELD(ID_DFR0, MMAPDBG, 8, 4) diff --git a/target/arm/helper.c b/target/arm/helper.c index d99661d4ea..d29722d8ac 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7073,11 +7073,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, .resetvalue = cpu->isar.id_aa64mmfr1 }, - { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa64_tid3, - .resetvalue = 0 }, + .resetvalue = cpu->isar.id_aa64mmfr2 }, { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, .access = PL1_R, .type = ARM_CP_CONST, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index fb21ab9e73..3bae9e4a66 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -549,6 +549,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 7, 0)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, ARM64_SYS_REG(3, 0, 0, 7, 1)); + err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2, + ARM64_SYS_REG(3, 0, 0, 7, 2)); /* * Note that if AArch32 support is not present in the host, From 9eeb7a1c9531cb3574bfe2c36eb7624802c3ec00 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:14 +0000 Subject: [PATCH 27/46] target/arm: Update MSR access to UAO Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-19-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 6 ++++++ target/arm/helper.c | 21 +++++++++++++++++++++ target/arm/internals.h | 3 +++ target/arm/translate-a64.c | 14 ++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 71879393c2..e943ffe8a9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1253,6 +1253,7 @@ void pmu_init(ARMCPU *cpu); #define PSTATE_IL (1U << 20) #define PSTATE_SS (1U << 21) #define PSTATE_PAN (1U << 22) +#define PSTATE_UAO (1U << 23) #define PSTATE_V (1U << 28) #define PSTATE_C (1U << 29) #define PSTATE_Z (1U << 30) @@ -3642,6 +3643,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; } +static inline bool isar_feature_aa64_uao(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0; +} + static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; diff --git a/target/arm/helper.c b/target/arm/helper.c index d29722d8ac..11a5f0be52 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -4191,6 +4191,24 @@ static const ARMCPRegInfo pan_reginfo = { .readfn = aa64_pan_read, .writefn = aa64_pan_write }; +static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return env->pstate & PSTATE_UAO; +} + +static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO); +} + +static const ARMCPRegInfo uao_reginfo = { + .name = "UAO", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4, + .type = ARM_CP_NO_RAW, .access = PL1_RW, + .readfn = aa64_uao_read, .writefn = aa64_uao_write +}; + static CPAccessResult aa64_cacheop_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -7664,6 +7682,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_arm_cp_regs(cpu, ats1cp_reginfo); } #endif + if (cpu_isar_feature(aa64_uao, cpu)) { + define_one_arm_cp_reg(cpu, &uao_reginfo); + } if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) { define_arm_cp_regs(cpu, vhe_reginfo); diff --git a/target/arm/internals.h b/target/arm/internals.h index 4a139644b5..58c4d707c5 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1112,6 +1112,9 @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) if (isar_feature_aa64_pan(id)) { valid |= PSTATE_PAN; } + if (isar_feature_aa64_uao(id)) { + valid |= PSTATE_UAO; + } return valid; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index d8ba240a15..7c26c3bfeb 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1602,6 +1602,20 @@ static void handle_msr_i(DisasContext *s, uint32_t insn, s->base.is_jmp = DISAS_NEXT; break; + case 0x03: /* UAO */ + if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) { + goto do_unallocated; + } + if (crm & 1) { + set_pstate_bits(PSTATE_UAO); + } else { + clear_pstate_bits(PSTATE_UAO); + } + t1 = tcg_const_i32(s->current_el); + gen_helper_rebuild_hflags_a64(cpu_env, t1); + tcg_temp_free_i32(t1); + break; + case 0x04: /* PAN */ if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) { goto do_unallocated; From 7a8014ab871d5320effd737dfe88b2e80f16a509 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:15 +0000 Subject: [PATCH 28/46] target/arm: Implement UAO semantics We need only override the current condition under which TBFLAG_A64.UNPRIV is set. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-20-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 11a5f0be52..366dbcf460 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -12198,28 +12198,29 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, } /* Compute the condition for using AccType_UNPRIV for LDTR et al. */ - /* TODO: ARMv8.2-UAO */ - switch (mmu_idx) { - case ARMMMUIdx_E10_1: - case ARMMMUIdx_E10_1_PAN: - case ARMMMUIdx_SE10_1: - case ARMMMUIdx_SE10_1_PAN: - /* TODO: ARMv8.3-NV */ - flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); - break; - case ARMMMUIdx_E20_2: - case ARMMMUIdx_E20_2_PAN: - /* TODO: ARMv8.4-SecEL2 */ - /* - * Note that E20_2 is gated by HCR_EL2.E2H == 1, but E20_0 is - * gated by HCR_EL2. == '11', and so is LDTR. - */ - if (env->cp15.hcr_el2 & HCR_TGE) { + if (!(env->pstate & PSTATE_UAO)) { + switch (mmu_idx) { + case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: + case ARMMMUIdx_SE10_1: + case ARMMMUIdx_SE10_1_PAN: + /* TODO: ARMv8.3-NV */ flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); + break; + case ARMMMUIdx_E20_2: + case ARMMMUIdx_E20_2_PAN: + /* TODO: ARMv8.4-SecEL2 */ + /* + * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is + * gated by HCR_EL2. == '11', and so is LDTR. + */ + if (env->cp15.hcr_el2 & HCR_TGE) { + flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1); + } + break; + default: + break; } - break; - default: - break; } return rebuild_hflags_common(env, fp_el, mmu_idx, flags); From e11f0eb6724571adb812a3ce5269c41586e0262b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 8 Feb 2020 12:58:16 +0000 Subject: [PATCH 29/46] target/arm: Enable ARMv8.2-UAO in -cpu max Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20200208125816.14954-21-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu64.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 57fbc5eade..1359564c55 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -676,6 +676,10 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ cpu->isar.id_aa64mmfr1 = t; + t = cpu->isar.id_aa64mmfr2; + t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); + cpu->isar.id_aa64mmfr2 = t; + /* Replicate the same data to the 32-bit id registers. */ u = cpu->isar.id_isar5; u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ From bfdd34f1caa9357ac66fc26973b4eb2d56373f2b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 6 Feb 2020 10:34:37 -0800 Subject: [PATCH 30/46] hw/arm: ast2400/ast2500: Wire up EHCI controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize EHCI controllers on AST2400 and AST2500 using the existing TYPE_PLATFORM_EHCI. After this change, booting ast2500-evb into Linux successfully instantiates a USB interface. ehci-platform 1e6a3000.usb: EHCI Host Controller ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1 ehci-platform 1e6a3000.usb: irq 21, io mem 0x1e6a3000 ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00 usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.05 usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 usb usb1: Product: EHCI Host Controller Signed-off-by: Guenter Roeck Reviewed-by: Cédric Le Goater Reviewed-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daudé Message-id: 20200206183437.3979-1-linux@roeck-us.net Signed-off-by: Peter Maydell --- hw/arm/aspeed_soc.c | 25 +++++++++++++++++++++++++ include/hw/arm/aspeed_soc.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index b5e809a1d3..696c7fda14 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -30,6 +30,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = { [ASPEED_IOMEM] = 0x1E600000, [ASPEED_FMC] = 0x1E620000, [ASPEED_SPI1] = 0x1E630000, + [ASPEED_EHCI1] = 0x1E6A1000, [ASPEED_VIC] = 0x1E6C0000, [ASPEED_SDMC] = 0x1E6E0000, [ASPEED_SCU] = 0x1E6E2000, @@ -59,6 +60,8 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = { [ASPEED_FMC] = 0x1E620000, [ASPEED_SPI1] = 0x1E630000, [ASPEED_SPI2] = 0x1E631000, + [ASPEED_EHCI1] = 0x1E6A1000, + [ASPEED_EHCI2] = 0x1E6A3000, [ASPEED_VIC] = 0x1E6C0000, [ASPEED_SDMC] = 0x1E6E0000, [ASPEED_SCU] = 0x1E6E2000, @@ -91,6 +94,8 @@ static const int aspeed_soc_ast2400_irqmap[] = { [ASPEED_UART5] = 10, [ASPEED_VUART] = 8, [ASPEED_FMC] = 19, + [ASPEED_EHCI1] = 5, + [ASPEED_EHCI2] = 13, [ASPEED_SDMC] = 0, [ASPEED_SCU] = 21, [ASPEED_ADC] = 31, @@ -180,6 +185,11 @@ static void aspeed_soc_init(Object *obj) sizeof(s->spi[i]), typename); } + for (i = 0; i < sc->ehcis_num; i++) { + sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), + sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); + } + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), typename); @@ -364,6 +374,19 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) s->spi[i].ctrl->flash_window_base); } + /* EHCI */ + for (i = 0; i < sc->ehcis_num; i++) { + object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, + sc->memmap[ASPEED_EHCI1 + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, + aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); + } + /* SDMC - SDRAM Memory Controller */ object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); if (err) { @@ -472,6 +495,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2400_A1_SILICON_REV; sc->sram_size = 0x8000; sc->spis_num = 1; + sc->ehcis_num = 1; sc->wdts_num = 2; sc->macs_num = 2; sc->irqmap = aspeed_soc_ast2400_irqmap; @@ -496,6 +520,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2500_A1_SILICON_REV; sc->sram_size = 0x9000; sc->spis_num = 2; + sc->ehcis_num = 2; sc->wdts_num = 3; sc->macs_num = 2; sc->irqmap = aspeed_soc_ast2500_irqmap; diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 90ac7f7ffa..78b9f6ae53 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -26,8 +26,10 @@ #include "target/arm/cpu.h" #include "hw/gpio/aspeed_gpio.h" #include "hw/sd/aspeed_sdhci.h" +#include "hw/usb/hcd-ehci.h" #define ASPEED_SPIS_NUM 2 +#define ASPEED_EHCIS_NUM 2 #define ASPEED_WDTS_NUM 4 #define ASPEED_CPUS_NUM 2 #define ASPEED_MACS_NUM 4 @@ -50,6 +52,7 @@ typedef struct AspeedSoCState { AspeedXDMAState xdma; AspeedSMCState fmc; AspeedSMCState spi[ASPEED_SPIS_NUM]; + EHCISysBusState ehci[ASPEED_EHCIS_NUM]; AspeedSDMCState sdmc; AspeedWDTState wdt[ASPEED_WDTS_NUM]; FTGMAC100State ftgmac100[ASPEED_MACS_NUM]; @@ -71,6 +74,7 @@ typedef struct AspeedSoCClass { uint32_t silicon_rev; uint64_t sram_size; int spis_num; + int ehcis_num; int wdts_num; int macs_num; const int *irqmap; @@ -94,6 +98,8 @@ enum { ASPEED_FMC, ASPEED_SPI1, ASPEED_SPI2, + ASPEED_EHCI1, + ASPEED_EHCI2, ASPEED_VIC, ASPEED_SDMC, ASPEED_SCU, From 917940ce69ef09490f486826f51c90b8c639a1b4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 7 Feb 2020 09:45:48 -0800 Subject: [PATCH 31/46] hw/arm: ast2600: Wire up EHCI controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize EHCI controllers on AST2600 using the existing TYPE_PLATFORM_EHCI. After this change, booting ast2600-evb into Linux successfully instantiates a USB interface after the necessary changes are made to its devicetree files. ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver ehci-platform: EHCI generic platform driver ehci-platform 1e6a3000.usb: EHCI Host Controller ehci-platform 1e6a3000.usb: new USB bus registered, assigned bus number 1 ehci-platform 1e6a3000.usb: irq 25, io mem 0x1e6a3000 ehci-platform 1e6a3000.usb: USB 2.0 started, EHCI 1.00 usb usb1: Manufacturer: Linux 5.5.0-09825-ga0802f2d0ef5-dirty ehci_hcd usb 1-1: new high-speed USB device number 2 using ehci-platform Reviewed-by: Cédric Le Goater Signed-off-by: Guenter Roeck Reviewed-by: Niek Linnenbank Message-id: 20200207174548.9087-1-linux@roeck-us.net Signed-off-by: Peter Maydell --- hw/arm/aspeed_ast2600.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 90cf1c755d..446b44d31c 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -31,6 +31,8 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = { [ASPEED_FMC] = 0x1E620000, [ASPEED_SPI1] = 0x1E630000, [ASPEED_SPI2] = 0x1E641000, + [ASPEED_EHCI1] = 0x1E6A1000, + [ASPEED_EHCI2] = 0x1E6A3000, [ASPEED_MII1] = 0x1E650000, [ASPEED_MII2] = 0x1E650008, [ASPEED_MII3] = 0x1E650010, @@ -79,6 +81,8 @@ static const int aspeed_soc_ast2600_irqmap[] = { [ASPEED_ADC] = 78, [ASPEED_XDMA] = 6, [ASPEED_SDHCI] = 43, + [ASPEED_EHCI1] = 5, + [ASPEED_EHCI2] = 9, [ASPEED_EMMC] = 15, [ASPEED_GPIO] = 40, [ASPEED_GPIO_1_8V] = 11, @@ -166,6 +170,11 @@ static void aspeed_soc_ast2600_init(Object *obj) sizeof(s->spi[i]), typename); } + for (i = 0; i < sc->ehcis_num; i++) { + sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), + sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); + } + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), typename); @@ -416,6 +425,19 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) s->spi[i].ctrl->flash_window_base); } + /* EHCI */ + for (i = 0; i < sc->ehcis_num; i++) { + object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, + sc->memmap[ASPEED_EHCI1 + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, + aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); + } + /* SDMC - SDRAM Memory Controller */ object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); if (err) { @@ -534,6 +556,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2600_A0_SILICON_REV; sc->sram_size = 0x10000; sc->spis_num = 2; + sc->ehcis_num = 2; sc->wdts_num = 4; sc->macs_num = 4; sc->irqmap = aspeed_soc_ast2600_irqmap; From 8bbc394c552cd003e034640f8e07a496de90e340 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 13 Feb 2020 10:56:03 +0800 Subject: [PATCH 32/46] hw/char/exynos4210_uart: Fix memleaks in exynos4210_uart_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's easy to reproduce as follow: virsh qemu-monitor-command vm1 --pretty '{"execute": "device-list-properties", "arguments":{"typename":"exynos4210.uart"}}' ASAN shows memory leak stack: #1 0xfffd896d71cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb) #2 0xaaad270beee3 in timer_new_full /qemu/include/qemu/timer.h:530 #3 0xaaad270beee3 in timer_new /qemu/include/qemu/timer.h:551 #4 0xaaad270beee3 in timer_new_ns /qemu/include/qemu/timer.h:569 #5 0xaaad270beee3 in exynos4210_uart_init /qemu/hw/char/exynos4210_uart.c:677 #6 0xaaad275c8f4f in object_initialize_with_type /qemu/qom/object.c:516 #7 0xaaad275c91bb in object_new_with_type /qemu/qom/object.c:684 #8 0xaaad2755df2f in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:152 Reported-by: Euler Robot Signed-off-by: Chen Qun Reviewed-by: Philippe Mathieu-Daudé Message-id: 20200213025603.149432-1-kuhn.chenqun@huawei.com Signed-off-by: Peter Maydell --- hw/char/exynos4210_uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 25d6588e41..96d5180e3e 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -674,8 +674,6 @@ static void exynos4210_uart_init(Object *obj) SysBusDevice *dev = SYS_BUS_DEVICE(obj); Exynos4210UartState *s = EXYNOS4210_UART(dev); - s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - exynos4210_uart_timeout_int, s); s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600; /* memory mapping */ @@ -691,6 +689,9 @@ static void exynos4210_uart_realize(DeviceState *dev, Error **errp) { Exynos4210UartState *s = EXYNOS4210_UART(dev); + s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + exynos4210_uart_timeout_int, s); + qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive, exynos4210_uart_receive, exynos4210_uart_event, NULL, s, NULL, true); From 918c81a53eb18ec4e9979876a39e86610cc565f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:33 +0100 Subject: [PATCH 33/46] hw/arm/raspi: Use BCM2708 machine type with pre Device Tree kernels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When booting without device tree, the Linux kernels uses the $R1 register to determine the machine type. The list of values is registered at [1]. There are two entries for the Raspberry Pi: - https://www.arm.linux.org.uk/developer/machines/list.php?mid=3138 name: MACH_TYPE_BCM2708 value: 0xc42 (3138) status: Active, not mainlined date: 15 Oct 2010 - https://www.arm.linux.org.uk/developer/machines/list.php?mid=4828 name: MACH_TYPE_BCM2835 value: 4828 status: Active, mainlined date: 6 Dec 2013 QEMU always used the non-mainlined type MACH_TYPE_BCM2708. The value 0xc43 is registered to 'MX51_GGC' (processor i.MX51), and 0xc44 to 'Western Digital Sharespace NAS' (processor Marvell 88F5182). The Raspberry Pi foundation bootloader only sets the BCM2708 machine type, see [2] or [3]: 133 9: 134 mov r0, #0 135 ldr r1, =3138 @ BCM2708 machine id 136 ldr r2, atags @ ATAGS 137 bx r4 U-Boot only uses MACH_TYPE_BCM2708 (see [4]): 25 /* 26 * 2835 is a SKU in a series for which the 2708 is the first or primary SoC, 27 * so 2708 has historically been used rather than a dedicated 2835 ID. 28 * 29 * We don't define a machine type for bcm2709/bcm2836 since the RPi Foundation 30 * chose to use someone else's previously registered machine ID (3139, MX51_GGC) 31 * rather than obtaining a valid ID:-/ 32 * 33 * For the bcm2837, hopefully a machine type is not needed, since everything 34 * is DT. 35 */ While the definition MACH_BCM2709 with value 0xc43 was introduced in a commit described "Add 2709 platform for Raspberry Pi 2" out of the mainline Linux kernel, it does not seem used, and the platform is introduced with Device Tree support anyway (see [5] and [6]). Remove the unused values (0xc43 introduced in commit 1df7d1f9303aef "raspi: add raspberry pi 2 machine" and 0xc44 in commit bade58166f4 "raspi: Raspberry Pi 3 support"), keeping only MACH_TYPE_BCM2708. [1] https://www.arm.linux.org.uk/developer/machines/ [2] https://github.com/raspberrypi/tools/blob/920c7ed2e/armstubs/armstub7.S#L135 [3] https://github.com/raspberrypi/tools/blob/49719d554/armstubs/armstub7.S#L64 [4] https://gitlab.denx.de/u-boot/u-boot/blob/v2015.04/include/configs/rpi-common.h#L18 [5] https://github.com/raspberrypi/linux/commit/d9fac63adac#diff-6722037d79570df5b392a49e0e006573R526 [6] http://lists.infradead.org/pipermail/linux-rpi-kernel/2015-February/001268.html Cc: Zoltán Baldaszti Cc: Pekka Enberg Cc: Stephen Warren Cc: Kshitij Soni Cc: Michael Chan Cc: Andrew Baumann Reviewed-by: Alistair Francis Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Niek Linnenbank Message-id: 20200208165645.15657-2-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 3996f6c63a..f2ccabc662 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -29,8 +29,8 @@ #define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */ #define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */ -/* Table of Linux board IDs for different Pi versions */ -static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44}; +/* Registered machine type (matches RPi Foundation bootloader and U-Boot) */ +#define MACH_TYPE_BCM2708 3138 typedef struct RasPiState { BCM283XState soc; @@ -116,7 +116,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) static struct arm_boot_info binfo; int r; - binfo.board_id = raspi_boardid[version]; + binfo.board_id = MACH_TYPE_BCM2708; binfo.ram_size = ram_size; binfo.nb_cpus = machine->smp.cpus; From fc78a990ec1032d8272db49988376f197efac817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:34 +0100 Subject: [PATCH 34/46] hw/arm/raspi: Correct the board descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We hardcode the board revision as 0xa21041 for the raspi2, and 0xa02082 for the raspi3: 166 static void raspi_init(MachineState *machine, int version) 167 { ... 194 int board_rev = version == 3 ? 0xa02082 : 0xa21041; These revision codes are for the 2B and 3B models, see: https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md Correct the board description. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-3-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index f2ccabc662..818146fdbb 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -221,7 +221,7 @@ static void raspi2_init(MachineState *machine) static void raspi2_machine_init(MachineClass *mc) { - mc->desc = "Raspberry Pi 2"; + mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; @@ -243,7 +243,7 @@ static void raspi3_init(MachineState *machine) static void raspi3_machine_init(MachineClass *mc) { - mc->desc = "Raspberry Pi 3"; + mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; From cd6c9977d3b34d3c5569bec8c5316735b7df5239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:35 +0100 Subject: [PATCH 35/46] hw/arm/raspi: Extract the version from the board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board revision encode the board version. Add a helper to extract the version, and use it. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-4-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 818146fdbb..f285e2988f 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/arm/bcm2836.h" +#include "hw/registerfields.h" #include "qemu/error-report.h" #include "hw/boards.h" #include "hw/loader.h" @@ -37,6 +38,28 @@ typedef struct RasPiState { MemoryRegion ram; } RasPiState; +/* + * Board revision codes: + * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/ + */ +FIELD(REV_CODE, REVISION, 0, 4); +FIELD(REV_CODE, TYPE, 4, 8); +FIELD(REV_CODE, PROCESSOR, 12, 4); +FIELD(REV_CODE, MANUFACTURER, 16, 4); +FIELD(REV_CODE, MEMORY_SIZE, 20, 3); +FIELD(REV_CODE, STYLE, 23, 1); + +static int board_processor_id(uint32_t board_rev) +{ + assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ + return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); +} + +static int board_version(uint32_t board_rev) +{ + return board_processor_id(board_rev) + 1; +} + static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info) { static const uint32_t smpboot[] = { @@ -164,9 +187,10 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } -static void raspi_init(MachineState *machine, int version) +static void raspi_init(MachineState *machine, uint32_t board_rev) { RasPiState *s = g_new0(RasPiState, 1); + int version = board_version(board_rev); uint32_t vcram_size; DriveInfo *di; BlockBackend *blk; @@ -192,7 +216,6 @@ static void raspi_init(MachineState *machine, int version) /* Setup the SOC */ object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram), &error_abort); - int board_rev = version == 3 ? 0xa02082 : 0xa21041; object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev", &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); @@ -216,7 +239,7 @@ static void raspi_init(MachineState *machine, int version) static void raspi2_init(MachineState *machine) { - raspi_init(machine, 2); + raspi_init(machine, 0xa21041); } static void raspi2_machine_init(MachineClass *mc) @@ -238,7 +261,7 @@ DEFINE_MACHINE("raspi2", raspi2_machine_init) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) { - raspi_init(machine, 3); + raspi_init(machine, 0xa02082); } static void raspi3_machine_init(MachineClass *mc) From f5bb124ecf34298246b4a776f2cf7545b1170638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:36 +0100 Subject: [PATCH 36/46] hw/arm/raspi: Extract the RAM size from the board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board revision encode the amount of RAM. Add a helper to extract the RAM size, and use it. Since the amount of RAM is fixed (it is impossible to physically modify to have more or less RAM), do not allow sizes different than the one anounced by the manufacturer. Acked-by: Igor Mammedov Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-5-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index f285e2988f..dcd8d2d6d3 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "qemu/cutils.h" #include "qapi/error.h" #include "cpu.h" #include "hw/arm/bcm2836.h" @@ -49,6 +50,12 @@ FIELD(REV_CODE, MANUFACTURER, 16, 4); FIELD(REV_CODE, MEMORY_SIZE, 20, 3); FIELD(REV_CODE, STYLE, 23, 1); +static uint64_t board_ram_size(uint32_t board_rev) +{ + assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ + return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE); +} + static int board_processor_id(uint32_t board_rev) { assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ @@ -191,15 +198,17 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) { RasPiState *s = g_new0(RasPiState, 1); int version = board_version(board_rev); + uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; DriveInfo *di; BlockBackend *blk; BusState *bus; DeviceState *carddev; - if (machine->ram_size > 1 * GiB) { - error_report("Requested ram size is too large for this machine: " - "maximum is 1GB"); + if (machine->ram_size != ram_size) { + char *size_str = size_to_str(ram_size); + error_report("Invalid RAM size, should be %s", size_str); + g_free(size_str); exit(1); } From 2e664b45f4d9e7449bd977980aa1454b16837713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:37 +0100 Subject: [PATCH 37/46] hw/arm/raspi: Extract the processor type from the board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board revision encode the processor type. Add a helper to extract the type, and use it. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-6-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index dcd8d2d6d3..7a2ca97347 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -67,6 +67,21 @@ static int board_version(uint32_t board_rev) return board_processor_id(board_rev) + 1; } +static const char *board_soc_type(uint32_t board_rev) +{ + static const char *soc_types[] = { + NULL, TYPE_BCM2836, TYPE_BCM2837, + }; + int proc_id = board_processor_id(board_rev); + + if (proc_id >= ARRAY_SIZE(soc_types) || !soc_types[proc_id]) { + error_report("Unsupported processor id '%d' (board revision: 0x%x)", + proc_id, board_rev); + exit(1); + } + return soc_types[proc_id]; +} + static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info) { static const uint32_t smpboot[] = { @@ -213,8 +228,7 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) } object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), - version == 3 ? TYPE_BCM2837 : TYPE_BCM2836, - &error_abort, NULL); + board_soc_type(board_rev), &error_abort, NULL); /* Allocate and map RAM */ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram", From cc360632f613ccef6676460b4fb5eaad9e82e267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:38 +0100 Subject: [PATCH 38/46] hw/arm/raspi: Trivial code movement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in creating the SoC object before allocating the RAM. Move the call to keep all the SoC-related calls together. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Igor Mammedov Message-id: 20200208165645.15657-7-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 7a2ca97347..b3e6f72b55 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -227,9 +227,6 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) exit(1); } - object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), - board_soc_type(board_rev), &error_abort, NULL); - /* Allocate and map RAM */ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram", machine->ram_size); @@ -237,6 +234,8 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0); /* Setup the SOC */ + object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), + board_soc_type(board_rev), &error_abort, NULL); object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram), &error_abort); object_property_set_int(OBJECT(&s->soc), board_rev, "board-rev", From cb57df6f7f5481904db987a2afa8aabdc1e1d545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:39 +0100 Subject: [PATCH 39/46] hw/arm/raspi: Make machines children of abstract RaspiMachineClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QOM'ify RaspiMachineState. Now machines inherit of RaspiMachineClass. Cc: Igor Mammedov Signed-off-by: Philippe Mathieu-Daudé Acked-by: Igor Mammedov Message-id: 20200208165645.15657-8-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 56 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index b3e6f72b55..62b8df3c2e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -34,10 +34,28 @@ /* Registered machine type (matches RPi Foundation bootloader and U-Boot) */ #define MACH_TYPE_BCM2708 3138 -typedef struct RasPiState { +typedef struct RaspiMachineState { + /*< private >*/ + MachineState parent_obj; + /*< public >*/ BCM283XState soc; MemoryRegion ram; -} RasPiState; +} RaspiMachineState; + +typedef struct RaspiMachineClass { + /*< private >*/ + MachineClass parent_obj; + /*< public >*/ +} RaspiMachineClass; + +#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common") +#define RASPI_MACHINE(obj) \ + OBJECT_CHECK(RaspiMachineState, (obj), TYPE_RASPI_MACHINE) + +#define RASPI_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(RaspiMachineClass, (klass), TYPE_RASPI_MACHINE) +#define RASPI_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(RaspiMachineClass, (obj), TYPE_RASPI_MACHINE) /* * Board revision codes: @@ -211,7 +229,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) static void raspi_init(MachineState *machine, uint32_t board_rev) { - RasPiState *s = g_new0(RasPiState, 1); + RaspiMachineState *s = RASPI_MACHINE(machine); int version = board_version(board_rev); uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; @@ -264,8 +282,10 @@ static void raspi2_init(MachineState *machine) raspi_init(machine, 0xa21041); } -static void raspi2_machine_init(MachineClass *mc) +static void raspi2_machine_class_init(ObjectClass *oc, void *data) { + MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; @@ -278,7 +298,6 @@ static void raspi2_machine_init(MachineClass *mc) mc->default_ram_size = 1 * GiB; mc->ignore_memory_transaction_failures = true; }; -DEFINE_MACHINE("raspi2", raspi2_machine_init) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) @@ -286,8 +305,10 @@ static void raspi3_init(MachineState *machine) raspi_init(machine, 0xa02082); } -static void raspi3_machine_init(MachineClass *mc) +static void raspi3_machine_class_init(ObjectClass *oc, void *data) { + MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; @@ -299,5 +320,26 @@ static void raspi3_machine_init(MachineClass *mc) mc->default_cpus = BCM283X_NCPUS; mc->default_ram_size = 1 * GiB; } -DEFINE_MACHINE("raspi3", raspi3_machine_init) #endif + +static const TypeInfo raspi_machine_types[] = { + { + .name = MACHINE_TYPE_NAME("raspi2"), + .parent = TYPE_RASPI_MACHINE, + .class_init = raspi2_machine_class_init, +#ifdef TARGET_AARCH64 + }, { + .name = MACHINE_TYPE_NAME("raspi3"), + .parent = TYPE_RASPI_MACHINE, + .class_init = raspi3_machine_class_init, +#endif + }, { + .name = TYPE_RASPI_MACHINE, + .parent = TYPE_MACHINE, + .instance_size = sizeof(RaspiMachineState), + .class_size = sizeof(RaspiMachineClass), + .abstract = true, + } +}; + +DEFINE_TYPES(raspi_machine_types) From c318c66c67ba143cd32d709cb2eb20eaf8cb9f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:40 +0100 Subject: [PATCH 40/46] hw/arm/raspi: Make board_rev a field of RaspiMachineClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to have a common class_init(). The only value that matters (and changes) is the board revision. Pass the board_rev as class_data to class_init(). Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-9-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 62b8df3c2e..fbfcd29732 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -46,6 +46,7 @@ typedef struct RaspiMachineClass { /*< private >*/ MachineClass parent_obj; /*< public >*/ + uint32_t board_rev; } RaspiMachineClass; #define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common") @@ -227,9 +228,11 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } -static void raspi_init(MachineState *machine, uint32_t board_rev) +static void raspi_init(MachineState *machine) { + RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine); RaspiMachineState *s = RASPI_MACHINE(machine); + uint32_t board_rev = mc->board_rev; int version = board_version(board_rev); uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; @@ -279,13 +282,16 @@ static void raspi_init(MachineState *machine, uint32_t board_rev) static void raspi2_init(MachineState *machine) { - raspi_init(machine, 0xa21041); + raspi_init(machine); } static void raspi2_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + uint32_t board_rev = (uint32_t)(uintptr_t)data; + rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 2B"; mc->init = raspi2_init; mc->block_default_type = IF_SD; @@ -302,13 +308,16 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) #ifdef TARGET_AARCH64 static void raspi3_init(MachineState *machine) { - raspi_init(machine, 0xa02082); + raspi_init(machine); } static void raspi3_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + uint32_t board_rev = (uint32_t)(uintptr_t)data; + rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 3B"; mc->init = raspi3_init; mc->block_default_type = IF_SD; @@ -327,11 +336,13 @@ static const TypeInfo raspi_machine_types[] = { .name = MACHINE_TYPE_NAME("raspi2"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi2_machine_class_init, + .class_data = (void *)0xa21041, #ifdef TARGET_AARCH64 }, { .name = MACHINE_TYPE_NAME("raspi3"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3_machine_class_init, + .class_data = (void *)0xa02082, #endif }, { .name = TYPE_RASPI_MACHINE, From 13c4e2c087924d62da006858baee20b1ffb44462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:41 +0100 Subject: [PATCH 41/46] hw/arm/raspi: Let class_init() directly call raspi_machine_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit raspi_machine_init() access to board_rev via RaspiMachineClass. raspi2_init() and raspi3_init() do nothing. Call raspi_machine_init directly. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-id: 20200208165645.15657-10-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index fbfcd29732..1628b0dda7 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -228,7 +228,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); } -static void raspi_init(MachineState *machine) +static void raspi_machine_init(MachineState *machine) { RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine); RaspiMachineState *s = RASPI_MACHINE(machine); @@ -280,11 +280,6 @@ static void raspi_init(MachineState *machine) setup_boot(machine, version, machine->ram_size - vcram_size); } -static void raspi2_init(MachineState *machine) -{ - raspi_init(machine); -} - static void raspi2_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -293,7 +288,7 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 2B"; - mc->init = raspi2_init; + mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; mc->no_floppy = 1; @@ -306,11 +301,6 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) }; #ifdef TARGET_AARCH64 -static void raspi3_init(MachineState *machine) -{ - raspi_init(machine); -} - static void raspi3_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -319,7 +309,7 @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data) rmc->board_rev = board_rev; mc->desc = "Raspberry Pi 3B"; - mc->init = raspi3_init; + mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; mc->no_floppy = 1; From 975f3402fad40dc2e530e2a7a91ba7d0c2cd6a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:42 +0100 Subject: [PATCH 42/46] hw/arm/raspi: Set default RAM size to size encoded in board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We added a helper to extract the RAM size from the board revision, and made board_rev a field of RaspiMachineClass. The class_init() can now use the helper to extract from the board revision the board-specific amount of RAM. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-11-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 1628b0dda7..f0dcffbc2e 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -296,7 +296,7 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) mc->max_cpus = BCM283X_NCPUS; mc->min_cpus = BCM283X_NCPUS; mc->default_cpus = BCM283X_NCPUS; - mc->default_ram_size = 1 * GiB; + mc->default_ram_size = board_ram_size(board_rev); mc->ignore_memory_transaction_failures = true; }; @@ -317,7 +317,7 @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data) mc->max_cpus = BCM283X_NCPUS; mc->min_cpus = BCM283X_NCPUS; mc->default_cpus = BCM283X_NCPUS; - mc->default_ram_size = 1 * GiB; + mc->default_ram_size = board_ram_size(board_rev); } #endif From 98b541e1b219054d4cde3b327f0ba8ef5c8d8ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:43 +0100 Subject: [PATCH 43/46] hw/arm/raspi: Extract the board model from the board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board revision encode the model type. Add a helper to extract the model, and use it. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-12-f4bug@amsat.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index f0dcffbc2e..0537fc0a2d 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -101,6 +101,20 @@ static const char *board_soc_type(uint32_t board_rev) return soc_types[proc_id]; } +static const char *board_type(uint32_t board_rev) +{ + static const char *types[] = { + "A", "B", "A+", "B+", "2B", "Alpha", "CM1", NULL, "3B", "Zero", + "CM3", NULL, "Zero W", "3B+", "3A+", NULL, "CM3+", "4B", + }; + assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ + int bt = FIELD_EX32(board_rev, REV_CODE, TYPE); + if (bt >= ARRAY_SIZE(types) || !types[bt]) { + return "Unknown"; + } + return types[bt]; +} + static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info) { static const uint32_t smpboot[] = { @@ -287,7 +301,7 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) uint32_t board_rev = (uint32_t)(uintptr_t)data; rmc->board_rev = board_rev; - mc->desc = "Raspberry Pi 2B"; + mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev)); mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; @@ -308,7 +322,7 @@ static void raspi3_machine_class_init(ObjectClass *oc, void *data) uint32_t board_rev = (uint32_t)(uintptr_t)data; rmc->board_rev = board_rev; - mc->desc = "Raspberry Pi 3B"; + mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev)); mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; From a03bde3674e400473717baec599da0a7ee0cf066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:44 +0100 Subject: [PATCH 44/46] hw/arm/raspi: Use a unique raspi_machine_class_init() method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the exception of the ignore_memory_transaction_failures flag set for the raspi2, both machine_class_init() methods are now identical. Merge them to keep a unique method. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Message-id: 20200208165645.15657-13-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 0537fc0a2d..bee6ca0a08 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -294,7 +294,7 @@ static void raspi_machine_init(MachineState *machine) setup_boot(machine, version, machine->ram_size - vcram_size); } -static void raspi2_machine_class_init(ObjectClass *oc, void *data) +static void raspi_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); @@ -311,41 +311,22 @@ static void raspi2_machine_class_init(ObjectClass *oc, void *data) mc->min_cpus = BCM283X_NCPUS; mc->default_cpus = BCM283X_NCPUS; mc->default_ram_size = board_ram_size(board_rev); - mc->ignore_memory_transaction_failures = true; + if (board_version(board_rev) == 2) { + mc->ignore_memory_transaction_failures = true; + } }; -#ifdef TARGET_AARCH64 -static void raspi3_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); - uint32_t board_rev = (uint32_t)(uintptr_t)data; - - rmc->board_rev = board_rev; - mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev)); - mc->init = raspi_machine_init; - mc->block_default_type = IF_SD; - mc->no_parallel = 1; - mc->no_floppy = 1; - mc->no_cdrom = 1; - mc->max_cpus = BCM283X_NCPUS; - mc->min_cpus = BCM283X_NCPUS; - mc->default_cpus = BCM283X_NCPUS; - mc->default_ram_size = board_ram_size(board_rev); -} -#endif - static const TypeInfo raspi_machine_types[] = { { .name = MACHINE_TYPE_NAME("raspi2"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi2_machine_class_init, + .class_init = raspi_machine_class_init, .class_data = (void *)0xa21041, #ifdef TARGET_AARCH64 }, { .name = MACHINE_TYPE_NAME("raspi3"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi3_machine_class_init, + .class_init = raspi_machine_class_init, .class_data = (void *)0xa02082, #endif }, { From 759f0f87e34fe63a475d926ea6db88d11d2cd018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sat, 8 Feb 2020 17:56:45 +0100 Subject: [PATCH 45/46] hw/arm/raspi: Extract the cores count from the board revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The count of ARM cores is encoded in the board revision. Add a helper to extract the number of cores, and use it. This will be helpful when we add the Raspi0/1 that have a single core. Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200208165645.15657-14-f4bug@amsat.org Reviewed-by: Peter Maydell [PMM: tweaked commit message as suggested by Igor] Signed-off-by: Peter Maydell --- hw/arm/raspi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index bee6ca0a08..90ad9b8115 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -101,6 +101,21 @@ static const char *board_soc_type(uint32_t board_rev) return soc_types[proc_id]; } +static int cores_count(uint32_t board_rev) +{ + static const int soc_cores_count[] = { + 0, BCM283X_NCPUS, BCM283X_NCPUS, + }; + int proc_id = board_processor_id(board_rev); + + if (proc_id >= ARRAY_SIZE(soc_cores_count) || !soc_cores_count[proc_id]) { + error_report("Unsupported processor id '%d' (board revision: 0x%x)", + proc_id, board_rev); + exit(1); + } + return soc_cores_count[proc_id]; +} + static const char *board_type(uint32_t board_rev) { static const char *types[] = { @@ -307,9 +322,7 @@ static void raspi_machine_class_init(ObjectClass *oc, void *data) mc->no_parallel = 1; mc->no_floppy = 1; mc->no_cdrom = 1; - mc->max_cpus = BCM283X_NCPUS; - mc->min_cpus = BCM283X_NCPUS; - mc->default_cpus = BCM283X_NCPUS; + mc->default_cpus = mc->min_cpus = mc->max_cpus = cores_count(board_rev); mc->default_ram_size = board_ram_size(board_rev); if (board_version(board_rev) == 2) { mc->ignore_memory_transaction_failures = true; From dc7a88d0810ad272bdcd2e0869359af78fdd9114 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 10 Feb 2020 12:01:46 +0000 Subject: [PATCH 46/46] target/arm: Implement ARMv8.1-VMID16 extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ARMv8.1-VMID16 extension extends the VMID from 8 bits to 16 bits: * the ID_AA64MMFR1_EL1.VMIDBits field specifies whether the VMID is 8 or 16 bits * the VMID field in VTTBR_EL2 is extended to 16 bits * VTCR_EL2.VS lets the guest specify whether to use the full 16 bits, or use the backwards-compatible 8 bits For QEMU implementing this is trivial: * we do not track VMIDs in TLB entries, so we never use the VMID field * we treat any write to VTTBR_EL2, not just a change to the VMID field bits, as a "possible VMID change" that causes us to throw away TLB entries, so that code doesn't need changing * we allow the guest to read/write the VTCR_EL2.VS bit already So all that's missing is the ID register part: report that we support VMID16 in our 'max' CPU. Signed-off-by: Peter Maydell Reviewed-by: Alex Bennée Reviewed-by: Richard Henderson Message-id: 20200210120146.17631-1-peter.maydell@linaro.org --- target/arm/cpu64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 1359564c55..f0d98bc79d 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -674,6 +674,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ + t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */ cpu->isar.id_aa64mmfr1 = t; t = cpu->isar.id_aa64mmfr2;