1 | The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1: | 1 | Hi; here's another arm pullreq; by volume most of this is |
---|---|---|---|
2 | refactoring from me, but there are also some bugfixes and | ||
3 | other bits and pieces here. | ||
2 | 4 | ||
3 | Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000) | 5 | thanks |
6 | -- PMM | ||
7 | |||
8 | The following changes since commit ed734377ab3f3f3cc15d7aa301a87ab6370f2eed: | ||
9 | |||
10 | Merge tag 'linux-user-fix-gupnp-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2025-01-24 14:43:07 -0500) | ||
4 | 11 | ||
5 | are available in the Git repository at: | 12 | are available in the Git repository at: |
6 | 13 | ||
7 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302 | 14 | https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250128-1 |
8 | 15 | ||
9 | for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2: | 16 | for you to fetch changes up to 664280abddcb3cacc9c6204706bb739fcc1316f7: |
10 | 17 | ||
11 | ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000) | 18 | hw/usb/canokey: Fix buffer overflow for OUT packet (2025-01-28 18:40:19 +0000) |
12 | 19 | ||
13 | ---------------------------------------------------------------- | 20 | ---------------------------------------------------------------- |
14 | target-arm queue: | 21 | target-arm queue: |
15 | * mps3-an547: Add missing user ahb interfaces | 22 | * hw/arm: Remove various uses of first_cpu global |
16 | * hw/arm/mps2-tz.c: Update AN547 documentation URL | 23 | * hw/char/imx_serial: Fix reset value of UFCR register |
17 | * hw/input/tsc210x: Don't abort on bad SPI word widths | 24 | * hw/char/imx_serial: Update all state before restarting ageing timer |
18 | * hw/i2c: flatten pca954x mux device | 25 | * hw/pci-host/designware: Expose MSI IRQ |
19 | * target/arm: Support PSCI 1.1 and SMCCC 1.0 | 26 | * hw/arm/stellaris: refactoring, cleanup |
20 | * target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv() | 27 | * hw/arm/stellaris: map both I2C controllers |
21 | * tests/qtest: add qtests for npcm7xx sdhci | 28 | * tests/functional: Add a test for the arm microbit machine |
22 | * Implement FEAT_LVA | 29 | * target/arm: arm_reset_sve_state() should set FPSR, not FPCR |
23 | * Implement FEAT_LPA | 30 | * target/arm: refactorings preparatory to FEAT_AFP implementation |
24 | * Implement FEAT_LPA2 (but do not enable it yet) | 31 | * fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed |
25 | * Report KVM's actual PSCI version to guest in dtb | 32 | * fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed |
26 | * ui/cocoa.m: Fix updateUIInfo threading issues | 33 | * hw/usb/canokey: Fix buffer overflow for OUT packet |
27 | * ui/cocoa.m: Remove unnecessary NSAutoreleasePools | ||
28 | 34 | ||
29 | ---------------------------------------------------------------- | 35 | ---------------------------------------------------------------- |
30 | Akihiko Odaki (1): | 36 | Bernhard Beschow (3): |
31 | target/arm: Support PSCI 1.1 and SMCCC 1.0 | 37 | hw/char/imx_serial: Fix reset value of UFCR register |
38 | hw/char/imx_serial: Update all state before restarting ageing timer | ||
39 | hw/pci-host/designware: Expose MSI IRQ | ||
32 | 40 | ||
33 | Jimmy Brisson (1): | 41 | Hongren Zheng (1): |
34 | mps3-an547: Add missing user ahb interfaces | 42 | hw/usb/canokey: Fix buffer overflow for OUT packet |
35 | 43 | ||
36 | Patrick Venture (1): | 44 | Peter Maydell (22): |
37 | hw/i2c: flatten pca954x mux device | 45 | target/arm: arm_reset_sve_state() should set FPSR, not FPCR |
46 | target/arm: Use FPSR_ constants in vfp_exceptbits_from_host() | ||
47 | target/arm: Use uint32_t in vfp_exceptbits_from_host() | ||
48 | target/arm: Define new fp_status_a32 and fp_status_a64 | ||
49 | target/arm: Use vfp.fp_status_a64 in A64-only helper functions | ||
50 | target/arm: Use fp_status_a64 or fp_status_a32 in is_ebf() | ||
51 | target/arm: Use fp_status_a32 in vjvct helper | ||
52 | target/arm: Use fp_status_a32 in vfp_cmp helpers | ||
53 | target/arm: Use FPST_A32 in A32 decoder | ||
54 | target/arm: Use FPST_A64 in A64 decoder | ||
55 | target/arm: Remove now-unused vfp.fp_status and FPST_FPCR | ||
56 | target/arm: Define new fp_status_f16_a32 and fp_status_f16_a64 | ||
57 | target/arm: Use fp_status_f16_a32 in AArch32-only helpers | ||
58 | target/arm: Use fp_status_f16_a64 in AArch64-only helpers | ||
59 | target/arm: Use FPST_A32_F16 in A32 decoder | ||
60 | target/arm: Use FPST_A64_F16 in A64 decoder | ||
61 | target/arm: Remove now-unused vfp.fp_status_f16 and FPST_FPCR_F16 | ||
62 | fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed | ||
63 | fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed | ||
64 | fpu: Fix a comment in softfloat-types.h | ||
65 | target/arm: Remove redundant advsimd float16 helpers | ||
66 | target/arm: Use FPST_A64_F16 for halfprec-to-other conversions | ||
38 | 67 | ||
39 | Peter Maydell (5): | 68 | Philippe Mathieu-Daudé (9): |
40 | hw/arm/mps2-tz.c: Update AN547 documentation URL | 69 | hw/arm/nrf51: Rename ARMv7MState 'cpu' -> 'armv7m' |
41 | hw/input/tsc210x: Don't abort on bad SPI word widths | 70 | hw/arm/stellaris: Add 'armv7m' local variable |
42 | target/arm: Report KVM's actual PSCI version to guest in dtb | 71 | hw/arm/v7m: Remove use of &first_cpu in machine_init() |
43 | ui/cocoa.m: Fix updateUIInfo threading issues | 72 | hw/arm/stellaris: Link each board schematic |
44 | ui/cocoa.m: Remove unnecessary NSAutoreleasePools | 73 | hw/arm/stellaris: Constify read-only arrays |
74 | hw/arm/stellaris: Remove incorrect unimplemented i2c-0 at 0x40002000 | ||
75 | hw/arm/stellaris: Replace magic numbers by definitions | ||
76 | hw/arm/stellaris: Use DEVCAP macro to access DeviceCapability registers | ||
77 | hw/arm/stellaris: Map both I2C controllers | ||
45 | 78 | ||
46 | Richard Henderson (16): | 79 | Thomas Huth (1): |
47 | hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N> | 80 | tests/functional: Add a test for the arm microbit machine |
48 | target/arm: Set TCR_EL1.TSZ for user-only | ||
49 | target/arm: Fault on invalid TCR_ELx.TxSZ | ||
50 | target/arm: Move arm_pamax out of line | ||
51 | target/arm: Pass outputsize down to check_s2_mmu_setup | ||
52 | target/arm: Use MAKE_64BIT_MASK to compute indexmask | ||
53 | target/arm: Honor TCR_ELx.{I}PS | ||
54 | target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA | ||
55 | target/arm: Implement FEAT_LVA | ||
56 | target/arm: Implement FEAT_LPA | ||
57 | target/arm: Extend arm_fi_to_lfsc to level -1 | ||
58 | target/arm: Introduce tlbi_aa64_get_range | ||
59 | target/arm: Fix TLBIRange.base for 16k and 64k pages | ||
60 | target/arm: Validate tlbi TG matches translation granule in use | ||
61 | target/arm: Advertise all page sizes for -cpu max | ||
62 | target/arm: Implement FEAT_LPA2 | ||
63 | 81 | ||
64 | Shengtan Mao (1): | 82 | MAINTAINERS | 1 + |
65 | tests/qtest: add qtests for npcm7xx sdhci | 83 | hw/usb/canokey.h | 4 -- |
84 | include/fpu/softfloat-types.h | 10 +-- | ||
85 | include/hw/arm/fsl-imx6.h | 4 +- | ||
86 | include/hw/arm/fsl-imx7.h | 4 +- | ||
87 | include/hw/arm/nrf51_soc.h | 2 +- | ||
88 | include/hw/char/imx_serial.h | 2 +- | ||
89 | include/hw/pci-host/designware.h | 1 + | ||
90 | target/arm/cpu.h | 12 ++-- | ||
91 | target/arm/tcg/helper-a64.h | 8 --- | ||
92 | target/arm/tcg/translate.h | 32 ++++++--- | ||
93 | fpu/softfloat.c | 6 +- | ||
94 | hw/arm/b-l475e-iot01a.c | 2 +- | ||
95 | hw/arm/fsl-imx6.c | 13 +++- | ||
96 | hw/arm/fsl-imx7.c | 13 +++- | ||
97 | hw/arm/microbit.c | 2 +- | ||
98 | hw/arm/mps2-tz.c | 2 +- | ||
99 | hw/arm/mps2.c | 2 +- | ||
100 | hw/arm/msf2-som.c | 2 +- | ||
101 | hw/arm/musca.c | 2 +- | ||
102 | hw/arm/netduino2.c | 2 +- | ||
103 | hw/arm/netduinoplus2.c | 2 +- | ||
104 | hw/arm/nrf51_soc.c | 18 ++--- | ||
105 | hw/arm/olimex-stm32-h405.c | 2 +- | ||
106 | hw/arm/stellaris.c | 118 +++++++++++++++++++----------- | ||
107 | hw/arm/stm32vldiscovery.c | 2 +- | ||
108 | hw/char/imx_serial.c | 7 +- | ||
109 | hw/pci-host/designware.c | 7 +- | ||
110 | hw/usb/canokey.c | 6 +- | ||
111 | target/arm/cpu.c | 6 +- | ||
112 | target/arm/helper.c | 2 +- | ||
113 | target/arm/tcg/helper-a64.c | 9 --- | ||
114 | target/arm/tcg/sme_helper.c | 6 +- | ||
115 | target/arm/tcg/sve_helper.c | 6 +- | ||
116 | target/arm/tcg/translate-a64.c | 103 ++++++++++++++------------- | ||
117 | target/arm/tcg/translate-sme.c | 4 +- | ||
118 | target/arm/tcg/translate-sve.c | 130 +++++++++++++++++----------------- | ||
119 | target/arm/tcg/translate-vfp.c | 78 ++++++++++---------- | ||
120 | target/arm/tcg/vec_helper.c | 22 +++--- | ||
121 | target/arm/vfp_helper.c | 73 +++++++++++-------- | ||
122 | target/i386/tcg/fpu_helper.c | 8 +-- | ||
123 | target/m68k/fpu_helper.c | 2 +- | ||
124 | target/mips/tcg/msa_helper.c | 4 +- | ||
125 | target/rx/op_helper.c | 4 +- | ||
126 | target/tricore/fpu_helper.c | 6 +- | ||
127 | fpu/softfloat-parts.c.inc | 4 +- | ||
128 | hw/arm/Kconfig | 2 + | ||
129 | tests/functional/meson.build | 1 + | ||
130 | tests/functional/test_arm_microbit.py | 31 ++++++++ | ||
131 | 49 files changed, 452 insertions(+), 337 deletions(-) | ||
132 | create mode 100755 tests/functional/test_arm_microbit.py | ||
66 | 133 | ||
67 | Wentao_Liang (1): | ||
68 | target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv() | ||
69 | |||
70 | docs/system/arm/emulation.rst | 3 + | ||
71 | include/hw/registerfields.h | 48 +++++- | ||
72 | target/arm/cpu-param.h | 4 +- | ||
73 | target/arm/cpu.h | 27 ++++ | ||
74 | target/arm/internals.h | 58 ++++--- | ||
75 | target/arm/kvm-consts.h | 14 +- | ||
76 | hw/arm/boot.c | 11 +- | ||
77 | hw/arm/mps2-tz.c | 6 +- | ||
78 | hw/i2c/i2c_mux_pca954x.c | 77 ++------- | ||
79 | hw/input/tsc210x.c | 8 +- | ||
80 | target/arm/cpu.c | 8 +- | ||
81 | target/arm/cpu64.c | 7 +- | ||
82 | target/arm/helper.c | 332 ++++++++++++++++++++++++++++++--------- | ||
83 | target/arm/hvf/hvf.c | 27 +++- | ||
84 | target/arm/kvm64.c | 14 +- | ||
85 | target/arm/psci.c | 35 ++++- | ||
86 | target/arm/translate-a64.c | 2 +- | ||
87 | tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++ | ||
88 | tests/qtest/meson.build | 1 + | ||
89 | ui/cocoa.m | 31 ++-- | ||
90 | 20 files changed, 736 insertions(+), 192 deletions(-) | ||
91 | create mode 100644 tests/qtest/npcm7xx_sdhci-test.c | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | The macro is a bit more readable than the inlined computation. | 3 | The ARMv7MState object is not simply a CPU, it also |
4 | contains the NVIC, SysTick timer, and various MemoryRegions. | ||
4 | 5 | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 6 | Rename the field as 'armv7m', like other Cortex-M boards. |
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 7 | |
7 | Message-id: 20220301215958.157011-7-richard.henderson@linaro.org | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-id: 20250112225614.33723-2-philmd@linaro.org | ||
8 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
9 | --- | 12 | --- |
10 | target/arm/helper.c | 4 ++-- | 13 | include/hw/arm/nrf51_soc.h | 2 +- |
11 | 1 file changed, 2 insertions(+), 2 deletions(-) | 14 | hw/arm/nrf51_soc.c | 18 +++++++++--------- |
15 | 2 files changed, 10 insertions(+), 10 deletions(-) | ||
12 | 16 | ||
13 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 17 | diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h |
14 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/arm/helper.c | 19 | --- a/include/hw/arm/nrf51_soc.h |
16 | +++ b/target/arm/helper.c | 20 | +++ b/include/hw/arm/nrf51_soc.h |
17 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | 21 | @@ -XXX,XX +XXX,XX @@ struct NRF51State { |
18 | level = startlevel; | 22 | SysBusDevice parent_obj; |
23 | |||
24 | /*< public >*/ | ||
25 | - ARMv7MState cpu; | ||
26 | + ARMv7MState armv7m; | ||
27 | |||
28 | NRF51UARTState uart; | ||
29 | NRF51RNGState rng; | ||
30 | diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/hw/arm/nrf51_soc.c | ||
33 | +++ b/hw/arm/nrf51_soc.c | ||
34 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) | ||
19 | } | 35 | } |
20 | 36 | /* This clock doesn't need migration because it is fixed-frequency */ | |
21 | - indexmask_grainsize = (1ULL << (stride + 3)) - 1; | 37 | clock_set_hz(s->sysclk, HCLK_FRQ); |
22 | - indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1; | 38 | - qdev_connect_clock_in(DEVICE(&s->cpu), "cpuclk", s->sysclk); |
23 | + indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3); | 39 | + qdev_connect_clock_in(DEVICE(&s->armv7m), "cpuclk", s->sysclk); |
24 | + indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level))); | 40 | /* |
25 | 41 | * This SoC has no systick device, so don't connect refclk. | |
26 | /* Now we can extract the actual base address from the TTBR */ | 42 | * TODO: model the lack of systick (currently the armv7m object |
27 | descaddr = extract64(ttbr, 0, 48); | 43 | * will always provide one). |
44 | */ | ||
45 | |||
46 | - object_property_set_link(OBJECT(&s->cpu), "memory", OBJECT(&s->container), | ||
47 | + object_property_set_link(OBJECT(&s->armv7m), "memory", OBJECT(&s->container), | ||
48 | &error_abort); | ||
49 | - if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu), errp)) { | ||
50 | + if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) { | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) | ||
55 | mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0); | ||
56 | memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0); | ||
57 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0, | ||
58 | - qdev_get_gpio_in(DEVICE(&s->cpu), | ||
59 | + qdev_get_gpio_in(DEVICE(&s->armv7m), | ||
60 | BASE_TO_IRQ(NRF51_UART_BASE))); | ||
61 | |||
62 | /* RNG */ | ||
63 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) | ||
64 | mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0); | ||
65 | memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0); | ||
66 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0, | ||
67 | - qdev_get_gpio_in(DEVICE(&s->cpu), | ||
68 | + qdev_get_gpio_in(DEVICE(&s->armv7m), | ||
69 | BASE_TO_IRQ(NRF51_RNG_BASE))); | ||
70 | |||
71 | /* UICR, FICR, NVMC, FLASH */ | ||
72 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) | ||
73 | |||
74 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr); | ||
75 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0, | ||
76 | - qdev_get_gpio_in(DEVICE(&s->cpu), | ||
77 | + qdev_get_gpio_in(DEVICE(&s->armv7m), | ||
78 | BASE_TO_IRQ(base_addr))); | ||
79 | } | ||
80 | |||
81 | @@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj) | ||
82 | |||
83 | memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX); | ||
84 | |||
85 | - object_initialize_child(OBJECT(s), "armv6m", &s->cpu, TYPE_ARMV7M); | ||
86 | - qdev_prop_set_string(DEVICE(&s->cpu), "cpu-type", | ||
87 | + object_initialize_child(OBJECT(s), "armv6m", &s->armv7m, TYPE_ARMV7M); | ||
88 | + qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type", | ||
89 | ARM_CPU_TYPE_NAME("cortex-m0")); | ||
90 | - qdev_prop_set_uint32(DEVICE(&s->cpu), "num-irq", 32); | ||
91 | + qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", 32); | ||
92 | |||
93 | object_initialize_child(obj, "uart", &s->uart, TYPE_NRF51_UART); | ||
94 | object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev"); | ||
28 | -- | 95 | -- |
29 | 2.25.1 | 96 | 2.34.1 |
30 | 97 | ||
31 | 98 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Add new macros to manipulate signed fields within the register. | 3 | While the TYPE_ARMV7M object forward its NVIC interrupt lines, |
4 | it is somehow misleading to name it 'nvic'. Add the 'armv7m' | ||
5 | local variable for clarity, but also keep the 'nvic' variable | ||
6 | behaving like before when used for wiring IRQ lines. | ||
4 | 7 | ||
5 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
6 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
7 | Message-id: 20220301215958.157011-2-richard.henderson@linaro.org | 10 | Message-id: 20250112225614.33723-3-philmd@linaro.org |
8 | Suggested-by: Peter Maydell <peter.maydell@linaro.org> | ||
9 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
11 | --- | 12 | --- |
12 | include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++- | 13 | hw/arm/stellaris.c | 21 +++++++++++---------- |
13 | 1 file changed, 47 insertions(+), 1 deletion(-) | 14 | 1 file changed, 11 insertions(+), 10 deletions(-) |
14 | 15 | ||
15 | diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h | 16 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
16 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/include/hw/registerfields.h | 18 | --- a/hw/arm/stellaris.c |
18 | +++ b/include/hw/registerfields.h | 19 | +++ b/hw/arm/stellaris.c |
19 | @@ -XXX,XX +XXX,XX @@ | 20 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
20 | extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 21 | */ |
21 | R_ ## reg ## _ ## field ## _LENGTH) | 22 | |
22 | 23 | Object *soc_container; | |
23 | +#define FIELD_SEX8(storage, reg, field) \ | 24 | - DeviceState *gpio_dev[7], *nvic; |
24 | + sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 25 | + DeviceState *gpio_dev[7], *armv7m, *nvic; |
25 | + R_ ## reg ## _ ## field ## _LENGTH) | 26 | qemu_irq gpio_in[7][8]; |
26 | +#define FIELD_SEX16(storage, reg, field) \ | 27 | qemu_irq gpio_out[7][8]; |
27 | + sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 28 | qemu_irq adc; |
28 | + R_ ## reg ## _ ## field ## _LENGTH) | 29 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
29 | +#define FIELD_SEX32(storage, reg, field) \ | 30 | qdev_prop_set_uint32(ssys_dev, "dc4", board->dc4); |
30 | + sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 31 | sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal); |
31 | + R_ ## reg ## _ ## field ## _LENGTH) | 32 | |
32 | +#define FIELD_SEX64(storage, reg, field) \ | 33 | - nvic = qdev_new(TYPE_ARMV7M); |
33 | + sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 34 | - object_property_add_child(soc_container, "v7m", OBJECT(nvic)); |
34 | + R_ ## reg ## _ ## field ## _LENGTH) | 35 | - qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); |
35 | + | 36 | - qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS); |
36 | /* Extract a field from an array of registers */ | 37 | - qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); |
37 | #define ARRAY_FIELD_EX32(regs, reg, field) \ | 38 | - qdev_prop_set_bit(nvic, "enable-bitband", true); |
38 | FIELD_EX32((regs)[R_ ## reg], reg, field) | 39 | - qdev_connect_clock_in(nvic, "cpuclk", |
39 | @@ -XXX,XX +XXX,XX @@ | 40 | + armv7m = qdev_new(TYPE_ARMV7M); |
40 | _d; }) | 41 | + object_property_add_child(soc_container, "v7m", OBJECT(armv7m)); |
41 | #define FIELD_DP64(storage, reg, field, val) ({ \ | 42 | + qdev_prop_set_uint32(armv7m, "num-irq", NUM_IRQ_LINES); |
42 | struct { \ | 43 | + qdev_prop_set_uint8(armv7m, "num-prio-bits", NUM_PRIO_BITS); |
43 | - uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \ | 44 | + qdev_prop_set_string(armv7m, "cpu-type", ms->cpu_type); |
44 | + uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \ | 45 | + qdev_prop_set_bit(armv7m, "enable-bitband", true); |
45 | + } _v = { .v = val }; \ | 46 | + qdev_connect_clock_in(armv7m, "cpuclk", |
46 | + uint64_t _d; \ | 47 | qdev_get_clock_out(ssys_dev, "SYSCLK")); |
47 | + _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 48 | /* This SoC does not connect the systick reference clock */ |
48 | + R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ | 49 | - object_property_set_link(OBJECT(nvic), "memory", |
49 | + _d; }) | 50 | + object_property_set_link(OBJECT(armv7m), "memory", |
50 | + | 51 | OBJECT(get_system_memory()), &error_abort); |
51 | +#define FIELD_SDP8(storage, reg, field, val) ({ \ | 52 | /* This will exit with an error if the user passed us a bad cpu_type */ |
52 | + struct { \ | 53 | - sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal); |
53 | + signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ | 54 | + sysbus_realize_and_unref(SYS_BUS_DEVICE(armv7m), &error_fatal); |
54 | + } _v = { .v = val }; \ | 55 | + nvic = armv7m; |
55 | + uint8_t _d; \ | 56 | |
56 | + _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | 57 | /* Now we can wire up the IRQ and MMIO of the system registers */ |
57 | + R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ | 58 | sysbus_mmio_map(SYS_BUS_DEVICE(ssys_dev), 0, 0x400fe000); |
58 | + _d; }) | ||
59 | +#define FIELD_SDP16(storage, reg, field, val) ({ \ | ||
60 | + struct { \ | ||
61 | + signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ | ||
62 | + } _v = { .v = val }; \ | ||
63 | + uint16_t _d; \ | ||
64 | + _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | ||
65 | + R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ | ||
66 | + _d; }) | ||
67 | +#define FIELD_SDP32(storage, reg, field, val) ({ \ | ||
68 | + struct { \ | ||
69 | + signed int v:R_ ## reg ## _ ## field ## _LENGTH; \ | ||
70 | + } _v = { .v = val }; \ | ||
71 | + uint32_t _d; \ | ||
72 | + _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | ||
73 | + R_ ## reg ## _ ## field ## _LENGTH, _v.v); \ | ||
74 | + _d; }) | ||
75 | +#define FIELD_SDP64(storage, reg, field, val) ({ \ | ||
76 | + struct { \ | ||
77 | + int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \ | ||
78 | } _v = { .v = val }; \ | ||
79 | uint64_t _d; \ | ||
80 | _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \ | ||
81 | -- | 59 | -- |
82 | 2.25.1 | 60 | 2.34.1 |
83 | 61 | ||
84 | 62 | diff view generated by jsdifflib |
1 | From: Jimmy Brisson <jimmy.brisson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | With these interfaces missing, TFM would delegate peripherals 0, 1, | 3 | When instanciating the machine model, the machine_init() |
4 | 2, 3 and 8, and qemu would ignore the delegation of interface 8, as | 4 | implementations usually create the CPUs, so have access |
5 | it thought interface 4 was eth & USB. | 5 | to its first CPU. Use that rather then the &first_cpu |
6 | global. | ||
6 | 7 | ||
7 | This patch corrects this behavior and allows TFM to delegate the | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
8 | eth & USB peripheral to NS mode. | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | 10 | Reviewed-by: Samuel Tardieu <sam@rfc1149.net> | |
10 | (The old QEMU behaviour was based on revision B of the AN547 | 11 | Message-id: 20250112225614.33723-4-philmd@linaro.org |
11 | appnote; revision C corrects this error in the documentation, | ||
12 | and this commit brings QEMU in to line with how the FPGA | ||
13 | image really behaves.) | ||
14 | |||
15 | Signed-off-by: Jimmy Brisson <jimmy.brisson@linaro.org> | ||
16 | Message-id: 20220210210227.3203883-1-jimmy.brisson@linaro.org | ||
17 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
18 | [PMM: added commit message note clarifying that the old behaviour | ||
19 | was a docs issue, not because there were two different versions | ||
20 | of the FPGA image] | ||
21 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
22 | --- | 13 | --- |
23 | hw/arm/mps2-tz.c | 4 ++++ | 14 | hw/arm/b-l475e-iot01a.c | 2 +- |
24 | 1 file changed, 4 insertions(+) | 15 | hw/arm/microbit.c | 2 +- |
16 | hw/arm/mps2-tz.c | 2 +- | ||
17 | hw/arm/mps2.c | 2 +- | ||
18 | hw/arm/msf2-som.c | 2 +- | ||
19 | hw/arm/musca.c | 2 +- | ||
20 | hw/arm/netduino2.c | 2 +- | ||
21 | hw/arm/netduinoplus2.c | 2 +- | ||
22 | hw/arm/olimex-stm32-h405.c | 2 +- | ||
23 | hw/arm/stellaris.c | 2 +- | ||
24 | hw/arm/stm32vldiscovery.c | 2 +- | ||
25 | 11 files changed, 11 insertions(+), 11 deletions(-) | ||
25 | 26 | ||
27 | diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/hw/arm/b-l475e-iot01a.c | ||
30 | +++ b/hw/arm/b-l475e-iot01a.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static void bl475e_init(MachineState *machine) | ||
32 | sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal); | ||
33 | |||
34 | sc = STM32L4X5_SOC_GET_CLASS(&s->soc); | ||
35 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0, | ||
36 | + armv7m_load_kernel(s->soc.armv7m.cpu, machine->kernel_filename, 0, | ||
37 | sc->flash_size); | ||
38 | |||
39 | if (object_class_by_name(TYPE_DM163)) { | ||
40 | diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/hw/arm/microbit.c | ||
43 | +++ b/hw/arm/microbit.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void microbit_init(MachineState *machine) | ||
45 | memory_region_add_subregion_overlap(&s->nrf51.container, NRF51_TWI_BASE, | ||
46 | mr, -1); | ||
47 | |||
48 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, | ||
49 | + armv7m_load_kernel(s->nrf51.armv7m.cpu, machine->kernel_filename, | ||
50 | 0, s->nrf51.flash_size); | ||
51 | } | ||
52 | |||
26 | diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c | 53 | diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c |
27 | index XXXXXXX..XXXXXXX 100644 | 54 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/hw/arm/mps2-tz.c | 55 | --- a/hw/arm/mps2-tz.c |
29 | +++ b/hw/arm/mps2-tz.c | 56 | +++ b/hw/arm/mps2-tz.c |
30 | @@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine) | 57 | @@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine) |
31 | { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 }, | 58 | mms->remap_irq); |
32 | { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 }, | 59 | } |
33 | { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 }, | 60 | |
34 | + { /* port 4 USER AHB interface 0 */ }, | 61 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, |
35 | + { /* port 5 USER AHB interface 1 */ }, | 62 | + armv7m_load_kernel(mms->iotkit.armv7m[0].cpu, machine->kernel_filename, |
36 | + { /* port 6 USER AHB interface 2 */ }, | 63 | 0, boot_ram_size(mms)); |
37 | + { /* port 7 USER AHB interface 3 */ }, | 64 | } |
38 | { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } }, | 65 | |
39 | }, | 66 | diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c |
40 | }, | 67 | index XXXXXXX..XXXXXXX 100644 |
68 | --- a/hw/arm/mps2.c | ||
69 | +++ b/hw/arm/mps2.c | ||
70 | @@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine) | ||
71 | qdev_get_gpio_in(armv7m, | ||
72 | mmc->fpga_type == FPGA_AN511 ? 47 : 13)); | ||
73 | |||
74 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, | ||
75 | + armv7m_load_kernel(mms->armv7m.cpu, machine->kernel_filename, | ||
76 | 0, 0x400000); | ||
77 | } | ||
78 | |||
79 | diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c | ||
80 | index XXXXXXX..XXXXXXX 100644 | ||
81 | --- a/hw/arm/msf2-som.c | ||
82 | +++ b/hw/arm/msf2-som.c | ||
83 | @@ -XXX,XX +XXX,XX @@ static void emcraft_sf2_s2s010_init(MachineState *machine) | ||
84 | cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0); | ||
85 | sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line); | ||
86 | |||
87 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, | ||
88 | + armv7m_load_kernel(soc->armv7m.cpu, machine->kernel_filename, | ||
89 | 0, soc->envm_size); | ||
90 | } | ||
91 | |||
92 | diff --git a/hw/arm/musca.c b/hw/arm/musca.c | ||
93 | index XXXXXXX..XXXXXXX 100644 | ||
94 | --- a/hw/arm/musca.c | ||
95 | +++ b/hw/arm/musca.c | ||
96 | @@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine) | ||
97 | "cfg_sec_resp", 0)); | ||
98 | } | ||
99 | |||
100 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, | ||
101 | + armv7m_load_kernel(mms->sse.armv7m[0].cpu, machine->kernel_filename, | ||
102 | 0, 0x2000000); | ||
103 | } | ||
104 | |||
105 | diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c | ||
106 | index XXXXXXX..XXXXXXX 100644 | ||
107 | --- a/hw/arm/netduino2.c | ||
108 | +++ b/hw/arm/netduino2.c | ||
109 | @@ -XXX,XX +XXX,XX @@ static void netduino2_init(MachineState *machine) | ||
110 | qdev_connect_clock_in(dev, "sysclk", sysclk); | ||
111 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
112 | |||
113 | - armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, | ||
114 | + armv7m_load_kernel(STM32F205_SOC(dev)->armv7m.cpu, machine->kernel_filename, | ||
115 | 0, FLASH_SIZE); | ||
116 | } | ||
117 | |||
118 | diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c | ||
119 | index XXXXXXX..XXXXXXX 100644 | ||
120 | --- a/hw/arm/netduinoplus2.c | ||
121 | +++ b/hw/arm/netduinoplus2.c | ||
122 | @@ -XXX,XX +XXX,XX @@ static void netduinoplus2_init(MachineState *machine) | ||
123 | qdev_connect_clock_in(dev, "sysclk", sysclk); | ||
124 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
125 | |||
126 | - armv7m_load_kernel(ARM_CPU(first_cpu), | ||
127 | + armv7m_load_kernel(STM32F405_SOC(dev)->armv7m.cpu, | ||
128 | machine->kernel_filename, | ||
129 | 0, FLASH_SIZE); | ||
130 | } | ||
131 | diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c | ||
132 | index XXXXXXX..XXXXXXX 100644 | ||
133 | --- a/hw/arm/olimex-stm32-h405.c | ||
134 | +++ b/hw/arm/olimex-stm32-h405.c | ||
135 | @@ -XXX,XX +XXX,XX @@ static void olimex_stm32_h405_init(MachineState *machine) | ||
136 | qdev_connect_clock_in(dev, "sysclk", sysclk); | ||
137 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
138 | |||
139 | - armv7m_load_kernel(ARM_CPU(first_cpu), | ||
140 | + armv7m_load_kernel(STM32F405_SOC(dev)->armv7m.cpu, | ||
141 | machine->kernel_filename, | ||
142 | 0, FLASH_SIZE); | ||
143 | } | ||
144 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c | ||
145 | index XXXXXXX..XXXXXXX 100644 | ||
146 | --- a/hw/arm/stellaris.c | ||
147 | +++ b/hw/arm/stellaris.c | ||
148 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
149 | create_unimplemented_device("hibernation", 0x400fc000, 0x1000); | ||
150 | create_unimplemented_device("flash-control", 0x400fd000, 0x1000); | ||
151 | |||
152 | - armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, 0, flash_size); | ||
153 | + armv7m_load_kernel(ARMV7M(armv7m)->cpu, ms->kernel_filename, 0, flash_size); | ||
154 | } | ||
155 | |||
156 | /* FIXME: Figure out how to generate these from stellaris_boards. */ | ||
157 | diff --git a/hw/arm/stm32vldiscovery.c b/hw/arm/stm32vldiscovery.c | ||
158 | index XXXXXXX..XXXXXXX 100644 | ||
159 | --- a/hw/arm/stm32vldiscovery.c | ||
160 | +++ b/hw/arm/stm32vldiscovery.c | ||
161 | @@ -XXX,XX +XXX,XX @@ static void stm32vldiscovery_init(MachineState *machine) | ||
162 | qdev_connect_clock_in(dev, "sysclk", sysclk); | ||
163 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | ||
164 | |||
165 | - armv7m_load_kernel(ARM_CPU(first_cpu), | ||
166 | + armv7m_load_kernel(STM32F100_SOC(dev)->armv7m.cpu, | ||
167 | machine->kernel_filename, | ||
168 | 0, FLASH_SIZE); | ||
169 | } | ||
41 | -- | 170 | -- |
42 | 2.25.1 | 171 | 2.34.1 |
172 | |||
173 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Bernhard Beschow <shentey@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | We support 16k pages, but do not advertize that in ID_AA64MMFR0. | 3 | The value of the UCFR register is respected when echoing characters to the |
4 | terminal, but its reset value is reserved. Fix the reset value to the one | ||
5 | documented in the datasheet. | ||
4 | 6 | ||
5 | The value 0 in the TGRAN*_2 fields indicates that stage2 lookups defer | 7 | While at it move the related attribute out of the section of unimplemented |
6 | to the same support as stage1 lookups. This setting is deprecated, so | 8 | registers since its value is actually respected. |
7 | indicate support for all stage2 page sizes directly. | ||
8 | 9 | ||
9 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 10 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> |
10 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 11 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
11 | Message-id: 20220301215958.157011-16-richard.henderson@linaro.org | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
13 | --- | 13 | --- |
14 | target/arm/cpu64.c | 4 ++++ | 14 | include/hw/char/imx_serial.h | 2 +- |
15 | 1 file changed, 4 insertions(+) | 15 | hw/char/imx_serial.c | 1 + |
16 | 2 files changed, 2 insertions(+), 1 deletion(-) | ||
16 | 17 | ||
17 | diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c | 18 | diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h |
18 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/arm/cpu64.c | 20 | --- a/include/hw/char/imx_serial.h |
20 | +++ b/target/arm/cpu64.c | 21 | +++ b/include/hw/char/imx_serial.h |
21 | @@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj) | 22 | @@ -XXX,XX +XXX,XX @@ struct IMXSerialState { |
22 | 23 | uint32_t ucr1; | |
23 | t = cpu->isar.id_aa64mmfr0; | 24 | uint32_t ucr2; |
24 | t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */ | 25 | uint32_t uts1; |
25 | + t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */ | 26 | + uint32_t ufcr; |
26 | + t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */ | 27 | |
27 | + t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */ | 28 | /* |
28 | + t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */ | 29 | * The registers below are implemented just so that the |
29 | cpu->isar.id_aa64mmfr0 = t; | 30 | * guest OS sees what it has written |
30 | 31 | */ | |
31 | t = cpu->isar.id_aa64mmfr1; | 32 | uint32_t onems; |
33 | - uint32_t ufcr; | ||
34 | uint32_t ubmr; | ||
35 | uint32_t ubrc; | ||
36 | uint32_t ucr3; | ||
37 | diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/hw/char/imx_serial.c | ||
40 | +++ b/hw/char/imx_serial.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void imx_serial_reset(IMXSerialState *s) | ||
42 | s->ucr3 = 0x700; | ||
43 | s->ubmr = 0; | ||
44 | s->ubrc = 4; | ||
45 | + s->ufcr = BIT(11) | BIT(0); | ||
46 | |||
47 | fifo32_reset(&s->rx_fifo); | ||
48 | timer_del(&s->ageing_timer); | ||
32 | -- | 49 | -- |
33 | 2.25.1 | 50 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Bernhard Beschow <shentey@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | With FEAT_LPA2, rather than introducing translation level 4, | 3 | Fixes characters to be "echoed" after each keystroke rather than after every |
4 | we introduce level -1, below the current level 0. Extend | 4 | other since imx_serial_rx_fifo_ageing_timer_restart() would see ~UTS1_RXEMPTY |
5 | arm_fi_to_lfsc to handle these faults. | 5 | only after every other keystroke. |
6 | 6 | ||
7 | Assert that this new translation level does not leak into | 7 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> |
8 | fault types for which it is not defined, which allows some | ||
9 | masking of fi->level to be removed. | ||
10 | |||
11 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
12 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
13 | Message-id: 20220301215958.157011-12-richard.henderson@linaro.org | ||
14 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
15 | --- | 10 | --- |
16 | target/arm/internals.h | 35 +++++++++++++++++++++++++++++------ | 11 | hw/char/imx_serial.c | 6 +++--- |
17 | 1 file changed, 29 insertions(+), 6 deletions(-) | 12 | 1 file changed, 3 insertions(+), 3 deletions(-) |
18 | 13 | ||
19 | diff --git a/target/arm/internals.h b/target/arm/internals.h | 14 | diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c |
20 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/arm/internals.h | 16 | --- a/hw/char/imx_serial.c |
22 | +++ b/target/arm/internals.h | 17 | +++ b/hw/char/imx_serial.c |
23 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi) | 18 | @@ -XXX,XX +XXX,XX @@ static void imx_put_data(void *opaque, uint32_t value) |
24 | case ARMFault_None: | 19 | if (fifo32_num_used(&s->rx_fifo) >= rxtl) { |
25 | return 0; | 20 | s->usr1 |= USR1_RRDY; |
26 | case ARMFault_AddressSize: | 21 | } |
27 | - fsc = fi->level & 3; | 22 | - |
28 | + assert(fi->level >= -1 && fi->level <= 3); | 23 | - imx_serial_rx_fifo_ageing_timer_restart(s); |
29 | + if (fi->level < 0) { | 24 | - |
30 | + fsc = 0b101001; | 25 | s->usr2 |= USR2_RDR; |
31 | + } else { | 26 | s->uts1 &= ~UTS1_RXEMPTY; |
32 | + fsc = fi->level; | 27 | if (value & URXD_BRK) { |
33 | + } | 28 | s->usr2 |= USR2_BRCD; |
34 | break; | 29 | } |
35 | case ARMFault_AccessFlag: | 30 | + |
36 | - fsc = (fi->level & 3) | (0x2 << 2); | 31 | + imx_serial_rx_fifo_ageing_timer_restart(s); |
37 | + assert(fi->level >= 0 && fi->level <= 3); | 32 | + |
38 | + fsc = 0b001000 | fi->level; | 33 | imx_update(s); |
39 | break; | 34 | } |
40 | case ARMFault_Permission: | 35 | |
41 | - fsc = (fi->level & 3) | (0x3 << 2); | ||
42 | + assert(fi->level >= 0 && fi->level <= 3); | ||
43 | + fsc = 0b001100 | fi->level; | ||
44 | break; | ||
45 | case ARMFault_Translation: | ||
46 | - fsc = (fi->level & 3) | (0x1 << 2); | ||
47 | + assert(fi->level >= -1 && fi->level <= 3); | ||
48 | + if (fi->level < 0) { | ||
49 | + fsc = 0b101011; | ||
50 | + } else { | ||
51 | + fsc = 0b000100 | fi->level; | ||
52 | + } | ||
53 | break; | ||
54 | case ARMFault_SyncExternal: | ||
55 | fsc = 0x10 | (fi->ea << 12); | ||
56 | break; | ||
57 | case ARMFault_SyncExternalOnWalk: | ||
58 | - fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12); | ||
59 | + assert(fi->level >= -1 && fi->level <= 3); | ||
60 | + if (fi->level < 0) { | ||
61 | + fsc = 0b010011; | ||
62 | + } else { | ||
63 | + fsc = 0b010100 | fi->level; | ||
64 | + } | ||
65 | + fsc |= fi->ea << 12; | ||
66 | break; | ||
67 | case ARMFault_SyncParity: | ||
68 | fsc = 0x18; | ||
69 | break; | ||
70 | case ARMFault_SyncParityOnWalk: | ||
71 | - fsc = (fi->level & 3) | (0x7 << 2); | ||
72 | + assert(fi->level >= -1 && fi->level <= 3); | ||
73 | + if (fi->level < 0) { | ||
74 | + fsc = 0b011011; | ||
75 | + } else { | ||
76 | + fsc = 0b011100 | fi->level; | ||
77 | + } | ||
78 | break; | ||
79 | case ARMFault_AsyncParity: | ||
80 | fsc = 0x19; | ||
81 | -- | 36 | -- |
82 | 2.25.1 | 37 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Bernhard Beschow <shentey@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base, | 3 | Fixes INTD and MSI interrupts poking the same IRQ line without keeping track of |
4 | returning a structure containing both results. Pass in the | 4 | each other's IRQ level. Furthermore, SoCs such as the i.MX 8M Plus don't share |
5 | ARMMMUIdx, rather than the digested two_ranges boolean. | 5 | the MSI IRQ with the INTx lines, so expose it as a dedicated pin. |
6 | 6 | ||
7 | This is in preparation for FEAT_LPA2, where the interpretation | 7 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> |
8 | of 'value' depends on the effective value of DS for the regime. | ||
9 | |||
10 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
11 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Message-id: 20220301215958.157011-13-richard.henderson@linaro.org | ||
13 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
14 | --- | 10 | --- |
15 | target/arm/helper.c | 58 +++++++++++++++++++-------------------------- | 11 | include/hw/arm/fsl-imx6.h | 4 +++- |
16 | 1 file changed, 24 insertions(+), 34 deletions(-) | 12 | include/hw/arm/fsl-imx7.h | 4 +++- |
13 | include/hw/pci-host/designware.h | 1 + | ||
14 | hw/arm/fsl-imx6.c | 13 ++++++++++++- | ||
15 | hw/arm/fsl-imx7.c | 13 ++++++++++++- | ||
16 | hw/pci-host/designware.c | 7 +++---- | ||
17 | hw/arm/Kconfig | 2 ++ | ||
18 | 7 files changed, 36 insertions(+), 8 deletions(-) | ||
17 | 19 | ||
18 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 20 | diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h |
19 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/arm/helper.c | 22 | --- a/include/hw/arm/fsl-imx6.h |
21 | +++ b/target/arm/helper.c | 23 | +++ b/include/hw/arm/fsl-imx6.h |
22 | @@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, | 24 | @@ -XXX,XX +XXX,XX @@ |
25 | #include "hw/usb/chipidea.h" | ||
26 | #include "hw/usb/imx-usb-phy.h" | ||
27 | #include "hw/pci-host/designware.h" | ||
28 | +#include "hw/or-irq.h" | ||
29 | #include "exec/memory.h" | ||
30 | #include "cpu.h" | ||
31 | #include "qom/object.h" | ||
32 | @@ -XXX,XX +XXX,XX @@ struct FslIMX6State { | ||
33 | ChipideaState usb[FSL_IMX6_NUM_USBS]; | ||
34 | IMXFECState eth; | ||
35 | DesignwarePCIEHost pcie; | ||
36 | + OrIRQState pcie4_msi_irq; | ||
37 | MemoryRegion rom; | ||
38 | MemoryRegion caam; | ||
39 | MemoryRegion ocram; | ||
40 | @@ -XXX,XX +XXX,XX @@ struct FslIMX6State { | ||
41 | #define FSL_IMX6_PCIE1_IRQ 120 | ||
42 | #define FSL_IMX6_PCIE2_IRQ 121 | ||
43 | #define FSL_IMX6_PCIE3_IRQ 122 | ||
44 | -#define FSL_IMX6_PCIE4_IRQ 123 | ||
45 | +#define FSL_IMX6_PCIE4_MSI_IRQ 123 | ||
46 | #define FSL_IMX6_DCIC1_IRQ 124 | ||
47 | #define FSL_IMX6_DCIC2_IRQ 125 | ||
48 | #define FSL_IMX6_MLB150_HIGH_IRQ 126 | ||
49 | diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h | ||
50 | index XXXXXXX..XXXXXXX 100644 | ||
51 | --- a/include/hw/arm/fsl-imx7.h | ||
52 | +++ b/include/hw/arm/fsl-imx7.h | ||
53 | @@ -XXX,XX +XXX,XX @@ | ||
54 | #include "hw/net/imx_fec.h" | ||
55 | #include "hw/pci-host/designware.h" | ||
56 | #include "hw/usb/chipidea.h" | ||
57 | +#include "hw/or-irq.h" | ||
58 | #include "cpu.h" | ||
59 | #include "qom/object.h" | ||
60 | #include "qemu/units.h" | ||
61 | @@ -XXX,XX +XXX,XX @@ struct FslIMX7State { | ||
62 | IMX7GPRState gpr; | ||
63 | ChipideaState usb[FSL_IMX7_NUM_USBS]; | ||
64 | DesignwarePCIEHost pcie; | ||
65 | + OrIRQState pcie4_msi_irq; | ||
66 | MemoryRegion rom; | ||
67 | MemoryRegion caam; | ||
68 | MemoryRegion ocram; | ||
69 | @@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs { | ||
70 | FSL_IMX7_PCI_INTA_IRQ = 125, | ||
71 | FSL_IMX7_PCI_INTB_IRQ = 124, | ||
72 | FSL_IMX7_PCI_INTC_IRQ = 123, | ||
73 | - FSL_IMX7_PCI_INTD_IRQ = 122, | ||
74 | + FSL_IMX7_PCI_INTD_MSI_IRQ = 122, | ||
75 | |||
76 | FSL_IMX7_UART7_IRQ = 126, | ||
77 | |||
78 | diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h | ||
79 | index XXXXXXX..XXXXXXX 100644 | ||
80 | --- a/include/hw/pci-host/designware.h | ||
81 | +++ b/include/hw/pci-host/designware.h | ||
82 | @@ -XXX,XX +XXX,XX @@ struct DesignwarePCIEHost { | ||
83 | MemoryRegion io; | ||
84 | |||
85 | qemu_irq irqs[4]; | ||
86 | + qemu_irq msi; | ||
87 | } pci; | ||
88 | |||
89 | MemoryRegion mmio; | ||
90 | diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c | ||
91 | index XXXXXXX..XXXXXXX 100644 | ||
92 | --- a/hw/arm/fsl-imx6.c | ||
93 | +++ b/hw/arm/fsl-imx6.c | ||
94 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj) | ||
95 | object_initialize_child(obj, "eth", &s->eth, TYPE_IMX_ENET); | ||
96 | |||
97 | object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST); | ||
98 | + object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq, | ||
99 | + TYPE_OR_IRQ); | ||
23 | } | 100 | } |
24 | 101 | ||
25 | #ifdef TARGET_AARCH64 | 102 | static void fsl_imx6_realize(DeviceState *dev, Error **errp) |
26 | -static uint64_t tlbi_aa64_range_get_length(CPUARMState *env, | 103 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) |
27 | - uint64_t value) | 104 | sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort); |
28 | -{ | 105 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX6_PCIe_REG_ADDR); |
29 | - unsigned int page_shift; | 106 | |
30 | - unsigned int page_size_granule; | 107 | + object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2, |
31 | - uint64_t num; | 108 | + &error_abort); |
32 | - uint64_t scale; | 109 | + qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort); |
33 | - uint64_t exponent; | 110 | + |
34 | +typedef struct { | 111 | + irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_MSI_IRQ); |
35 | + uint64_t base; | 112 | + qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq); |
36 | uint64_t length; | 113 | + |
37 | +} TLBIRange; | 114 | irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE1_IRQ); |
38 | + | 115 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq); |
39 | +static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, | 116 | irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE2_IRQ); |
40 | + uint64_t value) | 117 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq); |
41 | +{ | 118 | irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE3_IRQ); |
42 | + unsigned int page_size_granule, page_shift, num, scale, exponent; | 119 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq); |
43 | + TLBIRange ret = { }; | 120 | - irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_IRQ); |
44 | 121 | + irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0); | |
45 | - num = extract64(value, 39, 5); | 122 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq); |
46 | - scale = extract64(value, 44, 2); | 123 | + irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1); |
47 | page_size_granule = extract64(value, 46, 2); | 124 | + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq); |
48 | 125 | ||
49 | if (page_size_granule == 0) { | 126 | /* |
50 | qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n", | 127 | * PCIe PHY |
51 | page_size_granule); | 128 | diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c |
52 | - return 0; | 129 | index XXXXXXX..XXXXXXX 100644 |
53 | + return ret; | 130 | --- a/hw/arm/fsl-imx7.c |
54 | } | 131 | +++ b/hw/arm/fsl-imx7.c |
55 | 132 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj) | |
56 | page_shift = (page_size_granule - 1) * 2 + 12; | 133 | * PCIE |
134 | */ | ||
135 | object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST); | ||
136 | + object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq, | ||
137 | + TYPE_OR_IRQ); | ||
138 | |||
139 | /* | ||
140 | * USBs | ||
141 | @@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp) | ||
142 | sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort); | ||
143 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR); | ||
144 | |||
145 | + object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2, | ||
146 | + &error_abort); | ||
147 | + qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort); | ||
148 | + | ||
149 | + irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ); | ||
150 | + qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq); | ||
151 | + | ||
152 | irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ); | ||
153 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq); | ||
154 | irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ); | ||
155 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq); | ||
156 | irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ); | ||
157 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq); | ||
158 | - irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ); | ||
159 | + irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0); | ||
160 | sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq); | ||
161 | + irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1); | ||
162 | + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq); | ||
163 | |||
164 | /* | ||
165 | * USBs | ||
166 | diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c | ||
167 | index XXXXXXX..XXXXXXX 100644 | ||
168 | --- a/hw/pci-host/designware.c | ||
169 | +++ b/hw/pci-host/designware.c | ||
170 | @@ -XXX,XX +XXX,XX @@ | ||
171 | #define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff) | ||
172 | #define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C | ||
173 | |||
174 | -#define DESIGNWARE_PCIE_IRQ_MSI 3 | ||
57 | - | 175 | - |
58 | + num = extract64(value, 39, 5); | 176 | static DesignwarePCIEHost * |
59 | + scale = extract64(value, 44, 2); | 177 | designware_pcie_root_to_host(DesignwarePCIERoot *root) |
60 | exponent = (5 * scale) + 1; | ||
61 | - length = (num + 1) << (exponent + page_shift); | ||
62 | |||
63 | - return length; | ||
64 | -} | ||
65 | + ret.length = (num + 1) << (exponent + page_shift); | ||
66 | |||
67 | -static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value, | ||
68 | - bool two_ranges) | ||
69 | -{ | ||
70 | - /* TODO: ARMv8.7 FEAT_LPA2 */ | ||
71 | - uint64_t pageaddr; | ||
72 | - | ||
73 | - if (two_ranges) { | ||
74 | - pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS; | ||
75 | + if (regime_has_2_ranges(mmuidx)) { | ||
76 | + ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS; | ||
77 | } else { | ||
78 | - pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS; | ||
79 | + ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS; | ||
80 | } | ||
81 | |||
82 | - return pageaddr; | ||
83 | + return ret; | ||
84 | } | ||
85 | |||
86 | static void do_rvae_write(CPUARMState *env, uint64_t value, | ||
87 | int idxmap, bool synced) | ||
88 | { | 178 | { |
89 | ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap); | 179 | @@ -XXX,XX +XXX,XX @@ static void designware_pcie_root_msi_write(void *opaque, hwaddr addr, |
90 | - bool two_ranges = regime_has_2_ranges(one_idx); | 180 | root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable; |
91 | - uint64_t baseaddr, length; | 181 | |
92 | + TLBIRange range; | 182 | if (root->msi.intr[0].status & ~root->msi.intr[0].mask) { |
93 | int bits; | 183 | - qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 1); |
94 | 184 | + qemu_set_irq(host->pci.msi, 1); | |
95 | - baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges); | ||
96 | - length = tlbi_aa64_range_get_length(env, value); | ||
97 | - bits = tlbbits_for_regime(env, one_idx, baseaddr); | ||
98 | + range = tlbi_aa64_get_range(env, one_idx, value); | ||
99 | + bits = tlbbits_for_regime(env, one_idx, range.base); | ||
100 | |||
101 | if (synced) { | ||
102 | tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env), | ||
103 | - baseaddr, | ||
104 | - length, | ||
105 | + range.base, | ||
106 | + range.length, | ||
107 | idxmap, | ||
108 | bits); | ||
109 | } else { | ||
110 | - tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr, | ||
111 | - length, idxmap, bits); | ||
112 | + tlb_flush_range_by_mmuidx(env_cpu(env), range.base, | ||
113 | + range.length, idxmap, bits); | ||
114 | } | 185 | } |
115 | } | 186 | } |
116 | 187 | ||
188 | @@ -XXX,XX +XXX,XX @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address, | ||
189 | case DESIGNWARE_PCIE_MSI_INTR0_STATUS: | ||
190 | root->msi.intr[0].status ^= val; | ||
191 | if (!root->msi.intr[0].status) { | ||
192 | - qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 0); | ||
193 | + qemu_set_irq(host->pci.msi, 0); | ||
194 | } | ||
195 | break; | ||
196 | |||
197 | @@ -XXX,XX +XXX,XX @@ static void designware_pcie_host_realize(DeviceState *dev, Error **errp) | ||
198 | for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) { | ||
199 | sysbus_init_irq(sbd, &s->pci.irqs[i]); | ||
200 | } | ||
201 | + sysbus_init_irq(sbd, &s->pci.msi); | ||
202 | |||
203 | memory_region_init_io(&s->mmio, | ||
204 | OBJECT(s), | ||
205 | diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig | ||
206 | index XXXXXXX..XXXXXXX 100644 | ||
207 | --- a/hw/arm/Kconfig | ||
208 | +++ b/hw/arm/Kconfig | ||
209 | @@ -XXX,XX +XXX,XX @@ config FSL_IMX6 | ||
210 | select PL310 # cache controller | ||
211 | select PCI_EXPRESS_DESIGNWARE | ||
212 | select SDHCI | ||
213 | + select OR_IRQ | ||
214 | |||
215 | config ASPEED_SOC | ||
216 | bool | ||
217 | @@ -XXX,XX +XXX,XX @@ config FSL_IMX7 | ||
218 | select WDT_IMX2 | ||
219 | select PCI_EXPRESS_DESIGNWARE | ||
220 | select SDHCI | ||
221 | + select OR_IRQ | ||
222 | select UNIMP | ||
223 | |||
224 | config ARM_SMMUV3 | ||
117 | -- | 225 | -- |
118 | 2.25.1 | 226 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | This feature widens physical addresses (and intermediate physical | 3 | Board schematic is useful to corroborate GPIOs/IRQs wiring. |
4 | addresses for 2-stage translation) from 48 to 52 bits, when using | ||
5 | 64k pages. The only thing left at this point is to handle the | ||
6 | extra bits in the TTBR and in the table descriptors. | ||
7 | 4 | ||
8 | Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't | 5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
9 | mask out the high bits when writing to those registers, so no changes | ||
10 | are required there. | ||
11 | |||
12 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
13 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Message-id: 20250110160204.74997-2-philmd@linaro.org |
14 | Message-id: 20220301215958.157011-11-richard.henderson@linaro.org | 8 | [PMM: Use https:// URLs] |
15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
16 | --- | 10 | --- |
17 | docs/system/arm/emulation.rst | 1 + | 11 | hw/arm/stellaris.c | 8 ++++++++ |
18 | target/arm/cpu-param.h | 2 +- | 12 | 1 file changed, 8 insertions(+) |
19 | target/arm/cpu64.c | 2 +- | ||
20 | target/arm/helper.c | 19 ++++++++++++++++--- | ||
21 | 4 files changed, 19 insertions(+), 5 deletions(-) | ||
22 | 13 | ||
23 | diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst | 14 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
24 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/docs/system/arm/emulation.rst | 16 | --- a/hw/arm/stellaris.c |
26 | +++ b/docs/system/arm/emulation.rst | 17 | +++ b/hw/arm/stellaris.c |
27 | @@ -XXX,XX +XXX,XX @@ the following architecture extensions: | 18 | @@ -XXX,XX +XXX,XX @@ static void lm3s6965evb_init(MachineState *machine) |
28 | - FEAT_I8MM (AArch64 Int8 matrix multiplication instructions) | 19 | stellaris_init(machine, &stellaris_boards[1]); |
29 | - FEAT_JSCVT (JavaScript conversion instructions) | 20 | } |
30 | - FEAT_LOR (Limited ordering regions) | 21 | |
31 | +- FEAT_LPA (Large Physical Address space) | 22 | +/* |
32 | - FEAT_LRCPC (Load-acquire RCpc instructions) | 23 | + * Stellaris LM3S811 Evaluation Board Schematics: |
33 | - FEAT_LRCPC2 (Load-acquire RCpc instructions v2) | 24 | + * https://www.ti.com/lit/ug/symlink/spmu030.pdf |
34 | - FEAT_LSE (Large System Extensions) | 25 | + */ |
35 | diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h | 26 | static void lm3s811evb_class_init(ObjectClass *oc, void *data) |
36 | index XXXXXXX..XXXXXXX 100644 | 27 | { |
37 | --- a/target/arm/cpu-param.h | 28 | MachineClass *mc = MACHINE_CLASS(oc); |
38 | +++ b/target/arm/cpu-param.h | 29 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo lm3s811evb_type = { |
39 | @@ -XXX,XX +XXX,XX @@ | 30 | .class_init = lm3s811evb_class_init, |
40 | |||
41 | #ifdef TARGET_AARCH64 | ||
42 | # define TARGET_LONG_BITS 64 | ||
43 | -# define TARGET_PHYS_ADDR_SPACE_BITS 48 | ||
44 | +# define TARGET_PHYS_ADDR_SPACE_BITS 52 | ||
45 | # define TARGET_VIRT_ADDR_SPACE_BITS 52 | ||
46 | #else | ||
47 | # define TARGET_LONG_BITS 32 | ||
48 | diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/arm/cpu64.c | ||
51 | +++ b/target/arm/cpu64.c | ||
52 | @@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj) | ||
53 | cpu->isar.id_aa64pfr1 = t; | ||
54 | |||
55 | t = cpu->isar.id_aa64mmfr0; | ||
56 | - t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */ | ||
57 | + t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */ | ||
58 | cpu->isar.id_aa64mmfr0 = t; | ||
59 | |||
60 | t = cpu->isar.id_aa64mmfr1; | ||
61 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/target/arm/helper.c | ||
64 | +++ b/target/arm/helper.c | ||
65 | @@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = { | ||
66 | [3] = 42, | ||
67 | [4] = 44, | ||
68 | [5] = 48, | ||
69 | + [6] = 52, | ||
70 | }; | 31 | }; |
71 | 32 | ||
72 | /* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */ | 33 | +/* |
73 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | 34 | + * Stellaris: LM3S6965 Evaluation Board Schematics: |
74 | descaddr = extract64(ttbr, 0, 48); | 35 | + * https://www.ti.com/lit/ug/symlink/spmu029.pdf |
75 | 36 | + */ | |
76 | /* | 37 | static void lm3s6965evb_class_init(ObjectClass *oc, void *data) |
77 | - * If the base address is out of range, raise AddressSizeFault. | 38 | { |
78 | + * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR. | 39 | MachineClass *mc = MACHINE_CLASS(oc); |
79 | + * | ||
80 | + * Otherwise, if the base address is out of range, raise AddressSizeFault. | ||
81 | * In the pseudocode, this is !IsZero(baseregister<47:outputsize>), | ||
82 | * but we've just cleared the bits above 47, so simplify the test. | ||
83 | */ | ||
84 | - if (descaddr >> outputsize) { | ||
85 | + if (outputsize > 48) { | ||
86 | + descaddr |= extract64(ttbr, 2, 4) << 48; | ||
87 | + } else if (descaddr >> outputsize) { | ||
88 | level = 0; | ||
89 | fault_type = ARMFault_AddressSize; | ||
90 | goto do_fault; | ||
91 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
92 | } | ||
93 | |||
94 | descaddr = descriptor & descaddrmask; | ||
95 | - if (descaddr >> outputsize) { | ||
96 | + | ||
97 | + /* | ||
98 | + * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] | ||
99 | + * of descriptor. Otherwise, if descaddr is out of range, raise | ||
100 | + * AddressSizeFault. | ||
101 | + */ | ||
102 | + if (outputsize > 48) { | ||
103 | + descaddr |= extract64(descriptor, 12, 4) << 48; | ||
104 | + } else if (descaddr >> outputsize) { | ||
105 | fault_type = ARMFault_AddressSize; | ||
106 | goto do_fault; | ||
107 | } | ||
108 | -- | 40 | -- |
109 | 2.25.1 | 41 | 2.34.1 |
42 | |||
43 | diff view generated by jsdifflib |
1 | From: Patrick Venture <venture@google.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Previously this device created N subdevices which each owned an i2c bus. | 3 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
4 | Now this device simply owns the N i2c busses directly. | 4 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
5 | 5 | Message-id: 20250110160204.74997-3-philmd@linaro.org | |
6 | Tested: Verified devices behind mux are still accessible via qmp and i2c | ||
7 | from within an arm32 SoC. | ||
8 | |||
9 | Reviewed-by: Hao Wu <wuhaotsh@google.com> | ||
10 | Signed-off-by: Patrick Venture <venture@google.com> | ||
11 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
12 | Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
13 | Message-id: 20220202164533.1283668-1-venture@google.com | ||
14 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
15 | --- | 7 | --- |
16 | hw/i2c/i2c_mux_pca954x.c | 77 +++++++--------------------------------- | 8 | hw/arm/stellaris.c | 6 +++--- |
17 | 1 file changed, 13 insertions(+), 64 deletions(-) | 9 | 1 file changed, 3 insertions(+), 3 deletions(-) |
18 | 10 | ||
19 | diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c | 11 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
20 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/hw/i2c/i2c_mux_pca954x.c | 13 | --- a/hw/arm/stellaris.c |
22 | +++ b/hw/i2c/i2c_mux_pca954x.c | 14 | +++ b/hw/arm/stellaris.c |
23 | @@ -XXX,XX +XXX,XX @@ | 15 | @@ -XXX,XX +XXX,XX @@ static void ssys_update(ssys_state *s) |
24 | #define PCA9548_CHANNEL_COUNT 8 | 16 | qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0); |
25 | #define PCA9546_CHANNEL_COUNT 4 | ||
26 | |||
27 | -/* | ||
28 | - * struct Pca954xChannel - The i2c mux device will have N of these states | ||
29 | - * that own the i2c channel bus. | ||
30 | - * @bus: The owned channel bus. | ||
31 | - * @enabled: Is this channel active? | ||
32 | - */ | ||
33 | -typedef struct Pca954xChannel { | ||
34 | - SysBusDevice parent; | ||
35 | - | ||
36 | - I2CBus *bus; | ||
37 | - | ||
38 | - bool enabled; | ||
39 | -} Pca954xChannel; | ||
40 | - | ||
41 | -#define TYPE_PCA954X_CHANNEL "pca954x-channel" | ||
42 | -#define PCA954X_CHANNEL(obj) \ | ||
43 | - OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL) | ||
44 | - | ||
45 | /* | ||
46 | * struct Pca954xState - The pca954x state object. | ||
47 | * @control: The value written to the mux control. | ||
48 | @@ -XXX,XX +XXX,XX @@ typedef struct Pca954xState { | ||
49 | |||
50 | uint8_t control; | ||
51 | |||
52 | - /* The channel i2c buses. */ | ||
53 | - Pca954xChannel channel[PCA9548_CHANNEL_COUNT]; | ||
54 | + bool enabled[PCA9548_CHANNEL_COUNT]; | ||
55 | + I2CBus *bus[PCA9548_CHANNEL_COUNT]; | ||
56 | } Pca954xState; | ||
57 | |||
58 | /* | ||
59 | @@ -XXX,XX +XXX,XX @@ static bool pca954x_match(I2CSlave *candidate, uint8_t address, | ||
60 | } | ||
61 | |||
62 | for (i = 0; i < mc->nchans; i++) { | ||
63 | - if (!mux->channel[i].enabled) { | ||
64 | + if (!mux->enabled[i]) { | ||
65 | continue; | ||
66 | } | ||
67 | |||
68 | - if (i2c_scan_bus(mux->channel[i].bus, address, broadcast, | ||
69 | + if (i2c_scan_bus(mux->bus[i], address, broadcast, | ||
70 | current_devs)) { | ||
71 | if (!broadcast) { | ||
72 | return true; | ||
73 | @@ -XXX,XX +XXX,XX @@ static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask) | ||
74 | */ | ||
75 | for (i = 0; i < mc->nchans; i++) { | ||
76 | if (enable_mask & (1 << i)) { | ||
77 | - s->channel[i].enabled = true; | ||
78 | + s->enabled[i] = true; | ||
79 | } else { | ||
80 | - s->channel[i].enabled = false; | ||
81 | + s->enabled[i] = false; | ||
82 | } | ||
83 | } | ||
84 | } | 17 | } |
85 | @@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel) | 18 | |
86 | Pca954xState *pca954x = PCA954X(mux); | 19 | -static uint32_t pllcfg_sandstorm[16] = { |
87 | 20 | +static const uint32_t pllcfg_sandstorm[16] = { | |
88 | g_assert(channel < pc->nchans); | 21 | 0x31c0, /* 1 Mhz */ |
89 | - return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]), | 22 | 0x1ae0, /* 1.8432 Mhz */ |
90 | - "i2c-bus")); | 23 | 0x18c0, /* 2 Mhz */ |
91 | -} | 24 | @@ -XXX,XX +XXX,XX @@ static uint32_t pllcfg_sandstorm[16] = { |
92 | - | 25 | 0x585b /* 8.192 Mhz */ |
93 | -static void pca954x_channel_init(Object *obj) | 26 | }; |
94 | -{ | 27 | |
95 | - Pca954xChannel *s = PCA954X_CHANNEL(obj); | 28 | -static uint32_t pllcfg_fury[16] = { |
96 | - s->bus = i2c_init_bus(DEVICE(s), "i2c-bus"); | 29 | +static const uint32_t pllcfg_fury[16] = { |
97 | - | 30 | 0x3200, /* 1 Mhz */ |
98 | - /* Start all channels as disabled. */ | 31 | 0x1b20, /* 1.8432 Mhz */ |
99 | - s->enabled = false; | 32 | 0x1900, /* 2 Mhz */ |
100 | -} | 33 | @@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj) |
101 | - | ||
102 | -static void pca954x_channel_class_init(ObjectClass *klass, void *data) | ||
103 | -{ | ||
104 | - DeviceClass *dc = DEVICE_CLASS(klass); | ||
105 | - dc->desc = "Pca954x Channel"; | ||
106 | + return pca954x->bus[channel]; | ||
107 | } | 34 | } |
108 | 35 | ||
109 | static void pca9546_class_init(ObjectClass *klass, void *data) | 36 | /* Board init. */ |
110 | @@ -XXX,XX +XXX,XX @@ static void pca9548_class_init(ObjectClass *klass, void *data) | 37 | -static stellaris_board_info stellaris_boards[] = { |
111 | s->nchans = PCA9548_CHANNEL_COUNT; | 38 | +static const stellaris_board_info stellaris_boards[] = { |
112 | } | 39 | { "LM3S811EVB", |
113 | 40 | 0, | |
114 | -static void pca954x_realize(DeviceState *dev, Error **errp) | 41 | 0x0032000e, |
115 | -{ | ||
116 | - Pca954xState *s = PCA954X(dev); | ||
117 | - Pca954xClass *c = PCA954X_GET_CLASS(s); | ||
118 | - int i; | ||
119 | - | ||
120 | - /* SMBus modules. Cannot fail. */ | ||
121 | - for (i = 0; i < c->nchans; i++) { | ||
122 | - sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort); | ||
123 | - } | ||
124 | -} | ||
125 | - | ||
126 | static void pca954x_init(Object *obj) | ||
127 | { | ||
128 | Pca954xState *s = PCA954X(obj); | ||
129 | Pca954xClass *c = PCA954X_GET_CLASS(obj); | ||
130 | int i; | ||
131 | |||
132 | - /* Only initialize the children we expect. */ | ||
133 | + /* SMBus modules. Cannot fail. */ | ||
134 | for (i = 0; i < c->nchans; i++) { | ||
135 | - object_initialize_child(obj, "channel[*]", &s->channel[i], | ||
136 | - TYPE_PCA954X_CHANNEL); | ||
137 | + g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i); | ||
138 | + | ||
139 | + /* start all channels as disabled. */ | ||
140 | + s->enabled[i] = false; | ||
141 | + s->bus[i] = i2c_init_bus(DEVICE(s), bus_name); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | @@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data) | ||
146 | rc->phases.enter = pca954x_enter_reset; | ||
147 | |||
148 | dc->desc = "Pca954x i2c-mux"; | ||
149 | - dc->realize = pca954x_realize; | ||
150 | |||
151 | k->write_data = pca954x_write_data; | ||
152 | k->receive_byte = pca954x_read_byte; | ||
153 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = { | ||
154 | .parent = TYPE_PCA954X, | ||
155 | .class_init = pca9548_class_init, | ||
156 | }, | ||
157 | - { | ||
158 | - .name = TYPE_PCA954X_CHANNEL, | ||
159 | - .parent = TYPE_SYS_BUS_DEVICE, | ||
160 | - .class_init = pca954x_channel_class_init, | ||
161 | - .instance_size = sizeof(Pca954xChannel), | ||
162 | - .instance_init = pca954x_channel_init, | ||
163 | - } | ||
164 | }; | ||
165 | |||
166 | DEFINE_TYPES(pca954x_info) | ||
167 | -- | 42 | -- |
168 | 2.25.1 | 43 | 2.34.1 |
169 | 44 | ||
170 | 45 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | We will shortly share parts of this function with other portions | 3 | There is nothing mapped at 0x40002000. |
4 | of address translation. | ||
5 | 4 | ||
5 | I2C#0 is already mapped at 0x40021000. | ||
6 | |||
7 | Remove the invalid mapping added in commits aecfbbc97a2 & 394c8bbfb7a. | ||
8 | |||
9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 10 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
7 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | 11 | Message-id: 20250110160204.74997-4-philmd@linaro.org |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
10 | Message-id: 20220301215958.157011-5-richard.henderson@linaro.org | ||
11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
12 | --- | 13 | --- |
13 | target/arm/internals.h | 19 +------------------ | 14 | hw/arm/stellaris.c | 2 -- |
14 | target/arm/helper.c | 22 ++++++++++++++++++++++ | 15 | 1 file changed, 2 deletions(-) |
15 | 2 files changed, 23 insertions(+), 18 deletions(-) | ||
16 | 16 | ||
17 | diff --git a/target/arm/internals.h b/target/arm/internals.h | 17 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
18 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/arm/internals.h | 19 | --- a/hw/arm/stellaris.c |
20 | +++ b/target/arm/internals.h | 20 | +++ b/hw/arm/stellaris.c |
21 | @@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm) | 21 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
22 | * Returns the implementation defined bit-width of physical addresses. | 22 | * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf |
23 | * The ARMv8 reference manuals refer to this as PAMax(). | 23 | * |
24 | */ | 24 | * 40000000 wdtimer |
25 | -static inline unsigned int arm_pamax(ARMCPU *cpu) | 25 | - * 40002000 i2c (unimplemented) |
26 | -{ | 26 | * 40004000 GPIO |
27 | - static const unsigned int pamax_map[] = { | 27 | * 40005000 GPIO |
28 | - [0] = 32, | 28 | * 40006000 GPIO |
29 | - [1] = 36, | 29 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
30 | - [2] = 40, | 30 | /* Add dummy regions for the devices we don't implement yet, |
31 | - [3] = 42, | 31 | * so guest accesses don't cause unlogged crashes. |
32 | - [4] = 44, | 32 | */ |
33 | - [5] = 48, | 33 | - create_unimplemented_device("i2c-0", 0x40002000, 0x1000); |
34 | - }; | 34 | create_unimplemented_device("i2c-2", 0x40021000, 0x1000); |
35 | - unsigned int parange = | 35 | create_unimplemented_device("PWM", 0x40028000, 0x1000); |
36 | - FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); | 36 | create_unimplemented_device("QEI-0", 0x4002c000, 0x1000); |
37 | - | ||
38 | - /* id_aa64mmfr0 is a read-only register so values outside of the | ||
39 | - * supported mappings can be considered an implementation error. */ | ||
40 | - assert(parange < ARRAY_SIZE(pamax_map)); | ||
41 | - return pamax_map[parange]; | ||
42 | -} | ||
43 | +unsigned int arm_pamax(ARMCPU *cpu); | ||
44 | |||
45 | /* Return true if extended addresses are enabled. | ||
46 | * This is always the case if our translation regime is 64 bit, | ||
47 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/target/arm/helper.c | ||
50 | +++ b/target/arm/helper.c | ||
51 | @@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs) | ||
52 | } | ||
53 | #endif /* !CONFIG_USER_ONLY */ | ||
54 | |||
55 | +/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */ | ||
56 | +unsigned int arm_pamax(ARMCPU *cpu) | ||
57 | +{ | ||
58 | + static const unsigned int pamax_map[] = { | ||
59 | + [0] = 32, | ||
60 | + [1] = 36, | ||
61 | + [2] = 40, | ||
62 | + [3] = 42, | ||
63 | + [4] = 44, | ||
64 | + [5] = 48, | ||
65 | + }; | ||
66 | + unsigned int parange = | ||
67 | + FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); | ||
68 | + | ||
69 | + /* | ||
70 | + * id_aa64mmfr0 is a read-only register so values outside of the | ||
71 | + * supported mappings can be considered an implementation error. | ||
72 | + */ | ||
73 | + assert(parange < ARRAY_SIZE(pamax_map)); | ||
74 | + return pamax_map[parange]; | ||
75 | +} | ||
76 | + | ||
77 | static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx) | ||
78 | { | ||
79 | if (regime_has_2_ranges(mmu_idx)) { | ||
80 | -- | 37 | -- |
81 | 2.25.1 | 38 | 2.34.1 |
82 | 39 | ||
83 | 40 | diff view generated by jsdifflib |
1 | From: Wentao_Liang <Wentao_Liang_g@163.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | handle_simd_shift_fpint_conv() was accidentally freeing the TCG | 3 | Add definitions for the number of controllers. |
4 | temporary tcg_fpstatus too early, before the last use of it. Move | ||
5 | the free down to where it belongs. | ||
6 | 4 | ||
7 | Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com> | 5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
9 | [PMM: cleaned up commit message] | 7 | Message-id: 20250110160204.74997-5-philmd@linaro.org |
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 8 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
11 | --- | 9 | --- |
12 | target/arm/translate-a64.c | 2 +- | 10 | hw/arm/stellaris.c | 25 +++++++++++++++---------- |
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | 11 | 1 file changed, 15 insertions(+), 10 deletions(-) |
14 | 12 | ||
15 | diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c | 13 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
16 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/translate-a64.c | 15 | --- a/hw/arm/stellaris.c |
18 | +++ b/target/arm/translate-a64.c | 16 | +++ b/hw/arm/stellaris.c |
19 | @@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar, | 17 | @@ -XXX,XX +XXX,XX @@ |
18 | #define NUM_IRQ_LINES 64 | ||
19 | #define NUM_PRIO_BITS 3 | ||
20 | |||
21 | +#define NUM_GPIO 7 | ||
22 | +#define NUM_UART 4 | ||
23 | +#define NUM_GPTM 4 | ||
24 | +#define NUM_I2C 2 | ||
25 | + | ||
26 | typedef const struct { | ||
27 | const char *name; | ||
28 | uint32_t did0; | ||
29 | @@ -XXX,XX +XXX,XX @@ static const stellaris_board_info stellaris_boards[] = { | ||
30 | |||
31 | static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
32 | { | ||
33 | - static const int uart_irq[] = {5, 6, 33, 34}; | ||
34 | - static const int timer_irq[] = {19, 21, 23, 35}; | ||
35 | - static const uint32_t gpio_addr[7] = | ||
36 | + static const int uart_irq[NUM_UART] = {5, 6, 33, 34}; | ||
37 | + static const int timer_irq[NUM_GPTM] = {19, 21, 23, 35}; | ||
38 | + static const uint32_t gpio_addr[NUM_GPIO] = | ||
39 | { 0x40004000, 0x40005000, 0x40006000, 0x40007000, | ||
40 | 0x40024000, 0x40025000, 0x40026000}; | ||
41 | - static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; | ||
42 | + static const int gpio_irq[NUM_GPIO] = {0, 1, 2, 3, 4, 30, 31}; | ||
43 | |||
44 | /* Memory map of SoC devices, from | ||
45 | * Stellaris LM3S6965 Microcontroller Data Sheet (rev I) | ||
46 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
47 | */ | ||
48 | |||
49 | Object *soc_container; | ||
50 | - DeviceState *gpio_dev[7], *armv7m, *nvic; | ||
51 | - qemu_irq gpio_in[7][8]; | ||
52 | - qemu_irq gpio_out[7][8]; | ||
53 | + DeviceState *gpio_dev[NUM_GPIO], *armv7m, *nvic; | ||
54 | + qemu_irq gpio_in[NUM_GPIO][8]; | ||
55 | + qemu_irq gpio_out[NUM_GPIO][8]; | ||
56 | qemu_irq adc; | ||
57 | int sram_size; | ||
58 | int flash_size; | ||
59 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
60 | } else { | ||
61 | adc = NULL; | ||
62 | } | ||
63 | - for (i = 0; i < 4; i++) { | ||
64 | + for (i = 0; i < NUM_GPTM; i++) { | ||
65 | if (board->dc2 & (0x10000 << i)) { | ||
66 | SysBusDevice *sbd; | ||
67 | |||
68 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
69 | } | ||
70 | |||
71 | |||
72 | - for (i = 0; i < 7; i++) { | ||
73 | + for (i = 0; i < NUM_GPIO; i++) { | ||
74 | if (board->dc4 & (1 << i)) { | ||
75 | gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i], | ||
76 | qdev_get_gpio_in(nvic, | ||
77 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
20 | } | 78 | } |
21 | } | 79 | } |
22 | 80 | ||
23 | - tcg_temp_free_ptr(tcg_fpstatus); | 81 | - for (i = 0; i < 4; i++) { |
24 | tcg_temp_free_i32(tcg_shift); | 82 | + for (i = 0; i < NUM_UART; i++) { |
25 | gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus); | 83 | if (board->dc2 & (1 << i)) { |
26 | + tcg_temp_free_ptr(tcg_fpstatus); | 84 | SysBusDevice *sbd; |
27 | tcg_temp_free_i32(tcg_rmode); | ||
28 | } | ||
29 | 85 | ||
30 | -- | 86 | -- |
31 | 2.25.1 | 87 | 2.34.1 |
88 | |||
89 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | This field controls the output (intermediate) physical address size | 3 | Add definitions (DCx_periph) for the DeviceCapability bits, |
4 | of the translation process. V8 requires to raise an AddressSize | 4 | replace direct bitmask checks with the DEV_CAP() macro, |
5 | fault if the page tables are programmed incorrectly, such that any | 5 | which use the extract/deposit API. |
6 | intermediate descriptor address, or the final translated address, | ||
7 | is out of range. | ||
8 | 6 | ||
9 | Add a PS field to ARMVAParameters, and properly compute outputsize | 7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
10 | in get_phys_addr_lpae. Test the descaddr as extracted from TTBR | ||
11 | and from page table entries. | ||
12 | |||
13 | Restrict descaddrmask so that we won't raise the fault for v7. | ||
14 | |||
15 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
16 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | 9 | Message-id: 20250110160204.74997-6-philmd@linaro.org |
17 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
18 | Message-id: 20220301215958.157011-8-richard.henderson@linaro.org | ||
19 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
20 | --- | 11 | --- |
21 | target/arm/internals.h | 1 + | 12 | hw/arm/stellaris.c | 37 +++++++++++++++++++++++++++++-------- |
22 | target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++---------- | 13 | 1 file changed, 29 insertions(+), 8 deletions(-) |
23 | 2 files changed, 57 insertions(+), 16 deletions(-) | ||
24 | 14 | ||
25 | diff --git a/target/arm/internals.h b/target/arm/internals.h | 15 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
26 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/target/arm/internals.h | 17 | --- a/hw/arm/stellaris.c |
28 | +++ b/target/arm/internals.h | 18 | +++ b/hw/arm/stellaris.c |
29 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) | 19 | @@ -XXX,XX +XXX,XX @@ |
30 | */ | 20 | */ |
31 | typedef struct ARMVAParameters { | 21 | |
32 | unsigned tsz : 8; | 22 | #include "qemu/osdep.h" |
33 | + unsigned ps : 3; | 23 | +#include "qemu/bitops.h" |
34 | unsigned select : 1; | 24 | #include "qapi/error.h" |
35 | bool tbi : 1; | 25 | #include "hw/core/split-irq.h" |
36 | bool epd : 1; | 26 | #include "hw/sysbus.h" |
37 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 27 | @@ -XXX,XX +XXX,XX @@ |
38 | index XXXXXXX..XXXXXXX 100644 | 28 | #define NUM_GPTM 4 |
39 | --- a/target/arm/helper.c | 29 | #define NUM_I2C 2 |
40 | +++ b/target/arm/helper.c | 30 | |
41 | @@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs) | 31 | +/* |
42 | } | 32 | + * See Stellaris Data Sheet chapter 5.2.5 "System Control", |
43 | #endif /* !CONFIG_USER_ONLY */ | 33 | + * Register 13 .. 17: Device Capabilities 0 .. 4 (DC0 .. DC4). |
44 | 34 | + */ | |
45 | +/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */ | 35 | +#define DC1_WDT 3 |
46 | +static const uint8_t pamax_map[] = { | 36 | +#define DC1_HIB 6 |
47 | + [0] = 32, | 37 | +#define DC1_MPU 7 |
48 | + [1] = 36, | 38 | +#define DC1_ADC 16 |
49 | + [2] = 40, | 39 | +#define DC1_PWM 20 |
50 | + [3] = 42, | 40 | +#define DC2_UART(n) (n) |
51 | + [4] = 44, | 41 | +#define DC2_SSI 4 |
52 | + [5] = 48, | 42 | +#define DC2_QEI(n) (8 + n) |
53 | +}; | 43 | +#define DC2_I2C(n) (12 + 2 * n) |
44 | +#define DC2_GPTM(n) (16 + n) | ||
45 | +#define DC2_COMP(n) (24 + n) | ||
46 | +#define DC4_GPIO(n) (n) | ||
47 | +#define DC4_EMAC 28 | ||
54 | + | 48 | + |
55 | /* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */ | 49 | +#define DEV_CAP(_dc, _cap) extract32(board->dc##_dc, DC##_dc##_##_cap, 1) |
56 | unsigned int arm_pamax(ARMCPU *cpu) | 50 | + |
57 | { | 51 | typedef const struct { |
58 | - static const unsigned int pamax_map[] = { | 52 | const char *name; |
59 | - [0] = 32, | 53 | uint32_t did0; |
60 | - [1] = 36, | 54 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
61 | - [2] = 40, | 55 | sysbus_mmio_map(SYS_BUS_DEVICE(ssys_dev), 0, 0x400fe000); |
62 | - [3] = 42, | 56 | sysbus_connect_irq(SYS_BUS_DEVICE(ssys_dev), 0, qdev_get_gpio_in(nvic, 28)); |
63 | - [4] = 44, | 57 | |
64 | - [5] = 48, | 58 | - if (board->dc1 & (1 << 16)) { |
65 | - }; | 59 | + if (DEV_CAP(1, ADC)) { |
66 | unsigned int parange = | 60 | dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, |
67 | FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); | 61 | qdev_get_gpio_in(nvic, 14), |
68 | 62 | qdev_get_gpio_in(nvic, 15), | |
69 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 63 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
70 | { | 64 | adc = NULL; |
71 | uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; | 65 | } |
72 | bool epd, hpd, using16k, using64k, tsz_oob; | 66 | for (i = 0; i < NUM_GPTM; i++) { |
73 | - int select, tsz, tbi, max_tsz, min_tsz; | 67 | - if (board->dc2 & (0x10000 << i)) { |
74 | + int select, tsz, tbi, max_tsz, min_tsz, ps; | 68 | + if (DEV_CAP(2, GPTM(i))) { |
75 | 69 | SysBusDevice *sbd; | |
76 | if (!regime_has_2_ranges(mmu_idx)) { | 70 | |
77 | select = 0; | 71 | dev = qdev_new(TYPE_STELLARIS_GPTM); |
78 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 72 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
79 | hpd = extract32(tcr, 24, 1); | ||
80 | } | 73 | } |
81 | epd = false; | 74 | } |
82 | + ps = extract32(tcr, 16, 3); | 75 | |
83 | } else { | 76 | - if (board->dc1 & (1 << 3)) { /* watchdog present */ |
84 | /* | 77 | + if (DEV_CAP(1, WDT)) { |
85 | * Bit 55 is always between the two regions, and is canonical for | 78 | dev = qdev_new(TYPE_LUMINARY_WATCHDOG); |
86 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 79 | object_property_add_child(soc_container, "wdg", OBJECT(dev)); |
87 | epd = extract32(tcr, 23, 1); | 80 | qdev_connect_clock_in(dev, "WDOGCLK", |
88 | hpd = extract64(tcr, 42, 1); | 81 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
82 | |||
83 | |||
84 | for (i = 0; i < NUM_GPIO; i++) { | ||
85 | - if (board->dc4 & (1 << i)) { | ||
86 | + if (DEV_CAP(4, GPIO(i))) { | ||
87 | gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i], | ||
88 | qdev_get_gpio_in(nvic, | ||
89 | gpio_irq[i])); | ||
90 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
89 | } | 91 | } |
90 | + ps = extract64(tcr, 32, 3); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | if (cpu_isar_feature(aa64_st, env_archcpu(env))) { | 94 | - if (board->dc2 & (1 << 12)) { |
94 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 95 | + if (DEV_CAP(2, I2C(0))) { |
95 | 96 | dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, | |
96 | return (ARMVAParameters) { | 97 | qdev_get_gpio_in(nvic, 8)); |
97 | .tsz = tsz, | 98 | i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); |
98 | + .ps = ps, | 99 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
99 | .select = select, | 100 | } |
100 | .tbi = tbi, | 101 | |
101 | .epd = epd, | 102 | for (i = 0; i < NUM_UART; i++) { |
102 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | 103 | - if (board->dc2 & (1 << i)) { |
103 | 104 | + if (DEV_CAP(2, UART(i))) { | |
104 | /* TODO: This code does not support shareability levels. */ | 105 | SysBusDevice *sbd; |
105 | if (aarch64) { | 106 | |
106 | + int ps; | 107 | dev = qdev_new("pl011_luminary"); |
107 | + | 108 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
108 | param = aa64_va_parameters(env, address, mmu_idx, | 109 | sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i])); |
109 | access_type != MMU_INST_FETCH); | ||
110 | level = 0; | ||
111 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
112 | |||
113 | addrsize = 64 - 8 * param.tbi; | ||
114 | inputsize = 64 - param.tsz; | ||
115 | - outputsize = arm_pamax(cpu); | ||
116 | + | ||
117 | + /* | ||
118 | + * Bound PS by PARANGE to find the effective output address size. | ||
119 | + * ID_AA64MMFR0 is a read-only register so values outside of the | ||
120 | + * supported mappings can be considered an implementation error. | ||
121 | + */ | ||
122 | + ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); | ||
123 | + ps = MIN(ps, param.ps); | ||
124 | + assert(ps < ARRAY_SIZE(pamax_map)); | ||
125 | + outputsize = pamax_map[ps]; | ||
126 | } else { | ||
127 | param = aa32_va_parameters(env, address, mmu_idx); | ||
128 | level = 1; | ||
129 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
130 | |||
131 | /* Now we can extract the actual base address from the TTBR */ | ||
132 | descaddr = extract64(ttbr, 0, 48); | ||
133 | + | ||
134 | + /* | ||
135 | + * If the base address is out of range, raise AddressSizeFault. | ||
136 | + * In the pseudocode, this is !IsZero(baseregister<47:outputsize>), | ||
137 | + * but we've just cleared the bits above 47, so simplify the test. | ||
138 | + */ | ||
139 | + if (descaddr >> outputsize) { | ||
140 | + level = 0; | ||
141 | + fault_type = ARMFault_AddressSize; | ||
142 | + goto do_fault; | ||
143 | + } | ||
144 | + | ||
145 | /* | ||
146 | * We rely on this masking to clear the RES0 bits at the bottom of the TTBR | ||
147 | * and also to mask out CnP (bit 0) which could validly be non-zero. | ||
148 | */ | ||
149 | descaddr &= ~indexmask; | ||
150 | |||
151 | - /* The address field in the descriptor goes up to bit 39 for ARMv7 | ||
152 | - * but up to bit 47 for ARMv8, but we use the descaddrmask | ||
153 | - * up to bit 39 for AArch32, because we don't need other bits in that case | ||
154 | - * to construct next descriptor address (anyway they should be all zeroes). | ||
155 | + /* | ||
156 | + * For AArch32, the address field in the descriptor goes up to bit 39 | ||
157 | + * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0 | ||
158 | + * or an AddressSize fault is raised. So for v8 we extract those SBZ | ||
159 | + * bits as part of the address, which will be checked via outputsize. | ||
160 | + * For AArch64, the address field always goes up to bit 47 (with extra | ||
161 | + * bits for FEAT_LPA placed elsewhere). AArch64 implies v8. | ||
162 | */ | ||
163 | - descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) & | ||
164 | - ~indexmask_grainsize; | ||
165 | + if (arm_feature(env, ARM_FEATURE_V8)) { | ||
166 | + descaddrmask = MAKE_64BIT_MASK(0, 48); | ||
167 | + } else { | ||
168 | + descaddrmask = MAKE_64BIT_MASK(0, 40); | ||
169 | + } | ||
170 | + descaddrmask &= ~indexmask_grainsize; | ||
171 | |||
172 | /* Secure accesses start with the page table in secure memory and | ||
173 | * can be downgraded to non-secure at any step. Non-secure accesses | ||
174 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
175 | /* Invalid, or the Reserved level 3 encoding */ | ||
176 | goto do_fault; | ||
177 | } | 110 | } |
178 | + | 111 | } |
179 | descaddr = descriptor & descaddrmask; | 112 | - if (board->dc2 & (1 << 4)) { |
180 | + if (descaddr >> outputsize) { | 113 | + if (DEV_CAP(2, SSI)) { |
181 | + fault_type = ARMFault_AddressSize; | 114 | dev = sysbus_create_simple("pl022", 0x40008000, |
182 | + goto do_fault; | 115 | qdev_get_gpio_in(nvic, 7)); |
183 | + } | 116 | if (board->peripherals & BP_OLED_SSI) { |
184 | 117 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | |
185 | if ((descriptor & 2) && (level < 3)) { | 118 | qemu_irq_raise(gpio_out[GPIO_D][0]); |
186 | /* Table entry. The top five bits are attributes which may | 119 | } |
120 | } | ||
121 | - if (board->dc4 & (1 << 28)) { | ||
122 | + if (DEV_CAP(4, EMAC)) { | ||
123 | DeviceState *enet; | ||
124 | |||
125 | enet = qdev_new("stellaris_enet"); | ||
187 | -- | 126 | -- |
188 | 2.25.1 | 127 | 2.34.1 |
189 | 128 | ||
190 | 129 | diff view generated by jsdifflib |
1 | The tsc210x doesn't support anything other than 16-bit reads on the | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | SPI bus, but the guest can program the SPI controller to attempt | ||
3 | them anyway. If this happens, don't abort QEMU, just log this as | ||
4 | a guest error. | ||
5 | 2 | ||
6 | This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800 | 3 | There are 2 I2C controllers, map them both, removing |
7 | acceptance test, which hits this assertion. | 4 | the unimplemented one. Keep the OLED controller on the |
5 | first I2C bus. | ||
8 | 6 | ||
9 | The reason we hit the assertion is because the guest kernel thinks | 7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
10 | there is a TSC2005 on this SPI bus address, not a TSC210x. (The n810 | 8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
11 | *does* have a TSC2005 at this address.) The TSC2005 supports the | 9 | Message-id: 20250110160204.74997-7-philmd@linaro.org |
12 | 24-bit accesses which the guest driver makes, and the TSC210x does | 10 | [PMM: tweak to appease maybe-use-uninitialized warning] |
13 | not (that is, our TSC210x emulation is not missing support for a word | 11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
14 | width the hardware can handle). It's not clear whether the problem | 12 | --- |
15 | here is that the guest kernel incorrectly thinks the n800 has the | 13 | hw/arm/stellaris.c | 21 +++++++++++++-------- |
16 | same device at this SPI bus address as the n810, or that QEMU's n810 | 14 | 1 file changed, 13 insertions(+), 8 deletions(-) |
17 | board model doesn't get the SPI devices right. At this late date | ||
18 | there no longer appears to be any reliable information on the web | ||
19 | about the hardware behaviour, but I am inclined to think this is a | ||
20 | guest kernel bug. In any case, we prefer not to abort QEMU for | ||
21 | guest-triggerable conditions, so logging the error is the right thing | ||
22 | to do. | ||
23 | 15 | ||
24 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736 | 16 | diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c |
25 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
26 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
27 | Message-id: 20220221140750.514557-1-peter.maydell@linaro.org | ||
28 | --- | ||
29 | hw/input/tsc210x.c | 8 ++++++-- | ||
30 | 1 file changed, 6 insertions(+), 2 deletions(-) | ||
31 | |||
32 | diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/hw/input/tsc210x.c | 18 | --- a/hw/arm/stellaris.c |
35 | +++ b/hw/input/tsc210x.c | 19 | +++ b/hw/arm/stellaris.c |
36 | @@ -XXX,XX +XXX,XX @@ | 20 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
37 | #include "hw/hw.h" | 21 | { 0x40004000, 0x40005000, 0x40006000, 0x40007000, |
38 | #include "audio/audio.h" | 22 | 0x40024000, 0x40025000, 0x40026000}; |
39 | #include "qemu/timer.h" | 23 | static const int gpio_irq[NUM_GPIO] = {0, 1, 2, 3, 4, 30, 31}; |
40 | +#include "qemu/log.h" | 24 | + static const uint32_t i2c_addr[NUM_I2C] = {0x40020000, 0x40021000}; |
41 | #include "sysemu/reset.h" | 25 | + static const int i2c_irq[NUM_I2C] = {8, 37}; |
42 | #include "ui/console.h" | 26 | |
43 | #include "hw/arm/omap.h" /* For I2SCodec */ | 27 | /* Memory map of SoC devices, from |
44 | @@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len) | 28 | * Stellaris LM3S6965 Microcontroller Data Sheet (rev I) |
45 | TSC210xState *s = opaque; | 29 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) |
46 | uint32_t ret = 0; | 30 | qemu_irq adc; |
47 | 31 | int sram_size; | |
48 | - if (len != 16) | 32 | int flash_size; |
49 | - hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len); | 33 | - I2CBus *i2c; |
50 | + if (len != 16) { | 34 | + DeviceState *i2c_dev[NUM_I2C] = { }; |
51 | + qemu_log_mask(LOG_GUEST_ERROR, | 35 | DeviceState *dev; |
52 | + "%s: bad SPI word width %i\n", __func__, len); | 36 | DeviceState *ssys_dev; |
53 | + return 0; | 37 | int i; |
38 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
39 | } | ||
40 | } | ||
41 | |||
42 | - if (DEV_CAP(2, I2C(0))) { | ||
43 | - dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, | ||
44 | - qdev_get_gpio_in(nvic, 8)); | ||
45 | - i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); | ||
46 | - if (board->peripherals & BP_OLED_I2C) { | ||
47 | - i2c_slave_create_simple(i2c, "ssd0303", 0x3d); | ||
48 | + for (i = 0; i < NUM_I2C; i++) { | ||
49 | + if (DEV_CAP(2, I2C(i))) { | ||
50 | + i2c_dev[i] = sysbus_create_simple(TYPE_STELLARIS_I2C, i2c_addr[i], | ||
51 | + qdev_get_gpio_in(nvic, | ||
52 | + i2c_irq[i])); | ||
53 | } | ||
54 | } | ||
55 | + if (board->peripherals & BP_OLED_I2C) { | ||
56 | + I2CBus *bus = (I2CBus *)qdev_get_child_bus(i2c_dev[0], "i2c"); | ||
57 | + | ||
58 | + i2c_slave_create_simple(bus, "ssd0303", 0x3d); | ||
54 | + } | 59 | + } |
55 | 60 | ||
56 | /* TODO: sequential reads etc - how do we make sure the host doesn't | 61 | for (i = 0; i < NUM_UART; i++) { |
57 | * unintentionally read out a conversion result from a register while | 62 | if (DEV_CAP(2, UART(i))) { |
63 | @@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board) | ||
64 | /* Add dummy regions for the devices we don't implement yet, | ||
65 | * so guest accesses don't cause unlogged crashes. | ||
66 | */ | ||
67 | - create_unimplemented_device("i2c-2", 0x40021000, 0x1000); | ||
68 | create_unimplemented_device("PWM", 0x40028000, 0x1000); | ||
69 | create_unimplemented_device("QEI-0", 0x4002c000, 0x1000); | ||
70 | create_unimplemented_device("QEI-1", 0x4002d000, 0x1000); | ||
58 | -- | 71 | -- |
59 | 2.25.1 | 72 | 2.34.1 |
60 | 73 | ||
61 | 74 | diff view generated by jsdifflib |
1 | From: Shengtan Mao <stmao@google.com> | 1 | From: Thomas Huth <thuth@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Reviewed-by: Hao Wu <wuhaotsh@google.com> | 3 | We don't have any functional tests for this machine yet, thus let's |
4 | Reviewed-by: Chris Rauer <crauer@google.com> | 4 | add a test with a MicroPython binary that is available online |
5 | Signed-off-by: Shengtan Mao <stmao@google.com> | 5 | (thanks to Joel Stanley for providing it, see: |
6 | Signed-off-by: Patrick Venture <venture@google.com> | 6 | https://www.mail-archive.com/qemu-devel@nongnu.org/msg606064.html ). |
7 | Message-id: 20220225174451.192304-1-wuhaotsh@google.com | 7 | |
8 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
9 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
10 | Message-id: 20250124101709.1591761-1-thuth@redhat.com | ||
8 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
9 | --- | 12 | --- |
10 | tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++++++++ | 13 | MAINTAINERS | 1 + |
11 | tests/qtest/meson.build | 1 + | 14 | tests/functional/meson.build | 1 + |
12 | 2 files changed, 216 insertions(+) | 15 | tests/functional/test_arm_microbit.py | 31 +++++++++++++++++++++++++++ |
13 | create mode 100644 tests/qtest/npcm7xx_sdhci-test.c | 16 | 3 files changed, 33 insertions(+) |
17 | create mode 100755 tests/functional/test_arm_microbit.py | ||
14 | 18 | ||
15 | diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c | 19 | diff --git a/MAINTAINERS b/MAINTAINERS |
16 | new file mode 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/MAINTAINERS | ||
22 | +++ b/MAINTAINERS | ||
23 | @@ -XXX,XX +XXX,XX @@ F: hw/*/microbit*.c | ||
24 | F: include/hw/*/nrf51*.h | ||
25 | F: include/hw/*/microbit*.h | ||
26 | F: tests/qtest/microbit-test.c | ||
27 | +F: tests/functional/test_arm_microbit.py | ||
28 | F: docs/system/arm/nrf.rst | ||
29 | |||
30 | ARM PL011 Rust device | ||
31 | diff --git a/tests/functional/meson.build b/tests/functional/meson.build | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/tests/functional/meson.build | ||
34 | +++ b/tests/functional/meson.build | ||
35 | @@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [ | ||
36 | 'arm_cubieboard', | ||
37 | 'arm_emcraft_sf2', | ||
38 | 'arm_integratorcp', | ||
39 | + 'arm_microbit', | ||
40 | 'arm_orangepi', | ||
41 | 'arm_quanta_gsj', | ||
42 | 'arm_raspi2', | ||
43 | diff --git a/tests/functional/test_arm_microbit.py b/tests/functional/test_arm_microbit.py | ||
44 | new file mode 100755 | ||
17 | index XXXXXXX..XXXXXXX | 45 | index XXXXXXX..XXXXXXX |
18 | --- /dev/null | 46 | --- /dev/null |
19 | +++ b/tests/qtest/npcm7xx_sdhci-test.c | 47 | +++ b/tests/functional/test_arm_microbit.py |
20 | @@ -XXX,XX +XXX,XX @@ | 48 | @@ -XXX,XX +XXX,XX @@ |
21 | +/* | 49 | +#!/usr/bin/env python3 |
22 | + * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller | 50 | +# |
23 | + * | 51 | +# SPDX-License-Identifier: GPL-2.0-or-later |
24 | + * Copyright (c) 2022 Google LLC | 52 | +# |
25 | + * | 53 | +# Copyright 2025, The QEMU Project Developers. |
26 | + * This program is free software; you can redistribute it and/or modify it | 54 | +# |
27 | + * under the terms of the GNU General Public License as published by the | 55 | +# A functional test that runs MicroPython on the arm microbit machine. |
28 | + * Free Software Foundation; either version 2 of the License, or | ||
29 | + * (at your option) any later version. | ||
30 | + * | ||
31 | + * This program is distributed in the hope that it will be useful, but WITHOUT | ||
32 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
33 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
34 | + * for more details. | ||
35 | + */ | ||
36 | + | 56 | + |
37 | +#include "qemu/osdep.h" | 57 | +from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern |
38 | +#include "hw/sd/npcm7xx_sdhci.h" | 58 | +from qemu_test import wait_for_console_pattern |
39 | + | 59 | + |
40 | +#include "libqos/libqtest.h" | ||
41 | +#include "libqtest-single.h" | ||
42 | +#include "libqos/sdhci-cmd.h" | ||
43 | + | 60 | + |
44 | +#define NPCM7XX_REG_SIZE 0x100 | 61 | +class MicrobitMachine(QemuSystemTest): |
45 | +#define NPCM7XX_MMC_BA 0xF0842000 | ||
46 | +#define NPCM7XX_BLK_SIZE 512 | ||
47 | +#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30) | ||
48 | + | 62 | + |
49 | +char *sd_path; | 63 | + ASSET_MICRO = Asset('https://ozlabs.org/~joel/microbit-micropython.hex', |
64 | + '021641f93dfb11767d4978dbb3ca7f475d1b13c69e7f4aec3382f212636bffd6') | ||
50 | + | 65 | + |
51 | +static QTestState *setup_sd_card(void) | 66 | + def test_arm_microbit(self): |
52 | +{ | 67 | + self.set_machine('microbit') |
53 | + QTestState *qts = qtest_initf( | ||
54 | + "-machine kudo-bmc " | ||
55 | + "-device sd-card,drive=drive0 " | ||
56 | + "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off", | ||
57 | + sd_path); | ||
58 | + | 68 | + |
59 | + qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL); | 69 | + micropython = self.ASSET_MICRO.fetch() |
60 | + qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON, | 70 | + self.vm.set_console() |
61 | + SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE | | 71 | + self.vm.add_args('-device', f'loader,file={micropython}') |
62 | + SDHC_CLOCK_INT_EN); | 72 | + self.vm.launch() |
63 | + sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD); | 73 | + wait_for_console_pattern(self, 'Type "help()" for more information.') |
64 | + sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8)); | 74 | + exec_command_and_wait_for_pattern(self, 'import machine as mch', '>>>') |
65 | + sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID); | 75 | + exec_command_and_wait_for_pattern(self, 'mch.reset()', 'MicroPython') |
66 | + sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR); | 76 | + wait_for_console_pattern(self, '>>>') |
67 | + sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0, | ||
68 | + SDHC_SELECT_DESELECT_CARD); | ||
69 | + | 77 | + |
70 | + return qts; | 78 | +if __name__ == '__main__': |
71 | +} | 79 | + QemuSystemTest.main() |
72 | + | ||
73 | +static void write_sdread(QTestState *qts, const char *msg) | ||
74 | +{ | ||
75 | + int fd, ret; | ||
76 | + size_t len = strlen(msg); | ||
77 | + char *rmsg = g_malloc(len); | ||
78 | + | ||
79 | + /* write message to sd */ | ||
80 | + fd = open(sd_path, O_WRONLY); | ||
81 | + g_assert(fd >= 0); | ||
82 | + ret = write(fd, msg, len); | ||
83 | + close(fd); | ||
84 | + g_assert(ret == len); | ||
85 | + | ||
86 | + /* read message using sdhci */ | ||
87 | + ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len); | ||
88 | + g_assert(ret == len); | ||
89 | + g_assert(!memcmp(rmsg, msg, len)); | ||
90 | + | ||
91 | + g_free(rmsg); | ||
92 | +} | ||
93 | + | ||
94 | +/* Check MMC can read values from sd */ | ||
95 | +static void test_read_sd(void) | ||
96 | +{ | ||
97 | + QTestState *qts = setup_sd_card(); | ||
98 | + | ||
99 | + write_sdread(qts, "hello world"); | ||
100 | + write_sdread(qts, "goodbye"); | ||
101 | + | ||
102 | + qtest_quit(qts); | ||
103 | +} | ||
104 | + | ||
105 | +static void sdwrite_read(QTestState *qts, const char *msg) | ||
106 | +{ | ||
107 | + int fd, ret; | ||
108 | + size_t len = strlen(msg); | ||
109 | + char *rmsg = g_malloc(len); | ||
110 | + | ||
111 | + /* write message using sdhci */ | ||
112 | + sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE); | ||
113 | + | ||
114 | + /* read message from sd */ | ||
115 | + fd = open(sd_path, O_RDONLY); | ||
116 | + g_assert(fd >= 0); | ||
117 | + ret = read(fd, rmsg, len); | ||
118 | + close(fd); | ||
119 | + g_assert(ret == len); | ||
120 | + | ||
121 | + g_assert(!memcmp(rmsg, msg, len)); | ||
122 | + | ||
123 | + g_free(rmsg); | ||
124 | +} | ||
125 | + | ||
126 | +/* Check MMC can write values to sd */ | ||
127 | +static void test_write_sd(void) | ||
128 | +{ | ||
129 | + QTestState *qts = setup_sd_card(); | ||
130 | + | ||
131 | + sdwrite_read(qts, "hello world"); | ||
132 | + sdwrite_read(qts, "goodbye"); | ||
133 | + | ||
134 | + qtest_quit(qts); | ||
135 | +} | ||
136 | + | ||
137 | +/* Check SDHCI has correct default values. */ | ||
138 | +static void test_reset(void) | ||
139 | +{ | ||
140 | + QTestState *qts = qtest_init("-machine kudo-bmc"); | ||
141 | + uint64_t addr = NPCM7XX_MMC_BA; | ||
142 | + uint64_t end_addr = addr + NPCM7XX_REG_SIZE; | ||
143 | + uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET, | ||
144 | + NPCM7XX_PRSTVALS_1_RESET, | ||
145 | + 0, | ||
146 | + NPCM7XX_PRSTVALS_3_RESET, | ||
147 | + 0, | ||
148 | + 0}; | ||
149 | + int i; | ||
150 | + uint32_t mask; | ||
151 | + | ||
152 | + while (addr < end_addr) { | ||
153 | + switch (addr - NPCM7XX_MMC_BA) { | ||
154 | + case SDHC_PRNSTS: | ||
155 | + /* | ||
156 | + * ignores bits 20 to 24: they are changed when reading registers | ||
157 | + */ | ||
158 | + mask = 0x1f00000; | ||
159 | + g_assert_cmphex(qtest_readl(qts, addr) | mask, ==, | ||
160 | + NPCM7XX_PRSNTS_RESET | mask); | ||
161 | + addr += 4; | ||
162 | + break; | ||
163 | + case SDHC_BLKGAP: | ||
164 | + g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET); | ||
165 | + addr += 1; | ||
166 | + break; | ||
167 | + case SDHC_CAPAB: | ||
168 | + g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET); | ||
169 | + addr += 8; | ||
170 | + break; | ||
171 | + case SDHC_MAXCURR: | ||
172 | + g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET); | ||
173 | + addr += 8; | ||
174 | + break; | ||
175 | + case SDHC_HCVER: | ||
176 | + g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET); | ||
177 | + addr += 2; | ||
178 | + break; | ||
179 | + case NPCM7XX_PRSTVALS: | ||
180 | + for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) { | ||
181 | + g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==, | ||
182 | + prstvals_resets[i]); | ||
183 | + } | ||
184 | + addr += NPCM7XX_PRSTVALS_SIZE * 2; | ||
185 | + break; | ||
186 | + default: | ||
187 | + g_assert_cmphex(qtest_readb(qts, addr), ==, 0); | ||
188 | + addr += 1; | ||
189 | + } | ||
190 | + } | ||
191 | + | ||
192 | + qtest_quit(qts); | ||
193 | +} | ||
194 | + | ||
195 | +static void drive_destroy(void) | ||
196 | +{ | ||
197 | + unlink(sd_path); | ||
198 | + g_free(sd_path); | ||
199 | +} | ||
200 | + | ||
201 | +static void drive_create(void) | ||
202 | +{ | ||
203 | + int fd, ret; | ||
204 | + GError *error = NULL; | ||
205 | + | ||
206 | + /* Create a temporary raw image */ | ||
207 | + fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error); | ||
208 | + if (fd == -1) { | ||
209 | + fprintf(stderr, "unable to create sdhci file: %s\n", error->message); | ||
210 | + g_error_free(error); | ||
211 | + } | ||
212 | + g_assert(sd_path != NULL); | ||
213 | + | ||
214 | + ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE); | ||
215 | + g_assert_cmpint(ret, ==, 0); | ||
216 | + g_message("%s", sd_path); | ||
217 | + close(fd); | ||
218 | +} | ||
219 | + | ||
220 | +int main(int argc, char **argv) | ||
221 | +{ | ||
222 | + int ret; | ||
223 | + | ||
224 | + drive_create(); | ||
225 | + | ||
226 | + g_test_init(&argc, &argv, NULL); | ||
227 | + | ||
228 | + qtest_add_func("npcm7xx_sdhci/reset", test_reset); | ||
229 | + qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd); | ||
230 | + qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd); | ||
231 | + | ||
232 | + ret = g_test_run(); | ||
233 | + drive_destroy(); | ||
234 | + return ret; | ||
235 | +} | ||
236 | diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build | ||
237 | index XXXXXXX..XXXXXXX 100644 | ||
238 | --- a/tests/qtest/meson.build | ||
239 | +++ b/tests/qtest/meson.build | ||
240 | @@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \ | ||
241 | 'npcm7xx_gpio-test', | ||
242 | 'npcm7xx_pwm-test', | ||
243 | 'npcm7xx_rng-test', | ||
244 | + 'npcm7xx_sdhci-test', | ||
245 | 'npcm7xx_smbus-test', | ||
246 | 'npcm7xx_timer-test', | ||
247 | 'npcm7xx_watchdog_timer-test'] + \ | ||
248 | -- | 80 | -- |
249 | 2.25.1 | 81 | 2.34.1 |
82 | |||
83 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | The pseudocode ResetSVEState() does: |
---|---|---|---|
2 | FPSR = ZeroExtend(0x0800009f<31:0>, 64); | ||
3 | but QEMU's arm_reset_sve_state() called vfp_set_fpcr() by accident. | ||
2 | 4 | ||
3 | For FEAT_LPA2, we will need other ARMVAParameters, which themselves | 5 | Before the advent of FEAT_AFP, this was only setting a collection of |
4 | depend on the translation granule in use. We might as well validate | 6 | RES0 bits, which vfp_set_fpsr() would then ignore, so the only effect |
5 | that the given TG matches; the architecture "does not require that | 7 | was that we didn't actually set the FPSR the way we are supposed to |
6 | the instruction invalidates any entries" if this is not true. | 8 | do. Once FEAT_AFP is implemented, setting the bottom bits of FPSR |
9 | will change the floating point behaviour. | ||
7 | 10 | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 11 | Call vfp_set_fpsr(), as we ought to. |
9 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 12 | |
10 | Message-id: 20220301215958.157011-15-richard.henderson@linaro.org | 13 | (Note for stable backports: commit 7f2a01e7368f9 moved this function |
14 | from sme_helper.c to helper.c, but it had the same bug before the | ||
15 | move too.) | ||
16 | |||
17 | Cc: qemu-stable@nongnu.org | ||
18 | Fixes: f84734b87461 ("target/arm: Implement SMSTART, SMSTOP") | ||
11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 19 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
20 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
21 | Message-id: 20250124162836.2332150-4-peter.maydell@linaro.org | ||
12 | --- | 22 | --- |
13 | target/arm/helper.c | 10 +++++++--- | 23 | target/arm/helper.c | 2 +- |
14 | 1 file changed, 7 insertions(+), 3 deletions(-) | 24 | 1 file changed, 1 insertion(+), 1 deletion(-) |
15 | 25 | ||
16 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 26 | diff --git a/target/arm/helper.c b/target/arm/helper.c |
17 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/arm/helper.c | 28 | --- a/target/arm/helper.c |
19 | +++ b/target/arm/helper.c | 29 | +++ b/target/arm/helper.c |
20 | @@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, | 30 | @@ -XXX,XX +XXX,XX @@ static void arm_reset_sve_state(CPUARMState *env) |
21 | uint64_t value) | 31 | memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs)); |
22 | { | 32 | /* Recall that FFR is stored as pregs[16]. */ |
23 | unsigned int page_size_granule, page_shift, num, scale, exponent; | 33 | memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs)); |
24 | + /* Extract one bit to represent the va selector in use. */ | 34 | - vfp_set_fpcr(env, 0x0800009f); |
25 | + uint64_t select = sextract64(value, 36, 1); | 35 | + vfp_set_fpsr(env, 0x0800009f); |
26 | + ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true); | 36 | } |
27 | TLBIRange ret = { }; | 37 | |
28 | 38 | void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask) | |
29 | page_size_granule = extract64(value, 46, 2); | ||
30 | |||
31 | - if (page_size_granule == 0) { | ||
32 | - qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n", | ||
33 | + /* The granule encoded in value must match the granule in use. */ | ||
34 | + if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) { | ||
35 | + qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n", | ||
36 | page_size_granule); | ||
37 | return ret; | ||
38 | } | ||
39 | @@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, | ||
40 | |||
41 | ret.length = (num + 1) << (exponent + page_shift); | ||
42 | |||
43 | - if (regime_has_2_ranges(mmuidx)) { | ||
44 | + if (param.select) { | ||
45 | ret.base = sextract64(value, 0, 37); | ||
46 | } else { | ||
47 | ret.base = extract64(value, 0, 37); | ||
48 | -- | 39 | -- |
49 | 2.25.1 | 40 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | Use the FPSR_ named constants in vfp_exceptbits_from_host(), |
---|---|---|---|
2 | rather than hardcoded magic numbers. | ||
2 | 3 | ||
3 | The shift of the BaseADDR field depends on the translation | 4 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
4 | granule in use. | 5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
6 | Message-id: 20250124162836.2332150-5-peter.maydell@linaro.org | ||
7 | --- | ||
8 | target/arm/vfp_helper.c | 12 ++++++------ | ||
9 | 1 file changed, 6 insertions(+), 6 deletions(-) | ||
5 | 10 | ||
6 | Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE") | 11 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c |
7 | Reported-by: Peter Maydell <peter.maydell@linaro.org> | ||
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
9 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
10 | Message-id: 20220301215958.157011-14-richard.henderson@linaro.org | ||
11 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
12 | --- | ||
13 | target/arm/helper.c | 5 +++-- | ||
14 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/arm/helper.c | 13 | --- a/target/arm/vfp_helper.c |
19 | +++ b/target/arm/helper.c | 14 | +++ b/target/arm/vfp_helper.c |
20 | @@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, | 15 | @@ -XXX,XX +XXX,XX @@ static inline int vfp_exceptbits_from_host(int host_bits) |
21 | ret.length = (num + 1) << (exponent + page_shift); | 16 | int target_bits = 0; |
22 | 17 | ||
23 | if (regime_has_2_ranges(mmuidx)) { | 18 | if (host_bits & float_flag_invalid) { |
24 | - ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS; | 19 | - target_bits |= 1; |
25 | + ret.base = sextract64(value, 0, 37); | 20 | + target_bits |= FPSR_IOC; |
26 | } else { | ||
27 | - ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS; | ||
28 | + ret.base = extract64(value, 0, 37); | ||
29 | } | 21 | } |
30 | + ret.base <<= page_shift; | 22 | if (host_bits & float_flag_divbyzero) { |
31 | 23 | - target_bits |= 2; | |
32 | return ret; | 24 | + target_bits |= FPSR_DZC; |
25 | } | ||
26 | if (host_bits & float_flag_overflow) { | ||
27 | - target_bits |= 4; | ||
28 | + target_bits |= FPSR_OFC; | ||
29 | } | ||
30 | if (host_bits & (float_flag_underflow | float_flag_output_denormal)) { | ||
31 | - target_bits |= 8; | ||
32 | + target_bits |= FPSR_UFC; | ||
33 | } | ||
34 | if (host_bits & float_flag_inexact) { | ||
35 | - target_bits |= 0x10; | ||
36 | + target_bits |= FPSR_IXC; | ||
37 | } | ||
38 | if (host_bits & float_flag_input_denormal) { | ||
39 | - target_bits |= 0x80; | ||
40 | + target_bits |= FPSR_IDC; | ||
41 | } | ||
42 | return target_bits; | ||
33 | } | 43 | } |
34 | -- | 44 | -- |
35 | 2.25.1 | 45 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In vfp_exceptbits_from_host(), we accumulate the FPSR flags in | ||
2 | an "int", and our return type is also "int". However, the only | ||
3 | callsite returns the same information as a uint32_t, and | ||
4 | more generally we handle FPSR values in the code as uint32_t, | ||
5 | not int. Bring this function in to line with that convention. | ||
1 | 6 | ||
7 | There is no behaviour change because none of the FPSR bits | ||
8 | we set in this function are bit 31. The input argument to | ||
9 | the function remains 'int' because that is the return type | ||
10 | of the softfloat get_float_exception_flags(). | ||
11 | |||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Message-id: 20250124162836.2332150-6-peter.maydell@linaro.org | ||
15 | --- | ||
16 | target/arm/vfp_helper.c | 4 ++-- | ||
17 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
18 | |||
19 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/arm/vfp_helper.c | ||
22 | +++ b/target/arm/vfp_helper.c | ||
23 | @@ -XXX,XX +XXX,XX @@ | ||
24 | #ifdef CONFIG_TCG | ||
25 | |||
26 | /* Convert host exception flags to vfp form. */ | ||
27 | -static inline int vfp_exceptbits_from_host(int host_bits) | ||
28 | +static inline uint32_t vfp_exceptbits_from_host(int host_bits) | ||
29 | { | ||
30 | - int target_bits = 0; | ||
31 | + uint32_t target_bits = 0; | ||
32 | |||
33 | if (host_bits & float_flag_invalid) { | ||
34 | target_bits |= FPSR_IOC; | ||
35 | -- | ||
36 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | We want to split the existing fp_status in the Arm CPUState into |
---|---|---|---|
2 | separate float_status fields for AArch32 and AArch64. (This is | ||
3 | because new control bits defined by FEAT_AFP only have an effect for | ||
4 | AArch64, not AArch32.) To make this split we will: | ||
5 | * define new fp_status_a32 and fp_status_a64 which have | ||
6 | identical behaviour to the existing fp_status | ||
7 | * move existing uses of fp_status to fp_status_a32 or | ||
8 | fp_status_a64 as appropriate | ||
9 | * delete the old fp_status when it has no uses left | ||
2 | 10 | ||
3 | This feature widens physical addresses (and intermediate physical | 11 | In this patch we add the new float_status fields. |
4 | addresses for 2-stage translation) from 48 to 52 bits, when using | ||
5 | 4k or 16k pages. | ||
6 | 12 | ||
7 | This introduces the DS bit to TCR_ELx, which is RES0 unless the | 13 | We will also need to split fp_status_f16, but we will do that |
8 | page size is enabled and supports LPA2, resulting in the effective | 14 | as a separate series of patches. |
9 | value of DS for a given table walk. The DS bit changes the format | ||
10 | of the page table descriptor slightly, moving the PS field out to | ||
11 | TCR so that all pages have the same sharability and repurposing | ||
12 | those bits of the page table descriptor for the highest bits of | ||
13 | the output address. | ||
14 | 15 | ||
15 | Do not yet enable FEAT_LPA2; we need extra plumbing to avoid | 16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
16 | tickling an old kernel bug. | 17 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
18 | Message-id: 20250124162836.2332150-7-peter.maydell@linaro.org | ||
19 | --- | ||
20 | target/arm/cpu.h | 4 ++++ | ||
21 | target/arm/tcg/translate.h | 12 ++++++++++++ | ||
22 | target/arm/cpu.c | 2 ++ | ||
23 | target/arm/vfp_helper.c | 12 ++++++++++++ | ||
24 | 4 files changed, 30 insertions(+) | ||
17 | 25 | ||
18 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
19 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
20 | Message-id: 20220301215958.157011-17-richard.henderson@linaro.org | ||
21 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
22 | --- | ||
23 | docs/system/arm/emulation.rst | 1 + | ||
24 | target/arm/cpu.h | 22 ++++++++ | ||
25 | target/arm/internals.h | 2 + | ||
26 | target/arm/helper.c | 102 +++++++++++++++++++++++++++++----- | ||
27 | 4 files changed, 112 insertions(+), 15 deletions(-) | ||
28 | |||
29 | diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/docs/system/arm/emulation.rst | ||
32 | +++ b/docs/system/arm/emulation.rst | ||
33 | @@ -XXX,XX +XXX,XX @@ the following architecture extensions: | ||
34 | - FEAT_JSCVT (JavaScript conversion instructions) | ||
35 | - FEAT_LOR (Limited ordering regions) | ||
36 | - FEAT_LPA (Large Physical Address space) | ||
37 | +- FEAT_LPA2 (Large Physical and virtual Address space v2) | ||
38 | - FEAT_LRCPC (Load-acquire RCpc instructions) | ||
39 | - FEAT_LRCPC2 (Load-acquire RCpc instructions v2) | ||
40 | - FEAT_LSE (Large System Extensions) | ||
41 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | 26 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h |
42 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
43 | --- a/target/arm/cpu.h | 28 | --- a/target/arm/cpu.h |
44 | +++ b/target/arm/cpu.h | 29 | +++ b/target/arm/cpu.h |
45 | @@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id) | 30 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
46 | return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0; | 31 | /* There are a number of distinct float control structures: |
32 | * | ||
33 | * fp_status: is the "normal" fp status. | ||
34 | + * fp_status_a32: is the "normal" fp status for AArch32 insns | ||
35 | + * fp_status_a64: is the "normal" fp status for AArch64 insns | ||
36 | * fp_status_fp16: used for half-precision calculations | ||
37 | * standard_fp_status : the ARM "Standard FPSCR Value" | ||
38 | * standard_fp_status_fp16 : used for half-precision | ||
39 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { | ||
40 | * an explicit FPSCR read. | ||
41 | */ | ||
42 | float_status fp_status; | ||
43 | + float_status fp_status_a32; | ||
44 | + float_status fp_status_a64; | ||
45 | float_status fp_status_f16; | ||
46 | float_status standard_fp_status; | ||
47 | float_status standard_fp_status_f16; | ||
48 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/arm/tcg/translate.h | ||
51 | +++ b/target/arm/tcg/translate.h | ||
52 | @@ -XXX,XX +XXX,XX @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb) | ||
53 | */ | ||
54 | typedef enum ARMFPStatusFlavour { | ||
55 | FPST_FPCR, | ||
56 | + FPST_A32, | ||
57 | + FPST_A64, | ||
58 | FPST_FPCR_F16, | ||
59 | FPST_STD, | ||
60 | FPST_STD_F16, | ||
61 | @@ -XXX,XX +XXX,XX @@ typedef enum ARMFPStatusFlavour { | ||
62 | * | ||
63 | * FPST_FPCR | ||
64 | * for non-FP16 operations controlled by the FPCR | ||
65 | + * FPST_A32 | ||
66 | + * for AArch32 non-FP16 operations controlled by the FPCR | ||
67 | + * FPST_A64 | ||
68 | + * for AArch64 non-FP16 operations controlled by the FPCR | ||
69 | * FPST_FPCR_F16 | ||
70 | * for operations controlled by the FPCR where FPCR.FZ16 is to be used | ||
71 | * FPST_STD | ||
72 | @@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) | ||
73 | case FPST_FPCR: | ||
74 | offset = offsetof(CPUARMState, vfp.fp_status); | ||
75 | break; | ||
76 | + case FPST_A32: | ||
77 | + offset = offsetof(CPUARMState, vfp.fp_status_a32); | ||
78 | + break; | ||
79 | + case FPST_A64: | ||
80 | + offset = offsetof(CPUARMState, vfp.fp_status_a64); | ||
81 | + break; | ||
82 | case FPST_FPCR_F16: | ||
83 | offset = offsetof(CPUARMState, vfp.fp_status_f16); | ||
84 | break; | ||
85 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | ||
86 | index XXXXXXX..XXXXXXX 100644 | ||
87 | --- a/target/arm/cpu.c | ||
88 | +++ b/target/arm/cpu.c | ||
89 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) | ||
90 | set_default_nan_mode(1, &env->vfp.standard_fp_status); | ||
91 | set_default_nan_mode(1, &env->vfp.standard_fp_status_f16); | ||
92 | arm_set_default_fp_behaviours(&env->vfp.fp_status); | ||
93 | + arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); | ||
94 | + arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); | ||
95 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); | ||
96 | arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); | ||
97 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); | ||
98 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/target/arm/vfp_helper.c | ||
101 | +++ b/target/arm/vfp_helper.c | ||
102 | @@ -XXX,XX +XXX,XX @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) | ||
103 | uint32_t i; | ||
104 | |||
105 | i = get_float_exception_flags(&env->vfp.fp_status); | ||
106 | + i |= get_float_exception_flags(&env->vfp.fp_status_a32); | ||
107 | + i |= get_float_exception_flags(&env->vfp.fp_status_a64); | ||
108 | i |= get_float_exception_flags(&env->vfp.standard_fp_status); | ||
109 | /* FZ16 does not generate an input denormal exception. */ | ||
110 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16) | ||
111 | @@ -XXX,XX +XXX,XX @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) | ||
112 | * be the architecturally up-to-date exception flag information first. | ||
113 | */ | ||
114 | set_float_exception_flags(0, &env->vfp.fp_status); | ||
115 | + set_float_exception_flags(0, &env->vfp.fp_status_a32); | ||
116 | + set_float_exception_flags(0, &env->vfp.fp_status_a64); | ||
117 | set_float_exception_flags(0, &env->vfp.fp_status_f16); | ||
118 | set_float_exception_flags(0, &env->vfp.standard_fp_status); | ||
119 | set_float_exception_flags(0, &env->vfp.standard_fp_status_f16); | ||
120 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
121 | break; | ||
122 | } | ||
123 | set_float_rounding_mode(i, &env->vfp.fp_status); | ||
124 | + set_float_rounding_mode(i, &env->vfp.fp_status_a32); | ||
125 | + set_float_rounding_mode(i, &env->vfp.fp_status_a64); | ||
126 | set_float_rounding_mode(i, &env->vfp.fp_status_f16); | ||
127 | } | ||
128 | if (changed & FPCR_FZ16) { | ||
129 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
130 | bool ftz_enabled = val & FPCR_FZ; | ||
131 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); | ||
132 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); | ||
133 | + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a32); | ||
134 | + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32); | ||
135 | + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a64); | ||
136 | + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a64); | ||
137 | } | ||
138 | if (changed & FPCR_DN) { | ||
139 | bool dnan_enabled = val & FPCR_DN; | ||
140 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); | ||
141 | + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); | ||
142 | + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); | ||
143 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); | ||
144 | } | ||
47 | } | 145 | } |
48 | |||
49 | +static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id) | ||
50 | +{ | ||
51 | + return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1; | ||
52 | +} | ||
53 | + | ||
54 | +static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id) | ||
55 | +{ | ||
56 | + unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2); | ||
57 | + return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id)); | ||
58 | +} | ||
59 | + | ||
60 | +static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id) | ||
61 | +{ | ||
62 | + return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2; | ||
63 | +} | ||
64 | + | ||
65 | +static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id) | ||
66 | +{ | ||
67 | + unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2); | ||
68 | + return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id)); | ||
69 | +} | ||
70 | + | ||
71 | static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id) | ||
72 | { | ||
73 | return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0; | ||
74 | diff --git a/target/arm/internals.h b/target/arm/internals.h | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/target/arm/internals.h | ||
77 | +++ b/target/arm/internals.h | ||
78 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id) | ||
79 | typedef struct ARMVAParameters { | ||
80 | unsigned tsz : 8; | ||
81 | unsigned ps : 3; | ||
82 | + unsigned sh : 2; | ||
83 | unsigned select : 1; | ||
84 | bool tbi : 1; | ||
85 | bool epd : 1; | ||
86 | @@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters { | ||
87 | bool using16k : 1; | ||
88 | bool using64k : 1; | ||
89 | bool tsz_oob : 1; /* tsz has been clamped to legal range */ | ||
90 | + bool ds : 1; | ||
91 | } ARMVAParameters; | ||
92 | |||
93 | ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
94 | diff --git a/target/arm/helper.c b/target/arm/helper.c | ||
95 | index XXXXXXX..XXXXXXX 100644 | ||
96 | --- a/target/arm/helper.c | ||
97 | +++ b/target/arm/helper.c | ||
98 | @@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, | ||
99 | } else { | ||
100 | ret.base = extract64(value, 0, 37); | ||
101 | } | ||
102 | + if (param.ds) { | ||
103 | + /* | ||
104 | + * With DS=1, BaseADDR is always shifted 16 so that it is able | ||
105 | + * to address all 52 va bits. The input address is perforce | ||
106 | + * aligned on a 64k boundary regardless of translation granule. | ||
107 | + */ | ||
108 | + page_shift = 16; | ||
109 | + } | ||
110 | ret.base <<= page_shift; | ||
111 | |||
112 | return ret; | ||
113 | @@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, | ||
114 | const int grainsize = stride + 3; | ||
115 | int startsizecheck; | ||
116 | |||
117 | - /* Negative levels are never allowed. */ | ||
118 | - if (level < 0) { | ||
119 | + /* | ||
120 | + * Negative levels are usually not allowed... | ||
121 | + * Except for FEAT_LPA2, 4k page table, 52-bit address space, which | ||
122 | + * begins with level -1. Note that previous feature tests will have | ||
123 | + * eliminated this combination if it is not enabled. | ||
124 | + */ | ||
125 | + if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) { | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
130 | ARMMMUIdx mmu_idx, bool data) | ||
131 | { | ||
132 | uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; | ||
133 | - bool epd, hpd, using16k, using64k, tsz_oob; | ||
134 | - int select, tsz, tbi, max_tsz, min_tsz, ps; | ||
135 | + bool epd, hpd, using16k, using64k, tsz_oob, ds; | ||
136 | + int select, tsz, tbi, max_tsz, min_tsz, ps, sh; | ||
137 | + ARMCPU *cpu = env_archcpu(env); | ||
138 | |||
139 | if (!regime_has_2_ranges(mmu_idx)) { | ||
140 | select = 0; | ||
141 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
142 | hpd = extract32(tcr, 24, 1); | ||
143 | } | ||
144 | epd = false; | ||
145 | + sh = extract32(tcr, 12, 2); | ||
146 | ps = extract32(tcr, 16, 3); | ||
147 | + ds = extract64(tcr, 32, 1); | ||
148 | } else { | ||
149 | /* | ||
150 | * Bit 55 is always between the two regions, and is canonical for | ||
151 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
152 | if (!select) { | ||
153 | tsz = extract32(tcr, 0, 6); | ||
154 | epd = extract32(tcr, 7, 1); | ||
155 | + sh = extract32(tcr, 12, 2); | ||
156 | using64k = extract32(tcr, 14, 1); | ||
157 | using16k = extract32(tcr, 15, 1); | ||
158 | hpd = extract64(tcr, 41, 1); | ||
159 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
160 | using64k = tg == 3; | ||
161 | tsz = extract32(tcr, 16, 6); | ||
162 | epd = extract32(tcr, 23, 1); | ||
163 | + sh = extract32(tcr, 28, 2); | ||
164 | hpd = extract64(tcr, 42, 1); | ||
165 | } | ||
166 | ps = extract64(tcr, 32, 3); | ||
167 | + ds = extract64(tcr, 59, 1); | ||
168 | } | ||
169 | |||
170 | - if (cpu_isar_feature(aa64_st, env_archcpu(env))) { | ||
171 | + if (cpu_isar_feature(aa64_st, cpu)) { | ||
172 | max_tsz = 48 - using64k; | ||
173 | } else { | ||
174 | max_tsz = 39; | ||
175 | } | ||
176 | |||
177 | + /* | ||
178 | + * DS is RES0 unless FEAT_LPA2 is supported for the given page size; | ||
179 | + * adjust the effective value of DS, as documented. | ||
180 | + */ | ||
181 | min_tsz = 16; | ||
182 | if (using64k) { | ||
183 | - if (cpu_isar_feature(aa64_lva, env_archcpu(env))) { | ||
184 | + if (cpu_isar_feature(aa64_lva, cpu)) { | ||
185 | + min_tsz = 12; | ||
186 | + } | ||
187 | + ds = false; | ||
188 | + } else if (ds) { | ||
189 | + switch (mmu_idx) { | ||
190 | + case ARMMMUIdx_Stage2: | ||
191 | + case ARMMMUIdx_Stage2_S: | ||
192 | + if (using16k) { | ||
193 | + ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu); | ||
194 | + } else { | ||
195 | + ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu); | ||
196 | + } | ||
197 | + break; | ||
198 | + default: | ||
199 | + if (using16k) { | ||
200 | + ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu); | ||
201 | + } else { | ||
202 | + ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu); | ||
203 | + } | ||
204 | + break; | ||
205 | + } | ||
206 | + if (ds) { | ||
207 | min_tsz = 12; | ||
208 | } | ||
209 | } | ||
210 | - /* TODO: FEAT_LPA2 */ | ||
211 | |||
212 | if (tsz > max_tsz) { | ||
213 | tsz = max_tsz; | ||
214 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
215 | return (ARMVAParameters) { | ||
216 | .tsz = tsz, | ||
217 | .ps = ps, | ||
218 | + .sh = sh, | ||
219 | .select = select, | ||
220 | .tbi = tbi, | ||
221 | .epd = epd, | ||
222 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
223 | .using16k = using16k, | ||
224 | .using64k = using64k, | ||
225 | .tsz_oob = tsz_oob, | ||
226 | + .ds = ds, | ||
227 | }; | ||
228 | } | ||
229 | |||
230 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
231 | * VTCR_EL2.SL0 field (whose interpretation depends on the page size) | ||
232 | */ | ||
233 | uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2); | ||
234 | + uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1); | ||
235 | uint32_t startlevel; | ||
236 | bool ok; | ||
237 | |||
238 | - if (!aarch64 || stride == 9) { | ||
239 | + /* SL2 is RES0 unless DS=1 & 4kb granule. */ | ||
240 | + if (param.ds && stride == 9 && sl2) { | ||
241 | + if (sl0 != 0) { | ||
242 | + level = 0; | ||
243 | + fault_type = ARMFault_Translation; | ||
244 | + goto do_fault; | ||
245 | + } | ||
246 | + startlevel = -1; | ||
247 | + } else if (!aarch64 || stride == 9) { | ||
248 | /* AArch32 or 4KB pages */ | ||
249 | startlevel = 2 - sl0; | ||
250 | |||
251 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
252 | * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0 | ||
253 | * or an AddressSize fault is raised. So for v8 we extract those SBZ | ||
254 | * bits as part of the address, which will be checked via outputsize. | ||
255 | - * For AArch64, the address field always goes up to bit 47 (with extra | ||
256 | - * bits for FEAT_LPA placed elsewhere). AArch64 implies v8. | ||
257 | + * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2; | ||
258 | + * the highest bits of a 52-bit output are placed elsewhere. | ||
259 | */ | ||
260 | - if (arm_feature(env, ARM_FEATURE_V8)) { | ||
261 | + if (param.ds) { | ||
262 | + descaddrmask = MAKE_64BIT_MASK(0, 50); | ||
263 | + } else if (arm_feature(env, ARM_FEATURE_V8)) { | ||
264 | descaddrmask = MAKE_64BIT_MASK(0, 48); | ||
265 | } else { | ||
266 | descaddrmask = MAKE_64BIT_MASK(0, 40); | ||
267 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
268 | |||
269 | /* | ||
270 | * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] | ||
271 | - * of descriptor. Otherwise, if descaddr is out of range, raise | ||
272 | - * AddressSizeFault. | ||
273 | + * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of | ||
274 | + * descaddr are in [9:8]. Otherwise, if descaddr is out of range, | ||
275 | + * raise AddressSizeFault. | ||
276 | */ | ||
277 | if (outputsize > 48) { | ||
278 | - descaddr |= extract64(descriptor, 12, 4) << 48; | ||
279 | + if (param.ds) { | ||
280 | + descaddr |= extract64(descriptor, 8, 2) << 50; | ||
281 | + } else { | ||
282 | + descaddr |= extract64(descriptor, 12, 4) << 48; | ||
283 | + } | ||
284 | } else if (descaddr >> outputsize) { | ||
285 | fault_type = ARMFault_AddressSize; | ||
286 | goto do_fault; | ||
287 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
288 | assert(attrindx <= 7); | ||
289 | cacheattrs->attrs = extract64(mair, attrindx * 8, 8); | ||
290 | } | ||
291 | - cacheattrs->shareability = extract32(attrs, 6, 2); | ||
292 | + | ||
293 | + /* | ||
294 | + * For FEAT_LPA2 and effective DS, the SH field in the attributes | ||
295 | + * was re-purposed for output address bits. The SH attribute in | ||
296 | + * that case comes from TCR_ELx, which we extracted earlier. | ||
297 | + */ | ||
298 | + if (param.ds) { | ||
299 | + cacheattrs->shareability = param.sh; | ||
300 | + } else { | ||
301 | + cacheattrs->shareability = extract32(attrs, 6, 2); | ||
302 | + } | ||
303 | |||
304 | *phys_ptr = descaddr; | ||
305 | *page_size_ptr = page_size; | ||
306 | -- | 146 | -- |
307 | 2.25.1 | 147 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Switch from vfp.fp_status to vfp.fp_status_a64 for helpers which: | ||
2 | * directly reference an fp_status field | ||
3 | * are called only from the A64 decoder | ||
4 | * are not called inside a set_rmode/restore_rmode sequence | ||
1 | 5 | ||
6 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
7 | Message-id: 20250124162836.2332150-8-peter.maydell@linaro.org | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | --- | ||
10 | target/arm/tcg/sme_helper.c | 2 +- | ||
11 | target/arm/tcg/vec_helper.c | 8 ++++---- | ||
12 | 2 files changed, 5 insertions(+), 5 deletions(-) | ||
13 | |||
14 | diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/arm/tcg/sme_helper.c | ||
17 | +++ b/target/arm/tcg/sme_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn, | ||
19 | * round-to-odd -- see above. | ||
20 | */ | ||
21 | fpst_f16 = env->vfp.fp_status_f16; | ||
22 | - fpst_std = env->vfp.fp_status; | ||
23 | + fpst_std = env->vfp.fp_status_a64; | ||
24 | set_default_nan_mode(true, &fpst_std); | ||
25 | set_default_nan_mode(true, &fpst_f16); | ||
26 | fpst_odd = fpst_std; | ||
27 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/arm/tcg/vec_helper.c | ||
30 | +++ b/target/arm/tcg/vec_helper.c | ||
31 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_a32)(void *vd, void *vn, void *vm, | ||
32 | void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm, | ||
33 | CPUARMState *env, uint32_t desc) | ||
34 | { | ||
35 | - do_fmlal(vd, vn, vm, &env->vfp.fp_status, desc, | ||
36 | + do_fmlal(vd, vn, vm, &env->vfp.fp_status_a64, desc, | ||
37 | get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
38 | } | ||
39 | |||
40 | @@ -XXX,XX +XXX,XX @@ void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va, | ||
41 | intptr_t i, oprsz = simd_oprsz(desc); | ||
42 | uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15; | ||
43 | intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); | ||
44 | - float_status *status = &env->vfp.fp_status; | ||
45 | + float_status *status = &env->vfp.fp_status_a64; | ||
46 | bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); | ||
47 | |||
48 | for (i = 0; i < oprsz; i += sizeof(float32)) { | ||
49 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a32)(void *vd, void *vn, void *vm, | ||
50 | void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm, | ||
51 | CPUARMState *env, uint32_t desc) | ||
52 | { | ||
53 | - do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc, | ||
54 | + do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status_a64, desc, | ||
55 | get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
56 | } | ||
57 | |||
58 | @@ -XXX,XX +XXX,XX @@ void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va, | ||
59 | uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15; | ||
60 | intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); | ||
61 | intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 2, 3) * sizeof(float16); | ||
62 | - float_status *status = &env->vfp.fp_status; | ||
63 | + float_status *status = &env->vfp.fp_status_a64; | ||
64 | bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); | ||
65 | |||
66 | for (i = 0; i < oprsz; i += 16) { | ||
67 | -- | ||
68 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In is_ebf(), we might be called for A64 or A32, but we have | ||
2 | the CPUARMState* so we can select fp_status_a64 or | ||
3 | fp_status_a32 accordingly. | ||
1 | 4 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | --- | ||
8 | target/arm/tcg/vec_helper.c | 2 +- | ||
9 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
10 | |||
11 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/target/arm/tcg/vec_helper.c | ||
14 | +++ b/target/arm/tcg/vec_helper.c | ||
15 | @@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp) | ||
16 | */ | ||
17 | bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF; | ||
18 | |||
19 | - *statusp = env->vfp.fp_status; | ||
20 | + *statusp = is_a64(env) ? env->vfp.fp_status_a64 : env->vfp.fp_status_a32; | ||
21 | set_default_nan_mode(true, statusp); | ||
22 | |||
23 | if (ebf) { | ||
24 | -- | ||
25 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Use fp_status_a32 in the vjcvt helper function; this is called only | ||
2 | from the A32/T32 decoder and is not used inside a | ||
3 | set_rmode/restore_rmode sequence. | ||
1 | 4 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
7 | Message-id: 20250124162836.2332150-9-peter.maydell@linaro.org | ||
8 | --- | ||
9 | target/arm/vfp_helper.c | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/arm/vfp_helper.c | ||
15 | +++ b/target/arm/vfp_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(fjcvtzs)(float64 value, float_status *status) | ||
17 | |||
18 | uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env) | ||
19 | { | ||
20 | - uint64_t pair = HELPER(fjcvtzs)(value, &env->vfp.fp_status); | ||
21 | + uint64_t pair = HELPER(fjcvtzs)(value, &env->vfp.fp_status_a32); | ||
22 | uint32_t result = pair; | ||
23 | uint32_t z = (pair >> 32) == 0; | ||
24 | |||
25 | -- | ||
26 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | The helpers vfp_cmps, vfp_cmpes, vfp_cmpd, vfp_cmped are used only from | ||
2 | the A32 decoder; the A64 decoder uses separate vfp_cmps_a64 etc helpers | ||
3 | (because for A64 we update the main NZCV flags and for A32 we update | ||
4 | the FPSCR NZCV flags). So we can make these helpers use the fp_status_a32 | ||
5 | field instead of fp_status. | ||
1 | 6 | ||
7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Message-id: 20250124162836.2332150-10-peter.maydell@linaro.org | ||
10 | --- | ||
11 | target/arm/vfp_helper.c | 4 ++-- | ||
12 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/arm/vfp_helper.c | ||
17 | +++ b/target/arm/vfp_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void VFP_HELPER(cmpe, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \ | ||
19 | FLOATTYPE ## _compare(a, b, &env->vfp.FPST)); \ | ||
20 | } | ||
21 | DO_VFP_cmp(h, float16, dh_ctype_f16, fp_status_f16) | ||
22 | -DO_VFP_cmp(s, float32, float32, fp_status) | ||
23 | -DO_VFP_cmp(d, float64, float64, fp_status) | ||
24 | +DO_VFP_cmp(s, float32, float32, fp_status_a32) | ||
25 | +DO_VFP_cmp(d, float64, float64, fp_status_a32) | ||
26 | #undef DO_VFP_cmp | ||
27 | |||
28 | /* Integer to float and float to integer conversions */ | ||
29 | -- | ||
30 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In the A32 decoder, use FPST_A32 rather than FPST_FPCR. By | ||
2 | doing an automated conversion of the whole file we avoid possibly | ||
3 | using more than one fpst value in a set_rmode/op/restore_rmode | ||
4 | sequence. | ||
1 | 5 | ||
6 | Patch created with | ||
7 | perl -p -i -e 's/FPST_FPCR(?!_)/FPST_A32/g' target/arm/tcg/translate-vfp.c | ||
8 | |||
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Message-id: 20250124162836.2332150-11-peter.maydell@linaro.org | ||
12 | --- | ||
13 | target/arm/tcg/translate-vfp.c | 54 +++++++++++++++++----------------- | ||
14 | 1 file changed, 27 insertions(+), 27 deletions(-) | ||
15 | |||
16 | diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/arm/tcg/translate-vfp.c | ||
19 | +++ b/target/arm/tcg/translate-vfp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a) | ||
21 | if (sz == 1) { | ||
22 | fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
23 | } else { | ||
24 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
25 | + fpst = fpstatus_ptr(FPST_A32); | ||
26 | } | ||
27 | |||
28 | tcg_rmode = gen_set_rmode(rounding, fpst); | ||
29 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a) | ||
30 | if (sz == 1) { | ||
31 | fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
32 | } else { | ||
33 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
34 | + fpst = fpstatus_ptr(FPST_A32); | ||
35 | } | ||
36 | |||
37 | tcg_shift = tcg_constant_i32(0); | ||
38 | @@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn, | ||
39 | f0 = tcg_temp_new_i32(); | ||
40 | f1 = tcg_temp_new_i32(); | ||
41 | fd = tcg_temp_new_i32(); | ||
42 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
43 | + fpst = fpstatus_ptr(FPST_A32); | ||
44 | |||
45 | vfp_load_reg32(f0, vn); | ||
46 | vfp_load_reg32(f1, vm); | ||
47 | @@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn, | ||
48 | f0 = tcg_temp_new_i64(); | ||
49 | f1 = tcg_temp_new_i64(); | ||
50 | fd = tcg_temp_new_i64(); | ||
51 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
52 | + fpst = fpstatus_ptr(FPST_A32); | ||
53 | |||
54 | vfp_load_reg64(f0, vn); | ||
55 | vfp_load_reg64(f1, vm); | ||
56 | @@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d) | ||
57 | /* VFNMA, VFNMS */ | ||
58 | gen_vfp_negs(vd, vd); | ||
59 | } | ||
60 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
61 | + fpst = fpstatus_ptr(FPST_A32); | ||
62 | gen_helper_vfp_muladds(vd, vn, vm, vd, fpst); | ||
63 | vfp_store_reg32(vd, a->vd); | ||
64 | return true; | ||
65 | @@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d) | ||
66 | /* VFNMA, VFNMS */ | ||
67 | gen_vfp_negd(vd, vd); | ||
68 | } | ||
69 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
70 | + fpst = fpstatus_ptr(FPST_A32); | ||
71 | gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst); | ||
72 | vfp_store_reg64(vd, a->vd); | ||
73 | return true; | ||
74 | @@ -XXX,XX +XXX,XX @@ static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm) | ||
75 | |||
76 | static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm) | ||
77 | { | ||
78 | - gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_FPCR)); | ||
79 | + gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_A32)); | ||
80 | } | ||
81 | |||
82 | static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm) | ||
83 | { | ||
84 | - gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_FPCR)); | ||
85 | + gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_A32)); | ||
86 | } | ||
87 | |||
88 | DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith) | ||
89 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a) | ||
90 | return true; | ||
91 | } | ||
92 | |||
93 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
94 | + fpst = fpstatus_ptr(FPST_A32); | ||
95 | ahp_mode = get_ahp_flag(); | ||
96 | tmp = tcg_temp_new_i32(); | ||
97 | /* The T bit tells us if we want the low or high 16 bits of Vm */ | ||
98 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a) | ||
99 | return true; | ||
100 | } | ||
101 | |||
102 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
103 | + fpst = fpstatus_ptr(FPST_A32); | ||
104 | ahp_mode = get_ahp_flag(); | ||
105 | tmp = tcg_temp_new_i32(); | ||
106 | /* The T bit tells us if we want the low or high 16 bits of Vm */ | ||
107 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_b16_f32(DisasContext *s, arg_VCVT_b16_f32 *a) | ||
108 | return true; | ||
109 | } | ||
110 | |||
111 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
112 | + fpst = fpstatus_ptr(FPST_A32); | ||
113 | tmp = tcg_temp_new_i32(); | ||
114 | |||
115 | vfp_load_reg32(tmp, a->vm); | ||
116 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a) | ||
117 | return true; | ||
118 | } | ||
119 | |||
120 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
121 | + fpst = fpstatus_ptr(FPST_A32); | ||
122 | ahp_mode = get_ahp_flag(); | ||
123 | tmp = tcg_temp_new_i32(); | ||
124 | |||
125 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a) | ||
126 | return true; | ||
127 | } | ||
128 | |||
129 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
130 | + fpst = fpstatus_ptr(FPST_A32); | ||
131 | ahp_mode = get_ahp_flag(); | ||
132 | tmp = tcg_temp_new_i32(); | ||
133 | vm = tcg_temp_new_i64(); | ||
134 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a) | ||
135 | |||
136 | tmp = tcg_temp_new_i32(); | ||
137 | vfp_load_reg32(tmp, a->vm); | ||
138 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
139 | + fpst = fpstatus_ptr(FPST_A32); | ||
140 | gen_helper_rints(tmp, tmp, fpst); | ||
141 | vfp_store_reg32(tmp, a->vd); | ||
142 | return true; | ||
143 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a) | ||
144 | |||
145 | tmp = tcg_temp_new_i64(); | ||
146 | vfp_load_reg64(tmp, a->vm); | ||
147 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
148 | + fpst = fpstatus_ptr(FPST_A32); | ||
149 | gen_helper_rintd(tmp, tmp, fpst); | ||
150 | vfp_store_reg64(tmp, a->vd); | ||
151 | return true; | ||
152 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a) | ||
153 | |||
154 | tmp = tcg_temp_new_i32(); | ||
155 | vfp_load_reg32(tmp, a->vm); | ||
156 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
157 | + fpst = fpstatus_ptr(FPST_A32); | ||
158 | tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); | ||
159 | gen_helper_rints(tmp, tmp, fpst); | ||
160 | gen_restore_rmode(tcg_rmode, fpst); | ||
161 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a) | ||
162 | |||
163 | tmp = tcg_temp_new_i64(); | ||
164 | vfp_load_reg64(tmp, a->vm); | ||
165 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
166 | + fpst = fpstatus_ptr(FPST_A32); | ||
167 | tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); | ||
168 | gen_helper_rintd(tmp, tmp, fpst); | ||
169 | gen_restore_rmode(tcg_rmode, fpst); | ||
170 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a) | ||
171 | |||
172 | tmp = tcg_temp_new_i32(); | ||
173 | vfp_load_reg32(tmp, a->vm); | ||
174 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
175 | + fpst = fpstatus_ptr(FPST_A32); | ||
176 | gen_helper_rints_exact(tmp, tmp, fpst); | ||
177 | vfp_store_reg32(tmp, a->vd); | ||
178 | return true; | ||
179 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a) | ||
180 | |||
181 | tmp = tcg_temp_new_i64(); | ||
182 | vfp_load_reg64(tmp, a->vm); | ||
183 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
184 | + fpst = fpstatus_ptr(FPST_A32); | ||
185 | gen_helper_rintd_exact(tmp, tmp, fpst); | ||
186 | vfp_store_reg64(tmp, a->vd); | ||
187 | return true; | ||
188 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a) | ||
189 | vm = tcg_temp_new_i32(); | ||
190 | vd = tcg_temp_new_i64(); | ||
191 | vfp_load_reg32(vm, a->vm); | ||
192 | - gen_helper_vfp_fcvtds(vd, vm, fpstatus_ptr(FPST_FPCR)); | ||
193 | + gen_helper_vfp_fcvtds(vd, vm, fpstatus_ptr(FPST_A32)); | ||
194 | vfp_store_reg64(vd, a->vd); | ||
195 | return true; | ||
196 | } | ||
197 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a) | ||
198 | vd = tcg_temp_new_i32(); | ||
199 | vm = tcg_temp_new_i64(); | ||
200 | vfp_load_reg64(vm, a->vm); | ||
201 | - gen_helper_vfp_fcvtsd(vd, vm, fpstatus_ptr(FPST_FPCR)); | ||
202 | + gen_helper_vfp_fcvtsd(vd, vm, fpstatus_ptr(FPST_A32)); | ||
203 | vfp_store_reg32(vd, a->vd); | ||
204 | return true; | ||
205 | } | ||
206 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a) | ||
207 | |||
208 | vm = tcg_temp_new_i32(); | ||
209 | vfp_load_reg32(vm, a->vm); | ||
210 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
211 | + fpst = fpstatus_ptr(FPST_A32); | ||
212 | if (a->s) { | ||
213 | /* i32 -> f32 */ | ||
214 | gen_helper_vfp_sitos(vm, vm, fpst); | ||
215 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a) | ||
216 | vm = tcg_temp_new_i32(); | ||
217 | vd = tcg_temp_new_i64(); | ||
218 | vfp_load_reg32(vm, a->vm); | ||
219 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
220 | + fpst = fpstatus_ptr(FPST_A32); | ||
221 | if (a->s) { | ||
222 | /* i32 -> f64 */ | ||
223 | gen_helper_vfp_sitod(vd, vm, fpst); | ||
224 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a) | ||
225 | vd = tcg_temp_new_i32(); | ||
226 | vfp_load_reg32(vd, a->vd); | ||
227 | |||
228 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
229 | + fpst = fpstatus_ptr(FPST_A32); | ||
230 | shift = tcg_constant_i32(frac_bits); | ||
231 | |||
232 | /* Switch on op:U:sx bits */ | ||
233 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a) | ||
234 | vd = tcg_temp_new_i64(); | ||
235 | vfp_load_reg64(vd, a->vd); | ||
236 | |||
237 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
238 | + fpst = fpstatus_ptr(FPST_A32); | ||
239 | shift = tcg_constant_i32(frac_bits); | ||
240 | |||
241 | /* Switch on op:U:sx bits */ | ||
242 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a) | ||
243 | return true; | ||
244 | } | ||
245 | |||
246 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
247 | + fpst = fpstatus_ptr(FPST_A32); | ||
248 | vm = tcg_temp_new_i32(); | ||
249 | vfp_load_reg32(vm, a->vm); | ||
250 | |||
251 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a) | ||
252 | return true; | ||
253 | } | ||
254 | |||
255 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
256 | + fpst = fpstatus_ptr(FPST_A32); | ||
257 | vm = tcg_temp_new_i64(); | ||
258 | vd = tcg_temp_new_i32(); | ||
259 | vfp_load_reg64(vm, a->vm); | ||
260 | -- | ||
261 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In the A64 decoder, use FPST_A64 rather than FPST_FPCR. By | ||
2 | doing an automated conversion of the whole file we avoid possibly | ||
3 | using more than one fpst value in a set_rmode/op/restore_rmode | ||
4 | sequence. | ||
1 | 5 | ||
6 | Patch created with | ||
7 | |||
8 | perl -p -i -e 's/FPST_FPCR(?!_)/FPST_A64/g' target/arm/tcg/translate-{a64,sve,sme}.c | ||
9 | |||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
11 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
12 | Message-id: 20250124162836.2332150-12-peter.maydell@linaro.org | ||
13 | --- | ||
14 | target/arm/tcg/translate-a64.c | 70 +++++++++++----------- | ||
15 | target/arm/tcg/translate-sme.c | 4 +- | ||
16 | target/arm/tcg/translate-sve.c | 106 ++++++++++++++++----------------- | ||
17 | 3 files changed, 90 insertions(+), 90 deletions(-) | ||
18 | |||
19 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/arm/tcg/translate-a64.c | ||
22 | +++ b/target/arm/tcg/translate-a64.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn, | ||
24 | int rm, bool is_fp16, int data, | ||
25 | gen_helper_gvec_3_ptr *fn) | ||
26 | { | ||
27 | - TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
28 | + TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); | ||
29 | tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), | ||
30 | vec_full_reg_offset(s, rn), | ||
31 | vec_full_reg_offset(s, rm), fpst, | ||
32 | @@ -XXX,XX +XXX,XX @@ static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn, | ||
33 | int rm, int ra, bool is_fp16, int data, | ||
34 | gen_helper_gvec_4_ptr *fn) | ||
35 | { | ||
36 | - TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
37 | + TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); | ||
38 | tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), | ||
39 | vec_full_reg_offset(s, rn), | ||
40 | vec_full_reg_offset(s, rm), | ||
41 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f) | ||
42 | if (fp_access_check(s)) { | ||
43 | TCGv_i64 t0 = read_fp_dreg(s, a->rn); | ||
44 | TCGv_i64 t1 = read_fp_dreg(s, a->rm); | ||
45 | - f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
46 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
47 | write_fp_dreg(s, a->rd, t0); | ||
48 | } | ||
49 | break; | ||
50 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f) | ||
51 | if (fp_access_check(s)) { | ||
52 | TCGv_i32 t0 = read_fp_sreg(s, a->rn); | ||
53 | TCGv_i32 t1 = read_fp_sreg(s, a->rm); | ||
54 | - f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
55 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
56 | write_fp_sreg(s, a->rd, t0); | ||
57 | } | ||
58 | break; | ||
59 | @@ -XXX,XX +XXX,XX @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a, | ||
60 | TCGv_i64 t0 = read_fp_dreg(s, a->rn); | ||
61 | TCGv_i64 t1 = tcg_constant_i64(0); | ||
62 | if (swap) { | ||
63 | - f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); | ||
64 | + f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_A64)); | ||
65 | } else { | ||
66 | - f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
67 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
68 | } | ||
69 | write_fp_dreg(s, a->rd, t0); | ||
70 | } | ||
71 | @@ -XXX,XX +XXX,XX @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a, | ||
72 | TCGv_i32 t0 = read_fp_sreg(s, a->rn); | ||
73 | TCGv_i32 t1 = tcg_constant_i32(0); | ||
74 | if (swap) { | ||
75 | - f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); | ||
76 | + f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_A64)); | ||
77 | } else { | ||
78 | - f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
79 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
80 | } | ||
81 | write_fp_sreg(s, a->rd, t0); | ||
82 | } | ||
83 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f) | ||
84 | TCGv_i64 t1 = tcg_temp_new_i64(); | ||
85 | |||
86 | read_vec_element(s, t1, a->rm, a->idx, MO_64); | ||
87 | - f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
88 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
89 | write_fp_dreg(s, a->rd, t0); | ||
90 | } | ||
91 | break; | ||
92 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f) | ||
93 | TCGv_i32 t1 = tcg_temp_new_i32(); | ||
94 | |||
95 | read_vec_element_i32(s, t1, a->rm, a->idx, MO_32); | ||
96 | - f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
97 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
98 | write_fp_sreg(s, a->rd, t0); | ||
99 | } | ||
100 | break; | ||
101 | @@ -XXX,XX +XXX,XX @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg) | ||
102 | if (neg) { | ||
103 | gen_vfp_negd(t1, t1); | ||
104 | } | ||
105 | - gen_helper_vfp_muladdd(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR)); | ||
106 | + gen_helper_vfp_muladdd(t0, t1, t2, t0, fpstatus_ptr(FPST_A64)); | ||
107 | write_fp_dreg(s, a->rd, t0); | ||
108 | } | ||
109 | break; | ||
110 | @@ -XXX,XX +XXX,XX @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg) | ||
111 | if (neg) { | ||
112 | gen_vfp_negs(t1, t1); | ||
113 | } | ||
114 | - gen_helper_vfp_muladds(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR)); | ||
115 | + gen_helper_vfp_muladds(t0, t1, t2, t0, fpstatus_ptr(FPST_A64)); | ||
116 | write_fp_sreg(s, a->rd, t0); | ||
117 | } | ||
118 | break; | ||
119 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f) | ||
120 | |||
121 | read_vec_element(s, t0, a->rn, 0, MO_64); | ||
122 | read_vec_element(s, t1, a->rn, 1, MO_64); | ||
123 | - f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
124 | + f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
125 | write_fp_dreg(s, a->rd, t0); | ||
126 | } | ||
127 | break; | ||
128 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f) | ||
129 | |||
130 | read_vec_element_i32(s, t0, a->rn, 0, MO_32); | ||
131 | read_vec_element_i32(s, t1, a->rn, 1, MO_32); | ||
132 | - f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); | ||
133 | + f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64)); | ||
134 | write_fp_sreg(s, a->rd, t0); | ||
135 | } | ||
136 | break; | ||
137 | @@ -XXX,XX +XXX,XX @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n) | ||
138 | if (neg_n) { | ||
139 | gen_vfp_negd(tn, tn); | ||
140 | } | ||
141 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
142 | + fpst = fpstatus_ptr(FPST_A64); | ||
143 | gen_helper_vfp_muladdd(ta, tn, tm, ta, fpst); | ||
144 | write_fp_dreg(s, a->rd, ta); | ||
145 | } | ||
146 | @@ -XXX,XX +XXX,XX @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n) | ||
147 | if (neg_n) { | ||
148 | gen_vfp_negs(tn, tn); | ||
149 | } | ||
150 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
151 | + fpst = fpstatus_ptr(FPST_A64); | ||
152 | gen_helper_vfp_muladds(ta, tn, tm, ta, fpst); | ||
153 | write_fp_sreg(s, a->rd, ta); | ||
154 | } | ||
155 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_reduction(DisasContext *s, arg_qrr_e *a, | ||
156 | if (fp_access_check(s)) { | ||
157 | MemOp esz = a->esz; | ||
158 | int elts = (a->q ? 16 : 8) >> esz; | ||
159 | - TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
160 | + TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
161 | TCGv_i32 res = do_reduction_op(s, a->rn, esz, 0, elts, fpst, fn); | ||
162 | write_fp_sreg(s, a->rd, res); | ||
163 | } | ||
164 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, int size, | ||
165 | bool cmp_with_zero, bool signal_all_nans) | ||
166 | { | ||
167 | TCGv_i64 tcg_flags = tcg_temp_new_i64(); | ||
168 | - TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
169 | + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
170 | |||
171 | if (size == MO_64) { | ||
172 | TCGv_i64 tcg_vn, tcg_vm; | ||
173 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_scalar(DisasContext *s, arg_rr_e *a, | ||
174 | return check == 0; | ||
175 | } | ||
176 | |||
177 | - fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
178 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
179 | if (rmode >= 0) { | ||
180 | tcg_rmode = gen_set_rmode(rmode, fpst); | ||
181 | } | ||
182 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a) | ||
183 | if (fp_access_check(s)) { | ||
184 | TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn); | ||
185 | TCGv_i64 tcg_rd = tcg_temp_new_i64(); | ||
186 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
187 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
188 | |||
189 | gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, fpst); | ||
190 | write_fp_dreg(s, a->rd, tcg_rd); | ||
191 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_hs(DisasContext *s, arg_rr *a) | ||
192 | if (fp_access_check(s)) { | ||
193 | TCGv_i32 tmp = read_fp_sreg(s, a->rn); | ||
194 | TCGv_i32 ahp = get_ahp_flag(); | ||
195 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
196 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
197 | |||
198 | gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp); | ||
199 | /* write_fp_sreg is OK here because top half of result is zero */ | ||
200 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_sd(DisasContext *s, arg_rr *a) | ||
201 | if (fp_access_check(s)) { | ||
202 | TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); | ||
203 | TCGv_i32 tcg_rd = tcg_temp_new_i32(); | ||
204 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
205 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
206 | |||
207 | gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, fpst); | ||
208 | write_fp_sreg(s, a->rd, tcg_rd); | ||
209 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_hd(DisasContext *s, arg_rr *a) | ||
210 | TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); | ||
211 | TCGv_i32 tcg_rd = tcg_temp_new_i32(); | ||
212 | TCGv_i32 ahp = get_ahp_flag(); | ||
213 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
214 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
215 | |||
216 | gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); | ||
217 | /* write_fp_sreg is OK here because top half of tcg_rd is zero */ | ||
218 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a) | ||
219 | if (fp_access_check(s)) { | ||
220 | TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); | ||
221 | TCGv_i32 tcg_rd = tcg_temp_new_i32(); | ||
222 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); | ||
223 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64); | ||
224 | TCGv_i32 tcg_ahp = get_ahp_flag(); | ||
225 | |||
226 | gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | ||
227 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) | ||
228 | if (fp_access_check(s)) { | ||
229 | TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); | ||
230 | TCGv_i64 tcg_rd = tcg_temp_new_i64(); | ||
231 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); | ||
232 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64); | ||
233 | TCGv_i32 tcg_ahp = get_ahp_flag(); | ||
234 | |||
235 | gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | ||
236 | @@ -XXX,XX +XXX,XX @@ static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift, | ||
237 | TCGv_i32 tcg_shift, tcg_single; | ||
238 | TCGv_i64 tcg_double; | ||
239 | |||
240 | - tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
241 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
242 | tcg_shift = tcg_constant_i32(shift); | ||
243 | |||
244 | switch (esz) { | ||
245 | @@ -XXX,XX +XXX,XX @@ static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, | ||
246 | TCGv_ptr tcg_fpstatus; | ||
247 | TCGv_i32 tcg_shift, tcg_rmode, tcg_single; | ||
248 | |||
249 | - tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
250 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
251 | tcg_shift = tcg_constant_i32(shift); | ||
252 | tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); | ||
253 | |||
254 | @@ -XXX,XX +XXX,XX @@ static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a) | ||
255 | } | ||
256 | if (fp_access_check(s)) { | ||
257 | TCGv_i64 t = read_fp_dreg(s, a->rn); | ||
258 | - TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); | ||
259 | + TCGv_ptr fpstatus = fpstatus_ptr(FPST_A64); | ||
260 | |||
261 | gen_helper_fjcvtzs(t, t, fpstatus); | ||
262 | |||
263 | @@ -XXX,XX +XXX,XX @@ static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n) | ||
264 | * with von Neumann rounding (round to odd) | ||
265 | */ | ||
266 | TCGv_i32 tmp = tcg_temp_new_i32(); | ||
267 | - gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_FPCR)); | ||
268 | + gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_A64)); | ||
269 | tcg_gen_extu_i32_i64(d, tmp); | ||
270 | } | ||
271 | |||
272 | @@ -XXX,XX +XXX,XX @@ static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n) | ||
273 | { | ||
274 | TCGv_i32 tcg_lo = tcg_temp_new_i32(); | ||
275 | TCGv_i32 tcg_hi = tcg_temp_new_i32(); | ||
276 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
277 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
278 | TCGv_i32 ahp = get_ahp_flag(); | ||
279 | |||
280 | tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, n); | ||
281 | @@ -XXX,XX +XXX,XX @@ static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n) | ||
282 | static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n) | ||
283 | { | ||
284 | TCGv_i32 tmp = tcg_temp_new_i32(); | ||
285 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
286 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
287 | |||
288 | gen_helper_vfp_fcvtsd(tmp, n, fpst); | ||
289 | tcg_gen_extu_i32_i64(d, tmp); | ||
290 | @@ -XXX,XX +XXX,XX @@ TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn) | ||
291 | |||
292 | static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) | ||
293 | { | ||
294 | - TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); | ||
295 | + TCGv_ptr fpst = fpstatus_ptr(FPST_A64); | ||
296 | TCGv_i32 tmp = tcg_temp_new_i32(); | ||
297 | gen_helper_bfcvt_pair(tmp, n, fpst); | ||
298 | tcg_gen_extu_i32_i64(d, tmp); | ||
299 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_vector(DisasContext *s, arg_qrr_e *a, | ||
300 | return check == 0; | ||
301 | } | ||
302 | |||
303 | - fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
304 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
305 | if (rmode >= 0) { | ||
306 | tcg_rmode = gen_set_rmode(rmode, fpst); | ||
307 | } | ||
308 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_op2_fpst(DisasContext *s, MemOp esz, bool is_q, | ||
309 | return check == 0; | ||
310 | } | ||
311 | |||
312 | - fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
313 | + fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
314 | tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd), | ||
315 | vec_full_reg_offset(s, rn), fpst, | ||
316 | is_q ? 16 : 8, vec_full_reg_size(s), | ||
317 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a) | ||
318 | return true; | ||
319 | } | ||
320 | |||
321 | - fpst = fpstatus_ptr(FPST_FPCR); | ||
322 | + fpst = fpstatus_ptr(FPST_A64); | ||
323 | if (a->esz == MO_64) { | ||
324 | /* 32 -> 64 bit fp conversion */ | ||
325 | TCGv_i64 tcg_res[2]; | ||
326 | diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c | ||
327 | index XXXXXXX..XXXXXXX 100644 | ||
328 | --- a/target/arm/tcg/translate-sme.c | ||
329 | +++ b/target/arm/tcg/translate-sme.c | ||
330 | @@ -XXX,XX +XXX,XX @@ static bool do_outprod_env(DisasContext *s, arg_op *a, MemOp esz, | ||
331 | TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_env, a, | ||
332 | MO_32, gen_helper_sme_fmopa_h) | ||
333 | TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, | ||
334 | - MO_32, FPST_FPCR, gen_helper_sme_fmopa_s) | ||
335 | + MO_32, FPST_A64, gen_helper_sme_fmopa_s) | ||
336 | TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, | ||
337 | - MO_64, FPST_FPCR, gen_helper_sme_fmopa_d) | ||
338 | + MO_64, FPST_A64, gen_helper_sme_fmopa_d) | ||
339 | |||
340 | TRANS_FEAT(BFMOPA, aa64_sme, do_outprod_env, a, MO_32, gen_helper_sme_bfmopa) | ||
341 | |||
342 | diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c | ||
343 | index XXXXXXX..XXXXXXX 100644 | ||
344 | --- a/target/arm/tcg/translate-sve.c | ||
345 | +++ b/target/arm/tcg/translate-sve.c | ||
346 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn, | ||
347 | arg_rr_esz *a, int data) | ||
348 | { | ||
349 | return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data, | ||
350 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
351 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
352 | } | ||
353 | |||
354 | /* Invoke an out-of-line helper on 3 Zregs. */ | ||
355 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn, | ||
356 | arg_rrr_esz *a, int data) | ||
357 | { | ||
358 | return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data, | ||
359 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
360 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
361 | } | ||
362 | |||
363 | /* Invoke an out-of-line helper on 4 Zregs. */ | ||
364 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn, | ||
365 | arg_rprr_esz *a) | ||
366 | { | ||
367 | return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0, | ||
368 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
369 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
370 | } | ||
371 | |||
372 | /* Invoke a vector expander on two Zregs and an immediate. */ | ||
373 | @@ -XXX,XX +XXX,XX @@ static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub) | ||
374 | }; | ||
375 | return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, | ||
376 | (a->index << 1) | sub, | ||
377 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
378 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
379 | } | ||
380 | |||
381 | TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false) | ||
382 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const fmul_idx_fns[4] = { | ||
383 | }; | ||
384 | TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz, | ||
385 | fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index, | ||
386 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
387 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
388 | |||
389 | /* | ||
390 | *** SVE Floating Point Fast Reduction Group | ||
391 | @@ -XXX,XX +XXX,XX @@ static bool do_reduce(DisasContext *s, arg_rpr_esz *a, | ||
392 | |||
393 | tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); | ||
394 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); | ||
395 | - status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
396 | + status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
397 | |||
398 | fn(temp, t_zn, t_pg, status, t_desc); | ||
399 | |||
400 | @@ -XXX,XX +XXX,XX @@ static bool do_ppz_fp(DisasContext *s, arg_rpr_esz *a, | ||
401 | if (sve_access_check(s)) { | ||
402 | unsigned vsz = vec_full_reg_size(s); | ||
403 | TCGv_ptr status = | ||
404 | - fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
405 | + fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
406 | |||
407 | tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd), | ||
408 | vec_full_reg_offset(s, a->rn), | ||
409 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = { | ||
410 | }; | ||
411 | TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz, | ||
412 | ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm, | ||
413 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
414 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
415 | |||
416 | /* | ||
417 | *** SVE Floating Point Accumulating Reduction Group | ||
418 | @@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a) | ||
419 | t_pg = tcg_temp_new_ptr(); | ||
420 | tcg_gen_addi_ptr(t_rm, tcg_env, vec_full_reg_offset(s, a->rm)); | ||
421 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); | ||
422 | - t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
423 | + t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
424 | t_desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); | ||
425 | |||
426 | fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc); | ||
427 | @@ -XXX,XX +XXX,XX @@ static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16, | ||
428 | tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, zn)); | ||
429 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); | ||
430 | |||
431 | - status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
432 | + status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); | ||
433 | desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); | ||
434 | fn(t_zd, t_zn, t_pg, scalar, status, desc); | ||
435 | } | ||
436 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a, | ||
437 | } | ||
438 | if (sve_access_check(s)) { | ||
439 | unsigned vsz = vec_full_reg_size(s); | ||
440 | - TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
441 | + TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
442 | tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd), | ||
443 | vec_full_reg_offset(s, a->rn), | ||
444 | vec_full_reg_offset(s, a->rm), | ||
445 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_4_ptr * const fcadd_fns[] = { | ||
446 | }; | ||
447 | TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], | ||
448 | a->rd, a->rn, a->rm, a->pg, a->rot, | ||
449 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
450 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
451 | |||
452 | #define DO_FMLA(NAME, name) \ | ||
453 | static gen_helper_gvec_5_ptr * const name##_fns[4] = { \ | ||
454 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], | ||
455 | }; \ | ||
456 | TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_zzzzp, name##_fns[a->esz], \ | ||
457 | a->rd, a->rn, a->rm, a->ra, a->pg, 0, \ | ||
458 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
459 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
460 | |||
461 | DO_FMLA(FMLA_zpzzz, fmla_zpzzz) | ||
462 | DO_FMLA(FMLS_zpzzz, fmls_zpzzz) | ||
463 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_5_ptr * const fcmla_fns[4] = { | ||
464 | }; | ||
465 | TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_zzzzp, fcmla_fns[a->esz], | ||
466 | a->rd, a->rn, a->rm, a->ra, a->pg, a->rot, | ||
467 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
468 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
469 | |||
470 | static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = { | ||
471 | NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL | ||
472 | }; | ||
473 | TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz], | ||
474 | a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot, | ||
475 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
476 | + a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
477 | |||
478 | /* | ||
479 | *** SVE Floating Point Unary Operations Predicated Group | ||
480 | */ | ||
481 | |||
482 | TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
483 | - gen_helper_sve_fcvt_sh, a, 0, FPST_FPCR) | ||
484 | + gen_helper_sve_fcvt_sh, a, 0, FPST_A64) | ||
485 | TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
486 | - gen_helper_sve_fcvt_hs, a, 0, FPST_FPCR) | ||
487 | + gen_helper_sve_fcvt_hs, a, 0, FPST_A64) | ||
488 | |||
489 | TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, | ||
490 | - gen_helper_sve_bfcvt, a, 0, FPST_FPCR) | ||
491 | + gen_helper_sve_bfcvt, a, 0, FPST_A64) | ||
492 | |||
493 | TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
494 | - gen_helper_sve_fcvt_dh, a, 0, FPST_FPCR) | ||
495 | + gen_helper_sve_fcvt_dh, a, 0, FPST_A64) | ||
496 | TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
497 | - gen_helper_sve_fcvt_hd, a, 0, FPST_FPCR) | ||
498 | + gen_helper_sve_fcvt_hd, a, 0, FPST_A64) | ||
499 | TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
500 | - gen_helper_sve_fcvt_ds, a, 0, FPST_FPCR) | ||
501 | + gen_helper_sve_fcvt_ds, a, 0, FPST_A64) | ||
502 | TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
503 | - gen_helper_sve_fcvt_sd, a, 0, FPST_FPCR) | ||
504 | + gen_helper_sve_fcvt_sd, a, 0, FPST_A64) | ||
505 | |||
506 | TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
507 | gen_helper_sve_fcvtzs_hh, a, 0, FPST_FPCR_F16) | ||
508 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
509 | gen_helper_sve_fcvtzu_hd, a, 0, FPST_FPCR_F16) | ||
510 | |||
511 | TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
512 | - gen_helper_sve_fcvtzs_ss, a, 0, FPST_FPCR) | ||
513 | + gen_helper_sve_fcvtzs_ss, a, 0, FPST_A64) | ||
514 | TRANS_FEAT(FCVTZU_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
515 | - gen_helper_sve_fcvtzu_ss, a, 0, FPST_FPCR) | ||
516 | + gen_helper_sve_fcvtzu_ss, a, 0, FPST_A64) | ||
517 | TRANS_FEAT(FCVTZS_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
518 | - gen_helper_sve_fcvtzs_sd, a, 0, FPST_FPCR) | ||
519 | + gen_helper_sve_fcvtzs_sd, a, 0, FPST_A64) | ||
520 | TRANS_FEAT(FCVTZU_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
521 | - gen_helper_sve_fcvtzu_sd, a, 0, FPST_FPCR) | ||
522 | + gen_helper_sve_fcvtzu_sd, a, 0, FPST_A64) | ||
523 | TRANS_FEAT(FCVTZS_ds, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
524 | - gen_helper_sve_fcvtzs_ds, a, 0, FPST_FPCR) | ||
525 | + gen_helper_sve_fcvtzs_ds, a, 0, FPST_A64) | ||
526 | TRANS_FEAT(FCVTZU_ds, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
527 | - gen_helper_sve_fcvtzu_ds, a, 0, FPST_FPCR) | ||
528 | + gen_helper_sve_fcvtzu_ds, a, 0, FPST_A64) | ||
529 | |||
530 | TRANS_FEAT(FCVTZS_dd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
531 | - gen_helper_sve_fcvtzs_dd, a, 0, FPST_FPCR) | ||
532 | + gen_helper_sve_fcvtzs_dd, a, 0, FPST_A64) | ||
533 | TRANS_FEAT(FCVTZU_dd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
534 | - gen_helper_sve_fcvtzu_dd, a, 0, FPST_FPCR) | ||
535 | + gen_helper_sve_fcvtzu_dd, a, 0, FPST_A64) | ||
536 | |||
537 | static gen_helper_gvec_3_ptr * const frint_fns[] = { | ||
538 | NULL, | ||
539 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frint_fns[] = { | ||
540 | gen_helper_sve_frint_d | ||
541 | }; | ||
542 | TRANS_FEAT(FRINTI, aa64_sve, gen_gvec_fpst_arg_zpz, frint_fns[a->esz], | ||
543 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
544 | + a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
545 | |||
546 | static gen_helper_gvec_3_ptr * const frintx_fns[] = { | ||
547 | NULL, | ||
548 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frintx_fns[] = { | ||
549 | gen_helper_sve_frintx_d | ||
550 | }; | ||
551 | TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, frintx_fns[a->esz], | ||
552 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
553 | + a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
554 | |||
555 | static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, | ||
556 | ARMFPRounding mode, gen_helper_gvec_3_ptr *fn) | ||
557 | @@ -XXX,XX +XXX,XX @@ static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, | ||
558 | } | ||
559 | |||
560 | vsz = vec_full_reg_size(s); | ||
561 | - status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); | ||
562 | + status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
563 | tmode = gen_set_rmode(mode, status); | ||
564 | |||
565 | tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd), | ||
566 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frecpx_fns[] = { | ||
567 | gen_helper_sve_frecpx_s, gen_helper_sve_frecpx_d, | ||
568 | }; | ||
569 | TRANS_FEAT(FRECPX, aa64_sve, gen_gvec_fpst_arg_zpz, frecpx_fns[a->esz], | ||
570 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
571 | + a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
572 | |||
573 | static gen_helper_gvec_3_ptr * const fsqrt_fns[] = { | ||
574 | NULL, gen_helper_sve_fsqrt_h, | ||
575 | gen_helper_sve_fsqrt_s, gen_helper_sve_fsqrt_d, | ||
576 | }; | ||
577 | TRANS_FEAT(FSQRT, aa64_sve, gen_gvec_fpst_arg_zpz, fsqrt_fns[a->esz], | ||
578 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
579 | + a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
580 | |||
581 | TRANS_FEAT(SCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
582 | gen_helper_sve_scvt_hh, a, 0, FPST_FPCR_F16) | ||
583 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
584 | gen_helper_sve_scvt_dh, a, 0, FPST_FPCR_F16) | ||
585 | |||
586 | TRANS_FEAT(SCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
587 | - gen_helper_sve_scvt_ss, a, 0, FPST_FPCR) | ||
588 | + gen_helper_sve_scvt_ss, a, 0, FPST_A64) | ||
589 | TRANS_FEAT(SCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
590 | - gen_helper_sve_scvt_ds, a, 0, FPST_FPCR) | ||
591 | + gen_helper_sve_scvt_ds, a, 0, FPST_A64) | ||
592 | |||
593 | TRANS_FEAT(SCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
594 | - gen_helper_sve_scvt_sd, a, 0, FPST_FPCR) | ||
595 | + gen_helper_sve_scvt_sd, a, 0, FPST_A64) | ||
596 | TRANS_FEAT(SCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
597 | - gen_helper_sve_scvt_dd, a, 0, FPST_FPCR) | ||
598 | + gen_helper_sve_scvt_dd, a, 0, FPST_A64) | ||
599 | |||
600 | TRANS_FEAT(UCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
601 | gen_helper_sve_ucvt_hh, a, 0, FPST_FPCR_F16) | ||
602 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(UCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
603 | gen_helper_sve_ucvt_dh, a, 0, FPST_FPCR_F16) | ||
604 | |||
605 | TRANS_FEAT(UCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
606 | - gen_helper_sve_ucvt_ss, a, 0, FPST_FPCR) | ||
607 | + gen_helper_sve_ucvt_ss, a, 0, FPST_A64) | ||
608 | TRANS_FEAT(UCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
609 | - gen_helper_sve_ucvt_ds, a, 0, FPST_FPCR) | ||
610 | + gen_helper_sve_ucvt_ds, a, 0, FPST_A64) | ||
611 | TRANS_FEAT(UCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
612 | - gen_helper_sve_ucvt_sd, a, 0, FPST_FPCR) | ||
613 | + gen_helper_sve_ucvt_sd, a, 0, FPST_A64) | ||
614 | |||
615 | TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
616 | - gen_helper_sve_ucvt_dd, a, 0, FPST_FPCR) | ||
617 | + gen_helper_sve_ucvt_dd, a, 0, FPST_A64) | ||
618 | |||
619 | /* | ||
620 | *** SVE Memory - 32-bit Gather and Unsized Contiguous Group | ||
621 | @@ -XXX,XX +XXX,XX @@ DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz) | ||
622 | |||
623 | TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz, | ||
624 | gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra, | ||
625 | - 0, FPST_FPCR) | ||
626 | + 0, FPST_A64) | ||
627 | TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz, | ||
628 | gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra, | ||
629 | - 0, FPST_FPCR) | ||
630 | + 0, FPST_A64) | ||
631 | |||
632 | static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = { | ||
633 | NULL, gen_helper_sve2_sqdmlal_zzzw_h, | ||
634 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz, | ||
635 | gen_gvec_rax1, a) | ||
636 | |||
637 | TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz, | ||
638 | - gen_helper_sve2_fcvtnt_sh, a, 0, FPST_FPCR) | ||
639 | + gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64) | ||
640 | TRANS_FEAT(FCVTNT_ds, aa64_sve2, gen_gvec_fpst_arg_zpz, | ||
641 | - gen_helper_sve2_fcvtnt_ds, a, 0, FPST_FPCR) | ||
642 | + gen_helper_sve2_fcvtnt_ds, a, 0, FPST_A64) | ||
643 | |||
644 | TRANS_FEAT(BFCVTNT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, | ||
645 | - gen_helper_sve_bfcvtnt, a, 0, FPST_FPCR) | ||
646 | + gen_helper_sve_bfcvtnt, a, 0, FPST_A64) | ||
647 | |||
648 | TRANS_FEAT(FCVTLT_hs, aa64_sve2, gen_gvec_fpst_arg_zpz, | ||
649 | - gen_helper_sve2_fcvtlt_hs, a, 0, FPST_FPCR) | ||
650 | + gen_helper_sve2_fcvtlt_hs, a, 0, FPST_A64) | ||
651 | TRANS_FEAT(FCVTLT_sd, aa64_sve2, gen_gvec_fpst_arg_zpz, | ||
652 | - gen_helper_sve2_fcvtlt_sd, a, 0, FPST_FPCR) | ||
653 | + gen_helper_sve2_fcvtlt_sd, a, 0, FPST_A64) | ||
654 | |||
655 | TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a, | ||
656 | FPROUNDING_ODD, gen_helper_sve_fcvt_ds) | ||
657 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const flogb_fns[] = { | ||
658 | gen_helper_flogb_s, gen_helper_flogb_d | ||
659 | }; | ||
660 | TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz], | ||
661 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) | ||
662 | + a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
663 | |||
664 | static bool do_FMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sub, bool sel) | ||
665 | { | ||
666 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_env_arg_zzzz, | ||
667 | static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) | ||
668 | { | ||
669 | return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal, | ||
670 | - a->rd, a->rn, a->rm, a->ra, sel, FPST_FPCR); | ||
671 | + a->rd, a->rn, a->rm, a->ra, sel, FPST_A64); | ||
672 | } | ||
673 | |||
674 | TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false) | ||
675 | @@ -XXX,XX +XXX,XX @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel) | ||
676 | { | ||
677 | return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx, | ||
678 | a->rd, a->rn, a->rm, a->ra, | ||
679 | - (a->index << 1) | sel, FPST_FPCR); | ||
680 | + (a->index << 1) | sel, FPST_A64); | ||
681 | } | ||
682 | |||
683 | TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false) | ||
684 | -- | ||
685 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | Now we have moved all the uses of vfp.fp_status and FPST_FPCR |
---|---|---|---|
2 | to either the A32 or A64 fields, we can remove these. | ||
2 | 3 | ||
3 | This feature is relatively small, as it applies only to | 4 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
4 | 64k pages and thus requires no additional changes to the | 5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
5 | table descriptor walking algorithm, only a change to the | 6 | Message-id: 20250124162836.2332150-13-peter.maydell@linaro.org |
6 | minimum TSZ (which is the inverse of the maximum virtual | 7 | --- |
7 | address space size). | 8 | target/arm/cpu.h | 2 -- |
9 | target/arm/tcg/translate.h | 6 ------ | ||
10 | target/arm/cpu.c | 1 - | ||
11 | target/arm/vfp_helper.c | 8 +------- | ||
12 | 4 files changed, 1 insertion(+), 16 deletions(-) | ||
8 | 13 | ||
9 | Note that this feature widens VBAR_ELx, but we already | ||
10 | treat the register as being 64 bits wide. | ||
11 | |||
12 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Message-id: 20220301215958.157011-10-richard.henderson@linaro.org | ||
15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
16 | --- | ||
17 | docs/system/arm/emulation.rst | 1 + | ||
18 | target/arm/cpu-param.h | 2 +- | ||
19 | target/arm/cpu.h | 5 +++++ | ||
20 | target/arm/cpu64.c | 1 + | ||
21 | target/arm/helper.c | 9 ++++++++- | ||
22 | 5 files changed, 16 insertions(+), 2 deletions(-) | ||
23 | |||
24 | diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/docs/system/arm/emulation.rst | ||
27 | +++ b/docs/system/arm/emulation.rst | ||
28 | @@ -XXX,XX +XXX,XX @@ the following architecture extensions: | ||
29 | - FEAT_LRCPC (Load-acquire RCpc instructions) | ||
30 | - FEAT_LRCPC2 (Load-acquire RCpc instructions v2) | ||
31 | - FEAT_LSE (Large System Extensions) | ||
32 | +- FEAT_LVA (Large Virtual Address space) | ||
33 | - FEAT_MTE (Memory Tagging Extension) | ||
34 | - FEAT_MTE2 (Memory Tagging Extension) | ||
35 | - FEAT_MTE3 (MTE Asymmetric Fault Handling) | ||
36 | diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/target/arm/cpu-param.h | ||
39 | +++ b/target/arm/cpu-param.h | ||
40 | @@ -XXX,XX +XXX,XX @@ | ||
41 | #ifdef TARGET_AARCH64 | ||
42 | # define TARGET_LONG_BITS 64 | ||
43 | # define TARGET_PHYS_ADDR_SPACE_BITS 48 | ||
44 | -# define TARGET_VIRT_ADDR_SPACE_BITS 48 | ||
45 | +# define TARGET_VIRT_ADDR_SPACE_BITS 52 | ||
46 | #else | ||
47 | # define TARGET_LONG_BITS 32 | ||
48 | # define TARGET_PHYS_ADDR_SPACE_BITS 40 | ||
49 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h | 14 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h |
50 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
51 | --- a/target/arm/cpu.h | 16 | --- a/target/arm/cpu.h |
52 | +++ b/target/arm/cpu.h | 17 | +++ b/target/arm/cpu.h |
53 | @@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id) | 18 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
54 | return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0; | 19 | |
55 | } | 20 | /* There are a number of distinct float control structures: |
56 | 21 | * | |
57 | +static inline bool isar_feature_aa64_lva(const ARMISARegisters *id) | 22 | - * fp_status: is the "normal" fp status. |
58 | +{ | 23 | * fp_status_a32: is the "normal" fp status for AArch32 insns |
59 | + return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0; | 24 | * fp_status_a64: is the "normal" fp status for AArch64 insns |
60 | +} | 25 | * fp_status_fp16: used for half-precision calculations |
61 | + | 26 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
62 | static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) | 27 | * only thing which needs to read the exception flags being |
28 | * an explicit FPSCR read. | ||
29 | */ | ||
30 | - float_status fp_status; | ||
31 | float_status fp_status_a32; | ||
32 | float_status fp_status_a64; | ||
33 | float_status fp_status_f16; | ||
34 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/arm/tcg/translate.h | ||
37 | +++ b/target/arm/tcg/translate.h | ||
38 | @@ -XXX,XX +XXX,XX @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb) | ||
39 | * Enum for argument to fpstatus_ptr(). | ||
40 | */ | ||
41 | typedef enum ARMFPStatusFlavour { | ||
42 | - FPST_FPCR, | ||
43 | FPST_A32, | ||
44 | FPST_A64, | ||
45 | FPST_FPCR_F16, | ||
46 | @@ -XXX,XX +XXX,XX @@ typedef enum ARMFPStatusFlavour { | ||
47 | * been set up to point to the requested field in the CPU state struct. | ||
48 | * The options are: | ||
49 | * | ||
50 | - * FPST_FPCR | ||
51 | - * for non-FP16 operations controlled by the FPCR | ||
52 | * FPST_A32 | ||
53 | * for AArch32 non-FP16 operations controlled by the FPCR | ||
54 | * FPST_A64 | ||
55 | @@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) | ||
56 | int offset; | ||
57 | |||
58 | switch (flavour) { | ||
59 | - case FPST_FPCR: | ||
60 | - offset = offsetof(CPUARMState, vfp.fp_status); | ||
61 | - break; | ||
62 | case FPST_A32: | ||
63 | offset = offsetof(CPUARMState, vfp.fp_status_a32); | ||
64 | break; | ||
65 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/target/arm/cpu.c | ||
68 | +++ b/target/arm/cpu.c | ||
69 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) | ||
70 | set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); | ||
71 | set_default_nan_mode(1, &env->vfp.standard_fp_status); | ||
72 | set_default_nan_mode(1, &env->vfp.standard_fp_status_f16); | ||
73 | - arm_set_default_fp_behaviours(&env->vfp.fp_status); | ||
74 | arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); | ||
75 | arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); | ||
76 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); | ||
77 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/target/arm/vfp_helper.c | ||
80 | +++ b/target/arm/vfp_helper.c | ||
81 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vfp_exceptbits_from_host(int host_bits) | ||
82 | |||
83 | static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) | ||
63 | { | 84 | { |
64 | return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; | 85 | - uint32_t i; |
65 | diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c | 86 | + uint32_t i = 0; |
66 | index XXXXXXX..XXXXXXX 100644 | 87 | |
67 | --- a/target/arm/cpu64.c | 88 | - i = get_float_exception_flags(&env->vfp.fp_status); |
68 | +++ b/target/arm/cpu64.c | 89 | i |= get_float_exception_flags(&env->vfp.fp_status_a32); |
69 | @@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj) | 90 | i |= get_float_exception_flags(&env->vfp.fp_status_a64); |
70 | t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); | 91 | i |= get_float_exception_flags(&env->vfp.standard_fp_status); |
71 | t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */ | 92 | @@ -XXX,XX +XXX,XX @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) |
72 | t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */ | 93 | * values. The caller should have arranged for env->vfp.fpsr to |
73 | + t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */ | 94 | * be the architecturally up-to-date exception flag information first. |
74 | cpu->isar.id_aa64mmfr2 = t; | 95 | */ |
75 | 96 | - set_float_exception_flags(0, &env->vfp.fp_status); | |
76 | t = cpu->isar.id_aa64zfr0; | 97 | set_float_exception_flags(0, &env->vfp.fp_status_a32); |
77 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 98 | set_float_exception_flags(0, &env->vfp.fp_status_a64); |
78 | index XXXXXXX..XXXXXXX 100644 | 99 | set_float_exception_flags(0, &env->vfp.fp_status_f16); |
79 | --- a/target/arm/helper.c | 100 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) |
80 | +++ b/target/arm/helper.c | 101 | i = float_round_to_zero; |
81 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 102 | break; |
82 | } else { | 103 | } |
83 | max_tsz = 39; | 104 | - set_float_rounding_mode(i, &env->vfp.fp_status); |
105 | set_float_rounding_mode(i, &env->vfp.fp_status_a32); | ||
106 | set_float_rounding_mode(i, &env->vfp.fp_status_a64); | ||
107 | set_float_rounding_mode(i, &env->vfp.fp_status_f16); | ||
108 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
84 | } | 109 | } |
85 | - min_tsz = 16; /* TODO: ARMv8.2-LVA */ | 110 | if (changed & FPCR_FZ) { |
86 | + | 111 | bool ftz_enabled = val & FPCR_FZ; |
87 | + min_tsz = 16; | 112 | - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); |
88 | + if (using64k) { | 113 | - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); |
89 | + if (cpu_isar_feature(aa64_lva, env_archcpu(env))) { | 114 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a32); |
90 | + min_tsz = 12; | 115 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32); |
91 | + } | 116 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a64); |
92 | + } | 117 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) |
93 | + /* TODO: FEAT_LPA2 */ | 118 | } |
94 | 119 | if (changed & FPCR_DN) { | |
95 | if (tsz > max_tsz) { | 120 | bool dnan_enabled = val & FPCR_DN; |
96 | tsz = max_tsz; | 121 | - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); |
122 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); | ||
123 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); | ||
124 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); | ||
97 | -- | 125 | -- |
98 | 2.25.1 | 126 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Akihiko Odaki <akihiko.odaki@gmail.com> | 1 | As the first part of splitting the existing fp_status_f16 |
---|---|---|---|
2 | into separate float_status fields for AArch32 and AArch64 | ||
3 | (so that we can make FEAT_AFP control bits apply only | ||
4 | for AArch64), define the two new fp_status_f16_a32 and | ||
5 | fp_status_f16_a64 fields, but don't use them yet. | ||
2 | 6 | ||
3 | Support the latest PSCI on TCG and HVF. A 64-bit function called from | 7 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
4 | AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC | 8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
5 | Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since | 9 | Message-id: 20250124162836.2332150-14-peter.maydell@linaro.org |
6 | they do not implement mandatory functions. | 10 | --- |
11 | target/arm/cpu.h | 4 ++++ | ||
12 | target/arm/tcg/translate.h | 12 ++++++++++++ | ||
13 | target/arm/cpu.c | 2 ++ | ||
14 | target/arm/vfp_helper.c | 14 ++++++++++++++ | ||
15 | 4 files changed, 32 insertions(+) | ||
7 | 16 | ||
8 | Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com> | 17 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h |
9 | Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com | ||
10 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
11 | [PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match] | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | --- | ||
14 | target/arm/kvm-consts.h | 13 +++++++++---- | ||
15 | hw/arm/boot.c | 12 +++++++++--- | ||
16 | target/arm/cpu.c | 5 +++-- | ||
17 | target/arm/hvf/hvf.c | 27 ++++++++++++++++++++++++++- | ||
18 | target/arm/kvm64.c | 2 +- | ||
19 | target/arm/psci.c | 35 ++++++++++++++++++++++++++++++++--- | ||
20 | 6 files changed, 80 insertions(+), 14 deletions(-) | ||
21 | |||
22 | diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/arm/kvm-consts.h | 19 | --- a/target/arm/cpu.h |
25 | +++ b/target/arm/kvm-consts.h | 20 | +++ b/target/arm/cpu.h |
26 | @@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE); | 21 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
27 | #define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4) | 22 | * fp_status_a32: is the "normal" fp status for AArch32 insns |
28 | #define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5) | 23 | * fp_status_a64: is the "normal" fp status for AArch64 insns |
29 | 24 | * fp_status_fp16: used for half-precision calculations | |
30 | +#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10) | 25 | + * fp_status_fp16_a32: used for AArch32 half-precision calculations |
31 | + | 26 | + * fp_status_fp16_a64: used for AArch64 half-precision calculations |
32 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND); | 27 | * standard_fp_status : the ARM "Standard FPSCR Value" |
33 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF); | 28 | * standard_fp_status_fp16 : used for half-precision |
34 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON); | 29 | * calculations with the ARM "Standard FPSCR Value" |
35 | @@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE); | 30 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
36 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND); | 31 | float_status fp_status_a32; |
37 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON); | 32 | float_status fp_status_a64; |
38 | MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE); | 33 | float_status fp_status_f16; |
39 | +MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES); | 34 | + float_status fp_status_f16_a32; |
40 | 35 | + float_status fp_status_f16_a64; | |
41 | /* PSCI v0.2 return values used by TCG emulation of PSCI */ | 36 | float_status standard_fp_status; |
42 | 37 | float_status standard_fp_status_f16; | |
43 | /* No Trusted OS migration to worry about when offlining CPUs */ | 38 | |
44 | #define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2 | 39 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h |
45 | |||
46 | -/* We implement version 0.2 only */ | ||
47 | -#define QEMU_PSCI_0_2_RET_VERSION_0_2 2 | ||
48 | +#define QEMU_PSCI_VERSION_0_1 0x00001 | ||
49 | +#define QEMU_PSCI_VERSION_0_2 0x00002 | ||
50 | +#define QEMU_PSCI_VERSION_1_1 0x10001 | ||
51 | |||
52 | MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP); | ||
53 | -MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2, | ||
54 | - (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2))); | ||
55 | +/* We don't bother to check every possible version value */ | ||
56 | +MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2)); | ||
57 | +MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1)); | ||
58 | |||
59 | /* PSCI return values (inclusive of all PSCI versions) */ | ||
60 | #define QEMU_PSCI_RET_SUCCESS 0 | ||
61 | diff --git a/hw/arm/boot.c b/hw/arm/boot.c | ||
62 | index XXXXXXX..XXXXXXX 100644 | 40 | index XXXXXXX..XXXXXXX 100644 |
63 | --- a/hw/arm/boot.c | 41 | --- a/target/arm/tcg/translate.h |
64 | +++ b/hw/arm/boot.c | 42 | +++ b/target/arm/tcg/translate.h |
65 | @@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt) | 43 | @@ -XXX,XX +XXX,XX @@ typedef enum ARMFPStatusFlavour { |
66 | } | 44 | FPST_A32, |
67 | 45 | FPST_A64, | |
68 | qemu_fdt_add_subnode(fdt, "/psci"); | 46 | FPST_FPCR_F16, |
69 | - if (armcpu->psci_version == 2) { | 47 | + FPST_A32_F16, |
70 | - const char comp[] = "arm,psci-0.2\0arm,psci"; | 48 | + FPST_A64_F16, |
71 | - qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); | 49 | FPST_STD, |
72 | + if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 || | 50 | FPST_STD_F16, |
73 | + armcpu->psci_version == QEMU_PSCI_VERSION_1_1) { | 51 | } ARMFPStatusFlavour; |
74 | + if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) { | 52 | @@ -XXX,XX +XXX,XX @@ typedef enum ARMFPStatusFlavour { |
75 | + const char comp[] = "arm,psci-0.2\0arm,psci"; | 53 | * for AArch64 non-FP16 operations controlled by the FPCR |
76 | + qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); | 54 | * FPST_FPCR_F16 |
77 | + } else { | 55 | * for operations controlled by the FPCR where FPCR.FZ16 is to be used |
78 | + const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci"; | 56 | + * FPST_A32_F16 |
79 | + qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); | 57 | + * for AArch32 operations controlled by the FPCR where FPCR.FZ16 is to be used |
80 | + } | 58 | + * FPST_A64_F16 |
81 | 59 | + * for AArch64 operations controlled by the FPCR where FPCR.FZ16 is to be used | |
82 | cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; | 60 | * FPST_STD |
83 | if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { | 61 | * for A32/T32 Neon operations using the "standard FPSCR value" |
62 | * FPST_STD_F16 | ||
63 | @@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) | ||
64 | case FPST_FPCR_F16: | ||
65 | offset = offsetof(CPUARMState, vfp.fp_status_f16); | ||
66 | break; | ||
67 | + case FPST_A32_F16: | ||
68 | + offset = offsetof(CPUARMState, vfp.fp_status_f16_a32); | ||
69 | + break; | ||
70 | + case FPST_A64_F16: | ||
71 | + offset = offsetof(CPUARMState, vfp.fp_status_f16_a64); | ||
72 | + break; | ||
73 | case FPST_STD: | ||
74 | offset = offsetof(CPUARMState, vfp.standard_fp_status); | ||
75 | break; | ||
84 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | 76 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c |
85 | index XXXXXXX..XXXXXXX 100644 | 77 | index XXXXXXX..XXXXXXX 100644 |
86 | --- a/target/arm/cpu.c | 78 | --- a/target/arm/cpu.c |
87 | +++ b/target/arm/cpu.c | 79 | +++ b/target/arm/cpu.c |
88 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj) | 80 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) |
89 | * picky DTB consumer will also provide a helpful error message. | 81 | arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); |
90 | */ | 82 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); |
91 | cpu->dtb_compatible = "qemu,unknown"; | 83 | arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); |
92 | - cpu->psci_version = 1; /* By default assume PSCI v0.1 */ | 84 | + arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a32); |
93 | + cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */ | 85 | + arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a64); |
94 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; | 86 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); |
95 | 87 | ||
96 | if (tcg_enabled() || hvf_enabled()) { | 88 | #ifndef CONFIG_USER_ONLY |
97 | - cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */ | 89 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c |
98 | + /* TCG and HVF implement PSCI 1.1 */ | 90 | index XXXXXXX..XXXXXXX 100644 |
99 | + cpu->psci_version = QEMU_PSCI_VERSION_1_1; | 91 | --- a/target/arm/vfp_helper.c |
92 | +++ b/target/arm/vfp_helper.c | ||
93 | @@ -XXX,XX +XXX,XX @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) | ||
94 | /* FZ16 does not generate an input denormal exception. */ | ||
95 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16) | ||
96 | & ~float_flag_input_denormal); | ||
97 | + i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) | ||
98 | + & ~float_flag_input_denormal); | ||
99 | + i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) | ||
100 | + & ~float_flag_input_denormal); | ||
101 | i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) | ||
102 | & ~float_flag_input_denormal); | ||
103 | return vfp_exceptbits_from_host(i); | ||
104 | @@ -XXX,XX +XXX,XX @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) | ||
105 | set_float_exception_flags(0, &env->vfp.fp_status_a32); | ||
106 | set_float_exception_flags(0, &env->vfp.fp_status_a64); | ||
107 | set_float_exception_flags(0, &env->vfp.fp_status_f16); | ||
108 | + set_float_exception_flags(0, &env->vfp.fp_status_f16_a32); | ||
109 | + set_float_exception_flags(0, &env->vfp.fp_status_f16_a64); | ||
110 | set_float_exception_flags(0, &env->vfp.standard_fp_status); | ||
111 | set_float_exception_flags(0, &env->vfp.standard_fp_status_f16); | ||
112 | } | ||
113 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
114 | set_float_rounding_mode(i, &env->vfp.fp_status_a32); | ||
115 | set_float_rounding_mode(i, &env->vfp.fp_status_a64); | ||
116 | set_float_rounding_mode(i, &env->vfp.fp_status_f16); | ||
117 | + set_float_rounding_mode(i, &env->vfp.fp_status_f16_a32); | ||
118 | + set_float_rounding_mode(i, &env->vfp.fp_status_f16_a64); | ||
119 | } | ||
120 | if (changed & FPCR_FZ16) { | ||
121 | bool ftz_enabled = val & FPCR_FZ16; | ||
122 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); | ||
123 | + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); | ||
124 | + set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); | ||
125 | set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); | ||
126 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); | ||
127 | + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); | ||
128 | + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); | ||
129 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); | ||
130 | } | ||
131 | if (changed & FPCR_FZ) { | ||
132 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
133 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); | ||
134 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); | ||
135 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); | ||
136 | + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32); | ||
137 | + set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64); | ||
100 | } | 138 | } |
101 | } | 139 | } |
102 | 140 | ||
103 | diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/target/arm/hvf/hvf.c | ||
106 | +++ b/target/arm/hvf/hvf.c | ||
107 | @@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu) | ||
108 | |||
109 | switch (param[0]) { | ||
110 | case QEMU_PSCI_0_2_FN_PSCI_VERSION: | ||
111 | - ret = QEMU_PSCI_0_2_RET_VERSION_0_2; | ||
112 | + ret = QEMU_PSCI_VERSION_1_1; | ||
113 | break; | ||
114 | case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE: | ||
115 | ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */ | ||
116 | @@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu) | ||
117 | case QEMU_PSCI_0_2_FN_MIGRATE: | ||
118 | ret = QEMU_PSCI_RET_NOT_SUPPORTED; | ||
119 | break; | ||
120 | + case QEMU_PSCI_1_0_FN_PSCI_FEATURES: | ||
121 | + switch (param[1]) { | ||
122 | + case QEMU_PSCI_0_2_FN_PSCI_VERSION: | ||
123 | + case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE: | ||
124 | + case QEMU_PSCI_0_2_FN_AFFINITY_INFO: | ||
125 | + case QEMU_PSCI_0_2_FN64_AFFINITY_INFO: | ||
126 | + case QEMU_PSCI_0_2_FN_SYSTEM_RESET: | ||
127 | + case QEMU_PSCI_0_2_FN_SYSTEM_OFF: | ||
128 | + case QEMU_PSCI_0_1_FN_CPU_ON: | ||
129 | + case QEMU_PSCI_0_2_FN_CPU_ON: | ||
130 | + case QEMU_PSCI_0_2_FN64_CPU_ON: | ||
131 | + case QEMU_PSCI_0_1_FN_CPU_OFF: | ||
132 | + case QEMU_PSCI_0_2_FN_CPU_OFF: | ||
133 | + case QEMU_PSCI_0_1_FN_CPU_SUSPEND: | ||
134 | + case QEMU_PSCI_0_2_FN_CPU_SUSPEND: | ||
135 | + case QEMU_PSCI_0_2_FN64_CPU_SUSPEND: | ||
136 | + case QEMU_PSCI_1_0_FN_PSCI_FEATURES: | ||
137 | + ret = 0; | ||
138 | + break; | ||
139 | + case QEMU_PSCI_0_1_FN_MIGRATE: | ||
140 | + case QEMU_PSCI_0_2_FN_MIGRATE: | ||
141 | + default: | ||
142 | + ret = QEMU_PSCI_RET_NOT_SUPPORTED; | ||
143 | + } | ||
144 | + break; | ||
145 | default: | ||
146 | return false; | ||
147 | } | ||
148 | diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c | ||
149 | index XXXXXXX..XXXXXXX 100644 | ||
150 | --- a/target/arm/kvm64.c | ||
151 | +++ b/target/arm/kvm64.c | ||
152 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) | ||
153 | cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; | ||
154 | } | ||
155 | if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) { | ||
156 | - cpu->psci_version = 2; | ||
157 | + cpu->psci_version = QEMU_PSCI_VERSION_0_2; | ||
158 | cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2; | ||
159 | } | ||
160 | if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { | ||
161 | diff --git a/target/arm/psci.c b/target/arm/psci.c | ||
162 | index XXXXXXX..XXXXXXX 100644 | ||
163 | --- a/target/arm/psci.c | ||
164 | +++ b/target/arm/psci.c | ||
165 | @@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu) | ||
166 | { | ||
167 | /* | ||
168 | * This function partially implements the logic for dispatching Power State | ||
169 | - * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b), | ||
170 | + * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b), | ||
171 | * to the extent required for bringing up and taking down secondary cores, | ||
172 | * and for handling reset and poweroff requests. | ||
173 | * Additional information about the calling convention used is available in | ||
174 | @@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu) | ||
175 | } | ||
176 | |||
177 | if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) { | ||
178 | - ret = QEMU_PSCI_RET_INVALID_PARAMS; | ||
179 | + ret = QEMU_PSCI_RET_NOT_SUPPORTED; | ||
180 | goto err; | ||
181 | } | ||
182 | |||
183 | @@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu) | ||
184 | ARMCPU *target_cpu; | ||
185 | |||
186 | case QEMU_PSCI_0_2_FN_PSCI_VERSION: | ||
187 | - ret = QEMU_PSCI_0_2_RET_VERSION_0_2; | ||
188 | + ret = QEMU_PSCI_VERSION_1_1; | ||
189 | break; | ||
190 | case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE: | ||
191 | ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */ | ||
192 | @@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu) | ||
193 | } | ||
194 | helper_wfi(env, 4); | ||
195 | break; | ||
196 | + case QEMU_PSCI_1_0_FN_PSCI_FEATURES: | ||
197 | + switch (param[1]) { | ||
198 | + case QEMU_PSCI_0_2_FN_PSCI_VERSION: | ||
199 | + case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE: | ||
200 | + case QEMU_PSCI_0_2_FN_AFFINITY_INFO: | ||
201 | + case QEMU_PSCI_0_2_FN64_AFFINITY_INFO: | ||
202 | + case QEMU_PSCI_0_2_FN_SYSTEM_RESET: | ||
203 | + case QEMU_PSCI_0_2_FN_SYSTEM_OFF: | ||
204 | + case QEMU_PSCI_0_1_FN_CPU_ON: | ||
205 | + case QEMU_PSCI_0_2_FN_CPU_ON: | ||
206 | + case QEMU_PSCI_0_2_FN64_CPU_ON: | ||
207 | + case QEMU_PSCI_0_1_FN_CPU_OFF: | ||
208 | + case QEMU_PSCI_0_2_FN_CPU_OFF: | ||
209 | + case QEMU_PSCI_0_1_FN_CPU_SUSPEND: | ||
210 | + case QEMU_PSCI_0_2_FN_CPU_SUSPEND: | ||
211 | + case QEMU_PSCI_0_2_FN64_CPU_SUSPEND: | ||
212 | + case QEMU_PSCI_1_0_FN_PSCI_FEATURES: | ||
213 | + if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) { | ||
214 | + ret = 0; | ||
215 | + break; | ||
216 | + } | ||
217 | + /* fallthrough */ | ||
218 | + case QEMU_PSCI_0_1_FN_MIGRATE: | ||
219 | + case QEMU_PSCI_0_2_FN_MIGRATE: | ||
220 | + default: | ||
221 | + ret = QEMU_PSCI_RET_NOT_SUPPORTED; | ||
222 | + break; | ||
223 | + } | ||
224 | + break; | ||
225 | case QEMU_PSCI_0_1_FN_MIGRATE: | ||
226 | case QEMU_PSCI_0_2_FN_MIGRATE: | ||
227 | default: | ||
228 | -- | 141 | -- |
229 | 2.25.1 | 142 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | We directly use fp_status_f16 in a handful of helpers that | ||
2 | are AArch32-specific; switch to fp_status_f16_a32 for these. | ||
1 | 3 | ||
4 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Message-id: 20250124162836.2332150-15-peter.maydell@linaro.org | ||
7 | --- | ||
8 | target/arm/tcg/vec_helper.c | 4 ++-- | ||
9 | target/arm/vfp_helper.c | 2 +- | ||
10 | 2 files changed, 3 insertions(+), 3 deletions(-) | ||
11 | |||
12 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/arm/tcg/vec_helper.c | ||
15 | +++ b/target/arm/tcg/vec_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_a32)(void *vd, void *vn, void *vm, | ||
17 | CPUARMState *env, uint32_t desc) | ||
18 | { | ||
19 | do_fmlal(vd, vn, vm, &env->vfp.standard_fp_status, desc, | ||
20 | - get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
21 | + get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a32)); | ||
22 | } | ||
23 | |||
24 | void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm, | ||
25 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a32)(void *vd, void *vn, void *vm, | ||
26 | CPUARMState *env, uint32_t desc) | ||
27 | { | ||
28 | do_fmlal_idx(vd, vn, vm, &env->vfp.standard_fp_status, desc, | ||
29 | - get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
30 | + get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a32)); | ||
31 | } | ||
32 | |||
33 | void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm, | ||
34 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/arm/vfp_helper.c | ||
37 | +++ b/target/arm/vfp_helper.c | ||
38 | @@ -XXX,XX +XXX,XX @@ void VFP_HELPER(cmpe, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \ | ||
39 | softfloat_to_vfp_compare(env, \ | ||
40 | FLOATTYPE ## _compare(a, b, &env->vfp.FPST)); \ | ||
41 | } | ||
42 | -DO_VFP_cmp(h, float16, dh_ctype_f16, fp_status_f16) | ||
43 | +DO_VFP_cmp(h, float16, dh_ctype_f16, fp_status_f16_a32) | ||
44 | DO_VFP_cmp(s, float32, float32, fp_status_a32) | ||
45 | DO_VFP_cmp(d, float64, float64, fp_status_a32) | ||
46 | #undef DO_VFP_cmp | ||
47 | -- | ||
48 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | We directly use fp_status_f16 in a handful of helpers that are | ||
2 | AArch64-specific; switch to fp_status_f16_a64 for these. | ||
1 | 3 | ||
4 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Message-id: 20250124162836.2332150-16-peter.maydell@linaro.org | ||
7 | --- | ||
8 | target/arm/tcg/sme_helper.c | 4 ++-- | ||
9 | target/arm/tcg/vec_helper.c | 8 ++++---- | ||
10 | 2 files changed, 6 insertions(+), 6 deletions(-) | ||
11 | |||
12 | diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/arm/tcg/sme_helper.c | ||
15 | +++ b/target/arm/tcg/sme_helper.c | ||
16 | @@ -XXX,XX +XXX,XX @@ void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn, | ||
17 | float_status fpst_odd, fpst_std, fpst_f16; | ||
18 | |||
19 | /* | ||
20 | - * Make copies of fp_status and fp_status_f16, because this operation | ||
21 | + * Make copies of the fp status fields we use, because this operation | ||
22 | * does not update the cumulative fp exception status. It also | ||
23 | * produces default NaNs. We also need a second copy of fp_status with | ||
24 | * round-to-odd -- see above. | ||
25 | */ | ||
26 | - fpst_f16 = env->vfp.fp_status_f16; | ||
27 | + fpst_f16 = env->vfp.fp_status_f16_a64; | ||
28 | fpst_std = env->vfp.fp_status_a64; | ||
29 | set_default_nan_mode(true, &fpst_std); | ||
30 | set_default_nan_mode(true, &fpst_f16); | ||
31 | diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/arm/tcg/vec_helper.c | ||
34 | +++ b/target/arm/tcg/vec_helper.c | ||
35 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm, | ||
36 | CPUARMState *env, uint32_t desc) | ||
37 | { | ||
38 | do_fmlal(vd, vn, vm, &env->vfp.fp_status_a64, desc, | ||
39 | - get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
40 | + get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64)); | ||
41 | } | ||
42 | |||
43 | void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va, | ||
44 | @@ -XXX,XX +XXX,XX @@ void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va, | ||
45 | uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15; | ||
46 | intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); | ||
47 | float_status *status = &env->vfp.fp_status_a64; | ||
48 | - bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); | ||
49 | + bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64); | ||
50 | |||
51 | for (i = 0; i < oprsz; i += sizeof(float32)) { | ||
52 | float16 nn_16 = *(float16 *)(vn + H1_2(i + sel)) ^ negn; | ||
53 | @@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm, | ||
54 | CPUARMState *env, uint32_t desc) | ||
55 | { | ||
56 | do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status_a64, desc, | ||
57 | - get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); | ||
58 | + get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64)); | ||
59 | } | ||
60 | |||
61 | void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va, | ||
62 | @@ -XXX,XX +XXX,XX @@ void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va, | ||
63 | intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); | ||
64 | intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 2, 3) * sizeof(float16); | ||
65 | float_status *status = &env->vfp.fp_status_a64; | ||
66 | - bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); | ||
67 | + bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64); | ||
68 | |||
69 | for (i = 0; i < oprsz; i += 16) { | ||
70 | float16 mm_16 = *(float16 *)(vm + i + idx); | ||
71 | -- | ||
72 | 2.34.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | In the A32 decoder, use FPST_A32_F16 rather than FPST_FPCR_F16. | ||
2 | By doing an automated conversion of the whole file we avoid possibly | ||
3 | using more than one fpst value in a set_rmode/op/restore_rmode | ||
4 | sequence. | ||
1 | 5 | ||
6 | Patch created with | ||
7 | perl -p -i -e 's/FPST_FPCR_F16(?!_)/FPST_A32_F16/g' target/arm/tcg/translate-vfp.c | ||
8 | |||
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Message-id: 20250124162836.2332150-17-peter.maydell@linaro.org | ||
12 | --- | ||
13 | target/arm/tcg/translate-vfp.c | 24 ++++++++++++------------ | ||
14 | 1 file changed, 12 insertions(+), 12 deletions(-) | ||
15 | |||
16 | diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/arm/tcg/translate-vfp.c | ||
19 | +++ b/target/arm/tcg/translate-vfp.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a) | ||
21 | } | ||
22 | |||
23 | if (sz == 1) { | ||
24 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
25 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
26 | } else { | ||
27 | fpst = fpstatus_ptr(FPST_A32); | ||
28 | } | ||
29 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a) | ||
30 | } | ||
31 | |||
32 | if (sz == 1) { | ||
33 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
34 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
35 | } else { | ||
36 | fpst = fpstatus_ptr(FPST_A32); | ||
37 | } | ||
38 | @@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn, | ||
39 | /* | ||
40 | * Do a half-precision operation. Functionally this is | ||
41 | * the same as do_vfp_3op_sp(), except: | ||
42 | - * - it uses the FPST_FPCR_F16 | ||
43 | + * - it uses the FPST_A32_F16 | ||
44 | * - it doesn't need the VFP vector handling (fp16 is a | ||
45 | * v8 feature, and in v8 VFP vectors don't exist) | ||
46 | * - it does the aa32_fp16_arith feature test | ||
47 | @@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn, | ||
48 | f0 = tcg_temp_new_i32(); | ||
49 | f1 = tcg_temp_new_i32(); | ||
50 | fd = tcg_temp_new_i32(); | ||
51 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
52 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
53 | |||
54 | vfp_load_reg16(f0, vn); | ||
55 | vfp_load_reg16(f1, vm); | ||
56 | @@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d) | ||
57 | /* VFNMA, VFNMS */ | ||
58 | gen_vfp_negh(vd, vd); | ||
59 | } | ||
60 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
61 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
62 | gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst); | ||
63 | vfp_store_reg32(vd, a->vd); | ||
64 | return true; | ||
65 | @@ -XXX,XX +XXX,XX @@ DO_VFP_2OP(VNEG, dp, gen_vfp_negd, aa32_fpdp_v2) | ||
66 | |||
67 | static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm) | ||
68 | { | ||
69 | - gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_FPCR_F16)); | ||
70 | + gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_A32_F16)); | ||
71 | } | ||
72 | |||
73 | static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm) | ||
74 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a) | ||
75 | |||
76 | tmp = tcg_temp_new_i32(); | ||
77 | vfp_load_reg16(tmp, a->vm); | ||
78 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
79 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
80 | gen_helper_rinth(tmp, tmp, fpst); | ||
81 | vfp_store_reg32(tmp, a->vd); | ||
82 | return true; | ||
83 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a) | ||
84 | |||
85 | tmp = tcg_temp_new_i32(); | ||
86 | vfp_load_reg16(tmp, a->vm); | ||
87 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
88 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
89 | tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); | ||
90 | gen_helper_rinth(tmp, tmp, fpst); | ||
91 | gen_restore_rmode(tcg_rmode, fpst); | ||
92 | @@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a) | ||
93 | |||
94 | tmp = tcg_temp_new_i32(); | ||
95 | vfp_load_reg16(tmp, a->vm); | ||
96 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
97 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
98 | gen_helper_rinth_exact(tmp, tmp, fpst); | ||
99 | vfp_store_reg32(tmp, a->vd); | ||
100 | return true; | ||
101 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a) | ||
102 | |||
103 | vm = tcg_temp_new_i32(); | ||
104 | vfp_load_reg32(vm, a->vm); | ||
105 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
106 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
107 | if (a->s) { | ||
108 | /* i32 -> f16 */ | ||
109 | gen_helper_vfp_sitoh(vm, vm, fpst); | ||
110 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a) | ||
111 | vd = tcg_temp_new_i32(); | ||
112 | vfp_load_reg32(vd, a->vd); | ||
113 | |||
114 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
115 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
116 | shift = tcg_constant_i32(frac_bits); | ||
117 | |||
118 | /* Switch on op:U:sx bits */ | ||
119 | @@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a) | ||
120 | return true; | ||
121 | } | ||
122 | |||
123 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
124 | + fpst = fpstatus_ptr(FPST_A32_F16); | ||
125 | vm = tcg_temp_new_i32(); | ||
126 | vfp_load_reg16(vm, a->vm); | ||
127 | |||
128 | -- | ||
129 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | In the A32 decoder, use FPST_A64_F16 rather than FPST_FPCR_F16. |
---|---|---|---|
2 | By doing an automated conversion of the whole file we avoid possibly | ||
3 | using more than one fpst value in a set_rmode/op/restore_rmode | ||
4 | sequence. | ||
2 | 5 | ||
3 | Without FEAT_LVA, the behaviour of programming an invalid value | 6 | Patch created with |
4 | is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid | 7 | perl -p -i -e 's/FPST_FPCR_F16(?!_)/FPST_A64_F16/g' target/arm/tcg/translate-{a64,sve,sme}.c |
5 | minimum value requires a Translation fault. | ||
6 | 8 | ||
7 | It is most self-consistent to choose to generate the fault always. | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Message-id: 20250124162836.2332150-18-peter.maydell@linaro.org | ||
12 | --- | ||
13 | target/arm/tcg/translate-a64.c | 32 ++++++++--------- | ||
14 | target/arm/tcg/translate-sve.c | 66 +++++++++++++++++----------------- | ||
15 | 2 files changed, 49 insertions(+), 49 deletions(-) | ||
8 | 16 | ||
9 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 17 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
10 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
11 | Message-id: 20220301215958.157011-4-richard.henderson@linaro.org | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | ||
13 | --- | ||
14 | target/arm/internals.h | 1 + | ||
15 | target/arm/helper.c | 32 ++++++++++++++++++++++++++++---- | ||
16 | 2 files changed, 29 insertions(+), 4 deletions(-) | ||
17 | |||
18 | diff --git a/target/arm/internals.h b/target/arm/internals.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/arm/internals.h | 19 | --- a/target/arm/tcg/translate-a64.c |
21 | +++ b/target/arm/internals.h | 20 | +++ b/target/arm/tcg/translate-a64.c |
22 | @@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters { | 21 | @@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn, |
23 | bool hpd : 1; | 22 | int rm, bool is_fp16, int data, |
24 | bool using16k : 1; | 23 | gen_helper_gvec_3_ptr *fn) |
25 | bool using64k : 1; | 24 | { |
26 | + bool tsz_oob : 1; /* tsz has been clamped to legal range */ | 25 | - TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); |
27 | } ARMVAParameters; | 26 | + TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64); |
28 | 27 | tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), | |
29 | ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 28 | vec_full_reg_offset(s, rn), |
30 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 29 | vec_full_reg_offset(s, rm), fpst, |
30 | @@ -XXX,XX +XXX,XX @@ static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn, | ||
31 | int rm, int ra, bool is_fp16, int data, | ||
32 | gen_helper_gvec_4_ptr *fn) | ||
33 | { | ||
34 | - TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); | ||
35 | + TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64); | ||
36 | tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), | ||
37 | vec_full_reg_offset(s, rn), | ||
38 | vec_full_reg_offset(s, rm), | ||
39 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f) | ||
40 | if (fp_access_check(s)) { | ||
41 | TCGv_i32 t0 = read_fp_hreg(s, a->rn); | ||
42 | TCGv_i32 t1 = read_fp_hreg(s, a->rm); | ||
43 | - f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); | ||
44 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16)); | ||
45 | write_fp_sreg(s, a->rd, t0); | ||
46 | } | ||
47 | break; | ||
48 | @@ -XXX,XX +XXX,XX @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a, | ||
49 | TCGv_i32 t0 = read_fp_hreg(s, a->rn); | ||
50 | TCGv_i32 t1 = tcg_constant_i32(0); | ||
51 | if (swap) { | ||
52 | - f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_FPCR_F16)); | ||
53 | + f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_A64_F16)); | ||
54 | } else { | ||
55 | - f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); | ||
56 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16)); | ||
57 | } | ||
58 | write_fp_sreg(s, a->rd, t0); | ||
59 | } | ||
60 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f) | ||
61 | TCGv_i32 t1 = tcg_temp_new_i32(); | ||
62 | |||
63 | read_vec_element_i32(s, t1, a->rm, a->idx, MO_16); | ||
64 | - f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); | ||
65 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16)); | ||
66 | write_fp_sreg(s, a->rd, t0); | ||
67 | } | ||
68 | break; | ||
69 | @@ -XXX,XX +XXX,XX @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg) | ||
70 | gen_vfp_negh(t1, t1); | ||
71 | } | ||
72 | gen_helper_advsimd_muladdh(t0, t1, t2, t0, | ||
73 | - fpstatus_ptr(FPST_FPCR_F16)); | ||
74 | + fpstatus_ptr(FPST_A64_F16)); | ||
75 | write_fp_sreg(s, a->rd, t0); | ||
76 | } | ||
77 | break; | ||
78 | @@ -XXX,XX +XXX,XX @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f) | ||
79 | |||
80 | read_vec_element_i32(s, t0, a->rn, 0, MO_16); | ||
81 | read_vec_element_i32(s, t1, a->rn, 1, MO_16); | ||
82 | - f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); | ||
83 | + f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16)); | ||
84 | write_fp_sreg(s, a->rd, t0); | ||
85 | } | ||
86 | break; | ||
87 | @@ -XXX,XX +XXX,XX @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n) | ||
88 | if (neg_n) { | ||
89 | gen_vfp_negh(tn, tn); | ||
90 | } | ||
91 | - fpst = fpstatus_ptr(FPST_FPCR_F16); | ||
92 | + fpst = fpstatus_ptr(FPST_A64_F16); | ||
93 | gen_helper_advsimd_muladdh(ta, tn, tm, ta, fpst); | ||
94 | write_fp_sreg(s, a->rd, ta); | ||
95 | } | ||
96 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_reduction(DisasContext *s, arg_qrr_e *a, | ||
97 | if (fp_access_check(s)) { | ||
98 | MemOp esz = a->esz; | ||
99 | int elts = (a->q ? 16 : 8) >> esz; | ||
100 | - TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
101 | + TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
102 | TCGv_i32 res = do_reduction_op(s, a->rn, esz, 0, elts, fpst, fn); | ||
103 | write_fp_sreg(s, a->rd, res); | ||
104 | } | ||
105 | @@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, int size, | ||
106 | bool cmp_with_zero, bool signal_all_nans) | ||
107 | { | ||
108 | TCGv_i64 tcg_flags = tcg_temp_new_i64(); | ||
109 | - TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
110 | + TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
111 | |||
112 | if (size == MO_64) { | ||
113 | TCGv_i64 tcg_vn, tcg_vm; | ||
114 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_scalar(DisasContext *s, arg_rr_e *a, | ||
115 | return check == 0; | ||
116 | } | ||
117 | |||
118 | - fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
119 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
120 | if (rmode >= 0) { | ||
121 | tcg_rmode = gen_set_rmode(rmode, fpst); | ||
122 | } | ||
123 | @@ -XXX,XX +XXX,XX @@ static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift, | ||
124 | TCGv_i32 tcg_shift, tcg_single; | ||
125 | TCGv_i64 tcg_double; | ||
126 | |||
127 | - tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
128 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
129 | tcg_shift = tcg_constant_i32(shift); | ||
130 | |||
131 | switch (esz) { | ||
132 | @@ -XXX,XX +XXX,XX @@ static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz, | ||
133 | TCGv_ptr tcg_fpstatus; | ||
134 | TCGv_i32 tcg_shift, tcg_rmode, tcg_single; | ||
135 | |||
136 | - tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
137 | + tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
138 | tcg_shift = tcg_constant_i32(shift); | ||
139 | tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); | ||
140 | |||
141 | @@ -XXX,XX +XXX,XX @@ static bool do_fp1_vector(DisasContext *s, arg_qrr_e *a, | ||
142 | return check == 0; | ||
143 | } | ||
144 | |||
145 | - fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
146 | + fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
147 | if (rmode >= 0) { | ||
148 | tcg_rmode = gen_set_rmode(rmode, fpst); | ||
149 | } | ||
150 | @@ -XXX,XX +XXX,XX @@ static bool do_gvec_op2_fpst(DisasContext *s, MemOp esz, bool is_q, | ||
151 | return check == 0; | ||
152 | } | ||
153 | |||
154 | - fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
155 | + fpst = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
156 | tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd), | ||
157 | vec_full_reg_offset(s, rn), fpst, | ||
158 | is_q ? 16 : 8, vec_full_reg_size(s), | ||
159 | diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | 160 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/target/arm/helper.c | 161 | --- a/target/arm/tcg/translate-sve.c |
33 | +++ b/target/arm/helper.c | 162 | +++ b/target/arm/tcg/translate-sve.c |
34 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 163 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn, |
35 | ARMMMUIdx mmu_idx, bool data) | 164 | arg_rr_esz *a, int data) |
36 | { | 165 | { |
37 | uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr; | 166 | return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data, |
38 | - bool epd, hpd, using16k, using64k; | 167 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); |
39 | - int select, tsz, tbi, max_tsz; | 168 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); |
40 | + bool epd, hpd, using16k, using64k, tsz_oob; | 169 | } |
41 | + int select, tsz, tbi, max_tsz, min_tsz; | 170 | |
42 | 171 | /* Invoke an out-of-line helper on 3 Zregs. */ | |
43 | if (!regime_has_2_ranges(mmu_idx)) { | 172 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn, |
44 | select = 0; | 173 | arg_rrr_esz *a, int data) |
45 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | 174 | { |
46 | } else { | 175 | return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data, |
47 | max_tsz = 39; | 176 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); |
48 | } | 177 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); |
49 | + min_tsz = 16; /* TODO: ARMv8.2-LVA */ | 178 | } |
50 | 179 | ||
51 | - tsz = MIN(tsz, max_tsz); | 180 | /* Invoke an out-of-line helper on 4 Zregs. */ |
52 | - tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */ | 181 | @@ -XXX,XX +XXX,XX @@ static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn, |
53 | + if (tsz > max_tsz) { | 182 | arg_rprr_esz *a) |
54 | + tsz = max_tsz; | 183 | { |
55 | + tsz_oob = true; | 184 | return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0, |
56 | + } else if (tsz < min_tsz) { | 185 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); |
57 | + tsz = min_tsz; | 186 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); |
58 | + tsz_oob = true; | 187 | } |
59 | + } else { | 188 | |
60 | + tsz_oob = false; | 189 | /* Invoke a vector expander on two Zregs and an immediate. */ |
61 | + } | 190 | @@ -XXX,XX +XXX,XX @@ static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub) |
62 | |||
63 | /* Present TBI as a composite with TBID. */ | ||
64 | tbi = aa64_va_parameter_tbi(tcr, mmu_idx); | ||
65 | @@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, | ||
66 | .hpd = hpd, | ||
67 | .using16k = using16k, | ||
68 | .using64k = using64k, | ||
69 | + .tsz_oob = tsz_oob, | ||
70 | }; | 191 | }; |
192 | return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, | ||
193 | (a->index << 1) | sub, | ||
194 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
195 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
71 | } | 196 | } |
72 | 197 | ||
73 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | 198 | TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false) |
74 | param = aa64_va_parameters(env, address, mmu_idx, | 199 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const fmul_idx_fns[4] = { |
75 | access_type != MMU_INST_FETCH); | 200 | }; |
76 | level = 0; | 201 | TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz, |
77 | + | 202 | fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index, |
78 | + /* | 203 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) |
79 | + * If TxSZ is programmed to a value larger than the maximum, | 204 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) |
80 | + * or smaller than the effective minimum, it is IMPLEMENTATION | 205 | |
81 | + * DEFINED whether we behave as if the field were programmed | 206 | /* |
82 | + * within bounds, or if a level 0 Translation fault is generated. | 207 | *** SVE Floating Point Fast Reduction Group |
83 | + * | 208 | @@ -XXX,XX +XXX,XX @@ static bool do_reduce(DisasContext *s, arg_rpr_esz *a, |
84 | + * With FEAT_LVA, fault on less than minimum becomes required, | 209 | |
85 | + * so our choice is to always raise the fault. | 210 | tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); |
86 | + */ | 211 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); |
87 | + if (param.tsz_oob) { | 212 | - status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); |
88 | + fault_type = ARMFault_Translation; | 213 | + status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); |
89 | + goto do_fault; | 214 | |
90 | + } | 215 | fn(temp, t_zn, t_pg, status, t_desc); |
91 | + | 216 | |
92 | addrsize = 64 - 8 * param.tbi; | 217 | @@ -XXX,XX +XXX,XX @@ static bool do_ppz_fp(DisasContext *s, arg_rpr_esz *a, |
93 | inputsize = 64 - param.tsz; | 218 | if (sve_access_check(s)) { |
94 | } else { | 219 | unsigned vsz = vec_full_reg_size(s); |
220 | TCGv_ptr status = | ||
221 | - fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
222 | + fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
223 | |||
224 | tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd), | ||
225 | vec_full_reg_offset(s, a->rn), | ||
226 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = { | ||
227 | }; | ||
228 | TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz, | ||
229 | ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm, | ||
230 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
231 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
232 | |||
233 | /* | ||
234 | *** SVE Floating Point Accumulating Reduction Group | ||
235 | @@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a) | ||
236 | t_pg = tcg_temp_new_ptr(); | ||
237 | tcg_gen_addi_ptr(t_rm, tcg_env, vec_full_reg_offset(s, a->rm)); | ||
238 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); | ||
239 | - t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
240 | + t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
241 | t_desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); | ||
242 | |||
243 | fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc); | ||
244 | @@ -XXX,XX +XXX,XX @@ static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16, | ||
245 | tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, zn)); | ||
246 | tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); | ||
247 | |||
248 | - status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_A64); | ||
249 | + status = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64); | ||
250 | desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); | ||
251 | fn(t_zd, t_zn, t_pg, scalar, status, desc); | ||
252 | } | ||
253 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a, | ||
254 | } | ||
255 | if (sve_access_check(s)) { | ||
256 | unsigned vsz = vec_full_reg_size(s); | ||
257 | - TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
258 | + TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
259 | tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd), | ||
260 | vec_full_reg_offset(s, a->rn), | ||
261 | vec_full_reg_offset(s, a->rm), | ||
262 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_4_ptr * const fcadd_fns[] = { | ||
263 | }; | ||
264 | TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], | ||
265 | a->rd, a->rn, a->rm, a->pg, a->rot, | ||
266 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
267 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
268 | |||
269 | #define DO_FMLA(NAME, name) \ | ||
270 | static gen_helper_gvec_5_ptr * const name##_fns[4] = { \ | ||
271 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], | ||
272 | }; \ | ||
273 | TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_zzzzp, name##_fns[a->esz], \ | ||
274 | a->rd, a->rn, a->rm, a->ra, a->pg, 0, \ | ||
275 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
276 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
277 | |||
278 | DO_FMLA(FMLA_zpzzz, fmla_zpzzz) | ||
279 | DO_FMLA(FMLS_zpzzz, fmls_zpzzz) | ||
280 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_5_ptr * const fcmla_fns[4] = { | ||
281 | }; | ||
282 | TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_zzzzp, fcmla_fns[a->esz], | ||
283 | a->rd, a->rn, a->rm, a->ra, a->pg, a->rot, | ||
284 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
285 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
286 | |||
287 | static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = { | ||
288 | NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL | ||
289 | }; | ||
290 | TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz], | ||
291 | a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot, | ||
292 | - a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
293 | + a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
294 | |||
295 | /* | ||
296 | *** SVE Floating Point Unary Operations Predicated Group | ||
297 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
298 | gen_helper_sve_fcvt_sd, a, 0, FPST_A64) | ||
299 | |||
300 | TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
301 | - gen_helper_sve_fcvtzs_hh, a, 0, FPST_FPCR_F16) | ||
302 | + gen_helper_sve_fcvtzs_hh, a, 0, FPST_A64_F16) | ||
303 | TRANS_FEAT(FCVTZU_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
304 | - gen_helper_sve_fcvtzu_hh, a, 0, FPST_FPCR_F16) | ||
305 | + gen_helper_sve_fcvtzu_hh, a, 0, FPST_A64_F16) | ||
306 | TRANS_FEAT(FCVTZS_hs, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
307 | - gen_helper_sve_fcvtzs_hs, a, 0, FPST_FPCR_F16) | ||
308 | + gen_helper_sve_fcvtzs_hs, a, 0, FPST_A64_F16) | ||
309 | TRANS_FEAT(FCVTZU_hs, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
310 | - gen_helper_sve_fcvtzu_hs, a, 0, FPST_FPCR_F16) | ||
311 | + gen_helper_sve_fcvtzu_hs, a, 0, FPST_A64_F16) | ||
312 | TRANS_FEAT(FCVTZS_hd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
313 | - gen_helper_sve_fcvtzs_hd, a, 0, FPST_FPCR_F16) | ||
314 | + gen_helper_sve_fcvtzs_hd, a, 0, FPST_A64_F16) | ||
315 | TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
316 | - gen_helper_sve_fcvtzu_hd, a, 0, FPST_FPCR_F16) | ||
317 | + gen_helper_sve_fcvtzu_hd, a, 0, FPST_A64_F16) | ||
318 | |||
319 | TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
320 | gen_helper_sve_fcvtzs_ss, a, 0, FPST_A64) | ||
321 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frint_fns[] = { | ||
322 | gen_helper_sve_frint_d | ||
323 | }; | ||
324 | TRANS_FEAT(FRINTI, aa64_sve, gen_gvec_fpst_arg_zpz, frint_fns[a->esz], | ||
325 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
326 | + a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
327 | |||
328 | static gen_helper_gvec_3_ptr * const frintx_fns[] = { | ||
329 | NULL, | ||
330 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frintx_fns[] = { | ||
331 | gen_helper_sve_frintx_d | ||
332 | }; | ||
333 | TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, frintx_fns[a->esz], | ||
334 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
335 | + a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
336 | |||
337 | static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, | ||
338 | ARMFPRounding mode, gen_helper_gvec_3_ptr *fn) | ||
339 | @@ -XXX,XX +XXX,XX @@ static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, | ||
340 | } | ||
341 | |||
342 | vsz = vec_full_reg_size(s); | ||
343 | - status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64); | ||
344 | + status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64); | ||
345 | tmode = gen_set_rmode(mode, status); | ||
346 | |||
347 | tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd), | ||
348 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const frecpx_fns[] = { | ||
349 | gen_helper_sve_frecpx_s, gen_helper_sve_frecpx_d, | ||
350 | }; | ||
351 | TRANS_FEAT(FRECPX, aa64_sve, gen_gvec_fpst_arg_zpz, frecpx_fns[a->esz], | ||
352 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
353 | + a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
354 | |||
355 | static gen_helper_gvec_3_ptr * const fsqrt_fns[] = { | ||
356 | NULL, gen_helper_sve_fsqrt_h, | ||
357 | gen_helper_sve_fsqrt_s, gen_helper_sve_fsqrt_d, | ||
358 | }; | ||
359 | TRANS_FEAT(FSQRT, aa64_sve, gen_gvec_fpst_arg_zpz, fsqrt_fns[a->esz], | ||
360 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
361 | + a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
362 | |||
363 | TRANS_FEAT(SCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
364 | - gen_helper_sve_scvt_hh, a, 0, FPST_FPCR_F16) | ||
365 | + gen_helper_sve_scvt_hh, a, 0, FPST_A64_F16) | ||
366 | TRANS_FEAT(SCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
367 | - gen_helper_sve_scvt_sh, a, 0, FPST_FPCR_F16) | ||
368 | + gen_helper_sve_scvt_sh, a, 0, FPST_A64_F16) | ||
369 | TRANS_FEAT(SCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
370 | - gen_helper_sve_scvt_dh, a, 0, FPST_FPCR_F16) | ||
371 | + gen_helper_sve_scvt_dh, a, 0, FPST_A64_F16) | ||
372 | |||
373 | TRANS_FEAT(SCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
374 | gen_helper_sve_scvt_ss, a, 0, FPST_A64) | ||
375 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
376 | gen_helper_sve_scvt_dd, a, 0, FPST_A64) | ||
377 | |||
378 | TRANS_FEAT(UCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
379 | - gen_helper_sve_ucvt_hh, a, 0, FPST_FPCR_F16) | ||
380 | + gen_helper_sve_ucvt_hh, a, 0, FPST_A64_F16) | ||
381 | TRANS_FEAT(UCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
382 | - gen_helper_sve_ucvt_sh, a, 0, FPST_FPCR_F16) | ||
383 | + gen_helper_sve_ucvt_sh, a, 0, FPST_A64_F16) | ||
384 | TRANS_FEAT(UCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
385 | - gen_helper_sve_ucvt_dh, a, 0, FPST_FPCR_F16) | ||
386 | + gen_helper_sve_ucvt_dh, a, 0, FPST_A64_F16) | ||
387 | |||
388 | TRANS_FEAT(UCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, | ||
389 | gen_helper_sve_ucvt_ss, a, 0, FPST_A64) | ||
390 | @@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const flogb_fns[] = { | ||
391 | gen_helper_flogb_s, gen_helper_flogb_d | ||
392 | }; | ||
393 | TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz], | ||
394 | - a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_A64) | ||
395 | + a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64) | ||
396 | |||
397 | static bool do_FMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sub, bool sel) | ||
398 | { | ||
95 | -- | 399 | -- |
96 | 2.25.1 | 400 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | Now we have moved all the uses of vfp.fp_status_f16 and FPST_FPCR_F16 |
---|---|---|---|
2 | to the new A32 or A64 fields, we can remove these. | ||
2 | 3 | ||
3 | Set this as the kernel would, to 48 bits, to keep the computation | 4 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
4 | of the address space correct for PAuth. | 5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
6 | Message-id: 20250124162836.2332150-19-peter.maydell@linaro.org | ||
7 | --- | ||
8 | target/arm/cpu.h | 2 -- | ||
9 | target/arm/tcg/translate.h | 6 ------ | ||
10 | target/arm/cpu.c | 1 - | ||
11 | target/arm/vfp_helper.c | 7 ------- | ||
12 | 4 files changed, 16 deletions(-) | ||
5 | 13 | ||
6 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 14 | diff --git a/target/arm/cpu.h b/target/arm/cpu.h |
7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 15 | index XXXXXXX..XXXXXXX 100644 |
8 | Message-id: 20220301215958.157011-3-richard.henderson@linaro.org | 16 | --- a/target/arm/cpu.h |
9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 17 | +++ b/target/arm/cpu.h |
10 | --- | 18 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
11 | target/arm/cpu.c | 3 ++- | 19 | * |
12 | 1 file changed, 2 insertions(+), 1 deletion(-) | 20 | * fp_status_a32: is the "normal" fp status for AArch32 insns |
13 | 21 | * fp_status_a64: is the "normal" fp status for AArch64 insns | |
22 | - * fp_status_fp16: used for half-precision calculations | ||
23 | * fp_status_fp16_a32: used for AArch32 half-precision calculations | ||
24 | * fp_status_fp16_a64: used for AArch64 half-precision calculations | ||
25 | * standard_fp_status : the ARM "Standard FPSCR Value" | ||
26 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { | ||
27 | */ | ||
28 | float_status fp_status_a32; | ||
29 | float_status fp_status_a64; | ||
30 | - float_status fp_status_f16; | ||
31 | float_status fp_status_f16_a32; | ||
32 | float_status fp_status_f16_a64; | ||
33 | float_status standard_fp_status; | ||
34 | diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/arm/tcg/translate.h | ||
37 | +++ b/target/arm/tcg/translate.h | ||
38 | @@ -XXX,XX +XXX,XX @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb) | ||
39 | typedef enum ARMFPStatusFlavour { | ||
40 | FPST_A32, | ||
41 | FPST_A64, | ||
42 | - FPST_FPCR_F16, | ||
43 | FPST_A32_F16, | ||
44 | FPST_A64_F16, | ||
45 | FPST_STD, | ||
46 | @@ -XXX,XX +XXX,XX @@ typedef enum ARMFPStatusFlavour { | ||
47 | * for AArch32 non-FP16 operations controlled by the FPCR | ||
48 | * FPST_A64 | ||
49 | * for AArch64 non-FP16 operations controlled by the FPCR | ||
50 | - * FPST_FPCR_F16 | ||
51 | - * for operations controlled by the FPCR where FPCR.FZ16 is to be used | ||
52 | * FPST_A32_F16 | ||
53 | * for AArch32 operations controlled by the FPCR where FPCR.FZ16 is to be used | ||
54 | * FPST_A64_F16 | ||
55 | @@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour) | ||
56 | case FPST_A64: | ||
57 | offset = offsetof(CPUARMState, vfp.fp_status_a64); | ||
58 | break; | ||
59 | - case FPST_FPCR_F16: | ||
60 | - offset = offsetof(CPUARMState, vfp.fp_status_f16); | ||
61 | - break; | ||
62 | case FPST_A32_F16: | ||
63 | offset = offsetof(CPUARMState, vfp.fp_status_f16_a32); | ||
64 | break; | ||
14 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c | 65 | diff --git a/target/arm/cpu.c b/target/arm/cpu.c |
15 | index XXXXXXX..XXXXXXX 100644 | 66 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/target/arm/cpu.c | 67 | --- a/target/arm/cpu.c |
17 | +++ b/target/arm/cpu.c | 68 | +++ b/target/arm/cpu.c |
18 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev) | 69 | @@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) |
19 | aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1); | 70 | arm_set_default_fp_behaviours(&env->vfp.fp_status_a32); |
71 | arm_set_default_fp_behaviours(&env->vfp.fp_status_a64); | ||
72 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status); | ||
73 | - arm_set_default_fp_behaviours(&env->vfp.fp_status_f16); | ||
74 | arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a32); | ||
75 | arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a64); | ||
76 | arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); | ||
77 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/target/arm/vfp_helper.c | ||
80 | +++ b/target/arm/vfp_helper.c | ||
81 | @@ -XXX,XX +XXX,XX @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) | ||
82 | i |= get_float_exception_flags(&env->vfp.fp_status_a64); | ||
83 | i |= get_float_exception_flags(&env->vfp.standard_fp_status); | ||
84 | /* FZ16 does not generate an input denormal exception. */ | ||
85 | - i |= (get_float_exception_flags(&env->vfp.fp_status_f16) | ||
86 | - & ~float_flag_input_denormal); | ||
87 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) | ||
88 | & ~float_flag_input_denormal); | ||
89 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) | ||
90 | @@ -XXX,XX +XXX,XX @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) | ||
91 | */ | ||
92 | set_float_exception_flags(0, &env->vfp.fp_status_a32); | ||
93 | set_float_exception_flags(0, &env->vfp.fp_status_a64); | ||
94 | - set_float_exception_flags(0, &env->vfp.fp_status_f16); | ||
95 | set_float_exception_flags(0, &env->vfp.fp_status_f16_a32); | ||
96 | set_float_exception_flags(0, &env->vfp.fp_status_f16_a64); | ||
97 | set_float_exception_flags(0, &env->vfp.standard_fp_status); | ||
98 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
20 | } | 99 | } |
21 | /* | 100 | set_float_rounding_mode(i, &env->vfp.fp_status_a32); |
22 | + * Enable 48-bit address space (TODO: take reserved_va into account). | 101 | set_float_rounding_mode(i, &env->vfp.fp_status_a64); |
23 | * Enable TBI0 but not TBI1. | 102 | - set_float_rounding_mode(i, &env->vfp.fp_status_f16); |
24 | * Note that this must match useronly_clean_ptr. | 103 | set_float_rounding_mode(i, &env->vfp.fp_status_f16_a32); |
25 | */ | 104 | set_float_rounding_mode(i, &env->vfp.fp_status_f16_a64); |
26 | - env->cp15.tcr_el[1].raw_tcr = (1ULL << 37); | 105 | } |
27 | + env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37); | 106 | if (changed & FPCR_FZ16) { |
28 | 107 | bool ftz_enabled = val & FPCR_FZ16; | |
29 | /* Enable MTE */ | 108 | - set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); |
30 | if (cpu_isar_feature(aa64_mte, cpu)) { | 109 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); |
110 | set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); | ||
111 | set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); | ||
112 | - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); | ||
113 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32); | ||
114 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64); | ||
115 | set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); | ||
116 | @@ -XXX,XX +XXX,XX @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) | ||
117 | bool dnan_enabled = val & FPCR_DN; | ||
118 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32); | ||
119 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64); | ||
120 | - set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); | ||
121 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32); | ||
122 | set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64); | ||
123 | } | ||
31 | -- | 124 | -- |
32 | 2.25.1 | 125 | 2.34.1 | diff view generated by jsdifflib |
1 | In commit 6e657e64cdc478 in 2013 we added some autorelease pools to | 1 | Our float_flag_input_denormal exception flag is set when the fpu code |
---|---|---|---|
2 | deal with complaints from macOS when we made calls into Cocoa from | 2 | flushes an input denormal to zero. This is what many guest |
3 | threads that didn't have automatically created autorelease pools. | 3 | architectures (eg classic Arm behaviour) require, but it is not the |
4 | Later on, macOS got stricter about forbidding cross-thread Cocoa | 4 | only donarmal-related reason we might want to set an exception flag. |
5 | calls, and in commit 5588840ff77800e839d8 we restructured the code to | 5 | The x86 behaviour (which we do not currently model correctly) wants |
6 | avoid them. This left the autorelease pool creation in several | 6 | to see an exception flag when a denormal input is *not* flushed to |
7 | functions without any purpose; delete it. | 7 | zero and is actually used in an arithmetic operation. Arm's FEAT_AFP |
8 | 8 | also wants these semantics. | |
9 | We still need the pool in cocoa_refresh() for the clipboard related | 9 | |
10 | code which is called directly there. | 10 | Rename float_flag_input_denormal to float_flag_input_denormal_flushed |
11 | to make it clearer when it is set and to allow us to add a new | ||
12 | float_flag_input_denormal_used next to it for the x86/FEAT_AFP | ||
13 | semantics. | ||
14 | |||
15 | Commit created with | ||
16 | for f in `git grep -l float_flag_input_denormal`; do sed -i -e 's/float_flag_input_denormal/float_flag_input_denormal_flushed/' $f; done | ||
17 | |||
18 | and manual editing of softfloat-types.h and softfloat.c to clean | ||
19 | up the indentation afterwards and to fix a comment which wasn't | ||
20 | using the full name of the flag. | ||
11 | 21 | ||
12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 22 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
13 | Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com> | 23 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
14 | Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com> | 24 | Message-id: 20250124162836.2332150-20-peter.maydell@linaro.org |
15 | Message-id: 20220224101330.967429-3-peter.maydell@linaro.org | ||
16 | --- | 25 | --- |
17 | ui/cocoa.m | 6 ------ | 26 | include/fpu/softfloat-types.h | 5 +++-- |
18 | 1 file changed, 6 deletions(-) | 27 | fpu/softfloat.c | 4 ++-- |
19 | 28 | target/arm/tcg/sve_helper.c | 6 +++--- | |
20 | diff --git a/ui/cocoa.m b/ui/cocoa.m | 29 | target/arm/vfp_helper.c | 10 +++++----- |
21 | index XXXXXXX..XXXXXXX 100644 | 30 | target/i386/tcg/fpu_helper.c | 6 +++--- |
22 | --- a/ui/cocoa.m | 31 | target/mips/tcg/msa_helper.c | 2 +- |
23 | +++ b/ui/cocoa.m | 32 | target/rx/op_helper.c | 2 +- |
24 | @@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) { | 33 | fpu/softfloat-parts.c.inc | 2 +- |
25 | static void cocoa_update(DisplayChangeListener *dcl, | 34 | 8 files changed, 19 insertions(+), 18 deletions(-) |
26 | int x, int y, int w, int h) | 35 | |
36 | diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/include/fpu/softfloat-types.h | ||
39 | +++ b/include/fpu/softfloat-types.h | ||
40 | @@ -XXX,XX +XXX,XX @@ enum { | ||
41 | float_flag_overflow = 0x0004, | ||
42 | float_flag_underflow = 0x0008, | ||
43 | float_flag_inexact = 0x0010, | ||
44 | - float_flag_input_denormal = 0x0020, | ||
45 | + /* We flushed an input denormal to 0 (because of flush_inputs_to_zero) */ | ||
46 | + float_flag_input_denormal_flushed = 0x0020, | ||
47 | float_flag_output_denormal = 0x0040, | ||
48 | float_flag_invalid_isi = 0x0080, /* inf - inf */ | ||
49 | float_flag_invalid_imz = 0x0100, /* inf * 0 */ | ||
50 | @@ -XXX,XX +XXX,XX @@ typedef struct float_status { | ||
51 | bool tininess_before_rounding; | ||
52 | /* should denormalised results go to zero and set the inexact flag? */ | ||
53 | bool flush_to_zero; | ||
54 | - /* should denormalised inputs go to zero and set the input_denormal flag? */ | ||
55 | + /* should denormalised inputs go to zero and set input_denormal_flushed? */ | ||
56 | bool flush_inputs_to_zero; | ||
57 | bool default_nan_mode; | ||
58 | /* | ||
59 | diff --git a/fpu/softfloat.c b/fpu/softfloat.c | ||
60 | index XXXXXXX..XXXXXXX 100644 | ||
61 | --- a/fpu/softfloat.c | ||
62 | +++ b/fpu/softfloat.c | ||
63 | @@ -XXX,XX +XXX,XX @@ this code that are retained. | ||
64 | if (unlikely(soft_t ## _is_denormal(*a))) { \ | ||
65 | *a = soft_t ## _set_sign(soft_t ## _zero, \ | ||
66 | soft_t ## _is_neg(*a)); \ | ||
67 | - float_raise(float_flag_input_denormal, s); \ | ||
68 | + float_raise(float_flag_input_denormal_flushed, s); \ | ||
69 | } \ | ||
70 | } | ||
71 | |||
72 | @@ -XXX,XX +XXX,XX @@ float128 float128_silence_nan(float128 a, float_status *status) | ||
73 | static bool parts_squash_denormal(FloatParts64 p, float_status *status) | ||
27 | { | 74 | { |
28 | - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | 75 | if (p.exp == 0 && p.frac != 0) { |
29 | - | 76 | - float_raise(float_flag_input_denormal, status); |
30 | COCOA_DEBUG("qemu_cocoa: cocoa_update\n"); | 77 | + float_raise(float_flag_input_denormal_flushed, status); |
31 | 78 | return true; | |
32 | dispatch_async(dispatch_get_main_queue(), ^{ | 79 | } |
33 | @@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl, | 80 | |
34 | } | 81 | diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c |
35 | [cocoaView setNeedsDisplayInRect:rect]; | 82 | index XXXXXXX..XXXXXXX 100644 |
36 | }); | 83 | --- a/target/arm/tcg/sve_helper.c |
37 | - | 84 | +++ b/target/arm/tcg/sve_helper.c |
38 | - [pool release]; | 85 | @@ -XXX,XX +XXX,XX @@ static int16_t do_float16_logb_as_int(float16 a, float_status *s) |
86 | return -15 - clz32(frac); | ||
87 | } | ||
88 | /* flush to zero */ | ||
89 | - float_raise(float_flag_input_denormal, s); | ||
90 | + float_raise(float_flag_input_denormal_flushed, s); | ||
91 | } | ||
92 | } else if (unlikely(exp == 0x1f)) { | ||
93 | if (frac == 0) { | ||
94 | @@ -XXX,XX +XXX,XX @@ static int32_t do_float32_logb_as_int(float32 a, float_status *s) | ||
95 | return -127 - clz32(frac); | ||
96 | } | ||
97 | /* flush to zero */ | ||
98 | - float_raise(float_flag_input_denormal, s); | ||
99 | + float_raise(float_flag_input_denormal_flushed, s); | ||
100 | } | ||
101 | } else if (unlikely(exp == 0xff)) { | ||
102 | if (frac == 0) { | ||
103 | @@ -XXX,XX +XXX,XX @@ static int64_t do_float64_logb_as_int(float64 a, float_status *s) | ||
104 | return -1023 - clz64(frac); | ||
105 | } | ||
106 | /* flush to zero */ | ||
107 | - float_raise(float_flag_input_denormal, s); | ||
108 | + float_raise(float_flag_input_denormal_flushed, s); | ||
109 | } | ||
110 | } else if (unlikely(exp == 0x7ff)) { | ||
111 | if (frac == 0) { | ||
112 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
113 | index XXXXXXX..XXXXXXX 100644 | ||
114 | --- a/target/arm/vfp_helper.c | ||
115 | +++ b/target/arm/vfp_helper.c | ||
116 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vfp_exceptbits_from_host(int host_bits) | ||
117 | if (host_bits & float_flag_inexact) { | ||
118 | target_bits |= FPSR_IXC; | ||
119 | } | ||
120 | - if (host_bits & float_flag_input_denormal) { | ||
121 | + if (host_bits & float_flag_input_denormal_flushed) { | ||
122 | target_bits |= FPSR_IDC; | ||
123 | } | ||
124 | return target_bits; | ||
125 | @@ -XXX,XX +XXX,XX @@ static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) | ||
126 | i |= get_float_exception_flags(&env->vfp.standard_fp_status); | ||
127 | /* FZ16 does not generate an input denormal exception. */ | ||
128 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) | ||
129 | - & ~float_flag_input_denormal); | ||
130 | + & ~float_flag_input_denormal_flushed); | ||
131 | i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) | ||
132 | - & ~float_flag_input_denormal); | ||
133 | + & ~float_flag_input_denormal_flushed); | ||
134 | i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) | ||
135 | - & ~float_flag_input_denormal); | ||
136 | + & ~float_flag_input_denormal_flushed); | ||
137 | return vfp_exceptbits_from_host(i); | ||
39 | } | 138 | } |
40 | 139 | ||
41 | static void cocoa_switch(DisplayChangeListener *dcl, | 140 | @@ -XXX,XX +XXX,XX @@ uint64_t HELPER(fjcvtzs)(float64 value, float_status *status) |
42 | DisplaySurface *surface) | 141 | |
43 | { | 142 | /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */ |
44 | - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | 143 | inexact = e_new & (float_flag_inexact | |
45 | pixman_image_t *image = surface->image; | 144 | - float_flag_input_denormal | |
46 | 145 | + float_flag_input_denormal_flushed | | |
47 | COCOA_DEBUG("qemu_cocoa: cocoa_switch\n"); | 146 | float_flag_invalid); |
48 | @@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl, | 147 | |
49 | [cocoaView updateUIInfo]; | 148 | /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ |
50 | [cocoaView switchSurface:image]; | 149 | diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c |
51 | }); | 150 | index XXXXXXX..XXXXXXX 100644 |
52 | - [pool release]; | 151 | --- a/target/i386/tcg/fpu_helper.c |
152 | +++ b/target/i386/tcg/fpu_helper.c | ||
153 | @@ -XXX,XX +XXX,XX @@ static void merge_exception_flags(CPUX86State *env, uint8_t old_flags) | ||
154 | (new_flags & float_flag_overflow ? FPUS_OE : 0) | | ||
155 | (new_flags & float_flag_underflow ? FPUS_UE : 0) | | ||
156 | (new_flags & float_flag_inexact ? FPUS_PE : 0) | | ||
157 | - (new_flags & float_flag_input_denormal ? FPUS_DE : 0))); | ||
158 | + (new_flags & float_flag_input_denormal_flushed ? FPUS_DE : 0))); | ||
53 | } | 159 | } |
54 | 160 | ||
55 | static void cocoa_refresh(DisplayChangeListener *dcl) | 161 | static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b) |
162 | @@ -XXX,XX +XXX,XX @@ void helper_fxtract(CPUX86State *env) | ||
163 | int shift = clz64(temp.l.lower); | ||
164 | temp.l.lower <<= shift; | ||
165 | expdif = 1 - EXPBIAS - shift; | ||
166 | - float_raise(float_flag_input_denormal, &env->fp_status); | ||
167 | + float_raise(float_flag_input_denormal_flushed, &env->fp_status); | ||
168 | } else { | ||
169 | expdif = EXPD(temp) - EXPBIAS; | ||
170 | } | ||
171 | @@ -XXX,XX +XXX,XX @@ void update_mxcsr_from_sse_status(CPUX86State *env) | ||
172 | uint8_t flags = get_float_exception_flags(&env->sse_status); | ||
173 | /* | ||
174 | * The MXCSR denormal flag has opposite semantics to | ||
175 | - * float_flag_input_denormal (the softfloat code sets that flag | ||
176 | + * float_flag_input_denormal_flushed (the softfloat code sets that flag | ||
177 | * only when flushing input denormals to zero, but SSE sets it | ||
178 | * only when not flushing them to zero), so is not converted | ||
179 | * here. | ||
180 | diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c | ||
181 | index XXXXXXX..XXXXXXX 100644 | ||
182 | --- a/target/mips/tcg/msa_helper.c | ||
183 | +++ b/target/mips/tcg/msa_helper.c | ||
184 | @@ -XXX,XX +XXX,XX @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal) | ||
185 | enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED; | ||
186 | |||
187 | /* Set Inexact (I) when flushing inputs to zero */ | ||
188 | - if ((ieee_exception_flags & float_flag_input_denormal) && | ||
189 | + if ((ieee_exception_flags & float_flag_input_denormal_flushed) && | ||
190 | (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) { | ||
191 | if (action & CLEAR_IS_INEXACT) { | ||
192 | mips_exception_flags &= ~FP_INEXACT; | ||
193 | diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c | ||
194 | index XXXXXXX..XXXXXXX 100644 | ||
195 | --- a/target/rx/op_helper.c | ||
196 | +++ b/target/rx/op_helper.c | ||
197 | @@ -XXX,XX +XXX,XX @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr) | ||
198 | if (xcpt & float_flag_inexact) { | ||
199 | SET_FPSW(X); | ||
200 | } | ||
201 | - if ((xcpt & (float_flag_input_denormal | ||
202 | + if ((xcpt & (float_flag_input_denormal_flushed | ||
203 | | float_flag_output_denormal)) | ||
204 | && !FIELD_EX32(env->fpsw, FPSW, DN)) { | ||
205 | env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1); | ||
206 | diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc | ||
207 | index XXXXXXX..XXXXXXX 100644 | ||
208 | --- a/fpu/softfloat-parts.c.inc | ||
209 | +++ b/fpu/softfloat-parts.c.inc | ||
210 | @@ -XXX,XX +XXX,XX @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status, | ||
211 | if (likely(frac_eqz(p))) { | ||
212 | p->cls = float_class_zero; | ||
213 | } else if (status->flush_inputs_to_zero) { | ||
214 | - float_raise(float_flag_input_denormal, status); | ||
215 | + float_raise(float_flag_input_denormal_flushed, status); | ||
216 | p->cls = float_class_zero; | ||
217 | frac_clear(p); | ||
218 | } else { | ||
56 | -- | 219 | -- |
57 | 2.25.1 | 220 | 2.34.1 | diff view generated by jsdifflib |
1 | When we're using KVM, the PSCI implementation is provided by the | 1 | Our float_flag_output_denormal exception flag is set when |
---|---|---|---|
2 | kernel, but QEMU has to tell the guest about it via the device tree. | 2 | the fpu code flushes an output denormal to zero. Rename |
3 | Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine | 3 | it to float_flag_output_denormal_flushed: |
4 | if the kernel is providing at least PSCI 0.2, but if the kernel | 4 | * this keeps it parallel with the flag for flushing |
5 | provides a newer version than that we will still only tell the guest | 5 | input denormals, which we just renamed |
6 | it has PSCI 0.2. (This is fairly harmless; it just means the guest | 6 | * it makes it clearer that it doesn't mean "set when |
7 | won't use newer parts of the PSCI API.) | 7 | the output is a denormal" |
8 | 8 | ||
9 | The kernel exposes the specific PSCI version it is implementing via | 9 | Commit created with |
10 | the ONE_REG API; use this to report in the dtb that the PSCI | 10 | for f in `git grep -l float_flag_output_denormal`; do sed -i -e 's/float_flag_output_denormal/float_flag_output_denormal_flushed/' $f; done |
11 | implementation is 1.0-compatible if appropriate. (The device tree | ||
12 | binding currently only distinguishes "pre-0.2", "0.2-compatible" and | ||
13 | "1.0-compatible".) | ||
14 | 11 | ||
15 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 12 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
16 | Reviewed-by: Marc Zyngier <maz@kernel.org> | ||
17 | Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com> | ||
18 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 13 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
19 | Reviewed-by: Andrew Jones <drjones@redhat.com> | 14 | Message-id: 20250124162836.2332150-21-peter.maydell@linaro.org |
20 | Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org | ||
21 | --- | 15 | --- |
22 | target/arm/kvm-consts.h | 1 + | 16 | include/fpu/softfloat-types.h | 3 ++- |
23 | hw/arm/boot.c | 5 ++--- | 17 | fpu/softfloat.c | 2 +- |
24 | target/arm/kvm64.c | 12 ++++++++++++ | 18 | target/arm/vfp_helper.c | 2 +- |
25 | 3 files changed, 15 insertions(+), 3 deletions(-) | 19 | target/i386/tcg/fpu_helper.c | 2 +- |
20 | target/m68k/fpu_helper.c | 2 +- | ||
21 | target/mips/tcg/msa_helper.c | 2 +- | ||
22 | target/rx/op_helper.c | 2 +- | ||
23 | target/tricore/fpu_helper.c | 6 +++--- | ||
24 | fpu/softfloat-parts.c.inc | 2 +- | ||
25 | 9 files changed, 12 insertions(+), 11 deletions(-) | ||
26 | 26 | ||
27 | diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h | 27 | diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h |
28 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/target/arm/kvm-consts.h | 29 | --- a/include/fpu/softfloat-types.h |
30 | +++ b/target/arm/kvm-consts.h | 30 | +++ b/include/fpu/softfloat-types.h |
31 | @@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES); | 31 | @@ -XXX,XX +XXX,XX @@ enum { |
32 | 32 | float_flag_inexact = 0x0010, | |
33 | #define QEMU_PSCI_VERSION_0_1 0x00001 | 33 | /* We flushed an input denormal to 0 (because of flush_inputs_to_zero) */ |
34 | #define QEMU_PSCI_VERSION_0_2 0x00002 | 34 | float_flag_input_denormal_flushed = 0x0020, |
35 | +#define QEMU_PSCI_VERSION_1_0 0x10000 | 35 | - float_flag_output_denormal = 0x0040, |
36 | #define QEMU_PSCI_VERSION_1_1 0x10001 | 36 | + /* We flushed an output denormal to 0 (because of flush_to_zero) */ |
37 | 37 | + float_flag_output_denormal_flushed = 0x0040, | |
38 | MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP); | 38 | float_flag_invalid_isi = 0x0080, /* inf - inf */ |
39 | diff --git a/hw/arm/boot.c b/hw/arm/boot.c | 39 | float_flag_invalid_imz = 0x0100, /* inf * 0 */ |
40 | float_flag_invalid_idi = 0x0200, /* inf / inf */ | ||
41 | diff --git a/fpu/softfloat.c b/fpu/softfloat.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | 42 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/hw/arm/boot.c | 43 | --- a/fpu/softfloat.c |
42 | +++ b/hw/arm/boot.c | 44 | +++ b/fpu/softfloat.c |
43 | @@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt) | 45 | @@ -XXX,XX +XXX,XX @@ floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, |
46 | } | ||
47 | if ( zExp <= 0 ) { | ||
48 | if (status->flush_to_zero) { | ||
49 | - float_raise(float_flag_output_denormal, status); | ||
50 | + float_raise(float_flag_output_denormal_flushed, status); | ||
51 | return packFloatx80(zSign, 0, 0); | ||
52 | } | ||
53 | isTiny = status->tininess_before_rounding | ||
54 | diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/target/arm/vfp_helper.c | ||
57 | +++ b/target/arm/vfp_helper.c | ||
58 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vfp_exceptbits_from_host(int host_bits) | ||
59 | if (host_bits & float_flag_overflow) { | ||
60 | target_bits |= FPSR_OFC; | ||
44 | } | 61 | } |
45 | 62 | - if (host_bits & (float_flag_underflow | float_flag_output_denormal)) { | |
46 | qemu_fdt_add_subnode(fdt, "/psci"); | 63 | + if (host_bits & (float_flag_underflow | float_flag_output_denormal_flushed)) { |
47 | - if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 || | 64 | target_bits |= FPSR_UFC; |
48 | - armcpu->psci_version == QEMU_PSCI_VERSION_1_1) { | 65 | } |
49 | - if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) { | 66 | if (host_bits & float_flag_inexact) { |
50 | + if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) { | 67 | diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c |
51 | + if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) { | ||
52 | const char comp[] = "arm,psci-0.2\0arm,psci"; | ||
53 | qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); | ||
54 | } else { | ||
55 | diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | 68 | index XXXXXXX..XXXXXXX 100644 |
57 | --- a/target/arm/kvm64.c | 69 | --- a/target/i386/tcg/fpu_helper.c |
58 | +++ b/target/arm/kvm64.c | 70 | +++ b/target/i386/tcg/fpu_helper.c |
59 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) | 71 | @@ -XXX,XX +XXX,XX @@ void update_mxcsr_from_sse_status(CPUX86State *env) |
60 | uint64_t mpidr; | 72 | (flags & float_flag_overflow ? FPUS_OE : 0) | |
61 | ARMCPU *cpu = ARM_CPU(cs); | 73 | (flags & float_flag_underflow ? FPUS_UE : 0) | |
62 | CPUARMState *env = &cpu->env; | 74 | (flags & float_flag_inexact ? FPUS_PE : 0) | |
63 | + uint64_t psciver; | 75 | - (flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE : |
64 | 76 | + (flags & float_flag_output_denormal_flushed ? FPUS_UE | FPUS_PE : | |
65 | if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE || | 77 | 0)); |
66 | !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) { | 78 | } |
67 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) | 79 | |
80 | diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/target/m68k/fpu_helper.c | ||
83 | +++ b/target/m68k/fpu_helper.c | ||
84 | @@ -XXX,XX +XXX,XX @@ static int cpu_m68k_exceptbits_from_host(int host_bits) | ||
85 | if (host_bits & float_flag_overflow) { | ||
86 | target_bits |= 0x40; | ||
87 | } | ||
88 | - if (host_bits & (float_flag_underflow | float_flag_output_denormal)) { | ||
89 | + if (host_bits & (float_flag_underflow | float_flag_output_denormal_flushed)) { | ||
90 | target_bits |= 0x20; | ||
91 | } | ||
92 | if (host_bits & float_flag_divbyzero) { | ||
93 | diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/target/mips/tcg/msa_helper.c | ||
96 | +++ b/target/mips/tcg/msa_helper.c | ||
97 | @@ -XXX,XX +XXX,XX @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal) | ||
98 | } | ||
99 | |||
100 | /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */ | ||
101 | - if ((ieee_exception_flags & float_flag_output_denormal) && | ||
102 | + if ((ieee_exception_flags & float_flag_output_denormal_flushed) && | ||
103 | (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) { | ||
104 | mips_exception_flags |= FP_INEXACT; | ||
105 | if (action & CLEAR_FS_UNDERFLOW) { | ||
106 | diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c | ||
107 | index XXXXXXX..XXXXXXX 100644 | ||
108 | --- a/target/rx/op_helper.c | ||
109 | +++ b/target/rx/op_helper.c | ||
110 | @@ -XXX,XX +XXX,XX @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr) | ||
111 | SET_FPSW(X); | ||
68 | } | 112 | } |
113 | if ((xcpt & (float_flag_input_denormal_flushed | ||
114 | - | float_flag_output_denormal)) | ||
115 | + | float_flag_output_denormal_flushed)) | ||
116 | && !FIELD_EX32(env->fpsw, FPSW, DN)) { | ||
117 | env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1); | ||
118 | } | ||
119 | diff --git a/target/tricore/fpu_helper.c b/target/tricore/fpu_helper.c | ||
120 | index XXXXXXX..XXXXXXX 100644 | ||
121 | --- a/target/tricore/fpu_helper.c | ||
122 | +++ b/target/tricore/fpu_helper.c | ||
123 | @@ -XXX,XX +XXX,XX @@ static inline uint8_t f_get_excp_flags(CPUTriCoreState *env) | ||
124 | & (float_flag_invalid | ||
125 | | float_flag_overflow | ||
126 | | float_flag_underflow | ||
127 | - | float_flag_output_denormal | ||
128 | + | float_flag_output_denormal_flushed | ||
129 | | float_flag_divbyzero | ||
130 | | float_flag_inexact); | ||
131 | } | ||
132 | @@ -XXX,XX +XXX,XX @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags) | ||
133 | some_excp = 1; | ||
69 | } | 134 | } |
70 | 135 | ||
71 | + /* | 136 | - if (flags & float_flag_underflow || flags & float_flag_output_denormal) { |
72 | + * KVM reports the exact PSCI version it is implementing via a | 137 | + if (flags & float_flag_underflow || flags & float_flag_output_denormal_flushed) { |
73 | + * special sysreg. If it is present, use its contents to determine | 138 | env->FPU_FU = 1 << 31; |
74 | + * what to report to the guest in the dtb (it is the PSCI version, | 139 | some_excp = 1; |
75 | + * in the same 15-bits major 16-bits minor format that PSCI_VERSION | 140 | } |
76 | + * returns). | 141 | @@ -XXX,XX +XXX,XX @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags) |
77 | + */ | 142 | some_excp = 1; |
78 | + if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) { | 143 | } |
79 | + cpu->psci_version = psciver; | 144 | |
80 | + } | 145 | - if (flags & float_flag_inexact || flags & float_flag_output_denormal) { |
81 | + | 146 | + if (flags & float_flag_inexact || flags & float_flag_output_denormal_flushed) { |
82 | /* | 147 | env->PSW |= 1 << 26; |
83 | * When KVM is in use, PSCI is emulated in-kernel and not by qemu. | 148 | some_excp = 1; |
84 | * Currently KVM has its own idea about MPIDR assignment, so we | 149 | } |
150 | diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc | ||
151 | index XXXXXXX..XXXXXXX 100644 | ||
152 | --- a/fpu/softfloat-parts.c.inc | ||
153 | +++ b/fpu/softfloat-parts.c.inc | ||
154 | @@ -XXX,XX +XXX,XX @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, | ||
155 | } | ||
156 | frac_shr(p, frac_shift); | ||
157 | } else if (s->flush_to_zero) { | ||
158 | - flags |= float_flag_output_denormal; | ||
159 | + flags |= float_flag_output_denormal_flushed; | ||
160 | p->cls = float_class_zero; | ||
161 | exp = 0; | ||
162 | frac_clear(p); | ||
85 | -- | 163 | -- |
86 | 2.25.1 | 164 | 2.34.1 | diff view generated by jsdifflib |
1 | The AN547 application note URL has changed: update our comment | 1 | In softfloat-types.h a comment documents that if the float_status |
---|---|---|---|
2 | accordingly. (Rev B is still downloadable from the old URL, | 2 | field flush_to_zero is set then we flush denormalised results to 0 |
3 | but there is a new Rev C of the document now.) | 3 | and set the inexact flag. This isn't correct: the status flag that |
4 | we set when flush_to_zero causes us to flush an output to zero is | ||
5 | float_flag_output_denormal_flushed. | ||
6 | |||
7 | Correct the comment. | ||
4 | 8 | ||
5 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 9 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
6 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
7 | Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 11 | Message-id: 20250124162836.2332150-22-peter.maydell@linaro.org |
8 | Message-id: 20220221094144.426191-1-peter.maydell@linaro.org | ||
9 | --- | 12 | --- |
10 | hw/arm/mps2-tz.c | 2 +- | 13 | include/fpu/softfloat-types.h | 2 +- |
11 | 1 file changed, 1 insertion(+), 1 deletion(-) | 14 | 1 file changed, 1 insertion(+), 1 deletion(-) |
12 | 15 | ||
13 | diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c | 16 | diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h |
14 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/hw/arm/mps2-tz.c | 18 | --- a/include/fpu/softfloat-types.h |
16 | +++ b/hw/arm/mps2-tz.c | 19 | +++ b/include/fpu/softfloat-types.h |
17 | @@ -XXX,XX +XXX,XX @@ | 20 | @@ -XXX,XX +XXX,XX @@ typedef struct float_status { |
18 | * Application Note AN524: | 21 | Float3NaNPropRule float_3nan_prop_rule; |
19 | * https://developer.arm.com/documentation/dai0524/latest/ | 22 | FloatInfZeroNaNRule float_infzeronan_rule; |
20 | * Application Note AN547: | 23 | bool tininess_before_rounding; |
21 | - * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf | 24 | - /* should denormalised results go to zero and set the inexact flag? */ |
22 | + * https://developer.arm.com/documentation/dai0547/latest/ | 25 | + /* should denormalised results go to zero and set output_denormal_flushed? */ |
23 | * | 26 | bool flush_to_zero; |
24 | * The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide | 27 | /* should denormalised inputs go to zero and set input_denormal_flushed? */ |
25 | * (ARM ECM0601256) for the details of some of the device layout: | 28 | bool flush_inputs_to_zero; |
26 | -- | 29 | -- |
27 | 2.25.1 | 30 | 2.34.1 |
28 | |||
29 | diff view generated by jsdifflib |
1 | The updateUIInfo method makes Cocoa API calls. It also calls back | 1 | The advsimd_addh etc helpers defined in helper-a64.c are identical to |
---|---|---|---|
2 | into QEMU functions like dpy_set_ui_info(). To do this safely, we | 2 | the vfp_addh etc helpers defined in helper-vfp.c: both take two |
3 | need to follow two rules: | 3 | float16 inputs (in a uint32_t type) plus a float_status* and are |
4 | * Cocoa API calls are made on the Cocoa UI thread | 4 | simple wrappers around the softfloat float16_* functions. |
5 | * When calling back into QEMU we must hold the iothread lock | ||
6 | 5 | ||
7 | Fix the places where we got this wrong, by taking the iothread lock | 6 | (The duplication seems to be a historical accident: we added the |
8 | while executing updateUIInfo, and moving the call in cocoa_switch() | 7 | advsimd helpers in 2018 as part of the A64 implementation, and at |
9 | inside the dispatch_async block. | 8 | that time there was no f16 emulation in A32. Then later we added the |
9 | A32 f16 handling by extending the existing VFP helper macros to | ||
10 | generate f16 versions as well as f32 and f64, and didn't realise we | ||
11 | could clean things up.) | ||
10 | 12 | ||
11 | Some of the Cocoa UI methods which call updateUIInfo are invoked as | 13 | Remove the now-unnecessary advsimd helpers and make the places that |
12 | part of the initial application startup, while we're still doing the | 14 | generated calls to them use the vfp helpers instead. Many of the |
13 | little cross-thread dance described in the comment just above | 15 | helper functions were already unused. |
14 | call_qemu_main(). This meant they were calling back into the QEMU UI | 16 | |
15 | layer before we'd actually finished initializing our display and | 17 | (The remaining advsimd_ helpers are those which don't have vfp |
16 | registered the DisplayChangeListener, which isn't really valid. Once | 18 | versions.) |
17 | updateUIInfo takes the iothread lock, we no longer get away with | ||
18 | this, because during this startup phase the iothread lock is held by | ||
19 | the QEMU main-loop thread which is waiting for us to finish our | ||
20 | display initialization. So we must suppress updateUIInfo until | ||
21 | applicationDidFinishLaunching allows the QEMU main-loop thread to | ||
22 | continue. | ||
23 | 19 | ||
24 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 20 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
25 | Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com> | 21 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
26 | Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com> | 22 | Message-id: 20250124162836.2332150-26-peter.maydell@linaro.org |
27 | Message-id: 20220224101330.967429-2-peter.maydell@linaro.org | ||
28 | --- | 23 | --- |
29 | ui/cocoa.m | 25 ++++++++++++++++++++++--- | 24 | target/arm/tcg/helper-a64.h | 8 -------- |
30 | 1 file changed, 22 insertions(+), 3 deletions(-) | 25 | target/arm/tcg/helper-a64.c | 9 --------- |
26 | target/arm/tcg/translate-a64.c | 16 ++++++++-------- | ||
27 | 3 files changed, 8 insertions(+), 25 deletions(-) | ||
31 | 28 | ||
32 | diff --git a/ui/cocoa.m b/ui/cocoa.m | 29 | diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h |
33 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/ui/cocoa.m | 31 | --- a/target/arm/tcg/helper-a64.h |
35 | +++ b/ui/cocoa.m | 32 | +++ b/target/arm/tcg/helper-a64.h |
36 | @@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView; | 33 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, fpst) |
37 | } | 34 | DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, fpst) |
35 | DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) | ||
36 | DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) | ||
37 | -DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, fpst) | ||
38 | -DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, fpst) | ||
39 | -DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, fpst) | ||
40 | -DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, fpst) | ||
41 | -DEF_HELPER_3(advsimd_addh, f16, f16, f16, fpst) | ||
42 | -DEF_HELPER_3(advsimd_subh, f16, f16, f16, fpst) | ||
43 | -DEF_HELPER_3(advsimd_mulh, f16, f16, f16, fpst) | ||
44 | -DEF_HELPER_3(advsimd_divh, f16, f16, f16, fpst) | ||
45 | DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, fpst) | ||
46 | DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, fpst) | ||
47 | DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, fpst) | ||
48 | diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/arm/tcg/helper-a64.c | ||
51 | +++ b/target/arm/tcg/helper-a64.c | ||
52 | @@ -XXX,XX +XXX,XX @@ uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, float_status *fpst) \ | ||
53 | return float16_ ## name(a, b, fpst); \ | ||
38 | } | 54 | } |
39 | 55 | ||
40 | -- (void) updateUIInfo | 56 | -ADVSIMD_HALFOP(add) |
41 | +- (void) updateUIInfoLocked | 57 | -ADVSIMD_HALFOP(sub) |
42 | { | 58 | -ADVSIMD_HALFOP(mul) |
43 | + /* Must be called with the iothread lock, i.e. via updateUIInfo */ | 59 | -ADVSIMD_HALFOP(div) |
44 | NSSize frameSize; | 60 | -ADVSIMD_HALFOP(min) |
45 | QemuUIInfo info; | 61 | -ADVSIMD_HALFOP(max) |
46 | 62 | -ADVSIMD_HALFOP(minnum) | |
47 | @@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView; | 63 | -ADVSIMD_HALFOP(maxnum) |
48 | dpy_set_ui_info(dcl.con, &info, TRUE); | 64 | - |
65 | #define ADVSIMD_TWOHALFOP(name) \ | ||
66 | uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, \ | ||
67 | float_status *fpst) \ | ||
68 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/arm/tcg/translate-a64.c | ||
71 | +++ b/target/arm/tcg/translate-a64.c | ||
72 | @@ -XXX,XX +XXX,XX @@ static const FPScalar f_scalar_fmul = { | ||
73 | TRANS(FMUL_s, do_fp3_scalar, a, &f_scalar_fmul) | ||
74 | |||
75 | static const FPScalar f_scalar_fmax = { | ||
76 | - gen_helper_advsimd_maxh, | ||
77 | + gen_helper_vfp_maxh, | ||
78 | gen_helper_vfp_maxs, | ||
79 | gen_helper_vfp_maxd, | ||
80 | }; | ||
81 | TRANS(FMAX_s, do_fp3_scalar, a, &f_scalar_fmax) | ||
82 | |||
83 | static const FPScalar f_scalar_fmin = { | ||
84 | - gen_helper_advsimd_minh, | ||
85 | + gen_helper_vfp_minh, | ||
86 | gen_helper_vfp_mins, | ||
87 | gen_helper_vfp_mind, | ||
88 | }; | ||
89 | TRANS(FMIN_s, do_fp3_scalar, a, &f_scalar_fmin) | ||
90 | |||
91 | static const FPScalar f_scalar_fmaxnm = { | ||
92 | - gen_helper_advsimd_maxnumh, | ||
93 | + gen_helper_vfp_maxnumh, | ||
94 | gen_helper_vfp_maxnums, | ||
95 | gen_helper_vfp_maxnumd, | ||
96 | }; | ||
97 | TRANS(FMAXNM_s, do_fp3_scalar, a, &f_scalar_fmaxnm) | ||
98 | |||
99 | static const FPScalar f_scalar_fminnm = { | ||
100 | - gen_helper_advsimd_minnumh, | ||
101 | + gen_helper_vfp_minnumh, | ||
102 | gen_helper_vfp_minnums, | ||
103 | gen_helper_vfp_minnumd, | ||
104 | }; | ||
105 | @@ -XXX,XX +XXX,XX @@ static bool do_fp_reduction(DisasContext *s, arg_qrr_e *a, | ||
106 | return true; | ||
49 | } | 107 | } |
50 | 108 | ||
51 | +- (void) updateUIInfo | 109 | -TRANS_FEAT(FMAXNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_maxnumh) |
52 | +{ | 110 | -TRANS_FEAT(FMINNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_minnumh) |
53 | + if (!allow_events) { | 111 | -TRANS_FEAT(FMAXV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_maxh) |
54 | + /* | 112 | -TRANS_FEAT(FMINV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_minh) |
55 | + * Don't try to tell QEMU about UI information in the application | 113 | +TRANS_FEAT(FMAXNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_maxnumh) |
56 | + * startup phase -- we haven't yet registered dcl with the QEMU UI | 114 | +TRANS_FEAT(FMINNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_minnumh) |
57 | + * layer, and also trying to take the iothread lock would deadlock. | 115 | +TRANS_FEAT(FMAXV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_maxh) |
58 | + * When cocoa_display_init() does register the dcl, the UI layer | 116 | +TRANS_FEAT(FMINV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_minh) |
59 | + * will call cocoa_switch(), which will call updateUIInfo, so | 117 | |
60 | + * we don't lose any information here. | 118 | TRANS(FMAXNMV_s, do_fp_reduction, a, gen_helper_vfp_maxnums) |
61 | + */ | 119 | TRANS(FMINNMV_s, do_fp_reduction, a, gen_helper_vfp_minnums) |
62 | + return; | ||
63 | + } | ||
64 | + | ||
65 | + with_iothread_lock(^{ | ||
66 | + [self updateUIInfoLocked]; | ||
67 | + }); | ||
68 | +} | ||
69 | + | ||
70 | - (void)viewDidMoveToWindow | ||
71 | { | ||
72 | [self updateUIInfo]; | ||
73 | @@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl, | ||
74 | |||
75 | COCOA_DEBUG("qemu_cocoa: cocoa_switch\n"); | ||
76 | |||
77 | - [cocoaView updateUIInfo]; | ||
78 | - | ||
79 | // The DisplaySurface will be freed as soon as this callback returns. | ||
80 | // We take a reference to the underlying pixman image here so it does | ||
81 | // not disappear from under our feet; the switchSurface method will | ||
82 | @@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl, | ||
83 | pixman_image_ref(image); | ||
84 | |||
85 | dispatch_async(dispatch_get_main_queue(), ^{ | ||
86 | + [cocoaView updateUIInfo]; | ||
87 | [cocoaView switchSurface:image]; | ||
88 | }); | ||
89 | [pool release]; | ||
90 | -- | 120 | -- |
91 | 2.25.1 | 121 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | We should be using the F16-specific float_status for conversions from |
---|---|---|---|
2 | half-precision, because halfprec inputs never set Input Denormal. | ||
2 | 3 | ||
3 | Pass down the width of the output address from translation. | 4 | Without FEAT_AHP, using the wrong fpst here had no effect, because |
4 | For now this is still just PAMax, but a subsequent patch will | 5 | the only difference between the A64_F16 and A64 fpst is its handling |
5 | compute the correct value from TCR_ELx.{I}PS. | 6 | of flush-to-zero on input and output, and the helper functions |
7 | vfp_fcvt_f16_to_* and vfp_fcvt_*_to_f16 all explicitly squash the | ||
8 | relevant flushing flags, and flush_inputs_to_zero was the only way | ||
9 | that IDC could be set. | ||
6 | 10 | ||
7 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 11 | With FEAT_AHP, the FPCR.AH=1 behaviour sets IDC for |
8 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 12 | input_denormal_used, which we will only ignore in |
9 | Message-id: 20220301215958.157011-6-richard.henderson@linaro.org | 13 | vfp_get_fpsr_from_host() for the A64_F16 fpst; so it matters that we |
14 | use that one for f16 inputs (and the normal one for single/double to | ||
15 | f16 conversions). | ||
16 | |||
10 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 17 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
18 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
19 | Message-id: 20250124162836.2332150-27-peter.maydell@linaro.org | ||
11 | --- | 20 | --- |
12 | target/arm/helper.c | 21 ++++++++++----------- | 21 | target/arm/tcg/translate-a64.c | 9 ++++++--- |
13 | 1 file changed, 10 insertions(+), 11 deletions(-) | 22 | target/arm/tcg/translate-sve.c | 4 ++-- |
23 | 2 files changed, 8 insertions(+), 5 deletions(-) | ||
14 | 24 | ||
15 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 25 | diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c |
16 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/arm/helper.c | 27 | --- a/target/arm/tcg/translate-a64.c |
18 | +++ b/target/arm/helper.c | 28 | +++ b/target/arm/tcg/translate-a64.c |
19 | @@ -XXX,XX +XXX,XX @@ do_fault: | 29 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a) |
20 | * false otherwise. | 30 | if (fp_access_check(s)) { |
21 | */ | 31 | TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); |
22 | static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, | 32 | TCGv_i32 tcg_rd = tcg_temp_new_i32(); |
23 | - int inputsize, int stride) | 33 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64); |
24 | + int inputsize, int stride, int outputsize) | 34 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64_F16); |
25 | { | 35 | TCGv_i32 tcg_ahp = get_ahp_flag(); |
26 | const int grainsize = stride + 3; | 36 | |
27 | int startsizecheck; | 37 | gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); |
28 | @@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, | 38 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a) |
39 | if (fp_access_check(s)) { | ||
40 | TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); | ||
41 | TCGv_i64 tcg_rd = tcg_temp_new_i64(); | ||
42 | - TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64); | ||
43 | + TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64_F16); | ||
44 | TCGv_i32 tcg_ahp = get_ahp_flag(); | ||
45 | |||
46 | gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); | ||
47 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a) | ||
48 | return true; | ||
29 | } | 49 | } |
30 | 50 | ||
31 | if (is_aa64) { | 51 | - fpst = fpstatus_ptr(FPST_A64); |
32 | - CPUARMState *env = &cpu->env; | 52 | if (a->esz == MO_64) { |
33 | - unsigned int pamax = arm_pamax(cpu); | 53 | /* 32 -> 64 bit fp conversion */ |
34 | - | 54 | TCGv_i64 tcg_res[2]; |
35 | switch (stride) { | 55 | TCGv_i32 tcg_op = tcg_temp_new_i32(); |
36 | case 13: /* 64KB Pages. */ | 56 | int srcelt = a->q ? 2 : 0; |
37 | - if (level == 0 || (level == 1 && pamax <= 42)) { | 57 | |
38 | + if (level == 0 || (level == 1 && outputsize <= 42)) { | 58 | + fpst = fpstatus_ptr(FPST_A64); |
39 | return false; | 59 | + |
40 | } | 60 | for (pass = 0; pass < 2; pass++) { |
41 | break; | 61 | tcg_res[pass] = tcg_temp_new_i64(); |
42 | case 11: /* 16KB Pages. */ | 62 | read_vec_element_i32(s, tcg_op, a->rn, srcelt + pass, MO_32); |
43 | - if (level == 0 || (level == 1 && pamax <= 40)) { | 63 | @@ -XXX,XX +XXX,XX @@ static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a) |
44 | + if (level == 0 || (level == 1 && outputsize <= 40)) { | 64 | TCGv_i32 tcg_res[4]; |
45 | return false; | 65 | TCGv_i32 ahp = get_ahp_flag(); |
46 | } | 66 | |
47 | break; | 67 | + fpst = fpstatus_ptr(FPST_A64_F16); |
48 | case 9: /* 4KB Pages. */ | 68 | + |
49 | - if (level == 0 && pamax <= 42) { | 69 | for (pass = 0; pass < 4; pass++) { |
50 | + if (level == 0 && outputsize <= 42) { | 70 | tcg_res[pass] = tcg_temp_new_i32(); |
51 | return false; | 71 | read_vec_element_i32(s, tcg_res[pass], a->rn, srcelt + pass, MO_16); |
52 | } | 72 | diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c |
53 | break; | 73 | index XXXXXXX..XXXXXXX 100644 |
54 | @@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, | 74 | --- a/target/arm/tcg/translate-sve.c |
55 | } | 75 | +++ b/target/arm/tcg/translate-sve.c |
56 | 76 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz], | |
57 | /* Inputsize checks. */ | 77 | TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz, |
58 | - if (inputsize > pamax && | 78 | gen_helper_sve_fcvt_sh, a, 0, FPST_A64) |
59 | - (arm_el_is_aa64(env, 1) || inputsize > 40)) { | 79 | TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz, |
60 | + if (inputsize > outputsize && | 80 | - gen_helper_sve_fcvt_hs, a, 0, FPST_A64) |
61 | + (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) { | 81 | + gen_helper_sve_fcvt_hs, a, 0, FPST_A64_F16) |
62 | /* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */ | 82 | |
63 | return false; | 83 | TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, |
64 | } | 84 | gen_helper_sve_bfcvt, a, 0, FPST_A64) |
65 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | 85 | @@ -XXX,XX +XXX,XX @@ TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, |
66 | target_ulong page_size; | 86 | TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz, |
67 | uint32_t attrs; | 87 | gen_helper_sve_fcvt_dh, a, 0, FPST_A64) |
68 | int32_t stride; | 88 | TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz, |
69 | - int addrsize, inputsize; | 89 | - gen_helper_sve_fcvt_hd, a, 0, FPST_A64) |
70 | + int addrsize, inputsize, outputsize; | 90 | + gen_helper_sve_fcvt_hd, a, 0, FPST_A64_F16) |
71 | TCR *tcr = regime_tcr(env, mmu_idx); | 91 | TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz, |
72 | int ap, ns, xn, pxn; | 92 | gen_helper_sve_fcvt_ds, a, 0, FPST_A64) |
73 | uint32_t el = regime_el(env, mmu_idx); | 93 | TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz, |
74 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
75 | |||
76 | addrsize = 64 - 8 * param.tbi; | ||
77 | inputsize = 64 - param.tsz; | ||
78 | + outputsize = arm_pamax(cpu); | ||
79 | } else { | ||
80 | param = aa32_va_parameters(env, address, mmu_idx); | ||
81 | level = 1; | ||
82 | addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32); | ||
83 | inputsize = addrsize - param.tsz; | ||
84 | + outputsize = 40; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | @@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, | ||
89 | |||
90 | /* Check that the starting level is valid. */ | ||
91 | ok = check_s2_mmu_setup(cpu, aarch64, startlevel, | ||
92 | - inputsize, stride); | ||
93 | + inputsize, stride, outputsize); | ||
94 | if (!ok) { | ||
95 | fault_type = ARMFault_Translation; | ||
96 | goto do_fault; | ||
97 | -- | 94 | -- |
98 | 2.25.1 | 95 | 2.34.1 | diff view generated by jsdifflib |
1 | From: Richard Henderson <richard.henderson@linaro.org> | 1 | From: Hongren Zheng <i@zenithal.me> |
---|---|---|---|
2 | 2 | ||
3 | The original A.a revision of the AArch64 ARM required that we | 3 | When USBPacket in OUT direction has larger payload |
4 | force-extend the addresses in these registers from 49 bits. | 4 | than the ep_out_buffer (of size 512), a buffer overflow |
5 | This language has been loosened via a combination of IMPLEMENTATION | 5 | would occur. |
6 | DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of | ||
7 | the entire aligned address. | ||
8 | 6 | ||
9 | This means that we do not have to consider whether or not FEAT_LVA | 7 | It could be fixed by limiting the size of usb_packet_copy |
10 | is enabled, and decide from which bit an address might need to be | 8 | to be at most buffer size. Further optimization gets rid |
11 | extended. | 9 | of the ep_out_buffer and directly uses ep_out as the target |
10 | buffer. | ||
12 | 11 | ||
12 | This is reported by a security researcher who artificially | ||
13 | constructed an OUT packet of size 2047. The report has gone | ||
14 | through the QEMU security process, and as this device is for | ||
15 | testing purpose and no deployment of it in virtualization | ||
16 | environment is observed, it is triaged not to be a security bug. | ||
17 | |||
18 | Cc: qemu-stable@nongnu.org | ||
19 | Fixes: d7d34918551dc48 ("hw/usb: Add CanoKey Implementation") | ||
20 | Reported-by: Juan Jose Lopez Jaimez <thatjiaozi@gmail.com> | ||
21 | Signed-off-by: Hongren Zheng <i@zenithal.me> | ||
22 | Message-id: Z4TfMOrZz6IQYl_h@Sun | ||
13 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 23 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> |
14 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
15 | Message-id: 20220301215958.157011-9-richard.henderson@linaro.org | ||
16 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> | 24 | Signed-off-by: Peter Maydell <peter.maydell@linaro.org> |
17 | --- | 25 | --- |
18 | target/arm/helper.c | 32 ++++++++++++++++++++++++-------- | 26 | hw/usb/canokey.h | 4 ---- |
19 | 1 file changed, 24 insertions(+), 8 deletions(-) | 27 | hw/usb/canokey.c | 6 +++--- |
28 | 2 files changed, 3 insertions(+), 7 deletions(-) | ||
20 | 29 | ||
21 | diff --git a/target/arm/helper.c b/target/arm/helper.c | 30 | diff --git a/hw/usb/canokey.h b/hw/usb/canokey.h |
22 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/arm/helper.c | 32 | --- a/hw/usb/canokey.h |
24 | +++ b/target/arm/helper.c | 33 | +++ b/hw/usb/canokey.h |
25 | @@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri, | 34 | @@ -XXX,XX +XXX,XX @@ |
26 | ARMCPU *cpu = env_archcpu(env); | 35 | #define CANOKEY_EP_NUM 3 |
27 | int i = ri->crm; | 36 | /* BULK/INTR IN can be up to 1352 bytes, e.g. get key info */ |
28 | 37 | #define CANOKEY_EP_IN_BUFFER_SIZE 2048 | |
29 | - /* Bits [63:49] are hardwired to the value of bit [48]; that is, the | 38 | -/* BULK OUT can be up to 270 bytes, e.g. PIV import cert */ |
30 | - * register reads and behaves as if values written are sign extended. | 39 | -#define CANOKEY_EP_OUT_BUFFER_SIZE 512 |
31 | + /* | 40 | |
32 | * Bits [1:0] are RES0. | 41 | typedef enum { |
33 | + * | 42 | CANOKEY_EP_IN_WAIT, |
34 | + * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA) | 43 | @@ -XXX,XX +XXX,XX @@ typedef struct CanoKeyState { |
35 | + * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if | 44 | /* OUT pointer to canokey recv buffer */ |
36 | + * they contain the value written. It is CONSTRAINED UNPREDICTABLE | 45 | uint8_t *ep_out[CANOKEY_EP_NUM]; |
37 | + * whether the RESS bits are ignored when comparing an address. | 46 | uint32_t ep_out_size[CANOKEY_EP_NUM]; |
38 | + * | 47 | - /* For large BULK OUT, multiple write to ep_out is needed */ |
39 | + * Therefore we are allowed to compare the entire register, which lets | 48 | - uint8_t ep_out_buffer[CANOKEY_EP_NUM][CANOKEY_EP_OUT_BUFFER_SIZE]; |
40 | + * us avoid considering whether or not FEAT_LVA is actually enabled. | 49 | |
41 | */ | 50 | /* Properties */ |
42 | - value = sextract64(value, 0, 49) & ~3ULL; | 51 | char *file; /* canokey-file */ |
43 | + value &= ~3ULL; | 52 | diff --git a/hw/usb/canokey.c b/hw/usb/canokey.c |
44 | 53 | index XXXXXXX..XXXXXXX 100644 | |
45 | raw_write(env, ri, value); | 54 | --- a/hw/usb/canokey.c |
46 | hw_watchpoint_update(cpu, i); | 55 | +++ b/hw/usb/canokey.c |
47 | @@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n) | 56 | @@ -XXX,XX +XXX,XX @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p) |
48 | case 0: /* unlinked address match */ | 57 | switch (p->pid) { |
49 | case 1: /* linked address match */ | 58 | case USB_TOKEN_OUT: |
50 | { | 59 | trace_canokey_handle_data_out(ep_out, p->iov.size); |
51 | - /* Bits [63:49] are hardwired to the value of bit [48]; that is, | 60 | - usb_packet_copy(p, key->ep_out_buffer[ep_out], p->iov.size); |
52 | - * we behave as if the register was sign extended. Bits [1:0] are | 61 | out_pos = 0; |
53 | - * RES0. The BAS field is used to allow setting breakpoints on 16 | 62 | + /* segment packet into (possibly multiple) ep_out */ |
54 | - * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether | 63 | while (out_pos != p->iov.size) { |
55 | + /* | 64 | /* |
56 | + * Bits [1:0] are RES0. | 65 | * key->ep_out[ep_out] set by prepare_receive |
57 | + * | 66 | @@ -XXX,XX +XXX,XX @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p) |
58 | + * It is IMPLEMENTATION DEFINED whether bits [63:49] | 67 | * to be the buffer length |
59 | + * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit | 68 | */ |
60 | + * of the VA field ([48] or [52] for FEAT_LVA), or whether the | 69 | out_len = MIN(p->iov.size - out_pos, key->ep_out_size[ep_out]); |
61 | + * value is read as written. It is CONSTRAINED UNPREDICTABLE | 70 | - memcpy(key->ep_out[ep_out], |
62 | + * whether the RESS bits are ignored when comparing an address. | 71 | - key->ep_out_buffer[ep_out] + out_pos, out_len); |
63 | + * Therefore we are allowed to compare the entire register, which | 72 | + /* usb_packet_copy would update the pos offset internally */ |
64 | + * lets us avoid considering whether FEAT_LVA is actually enabled. | 73 | + usb_packet_copy(p, key->ep_out[ep_out], out_len); |
65 | + * | 74 | out_pos += out_len; |
66 | + * The BAS field is used to allow setting breakpoints on 16-bit | 75 | /* update ep_out_size to actual len */ |
67 | + * wide instructions; it is CONSTRAINED UNPREDICTABLE whether | 76 | key->ep_out_size[ep_out] = out_len; |
68 | * a bp will fire if the addresses covered by the bp and the addresses | ||
69 | * covered by the insn overlap but the insn doesn't start at the | ||
70 | * start of the bp address range. We choose to require the insn and | ||
71 | @@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n) | ||
72 | * See also figure D2-3 in the v8 ARM ARM (DDI0487A.c). | ||
73 | */ | ||
74 | int bas = extract64(bcr, 5, 4); | ||
75 | - addr = sextract64(bvr, 0, 49) & ~3ULL; | ||
76 | + addr = bvr & ~3ULL; | ||
77 | if (bas == 0) { | ||
78 | return; | ||
79 | } | ||
80 | -- | 77 | -- |
81 | 2.25.1 | 78 | 2.34.1 | diff view generated by jsdifflib |