diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-10-01 16:41:30 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-10-01 16:41:30 +0100 |
commit | 625581c2602b5b43e115b779a9a782478e6f92e7 (patch) | |
tree | 0c4125a4d194fe665816717e013ee312f7d5c012 | |
parent | b23317eec4715aa62de9a6e5490a01122c8eef0e (diff) | |
parent | cdfaa57dcb53ba012439765a1462247dfda8595d (diff) | |
download | qemu-625581c2602b5b43e115b779a9a782478e6f92e7.zip qemu-625581c2602b5b43e115b779a9a782478e6f92e7.tar.gz qemu-625581c2602b5b43e115b779a9a782478e6f92e7.tar.bz2 |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20201001' into staging
target-arm queue:
* Make isar_feature_aa32_fp16_arith() handle M-profile
* Fix SVE splice
* Fix SVE LDR/STR
* Remove ignore_memory_transaction_failures on the raspi2
* raspi: Various cleanup/refactoring
# gpg: Signature made Thu 01 Oct 2020 15:46:47 BST
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20201001:
hw/arm/raspi: Remove use of the 'version' value in the board code
hw/arm/raspi: Use RaspiProcessorId to set the firmware load address
hw/arm/raspi: Introduce RaspiProcessorId enum
hw/arm/raspi: Use more specific machine names
hw/arm/raspi: Avoid using TypeInfo::class_data pointer
hw/arm/raspi: Move arm_boot_info structure to RaspiMachineState
hw/arm/raspi: Load the firmware on the first core
hw/arm/raspi: Display the board revision in the machine description
hw/arm/raspi: Remove ignore_memory_transaction_failures on the raspi2
hw/arm/bcm2835: Add more unimplemented peripherals
hw/arm/raspi: Define various blocks base addresses
target/arm: Fix SVE splice
target/arm: Fix sve ldr/str
target/arm: Make isar_feature_aa32_fp16_arith() handle M-profile
target/arm: Add ID register values for Cortex-M0
hw/intc/armv7m_nvic: Only show ID register values for Main Extension CPUs
target/arm: Move id_pfr0, id_pfr1 into ARMISARegisters
target/arm: Replace ARM_FEATURE_PXN with ID_MMFR0.VMSA check
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/arm/bcm2835_peripherals.c | 2 | ||||
-rw-r--r-- | hw/arm/raspi.c | 153 | ||||
-rw-r--r-- | hw/intc/armv7m_nvic.c | 46 | ||||
-rw-r--r-- | include/hw/arm/bcm2835_peripherals.h | 2 | ||||
-rw-r--r-- | include/hw/arm/raspi_platform.h | 51 | ||||
-rw-r--r-- | target/arm/cpu.c | 21 | ||||
-rw-r--r-- | target/arm/cpu.h | 50 | ||||
-rw-r--r-- | target/arm/cpu64.c | 12 | ||||
-rw-r--r-- | target/arm/cpu_tcg.c | 60 | ||||
-rw-r--r-- | target/arm/helper.c | 9 | ||||
-rw-r--r-- | target/arm/kvm64.c | 4 | ||||
-rw-r--r-- | target/arm/translate-sve.c | 6 |
12 files changed, 285 insertions, 131 deletions
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index a9d7f53..15c5c72 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -343,6 +343,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_USB)); + create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000); create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40); create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000); create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000); @@ -356,6 +357,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80); create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000); create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000); + create_unimp(s, &s->v3d, "bcm2835-v3d", V3D_OFFSET, 0x1000); create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100); } diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index d2f6745..b5b30f0 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -41,6 +41,7 @@ struct RaspiMachineState { MachineState parent_obj; /*< public >*/ BCM283XState soc; + struct arm_boot_info binfo; }; typedef struct RaspiMachineState RaspiMachineState; @@ -68,51 +69,43 @@ FIELD(REV_CODE, MANUFACTURER, 16, 4); FIELD(REV_CODE, MEMORY_SIZE, 20, 3); FIELD(REV_CODE, STYLE, 23, 1); +typedef enum RaspiProcessorId { + PROCESSOR_ID_BCM2836 = 1, + PROCESSOR_ID_BCM2837 = 2, +} RaspiProcessorId; + +static const struct { + const char *type; + int cores_count; +} soc_property[] = { + [PROCESSOR_ID_BCM2836] = {TYPE_BCM2836, BCM283X_NCPUS}, + [PROCESSOR_ID_BCM2837] = {TYPE_BCM2837, BCM283X_NCPUS}, +}; + 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) +static RaspiProcessorId board_processor_id(uint32_t board_rev) { + int proc_id = FIELD_EX32(board_rev, REV_CODE, PROCESSOR); + assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ - return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); -} + assert(proc_id < ARRAY_SIZE(soc_property) && soc_property[proc_id].type); -static int board_version(uint32_t board_rev) -{ - return board_processor_id(board_rev) + 1; + return proc_id; } 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]; + return soc_property[board_processor_id(board_rev)].type; } 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]; + return soc_property[board_processor_id(board_rev)].cores_count; } static const char *board_type(uint32_t board_rev) @@ -203,44 +196,47 @@ static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info) cpu_set_pc(cs, info->smp_loader_start); } -static void setup_boot(MachineState *machine, int version, size_t ram_size) +static void setup_boot(MachineState *machine, RaspiProcessorId processor_id, + size_t ram_size) { - static struct arm_boot_info binfo; + RaspiMachineState *s = RASPI_MACHINE(machine); int r; - binfo.board_id = MACH_TYPE_BCM2708; - binfo.ram_size = ram_size; - binfo.nb_cpus = machine->smp.cpus; + s->binfo.board_id = MACH_TYPE_BCM2708; + s->binfo.ram_size = ram_size; + s->binfo.nb_cpus = machine->smp.cpus; - if (version <= 2) { - /* The rpi1 and 2 require some custom setup code to run in Secure - * mode before booting a kernel (to set up the SMC vectors so - * that we get a no-op SMC; this is used by Linux to call the + if (processor_id <= PROCESSOR_ID_BCM2836) { + /* + * The BCM2835 and BCM2836 require some custom setup code to run + * in Secure mode before booting a kernel (to set up the SMC vectors + * so that we get a no-op SMC; this is used by Linux to call the * firmware for some cache maintenance operations. - * The rpi3 doesn't need this. + * The BCM2837 doesn't need this. */ - binfo.board_setup_addr = BOARDSETUP_ADDR; - binfo.write_board_setup = write_board_setup; - binfo.secure_board_setup = true; - binfo.secure_boot = true; + s->binfo.board_setup_addr = BOARDSETUP_ADDR; + s->binfo.write_board_setup = write_board_setup; + s->binfo.secure_board_setup = true; + s->binfo.secure_boot = true; } - /* Pi2 and Pi3 requires SMP setup */ - if (version >= 2) { - binfo.smp_loader_start = SMPBOOT_ADDR; - if (version == 2) { - binfo.write_secondary_boot = write_smpboot; + /* BCM2836 and BCM2837 requires SMP setup */ + if (processor_id >= PROCESSOR_ID_BCM2836) { + s->binfo.smp_loader_start = SMPBOOT_ADDR; + if (processor_id == PROCESSOR_ID_BCM2836) { + s->binfo.write_secondary_boot = write_smpboot; } else { - binfo.write_secondary_boot = write_smpboot64; + s->binfo.write_secondary_boot = write_smpboot64; } - binfo.secondary_cpu_reset_hook = reset_secondary; + s->binfo.secondary_cpu_reset_hook = reset_secondary; } /* If the user specified a "firmware" image (e.g. UEFI), we bypass * the normal Linux boot process */ if (machine->firmware) { - hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2; + hwaddr firmware_addr = processor_id <= PROCESSOR_ID_BCM2836 + ? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3; /* load the firmware image (typically kernel.img) */ r = load_image_targphys(machine->firmware, firmware_addr, ram_size - firmware_addr); @@ -249,11 +245,11 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) exit(1); } - binfo.entry = firmware_addr; - binfo.firmware_loaded = true; + s->binfo.entry = firmware_addr; + s->binfo.firmware_loaded = true; } - arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); + arm_load_kernel(&s->soc.cpu[0].core, machine, &s->binfo); } static void raspi_machine_init(MachineState *machine) @@ -261,7 +257,6 @@ static void raspi_machine_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; DriveInfo *di; @@ -302,17 +297,16 @@ static void raspi_machine_init(MachineState *machine) vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size", &error_abort); - setup_boot(machine, version, machine->ram_size - vcram_size); + setup_boot(machine, board_processor_id(mc->board_rev), + machine->ram_size - vcram_size); } -static void raspi_machine_class_init(ObjectClass *oc, void *data) +static void raspi_machine_class_common_init(MachineClass *mc, + uint32_t board_rev) { - 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->desc = g_strdup_printf("Raspberry Pi %s (revision 1.%u)", + board_type(board_rev), + FIELD_EX32(board_rev, REV_CODE, REVISION)); mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; @@ -321,23 +315,40 @@ static void raspi_machine_class_init(ObjectClass *oc, void *data) mc->default_cpus = mc->min_cpus = mc->max_cpus = cores_count(board_rev); mc->default_ram_size = board_ram_size(board_rev); mc->default_ram_id = "ram"; - if (board_version(board_rev) == 2) { - mc->ignore_memory_transaction_failures = true; - } }; +static void raspi2b_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + + mc->alias = "raspi2"; + rmc->board_rev = 0xa21041; + raspi_machine_class_common_init(mc, rmc->board_rev); +}; + +#ifdef TARGET_AARCH64 +static void raspi3b_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + + mc->alias = "raspi3"; + rmc->board_rev = 0xa02082; + raspi_machine_class_common_init(mc, rmc->board_rev); +}; +#endif /* TARGET_AARCH64 */ + static const TypeInfo raspi_machine_types[] = { { - .name = MACHINE_TYPE_NAME("raspi2"), + .name = MACHINE_TYPE_NAME("raspi2b"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi_machine_class_init, - .class_data = (void *)0xa21041, + .class_init = raspi2b_machine_class_init, #ifdef TARGET_AARCH64 }, { - .name = MACHINE_TYPE_NAME("raspi3"), + .name = MACHINE_TYPE_NAME("raspi3b"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi_machine_class_init, - .class_data = (void *)0xa02082, + .class_init = raspi3b_machine_class_init, #endif }, { .name = TYPE_RASPI_MACHINE, diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 7876c1b..42b1ad5 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1238,32 +1238,74 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) "Aux Fault status registers unimplemented\n"); return 0; case 0xd40: /* PFR0. */ - return cpu->id_pfr0; + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } + return cpu->isar.id_pfr0; case 0xd44: /* PFR1. */ - return cpu->id_pfr1; + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } + return cpu->isar.id_pfr1; case 0xd48: /* DFR0. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_dfr0; case 0xd4c: /* AFR0. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->id_afr0; case 0xd50: /* MMFR0. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_mmfr0; case 0xd54: /* MMFR1. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_mmfr1; case 0xd58: /* MMFR2. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_mmfr2; case 0xd5c: /* MMFR3. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_mmfr3; case 0xd60: /* ISAR0. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar0; case 0xd64: /* ISAR1. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar1; case 0xd68: /* ISAR2. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar2; case 0xd6c: /* ISAR3. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar3; case 0xd70: /* ISAR4. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar4; case 0xd74: /* ISAR5. */ + if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { + goto bad_offset; + } return cpu->isar.id_isar5; case 0xd78: /* CLIDR */ return cpu->clidr; diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h index 13d7c4c..c9ac941 100644 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -45,6 +45,7 @@ struct BCM2835PeripheralState { BCM2835SystemTimerState systmr; BCM2835MphiState mphi; + UnimplementedDeviceState txp; UnimplementedDeviceState armtmr; UnimplementedDeviceState cprman; UnimplementedDeviceState a2w; @@ -66,6 +67,7 @@ struct BCM2835PeripheralState { UnimplementedDeviceState otp; UnimplementedDeviceState dbus; UnimplementedDeviceState ave0; + UnimplementedDeviceState v3d; UnimplementedDeviceState bscsl; UnimplementedDeviceState smi; DWC2State dwc2; diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h index 61b04a1..c7f50b2 100644 --- a/include/hw/arm/raspi_platform.h +++ b/include/hw/arm/raspi_platform.h @@ -20,20 +20,29 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Various undocumented addresses and names come from Herman Hermitage's VC4 + * documentation: + * https://github.com/hermanhermitage/videocoreiv/wiki/MMIO-Register-map */ #ifndef HW_ARM_RASPI_PLATFORM_H #define HW_ARM_RASPI_PLATFORM_H #define MSYNC_OFFSET 0x0000 /* Multicore Sync Block */ -#define IC0_OFFSET 0x2000 +#define CCPT_OFFSET 0x1000 /* Compact Camera Port 2 TX */ +#define INTE_OFFSET 0x2000 /* VC Interrupt controller */ #define ST_OFFSET 0x3000 /* System Timer */ +#define TXP_OFFSET 0x4000 /* Transposer */ +#define JPEG_OFFSET 0x5000 #define MPHI_OFFSET 0x6000 /* Message-based Parallel Host Intf. */ #define DMA_OFFSET 0x7000 /* DMA controller, channels 0-14 */ -#define ARM_OFFSET 0xB000 /* BCM2708 ARM control block */ +#define ARBA_OFFSET 0x9000 +#define BRDG_OFFSET 0xa000 +#define ARM_OFFSET 0xB000 /* ARM control block */ #define ARMCTRL_OFFSET (ARM_OFFSET + 0x000) #define ARMCTRL_IC_OFFSET (ARM_OFFSET + 0x200) /* Interrupt controller */ -#define ARMCTRL_TIMER0_1_OFFSET (ARM_OFFSET + 0x400) /* Timer 0 and 1 */ +#define ARMCTRL_TIMER0_1_OFFSET (ARM_OFFSET + 0x400) /* Timer 0 and 1 (SP804) */ #define ARMCTRL_0_SBM_OFFSET (ARM_OFFSET + 0x800) /* User 0 (ARM) Semaphores * Doorbells & Mailboxes */ #define CPRMAN_OFFSET 0x100000 /* Power Management, Watchdog */ @@ -42,24 +51,50 @@ #define AVS_OFFSET 0x103000 /* Audio Video Standard */ #define RNG_OFFSET 0x104000 #define GPIO_OFFSET 0x200000 -#define UART0_OFFSET 0x201000 -#define MMCI0_OFFSET 0x202000 -#define I2S_OFFSET 0x203000 -#define SPI0_OFFSET 0x204000 +#define UART0_OFFSET 0x201000 /* PL011 */ +#define MMCI0_OFFSET 0x202000 /* Legacy MMC */ +#define I2S_OFFSET 0x203000 /* PCM */ +#define SPI0_OFFSET 0x204000 /* SPI master */ #define BSC0_OFFSET 0x205000 /* BSC0 I2C/TWI */ +#define PIXV0_OFFSET 0x206000 +#define PIXV1_OFFSET 0x207000 +#define DPI_OFFSET 0x208000 +#define DSI0_OFFSET 0x209000 /* Display Serial Interface */ +#define PWM_OFFSET 0x20c000 +#define PERM_OFFSET 0x20d000 +#define TEC_OFFSET 0x20e000 #define OTP_OFFSET 0x20f000 +#define SLIM_OFFSET 0x210000 /* SLIMbus */ +#define CPG_OFFSET 0x211000 #define THERMAL_OFFSET 0x212000 -#define BSC_SL_OFFSET 0x214000 /* SPI slave */ +#define AVSP_OFFSET 0x213000 +#define BSC_SL_OFFSET 0x214000 /* SPI slave (bootrom) */ #define AUX_OFFSET 0x215000 /* AUX: UART1/SPI1/SPI2 */ #define EMMC1_OFFSET 0x300000 +#define EMMC2_OFFSET 0x340000 +#define HVS_OFFSET 0x400000 #define SMI_OFFSET 0x600000 +#define DSI1_OFFSET 0x700000 +#define UCAM_OFFSET 0x800000 +#define CMI_OFFSET 0x802000 #define BSC1_OFFSET 0x804000 /* BSC1 I2C/TWI */ #define BSC2_OFFSET 0x805000 /* BSC2 I2C/TWI */ +#define VECA_OFFSET 0x806000 +#define PIXV2_OFFSET 0x807000 +#define HDMI_OFFSET 0x808000 +#define HDCP_OFFSET 0x809000 +#define ARBR0_OFFSET 0x80a000 #define DBUS_OFFSET 0x900000 #define AVE0_OFFSET 0x910000 #define USB_OTG_OFFSET 0x980000 /* DTC_OTG USB controller */ +#define V3D_OFFSET 0xc00000 #define SDRAMC_OFFSET 0xe00000 +#define L2CC_OFFSET 0xe01000 /* Level 2 Cache controller */ +#define L1CC_OFFSET 0xe02000 /* Level 1 Cache controller */ +#define ARBR1_OFFSET 0xe04000 #define DMA15_OFFSET 0xE05000 /* DMA controller, channel 15 */ +#define DCRC_OFFSET 0xe07000 +#define AXIP_OFFSET 0xe08000 /* GPU interrupts */ #define INTERRUPT_TIMER0 0 diff --git a/target/arm/cpu.c b/target/arm/cpu.c index a7643de..858c5a4 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1588,7 +1588,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (arm_feature(env, ARM_FEATURE_LPAE)) { set_feature(env, ARM_FEATURE_V7MP); - set_feature(env, ARM_FEATURE_PXN); } if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { set_feature(env, ARM_FEATURE_CBAR); @@ -1660,7 +1659,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) /* Disable the security extension feature bits in the processor feature * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12]. */ - cpu->id_pfr1 &= ~0xf0; + cpu->isar.id_pfr1 &= ~0xf0; cpu->isar.id_aa64pfr0 &= ~0xf000; } @@ -1697,7 +1696,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) * id_aa64pfr0_el1[11:8]. */ cpu->isar.id_aa64pfr0 &= ~0xf00; - cpu->id_pfr1 &= ~0xf000; + cpu->isar.id_pfr1 &= ~0xf000; } #ifndef CONFIG_USER_ONLY @@ -1895,8 +1894,8 @@ static void cortex_a8_initfn(Object *obj) cpu->isar.mvfr1 = 0x00011111; cpu->ctr = 0x82048004; cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x1031; - cpu->id_pfr1 = 0x11; + cpu->isar.id_pfr0 = 0x1031; + cpu->isar.id_pfr1 = 0x11; cpu->isar.id_dfr0 = 0x400; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x31100003; @@ -1967,8 +1966,8 @@ static void cortex_a9_initfn(Object *obj) cpu->isar.mvfr1 = 0x01111111; cpu->ctr = 0x80038003; cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x1031; - cpu->id_pfr1 = 0x11; + cpu->isar.id_pfr0 = 0x1031; + cpu->isar.id_pfr1 = 0x11; cpu->isar.id_dfr0 = 0x000; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x00100103; @@ -2031,8 +2030,8 @@ static void cortex_a7_initfn(Object *obj) cpu->isar.mvfr1 = 0x11111111; cpu->ctr = 0x84448003; cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x00001131; - cpu->id_pfr1 = 0x00011011; + cpu->isar.id_pfr0 = 0x00001131; + cpu->isar.id_pfr1 = 0x00011011; cpu->isar.id_dfr0 = 0x02010555; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -2076,8 +2075,8 @@ static void cortex_a15_initfn(Object *obj) cpu->isar.mvfr1 = 0x11111111; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50078; - cpu->id_pfr0 = 0x00001131; - cpu->id_pfr1 = 0x00011011; + cpu->isar.id_pfr0 = 0x00001131; + cpu->isar.id_pfr1 = 0x00011011; cpu->isar.id_dfr0 = 0x02010555; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 6036f61..e4549a8 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -906,6 +906,8 @@ struct ARMCPU { uint32_t id_mmfr2; uint32_t id_mmfr3; uint32_t id_mmfr4; + uint32_t id_pfr0; + uint32_t id_pfr1; uint32_t mvfr0; uint32_t mvfr1; uint32_t mvfr2; @@ -926,8 +928,6 @@ struct ARMCPU { uint32_t reset_fpsid; uint32_t ctr; uint32_t reset_sctlr; - uint32_t id_pfr0; - uint32_t id_pfr1; uint64_t pmceid0; uint64_t pmceid1; uint32_t id_afr0; @@ -1772,6 +1772,15 @@ FIELD(ID_ISAR6, FHM, 8, 4) FIELD(ID_ISAR6, SB, 12, 4) FIELD(ID_ISAR6, SPECRES, 16, 4) +FIELD(ID_MMFR0, VMSA, 0, 4) +FIELD(ID_MMFR0, PMSA, 4, 4) +FIELD(ID_MMFR0, OUTERSHR, 8, 4) +FIELD(ID_MMFR0, SHARELVL, 12, 4) +FIELD(ID_MMFR0, TCM, 16, 4) +FIELD(ID_MMFR0, AUXREG, 20, 4) +FIELD(ID_MMFR0, FCSE, 24, 4) +FIELD(ID_MMFR0, INNERSHR, 28, 4) + FIELD(ID_MMFR3, CMAINTVA, 0, 4) FIELD(ID_MMFR3, CMAINTSW, 4, 4) FIELD(ID_MMFR3, BPMAINT, 8, 4) @@ -1790,6 +1799,15 @@ FIELD(ID_MMFR4, LSM, 20, 4) FIELD(ID_MMFR4, CCIDX, 24, 4) FIELD(ID_MMFR4, EVT, 28, 4) +FIELD(ID_PFR1, PROGMOD, 0, 4) +FIELD(ID_PFR1, SECURITY, 4, 4) +FIELD(ID_PFR1, MPROGMOD, 8, 4) +FIELD(ID_PFR1, VIRTUALIZATION, 12, 4) +FIELD(ID_PFR1, GENTIMER, 16, 4) +FIELD(ID_PFR1, SEC_FRAC, 20, 4) +FIELD(ID_PFR1, VIRT_FRAC, 24, 4) +FIELD(ID_PFR1, GIC, 28, 4) + FIELD(ID_AA64ISAR0, AES, 4, 4) FIELD(ID_AA64ISAR0, SHA1, 8, 4) FIELD(ID_AA64ISAR0, SHA2, 12, 4) @@ -1907,10 +1925,12 @@ FIELD(MVFR0, FPROUND, 28, 4) FIELD(MVFR1, FPFTZ, 0, 4) FIELD(MVFR1, FPDNAN, 4, 4) -FIELD(MVFR1, SIMDLS, 8, 4) -FIELD(MVFR1, SIMDINT, 12, 4) -FIELD(MVFR1, SIMDSP, 16, 4) -FIELD(MVFR1, SIMDHP, 20, 4) +FIELD(MVFR1, SIMDLS, 8, 4) /* A-profile only */ +FIELD(MVFR1, SIMDINT, 12, 4) /* A-profile only */ +FIELD(MVFR1, SIMDSP, 16, 4) /* A-profile only */ +FIELD(MVFR1, SIMDHP, 20, 4) /* A-profile only */ +FIELD(MVFR1, MVE, 8, 4) /* M-profile only */ +FIELD(MVFR1, FP16, 20, 4) /* M-profile only */ FIELD(MVFR1, FPHP, 24, 4) FIELD(MVFR1, SIMDFMAC, 28, 4) @@ -1949,7 +1969,6 @@ enum arm_features { ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */ ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */ ARM_FEATURE_MPIDR, /* has cp15 MPIDR */ - ARM_FEATURE_PXN, /* has Privileged Execute Never bit */ ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ ARM_FEATURE_V8, ARM_FEATURE_AARCH64, /* supports 64 bit mode */ @@ -3514,9 +3533,19 @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id) return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0; } +static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id) +{ + return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0; +} + static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) { - return FIELD_EX32(id->mvfr1, MVFR1, FPHP) >= 3; + /* Sadly this is encoded differently for A-profile and M-profile */ + if (isar_feature_aa32_mprofile(id)) { + return FIELD_EX32(id->mvfr1, MVFR1, FP16) > 0; + } else { + return FIELD_EX32(id->mvfr1, MVFR1, FPHP) >= 3; + } } static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id) @@ -3615,6 +3644,11 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id) return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4; } +static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id) +{ + return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4; +} + static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) { return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 3c2b3d9..e00271b 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -108,8 +108,8 @@ static void aarch64_a57_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->id_pfr0 = 0x00000131; - cpu->id_pfr1 = 0x00011011; + cpu->isar.id_pfr0 = 0x00000131; + cpu->isar.id_pfr1 = 0x00011011; cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -161,8 +161,8 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x84448004; /* L1Ip = VIPT */ cpu->reset_sctlr = 0x00c50838; - cpu->id_pfr0 = 0x00000131; - cpu->id_pfr1 = 0x00011011; + cpu->isar.id_pfr0 = 0x00000131; + cpu->isar.id_pfr1 = 0x00011011; cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10101105; @@ -213,8 +213,8 @@ static void aarch64_a72_initfn(Object *obj) cpu->isar.mvfr2 = 0x00000043; cpu->ctr = 0x8444c004; cpu->reset_sctlr = 0x00c50838; - cpu->id_pfr0 = 0x00000131; - cpu->id_pfr1 = 0x00011011; + cpu->isar.id_pfr0 = 0x00000131; + cpu->isar.id_pfr1 = 0x00011011; cpu->isar.id_dfr0 = 0x03010066; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x10201105; diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index 00b0e08..0013e25 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -142,8 +142,8 @@ static void arm1136_r2_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; + cpu->isar.id_pfr0 = 0x111; + cpu->isar.id_pfr1 = 0x1; cpu->isar.id_dfr0 = 0x2; cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; @@ -173,8 +173,8 @@ static void arm1136_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; + cpu->isar.id_pfr0 = 0x111; + cpu->isar.id_pfr1 = 0x1; cpu->isar.id_dfr0 = 0x2; cpu->id_afr0 = 0x3; cpu->isar.id_mmfr0 = 0x01130003; @@ -205,8 +205,8 @@ static void arm1176_initfn(Object *obj) cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1dd20d2; cpu->reset_sctlr = 0x00050078; - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x11; + cpu->isar.id_pfr0 = 0x111; + cpu->isar.id_pfr1 = 0x11; cpu->isar.id_dfr0 = 0x33; cpu->id_afr0 = 0; cpu->isar.id_mmfr0 = 0x01130003; @@ -234,8 +234,8 @@ static void arm11mpcore_initfn(Object *obj) cpu->isar.mvfr0 = 0x11111111; cpu->isar.mvfr1 = 0x00000000; cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ - cpu->id_pfr0 = 0x111; - cpu->id_pfr1 = 0x1; + cpu->isar.id_pfr0 = 0x111; + cpu->isar.id_pfr1 = 0x1; cpu->isar.id_dfr0 = 0; cpu->id_afr0 = 0x2; cpu->isar.id_mmfr0 = 0x01100103; @@ -256,6 +256,30 @@ static void cortex_m0_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_M); cpu->midr = 0x410cc200; + + /* + * These ID register values are not guest visible, because + * we do not implement the Main Extension. They must be set + * to values corresponding to the Cortex-M0's implemented + * features, because QEMU generally controls its emulation + * by looking at ID register fields. We use the same values as + * for the M3. + */ + cpu->isar.id_pfr0 = 0x00000030; + cpu->isar.id_pfr1 = 0x00000200; + cpu->isar.id_dfr0 = 0x00100000; + cpu->id_afr0 = 0x00000000; + cpu->isar.id_mmfr0 = 0x00000030; + cpu->isar.id_mmfr1 = 0x00000000; + cpu->isar.id_mmfr2 = 0x00000000; + cpu->isar.id_mmfr3 = 0x00000000; + cpu->isar.id_isar0 = 0x01141110; + cpu->isar.id_isar1 = 0x02111000; + cpu->isar.id_isar2 = 0x21112231; + cpu->isar.id_isar3 = 0x01111110; + cpu->isar.id_isar4 = 0x01310102; + cpu->isar.id_isar5 = 0x00000000; + cpu->isar.id_isar6 = 0x00000000; } static void cortex_m3_initfn(Object *obj) @@ -266,8 +290,8 @@ static void cortex_m3_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_M_MAIN); cpu->midr = 0x410fc231; cpu->pmsav7_dregion = 8; - cpu->id_pfr0 = 0x00000030; - cpu->id_pfr1 = 0x00000200; + cpu->isar.id_pfr0 = 0x00000030; + cpu->isar.id_pfr1 = 0x00000200; cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; @@ -296,8 +320,8 @@ static void cortex_m4_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr2 = 0x00000000; - cpu->id_pfr0 = 0x00000030; - cpu->id_pfr1 = 0x00000200; + cpu->isar.id_pfr0 = 0x00000030; + cpu->isar.id_pfr1 = 0x00000200; cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00000030; @@ -326,8 +350,8 @@ static void cortex_m7_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110221; cpu->isar.mvfr1 = 0x12000011; cpu->isar.mvfr2 = 0x00000040; - cpu->id_pfr0 = 0x00000030; - cpu->id_pfr1 = 0x00000200; + cpu->isar.id_pfr0 = 0x00000030; + cpu->isar.id_pfr1 = 0x00000200; cpu->isar.id_dfr0 = 0x00100000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00100030; @@ -358,8 +382,8 @@ static void cortex_m33_initfn(Object *obj) cpu->isar.mvfr0 = 0x10110021; cpu->isar.mvfr1 = 0x11000011; cpu->isar.mvfr2 = 0x00000040; - cpu->id_pfr0 = 0x00000030; - cpu->id_pfr1 = 0x00000210; + cpu->isar.id_pfr0 = 0x00000030; + cpu->isar.id_pfr1 = 0x00000210; cpu->isar.id_dfr0 = 0x00200000; cpu->id_afr0 = 0x00000000; cpu->isar.id_mmfr0 = 0x00101F40; @@ -397,8 +421,8 @@ static void cortex_r5_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_PMSA); set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->midr = 0x411fc153; /* r1p3 */ - cpu->id_pfr0 = 0x0131; - cpu->id_pfr1 = 0x001; + cpu->isar.id_pfr0 = 0x0131; + cpu->isar.id_pfr1 = 0x001; cpu->isar.id_dfr0 = 0x010400; cpu->id_afr0 = 0x0; cpu->isar.id_mmfr0 = 0x0210030; diff --git a/target/arm/helper.c b/target/arm/helper.c index 88bd9dd..b394db3 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6625,7 +6625,7 @@ static void define_pmu_regs(ARMCPU *cpu) static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) { ARMCPU *cpu = env_archcpu(env); - uint64_t pfr1 = cpu->id_pfr1; + uint64_t pfr1 = cpu->isar.id_pfr1; if (env->gicv3state) { pfr1 |= 1 << 28; @@ -7258,7 +7258,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, .accessfn = access_aa32_tid3, - .resetvalue = cpu->id_pfr0 }, + .resetvalue = cpu->isar.id_pfr0 }, /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know * the value of the GIC field until after we define these regs. */ @@ -10537,6 +10537,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, target_ulong *page_size, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); + ARMCPU *cpu = env_archcpu(env); int level = 1; uint32_t table; uint32_t desc; @@ -10563,7 +10564,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, goto do_fault; } type = (desc & 3); - if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) { + if (type == 0 || (type == 3 && !cpu_isar_feature(aa32_pxn, cpu))) { /* Section translation fault, or attempt to use the encoding * which is Reserved on implementations without PXN. */ @@ -10605,7 +10606,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, pxn = desc & 1; ns = extract32(desc, 19, 1); } else { - if (arm_feature(env, ARM_FEATURE_PXN)) { + if (cpu_isar_feature(aa32_pxn, cpu)) { pxn = (desc >> 2) & 1; } ns = extract32(desc, 3, 1); diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 987b35e..fae07c3 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -555,6 +555,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) * than skipping the reads and leaving 0, as we must avoid * considering the values in every case. */ + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0, + ARM64_SYS_REG(3, 0, 0, 1, 0)); + err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1, + ARM64_SYS_REG(3, 0, 0, 1, 1)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0, ARM64_SYS_REG(3, 0, 0, 1, 2)); err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c index e4cd6b6..9095586 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -2689,7 +2689,7 @@ static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a) { if (sve_access_check(s)) { gen_gvec_ool_zzzp(s, gen_helper_sve_splice, - a->rd, a->rn, a->rm, a->pg, 0); + a->rd, a->rn, a->rm, a->pg, a->esz); } return true; } @@ -4290,7 +4290,7 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm) for (i = 0; i < len_align; i += 8) { tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEQ); tcg_gen_st_i64(t0, cpu_env, vofs + i); - tcg_gen_addi_i64(clean_addr, cpu_reg_sp(s, rn), 8); + tcg_gen_addi_i64(clean_addr, clean_addr, 8); } tcg_temp_free_i64(t0); } else { @@ -4379,7 +4379,7 @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm) for (i = 0; i < len_align; i += 8) { tcg_gen_ld_i64(t0, cpu_env, vofs + i); tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEQ); - tcg_gen_addi_i64(clean_addr, cpu_reg_sp(s, rn), 8); + tcg_gen_addi_i64(clean_addr, clean_addr, 8); } tcg_temp_free_i64(t0); } else { |