* [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!)
@ 2026-02-24 12:10 Alex Bennée
2026-02-24 12:10 ` [PATCH 1/8] target/arm: set the correct TI bits for WFIT traps Alex Bennée
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
*************************************************************************
** GenAI was used in the production of this series, it is not intended **
** for merging but an experiment to explore the capabilities of the **
** current models and perhaps inform future discussions. There is no **
** obligation to review this code. **
*************************************************************************
This order and layout of this series is a little unusual as I've
included patches for tooling which wouldn't normally be included. This
includes the PLAN.md which obviously wouldn't be something you keep in
the tree.
I've also included fixup patches where I cleaned up after the agent had a
go. I also have noted what tweaks I've made to the agent commits under
the ---. The patches with my s-o-b are pure human generated.
I decided to try this experiment when fixing the WFIT syndrome data
and could see a larger re-factoring would be needed to properly handle
the RN/RD fields of the ISS. In total I've spent about 6 hours (3
idly prompting the agent on a Sunday afternoon and 3 actually
debugging and following up on failures). The total API cost was about
£1.60 which means it didn't need to save much of my time to make it
worthwhile. The model used was gemini-3-flash-preview driven by Editor
Code Assistant (https://eca.dev) in my Emacs session.
My impression is it did help me get something working faster than if
I'd gone from scratch. Even though the agent failed to account for GIC
and page table device mapping it was helped that it was being driven
by someone with a fairly good understanding of QEMU's internals.
Rather than leaving it to figure out why it was seeing data aborts I
was able to quickly theorise the reason (no mapping) and direct it to
add the needed support. I suspect it would have taken me longer to get
through that bit myself because I would be digging into the
kvm-unit-test code or re-reading the page table format documentation.
When IRQs weren't firing feeding results of the test case with the
additional "-d trace:gic\*" debug output gave the model enough context
to figure out what it had missed in the setup.
Despite the plan it smooshed a lot of stuff into each commit which
make them not ideal for review.
From what I've seen in this example the potential for inadvertent
copyright infringement is fairly low. Certainly the TCG code was
following existing styles for QEMU code and the page table setup was a
straight evolution. I'm not sure if the gic initialisation code would
count as novel enough to be copyrightable anyway.
As a first draft I think it worked quite well. To actually turn it
into a proper series I would break the code apart into much more
discreet steps and include re-factor steps before functionality
changes. For example the addition of the rd field to the helper while
correct missed the fact the timeout from rd is also in the args. I
would have just pushed the reading of rd into the helper instead.
I think it might be worth going through those steps to make a "proper"
series and seeing how different a pure human series would make.
However having a working reference with tests will be pretty helpful.
Any thoughts?
Alex.
Alex Bennée (8):
target/arm: set the correct TI bits for WFIT traps
.eca: basic configuration for Editor Code Assistant
AGENTS.md: add basic AGENTS.md for QEMU
PLAN.md: add plan for the current work
target/arm: extend WFX support for A-profile
tests/tcg/aarch64: Add WFX instructions system test
tests/tcg/aarch64: fixes for WFX instructions system test
target/arm: fixes for WFx[T] support
target/arm/syndrome.h | 24 ++++-
target/arm/tcg/helper-defs.h | 3 +-
tests/tcg/aarch64/system/lib/gicv3.h | 56 ++++++++++
target/arm/tcg/a64.decode | 3 +-
target/arm/cpu.c | 6 +-
target/arm/tcg/op_helper.c | 101 +++++++++++------
target/arm/tcg/translate-a64.c | 27 +++--
target/arm/tcg/translate.c | 4 +-
tests/tcg/aarch64/system/lib/gicv3.c | 77 +++++++++++++
tests/tcg/aarch64/system/wfx.c | 126 ++++++++++++++++++++++
.eca/config.json | 43 ++++++++
.eca/skills/checkpatch/SKILL.md | 9 ++
.eca/skills/gtags/SKILL.md | 7 ++
AGENTS.md | 18 ++++
PLAN.md | 77 +++++++++++++
tests/tcg/aarch64/Makefile.softmmu-target | 15 ++-
tests/tcg/aarch64/system/boot.S | 55 ++++++----
17 files changed, 579 insertions(+), 72 deletions(-)
create mode 100644 tests/tcg/aarch64/system/lib/gicv3.h
create mode 100644 tests/tcg/aarch64/system/lib/gicv3.c
create mode 100644 tests/tcg/aarch64/system/wfx.c
create mode 100644 .eca/config.json
create mode 100644 .eca/skills/checkpatch/SKILL.md
create mode 100644 .eca/skills/gtags/SKILL.md
create mode 100644 AGENTS.md
create mode 100644 PLAN.md
--
2.47.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/8] target/arm: set the correct TI bits for WFIT traps
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:10 ` [PATCH 2/8] .eca: basic configuration for Editor Code Assistant Alex Bennée
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
The WFIT trap should be reported as 0b10.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/tcg/op_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index 4d708635068..aa14f15eb62 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -448,7 +448,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
if (target_el) {
env->pc -= 4;
- raise_exception(env, excp, syn_wfx(1, 0xe, 0, false), target_el);
+ raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
}
if (uadd64_overflow(timeout, offset, &nexttick)) {
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/8] .eca: basic configuration for Editor Code Assistant
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
2026-02-24 12:10 ` [PATCH 1/8] target/arm: set the correct TI bits for WFIT traps Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:10 ` [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU Alex Bennée
` (5 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
This is a basic configuration for eca which is a editor agnostic frame
work for connecting skills and tools to an agententic workflow. This
is important if you don't want to be tied to a particular platforms
editor choice.
These would often be user specific but I've included them in this
series to show what sort of things they can do.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
.eca/config.json | 43 +++++++++++++++++++++++++++++++++
.eca/skills/checkpatch/SKILL.md | 9 +++++++
.eca/skills/gtags/SKILL.md | 7 ++++++
3 files changed, 59 insertions(+)
create mode 100644 .eca/config.json
create mode 100644 .eca/skills/checkpatch/SKILL.md
create mode 100644 .eca/skills/gtags/SKILL.md
diff --git a/.eca/config.json b/.eca/config.json
new file mode 100644
index 00000000000..81b0c97782e
--- /dev/null
+++ b/.eca/config.json
@@ -0,0 +1,43 @@
+{
+ "customTools": {
+ "gtag_find_symbol_definition": {
+ "description": "Use GNU global tags to search for the symbol defintion. Return in ctags-x format",
+ "command": "global --result ctags-x -d {{pattern}}",
+ "schema": {
+ "properties": {
+ "pattern": {
+ "type": "string",
+ "description": "an extended regex pattern or literal string to search for"
+ }
+ },
+ "required": ["pattern"]
+ }
+ },
+ "gtag_find_symbol_completions": {
+ "description": "Use GNU global tags to list potential symbol completions for a word stem.",
+ "command": "global -c {{stem}}",
+ "schema": {
+ "properties": {
+ "stem": {
+ "type": "string",
+ "description": "an string stem of a symbol"
+ }
+ },
+ "required": ["stem"]
+ }
+ },
+ "gtag_find_symbol_references": {
+ "description": "Use GNU global tags to find references to a symbol. Returns results in ctags-x format.",
+ "command": "global --results ctags-x -r {{pattern}}",
+ "schema": {
+ "properties": {
+ "pattern": {
+ "type": "string",
+ "description": "an extended regex pattern or literal string to search for."
+ }
+ },
+ "required": ["pattern"]
+ }
+ }
+ }
+}
diff --git a/.eca/skills/checkpatch/SKILL.md b/.eca/skills/checkpatch/SKILL.md
new file mode 100644
index 00000000000..49c556bed2e
--- /dev/null
+++ b/.eca/skills/checkpatch/SKILL.md
@@ -0,0 +1,9 @@
+---
+name: checkpatch
+description: run checkpatch on a file or patch to validate style issues
+---
+
+# Instructions
+Run `./scripts/checkpatch.pl [FILE]` to check a file for style issues.
+
+You can also use a GIT-REV-LIST to check against git, e.g. run `./scripts/checkpatch.pl HEAD^..` to run checkpatch on the last commit.
diff --git a/.eca/skills/gtags/SKILL.md b/.eca/skills/gtags/SKILL.md
new file mode 100644
index 00000000000..b158981b1ae
--- /dev/null
+++ b/.eca/skills/gtags/SKILL.md
@@ -0,0 +1,7 @@
+---
+name: update gtags
+description: update the GNU global tags file.
+---
+
+# Instructions
+Run `make gtags` in the root of the source tree.
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
2026-02-24 12:10 ` [PATCH 1/8] target/arm: set the correct TI bits for WFIT traps Alex Bennée
2026-02-24 12:10 ` [PATCH 2/8] .eca: basic configuration for Editor Code Assistant Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-03-20 16:01 ` Daniel P. Berrangé
2026-02-24 12:10 ` [PATCH 4/8] PLAN.md: add plan for the current work Alex Bennée
` (4 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
This was written by ECA based on it's initial understanding of the
code base. It's mostly quick facts and pointers to common tasks.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
ajb:
- I made a slight tweak to use pyenv to run single tests
---
AGENTS.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 AGENTS.md
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000000..5b54763f4b1
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,18 @@
+# QEMU Agent Guide
+
+## Build & Test
+- **Build**: `ninja -C build` (from build directory) or `make`
+- **Test All**: `make check`
+- **Single Test**: `./pyvenv/bin/meson test <testname>` (e.g., `meson test qtest-x86_64/boot-serial-test`)
+- **Suites**: `make check-unit`, `make check-qtest`, `make check-functional`, `make check-rust`
+- **Debug**: Append `V=1` for verbose output or `DEBUG=1` for interactive test debugging.
+
+## Code Style
+- **Formatting**: 4-space indents, NO tabs, 80-char line limit (max 100).
+- **C Braces**: Mandatory for all blocks (if/while/for). Open brace on same line (except functions).
+- **C Includes**: `#include "qemu/osdep.h"` MUST be the first include in every `.c` file.
+- **C Comments**: Use `/* ... */` only. No `//` comments.
+- **Naming**: `snake_case` for variables and functions; `CamelCase` for types and enums.
+- **Memory**: Use GLib (`g_malloc`, `g_free`, `g_autofree`) or QEMU (`qemu_memalign`) APIs. No `malloc`.
+- **Errors**: Use `error_report()` or `error_setg()`. Avoid `printf` for errors.
+- **Lints**: Run `./scripts/checkpatch.pl` on C patches. Use `make clippy` and `make rustfmt` for Rust.
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/8] PLAN.md: add plan for the current work
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
` (2 preceding siblings ...)
2026-02-24 12:10 ` [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:10 ` [PATCH 5/8] target/arm: extend WFX support for A-profile Alex Bennée
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
This is entirely generated by ECA/Gemini using the
gemini-3-flash-preview model. My initial prompt was:
I want to generate a PLAN.md for a piece of development work. Recently
support for WFE was added for M-profile but I want to extend that
support to A-profile along side proper semantics for WFI, WFE, WFIT
and WFET instructions. That includes setting the full ISS fields for
the traps (RN and RV fields of the ISS encoding from WF* intructions).
See syn_wfx() for where we currently build this up. Keep in mind we
want each commit to be kept small and review-able while maintaining
bisect-ability. We also should think about how we can test and defend
the functionality in QEMU's testing suite.
This will form the "guide" for the agents next steps.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
PLAN.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
create mode 100644 PLAN.md
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 00000000000..49f330b802d
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,77 @@
+# Plan: Extend WFX Support for A-profile
+
+This document outlines the plan to extend WFE support to A-profile ARM and ensure proper semantics for WFI, WFE, WFIT, and WFET instructions, including full ISS field support for traps.
+
+## 1. Syndrome Enhancements
+
+### 1.1 Update `syn_wfx` in `target/arm/syndrome.h`
+- Modify `syn_wfx` to include `rd` (RN) and `rv` (Register Valid) fields.
+- Ensure the bitfields match the ARM ARM for EC 0x01.
+- Bit layout:
+ - ISS[24]: CV
+ - ISS[23:20]: COND
+ - ISS[19:15]: RN (rd)
+ - ISS[14]: RV
+ - ISS[1:0]: TI
+
+### 1.2 Update WFX Syndrome Construction in Helpers
+- In `target/arm/tcg/op_helper.c`, update `HELPER(wfi)`, `HELPER(wfit)`, and implement `HELPER(wfet)` to:
+ - Check `is_a64(env)`.
+ - For AArch64: Set `cv = 0` and `cond = 0xf`.
+ - For AArch32: Maintain `cv = 1` and `cond = 0xe` (or pass the actual condition).
+ - Pass the correct `rd` and `rv` based on the instruction.
+
+## 2. Instruction Helpers and Translation
+
+### 2.1 Update `HELPER(wfit)` and `trans_WFIT`
+- Change `HELPER(wfit)` to accept the register number `rd`.
+- Update `trans_WFIT` in `target/arm/tcg/translate-a64.c` to pass `a->rd`.
+
+### 2.2 Implement `HELPER(wfet)` and update `trans_WFET`
+- Create `HELPER(wfet)` in `op_helper.c`. It should:
+ - Check for traps using `check_wfx_trap(env, true, &excp)`.
+ - If trapped, raise exception with `ti=1` and `rv=true, rd=rd`.
+ - If not trapped, check `event_register` and timeout.
+- Update `trans_WFET` to call the new helper instead of just setting `DISAS_WFE`.
+
+### 2.3 Refactor `HELPER(wfe)` for A-profile
+- Update `HELPER(wfe)` to handle A-profile:
+ - Check for traps using `check_wfx_trap(env, true, &excp)`.
+ - If trapped, raise exception.
+ - If not trapped:
+ - If `env->event_register` is set, clear it and return.
+ - Otherwise, halt the CPU (`cs->halted = 1`, `cs->exception_index = EXCP_HLT`, `cpu_loop_exit`).
+
+## 3. Wake-up Logic and Event Register
+
+### 3.1 Update `HELPER(sev)`
+- Ensure `event_register` is set for all CPUs, not just M-profile.
+- Kick all other CPUs to wake them from `EXCP_HLT`.
+
+### 3.2 Update `arm_cpu_has_work`
+- Modify `target/arm/cpu.c` to check `event_register` for A-profile CPUs as well.
+- This ensures that a CPU halted by WFE wakes up when the event register is set.
+
+## 4. Testing and Verification
+
+### 4.1 TCG Tests
+- Add a new test case in `tests/tcg/aarch64` that:
+ - Executes WFI, WFE, WFIT, WFET.
+ - Verifies that WFE/WFI halt the CPU and can be woken up.
+ - (Optional) Exercises traps by running at EL0 with SCTLR_EL1.nTWE/nTWI = 0 and verifying the syndrome in a signal handler or a small EL1 kernel.
+
+### 4.2 Regression Testing
+- Ensure no regressions for M-profile WFE.
+- Run `make check-qtest` and `make check-tcg`.
+
+## Commit Breakdown (Proposed)
+
+1. `target/arm: Update syn_wfx to include RN and RV`
+2. `target/arm: Update HELPER(wfi) to use correct CV/COND for AArch64`
+3. `target/arm: Update HELPER(wfit) to accept rd and use correct syndrome`
+4. `target/arm: Implement HELPER(wfet) and update trans_WFET`
+5. `target/arm: Update HELPER(wfe) to implement proper A-profile semantics`
+6. `target/arm: Update HELPER(sev) and arm_cpu_has_work for A-profile event register`
+7. `tests/tcg/aarch64: Add tests for WFX instructions`
+
+🤖 Generated with [eca](https://eca.dev)
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/8] target/arm: extend WFX support for A-profile
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
` (3 preceding siblings ...)
2026-02-24 12:10 ` [PATCH 4/8] PLAN.md: add plan for the current work Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:26 ` Peter Maydell
2026-02-24 12:10 ` [PATCH 6/8] tests/tcg/aarch64: Add WFX instructions system test Alex Bennée
` (2 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée, eca
This commit extends support for WFI, WFE, WFIT, and WFET instructions
for A-profile ARM CPUs, ensuring proper architectural semantics and
full ISS (Instruction Specific Syndrome) field support for traps.
Key changes:
- Update `syn_wfx` in `target/arm/syndrome.h` to include `RN` (register
number) and `RV` (register valid) fields using `registerfields.h`
macros.
- Refactor `HELPER(wfi)` and `HELPER(wfit)` to use correct AArch64
syndrome values (CV=0, COND=0xf).
- Implement `HELPER(wfet)` and update `trans_WFET` to support the new
Wait For Event with Timeout instruction.
- Update `HELPER(wfe)` to implement proper A-profile semantics,
including trap checks and event register handling.
- Extend `event_register` handling to all ARM CPUs (not just M-profile)
by updating `HELPER(sev)` and `arm_cpu_has_work`.
- Declare WFxT helpers as `TCG_CALL_NO_WG` as they can raise
exceptions.
🤖 Generated with [eca](https://eca.dev)
Co-Authored-By: eca <noreply@eca.dev>
---
ajb
- this commit is a bit big, it didn't follow the instructions to
keep the commits small
- I had to add DEF_HELPER_FLAGS_3 to the helpers as it didn't
realise we need to ensure rd is potentially rectified.
---
target/arm/syndrome.h | 24 ++++++--
target/arm/tcg/helper-defs.h | 3 +-
target/arm/cpu.c | 6 +-
target/arm/tcg/op_helper.c | 101 +++++++++++++++++++++++----------
target/arm/tcg/translate-a64.c | 17 +++---
5 files changed, 104 insertions(+), 47 deletions(-)
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index bff61f052cc..49861758262 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -26,6 +26,7 @@
#define TARGET_ARM_SYNDROME_H
#include "qemu/bitops.h"
+#include "hw/core/registerfields.h"
/* Valid Syndrome Register EC field values */
enum arm_exception_class {
@@ -352,11 +353,26 @@ static inline uint32_t syn_breakpoint(int same_el)
| ARM_EL_IL | 0x22;
}
-static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
+FIELD(WFX_ISS, TI, 0, 2)
+FIELD(WFX_ISS, RV, 14, 1)
+FIELD(WFX_ISS, RN, 15, 5)
+FIELD(WFX_ISS, COND, 20, 4)
+FIELD(WFX_ISS, CV, 24, 1)
+
+static inline uint32_t syn_wfx(int cv, int cond, int rd, int rv, int ti, bool is_16bit)
{
- return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
- (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
- (cv << 24) | (cond << 20) | ti;
+ uint32_t res = (EC_WFX_TRAP << ARM_EL_EC_SHIFT);
+
+ res = FIELD_DP32(res, WFX_ISS, CV, cv);
+ res = FIELD_DP32(res, WFX_ISS, COND, cond);
+ res = FIELD_DP32(res, WFX_ISS, RN, rd);
+ res = FIELD_DP32(res, WFX_ISS, RV, rv);
+ res = FIELD_DP32(res, WFX_ISS, TI, ti);
+
+ if (!is_16bit) {
+ res |= ARM_EL_IL;
+ }
+ return res;
}
static inline uint32_t syn_illegalstate(void)
diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h
index 5a10a9fba3b..d54eb63eef6 100644
--- a/target/arm/tcg/helper-defs.h
+++ b/target/arm/tcg/helper-defs.h
@@ -55,7 +55,8 @@ DEF_HELPER_2(exception_pc_alignment, noreturn, env, vaddr)
DEF_HELPER_1(setend, void, env)
DEF_HELPER_2(wfi, void, env, i32)
DEF_HELPER_1(wfe, void, env)
-DEF_HELPER_2(wfit, void, env, i64)
+DEF_HELPER_FLAGS_3(wfit, TCG_CALL_NO_WG, void, env, i64, i32)
+DEF_HELPER_FLAGS_3(wfet, TCG_CALL_NO_WG, void, env, i64, i32)
DEF_HELPER_1(yield, void, env)
DEF_HELPER_1(pre_hvc, void, env)
DEF_HELPER_2(pre_smc, void, env, i32)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 10f8280eef2..bc789515af9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -144,10 +144,8 @@ static bool arm_cpu_has_work(CPUState *cs)
{
ARMCPU *cpu = ARM_CPU(cs);
- if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
- if (cpu->env.event_register) {
- return true;
- }
+ if (cpu->env.event_register) {
+ return true;
}
return (cpu->power_state != PSCI_OFF)
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index aa14f15eb62..37538daea74 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -393,13 +393,17 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
}
if (target_el) {
- if (env->aarch64) {
+ int cv = 1, cond = 0xe;
+
+ if (is_a64(env)) {
env->pc -= insn_len;
+ cv = 0;
+ cond = 0xf;
} else {
env->regs[15] -= insn_len;
}
- raise_exception(env, excp, syn_wfx(1, 0xe, 0, insn_len == 2),
+ raise_exception(env, excp, syn_wfx(cv, cond, 0, 0, 0, insn_len == 2),
target_el);
}
@@ -409,7 +413,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
#endif
}
-void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
+void HELPER(wfit)(CPUARMState *env, uint64_t timeout, uint32_t rd)
{
#ifdef CONFIG_USER_ONLY
/*
@@ -448,7 +452,7 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
if (target_el) {
env->pc -= 4;
- raise_exception(env, excp, syn_wfx(1, 0xe, 2, false), target_el);
+ raise_exception(env, excp, syn_wfx(0, 0xf, rd, 1, 2, false), target_el);
}
if (uadd64_overflow(timeout, offset, &nexttick)) {
@@ -469,14 +473,50 @@ void HELPER(wfit)(CPUARMState *env, uint64_t timeout)
#endif
}
+void HELPER(wfet)(CPUARMState *env, uint64_t timeout, uint32_t rd)
+{
+#ifdef CONFIG_USER_ONLY
+ return;
+#else
+ ARMCPU *cpu = env_archcpu(env);
+ CPUState *cs = env_cpu(env);
+ uint32_t excp;
+ int target_el = check_wfx_trap(env, true, &excp);
+ uint64_t cntval = gt_get_countervalue(env);
+ uint64_t offset = gt_direct_access_timer_offset(env, GTIMER_VIRT);
+ uint64_t cntvct = cntval - offset;
+ uint64_t nexttick;
+
+ if (env->event_register || cpu_has_work(cs) || cntvct >= timeout) {
+ env->event_register = false;
+ return;
+ }
+
+ if (target_el) {
+ env->pc -= 4;
+ raise_exception(env, excp, syn_wfx(0, 0xf, rd, 1, 3, false), target_el);
+ }
+
+ if (uadd64_overflow(timeout, offset, &nexttick)) {
+ nexttick = UINT64_MAX;
+ }
+ if (nexttick > INT64_MAX / gt_cntfrq_period_ns(cpu)) {
+ timer_mod_ns(cpu->wfxt_timer, INT64_MAX);
+ } else {
+ timer_mod(cpu->wfxt_timer, nexttick);
+ }
+ cs->exception_index = EXCP_HLT;
+ cs->halted = 1;
+ cpu_loop_exit(cs);
+#endif
+}
+
void HELPER(sev)(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
CPU_FOREACH(cs) {
ARMCPU *target_cpu = ARM_CPU(cs);
- if (arm_feature(&target_cpu->env, ARM_FEATURE_M)) {
- target_cpu->env.event_register = true;
- }
+ target_cpu->env.event_register = true;
if (!qemu_cpu_is_self(cs)) {
qemu_cpu_kick(cs);
}
@@ -493,33 +533,34 @@ void HELPER(wfe)(CPUARMState *env)
*/
return;
#else
- /*
- * WFE (Wait For Event) is a hint instruction.
- * For Cortex-M (M-profile), we implement the strict architectural behavior:
- * 1. Check the Event Register (set by SEV or SEVONPEND).
- * 2. If set, clear it and continue (consume the event).
- */
- if (arm_feature(env, ARM_FEATURE_M)) {
- CPUState *cs = env_cpu(env);
+ CPUState *cs = env_cpu(env);
+ uint32_t excp;
+ int target_el = check_wfx_trap(env, true, &excp);
- if (env->event_register) {
- env->event_register = false;
- return;
+ if (env->event_register) {
+ env->event_register = false;
+ return;
+ }
+
+ if (target_el) {
+ bool is_16bit = false;
+ if (is_a64(env)) {
+ env->pc -= 4;
+ } else {
+ is_16bit = env->thumb;
+ env->regs[15] -= (is_16bit ? 2 : 4);
}
- cs->exception_index = EXCP_HLT;
- cs->halted = 1;
- cpu_loop_exit(cs);
- } else {
- /*
- * For A-profile and others, we rely on the existing "yield" behavior.
- * Don't actually halt the CPU, just yield back to top
- * level loop. This is not going into a "low power state"
- * (ie halting until some event occurs), so we never take
- * a configurable trap to a different exception level
- */
- HELPER(yield)(env);
+ raise_exception(env, excp,
+ syn_wfx(is_a64(env) ? 0 : 1,
+ is_a64(env) ? 0xf : 0xe,
+ 0, 0, 1, is_16bit),
+ target_el);
}
+
+ cs->exception_index = EXCP_HLT;
+ cs->halted = 1;
+ cpu_loop_exit(cs);
#endif
}
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5d261a5e32b..f76a00d1329 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -2064,7 +2064,7 @@ static bool trans_WFIT(DisasContext *s, arg_WFIT *a)
}
gen_a64_update_pc(s, 4);
- gen_helper_wfit(tcg_env, cpu_reg(s, a->rd));
+ gen_helper_wfit(tcg_env, cpu_reg(s, a->rd), tcg_constant_i32(a->rd));
/* Go back to the main loop to check for interrupts */
s->base.is_jmp = DISAS_EXIT;
return true;
@@ -2076,14 +2076,15 @@ static bool trans_WFET(DisasContext *s, arg_WFET *a)
return false;
}
- /*
- * We rely here on our WFE implementation being a NOP, so we
- * don't need to do anything different to handle the WFET timeout
- * from what trans_WFE does.
- */
- if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
- s->base.is_jmp = DISAS_WFE;
+ if (s->ss_active) {
+ /* Act like a NOP under architectural singlestep */
+ return true;
}
+
+ gen_a64_update_pc(s, 4);
+ gen_helper_wfet(tcg_env, cpu_reg(s, a->rd), tcg_constant_i32(a->rd));
+ /* Go back to the main loop to check for interrupts */
+ s->base.is_jmp = DISAS_EXIT;
return true;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/8] tests/tcg/aarch64: Add WFX instructions system test
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
` (4 preceding siblings ...)
2026-02-24 12:10 ` [PATCH 5/8] target/arm: extend WFX support for A-profile Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:10 ` [PATCH 7/8] tests/tcg/aarch64: fixes for " Alex Bennée
2026-02-24 12:10 ` [PATCH 8/8] target/arm: fixes for WFx[T] support Alex Bennée
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée, eca
This commit adds a new system-mode TCG test to verify the behavior of
WFI, WFE, WFIT, and WFET instructions on AArch64.
The test ensures:
- WFI correctly wakes on a timer interrupt.
- WFE returns immediately if the event register is set (via SEV).
- WFIT and WFET correctly sleep until the specified timeout.
🤖 Generated with [eca](https://eca.dev)
Co-Authored-By: eca <noreply@eca.dev>
---
ajb:
- removed an excess setting of QEMU_OPTS in the Makefile
---
tests/tcg/aarch64/system/wfx.c | 113 ++++++++++++++++++++++
tests/tcg/aarch64/Makefile.softmmu-target | 2 +
2 files changed, 115 insertions(+)
create mode 100644 tests/tcg/aarch64/system/wfx.c
diff --git a/tests/tcg/aarch64/system/wfx.c b/tests/tcg/aarch64/system/wfx.c
new file mode 100644
index 00000000000..59436c381fd
--- /dev/null
+++ b/tests/tcg/aarch64/system/wfx.c
@@ -0,0 +1,113 @@
+/*
+ * WFX Instructions Test (WFI, WFE, WFIT, WFET)
+ *
+ * Copyright (c) 2024 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <stdint.h>
+#include <minilib.h>
+
+#define __stringify_1(x...) #x
+#define __stringify(x...) __stringify_1(x)
+
+#define read_sysreg(r) ({ \
+ uint64_t __val; \
+ asm volatile("mrs %0, " __stringify(r) : "=r" (__val)); \
+ __val; \
+})
+
+#define write_sysreg(r, v) do { \
+ uint64_t __val = (uint64_t)(v); \
+ asm volatile("msr " __stringify(r) ", %x0" \
+ : : "rZ" (__val)); \
+} while (0)
+
+#define isb() asm volatile("isb" : : : "memory")
+#define sev() asm volatile("sev" : : : "memory")
+#define wfi() asm volatile("wfi" : : : "memory")
+#define wfe() asm volatile("wfe" : : : "memory")
+#define wfit(reg) asm volatile("wfit %0" : : "r" (reg) : "memory")
+#define wfet(reg) asm volatile("wfet %0" : : "r" (reg) : "memory")
+
+static void wait_ticks(uint64_t ticks)
+{
+ uint64_t start = read_sysreg(cntvct_el0);
+ while ((read_sysreg(cntvct_el0) - start) < ticks) {
+ /* spin */
+ }
+}
+
+int main(void)
+{
+ uint64_t start, end, elapsed;
+ uint64_t timeout;
+
+ ml_printf("WFX Test\n");
+
+ /* 1. Test WFI with timer interrupt */
+ ml_printf("Testing WFI...");
+ /* Setup virtual timer to fire in 100000 ticks (~2ms at 50MHz) */
+ start = read_sysreg(cntvct_el0);
+ write_sysreg(cntv_tval_el0, 100000);
+ write_sysreg(cntv_ctl_el0, 1); /* Enable timer, no mask */
+ isb();
+
+ /*
+ * We don't have a full interrupt handler, but WFI should wake up
+ * when the interrupt is pending even if we have it masked at the CPU.
+ * PSTATE.I is set by boot code.
+ */
+ wfi();
+ end = read_sysreg(cntvct_el0);
+ elapsed = end - start;
+ if (elapsed < 100000) {
+ ml_printf("FAILED: WFI woke too early (%ld ticks)\n", elapsed);
+ return 1;
+ }
+ ml_printf("PASSED (elapsed %ld ticks)\n", elapsed);
+ write_sysreg(cntv_ctl_el0, 0); /* Disable timer */
+
+ /* 2. Test WFE and SEV */
+ ml_printf("Testing WFE/SEV...");
+ sev(); /* Set event register */
+ start = read_sysreg(cntvct_el0);
+ wfe(); /* Should return immediately */
+ end = read_sysreg(cntvct_el0);
+ elapsed = end - start;
+ if (elapsed > 1000) { /* Should be very fast */
+ ml_printf("FAILED: WFE slept despite SEV (%ld ticks)\n", elapsed);
+ return 1;
+ }
+ ml_printf("PASSED\n");
+
+ /* 3. Test WFIT */
+ ml_printf("Testing WFIT...");
+ start = read_sysreg(cntvct_el0);
+ timeout = start + 200000;
+ wfit(timeout);
+ end = read_sysreg(cntvct_el0);
+ elapsed = end - start;
+ if (elapsed < 200000) {
+ ml_printf("FAILED: WFIT woke too early (%ld ticks)\n", elapsed);
+ return 1;
+ }
+ ml_printf("PASSED (elapsed %ld ticks)\n", elapsed);
+
+ /* 4. Test WFET */
+ ml_printf("Testing WFET...");
+ start = read_sysreg(cntvct_el0);
+ timeout = start + 200000;
+ wfet(timeout);
+ end = read_sysreg(cntvct_el0);
+ elapsed = end - start;
+ if (elapsed < 200000) {
+ ml_printf("FAILED: WFET woke too early (%ld ticks)\n", elapsed);
+ return 1;
+ }
+ ml_printf("PASSED (elapsed %ld ticks)\n", elapsed);
+
+ ml_printf("ALL WFX TESTS PASSED\n");
+ return 0;
+}
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index f7a7d2b800f..84342c52cd7 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -102,6 +102,8 @@ run-pauth-3:
$(call skip-test, "RUN of pauth-3", "not built")
endif
+wfx: CFLAGS += -march=armv8.7-a
+
ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
QEMU_MTE_ENABLED_MACHINE=-M virt,mte=on -cpu max -display none
QEMU_OPTS_WITH_MTE_ON = $(QEMU_MTE_ENABLED_MACHINE) $(QEMU_BASE_ARGS) -kernel
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/8] tests/tcg/aarch64: fixes for WFX instructions system test
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
` (5 preceding siblings ...)
2026-02-24 12:10 ` [PATCH 6/8] tests/tcg/aarch64: Add WFX instructions system test Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
2026-02-24 12:10 ` [PATCH 8/8] target/arm: fixes for WFx[T] support Alex Bennée
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
This required some iteration with the model to add bits it missed in
the initial implementation. I ended up debugging and then prompting
for the missing bits:
- a basic gicv3 implementation
- a couple of rounds of tweaking the config
- mapping the GIC via page tables
- fixing the compilation of the support library
- extending the elapsed time check for WFE
- light re-ordering of Makefile, setting correct machine opts
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/tcg/aarch64/system/lib/gicv3.h | 56 +++++++++++++++++
tests/tcg/aarch64/system/lib/gicv3.c | 77 +++++++++++++++++++++++
tests/tcg/aarch64/system/wfx.c | 17 ++++-
tests/tcg/aarch64/Makefile.softmmu-target | 13 +++-
tests/tcg/aarch64/system/boot.S | 55 ++++++++++------
5 files changed, 196 insertions(+), 22 deletions(-)
create mode 100644 tests/tcg/aarch64/system/lib/gicv3.h
create mode 100644 tests/tcg/aarch64/system/lib/gicv3.c
diff --git a/tests/tcg/aarch64/system/lib/gicv3.h b/tests/tcg/aarch64/system/lib/gicv3.h
new file mode 100644
index 00000000000..9a1268937c6
--- /dev/null
+++ b/tests/tcg/aarch64/system/lib/gicv3.h
@@ -0,0 +1,56 @@
+/*
+ * GICv3 Helper Library
+ *
+ * Copyright (c) 2024 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef GICV3_H
+#define GICV3_H
+
+#include <stdint.h>
+
+/* Virt machine GICv3 base addresses */
+#define GICD_BASE 0x08000000 /* c.f. VIRT_GIC_DIST */
+#define GICR_BASE 0x080a0000 /* c.f. VIRT_GIC_REDIST */
+
+/* Distributor registers */
+#define GICD_CTLR (GICD_BASE + 0x0000)
+#define GICD_TYPER (GICD_BASE + 0x0004)
+#define GICD_IIDR (GICD_BASE + 0x0008)
+
+/* Redistributor registers (per-CPU) */
+#define GICR_SGI_OFFSET 0x00010000
+
+#define GICR_CTLR 0x0000
+#define GICR_WAKER 0x0014
+#define GICR_IGROUPR0 (GICR_SGI_OFFSET + 0x0080)
+#define GICR_ISENABLER0 (GICR_SGI_OFFSET + 0x0100)
+#define GICR_IPRIORITYR0 (GICR_SGI_OFFSET + 0x0400)
+
+/* GICD_CTLR bits */
+#define GICD_CTLR_ARE_NS (1U << 4)
+#define GICD_CTLR_ENA_G1NS (1U << 1)
+#define GICD_CTLR_ENA_G0 (1U << 0)
+
+/* GICR_WAKER bits */
+#define GICR_WAKER_ChildrenAsleep (1U << 2)
+#define GICR_WAKER_ProcessorSleep (1U << 1)
+
+/**
+ * gicv3_init:
+ *
+ * Initialize GICv3 distributor and the redistributor for the current CPU.
+ */
+void gicv3_init(void);
+
+/**
+ * gicv3_enable_irq:
+ * @irq: The IRQ number to enable
+ *
+ * Enable the specified IRQ (SPI or PPI).
+ */
+void gicv3_enable_irq(unsigned int irq);
+
+#endif /* GICV3_H */
diff --git a/tests/tcg/aarch64/system/lib/gicv3.c b/tests/tcg/aarch64/system/lib/gicv3.c
new file mode 100644
index 00000000000..a09a0e430e6
--- /dev/null
+++ b/tests/tcg/aarch64/system/lib/gicv3.c
@@ -0,0 +1,77 @@
+/*
+ * GICv3 Helper Library Implementation
+ *
+ * Copyright (c) 2024 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "gicv3.h"
+
+#define write_sysreg(r, v) do { \
+ uint64_t __val = (uint64_t)(v); \
+ asm volatile("msr " #r ", %x0" \
+ : : "rZ" (__val)); \
+} while (0)
+
+#define isb() asm volatile("isb" : : : "memory")
+
+static inline void write_reg(uintptr_t addr, uint32_t val)
+{
+ *(volatile uint32_t *)addr = val;
+}
+
+static inline uint32_t read_reg(uintptr_t addr)
+{
+ return *(volatile uint32_t *)addr;
+}
+
+void gicv3_init(void)
+{
+ uint32_t val;
+
+ /* 1. Enable Distributor ARE and Group 1 NS */
+ val = read_reg(GICD_CTLR);
+ val |= GICD_CTLR_ARE_NS | GICD_CTLR_ENA_G1NS;
+ write_reg(GICD_CTLR, val);
+
+ /* 2. Wake up Redistributor 0 */
+ /* Clear ProcessorSleep */
+ val = read_reg(GICR_BASE + GICR_WAKER);
+ val &= ~GICR_WAKER_ProcessorSleep;
+ write_reg(GICR_BASE + GICR_WAKER, val);
+
+ /* Wait for ChildrenAsleep to be cleared */
+ while (read_reg(GICR_BASE + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) {
+ /* spin */
+ }
+
+ /* 3. Enable CPU interface */
+ /* Set Priority Mask to allow all interrupts */
+ write_sysreg(ICC_PMR_EL1, 0xff);
+ /* Enable Group 1 Non-Secure interrupts */
+ write_sysreg(ICC_IGRPEN1_EL1, 1);
+ isb();
+}
+
+void gicv3_enable_irq(unsigned int irq)
+{
+ if (irq < 32) {
+ /* PPI: use GICR_ISENABLER0 */
+ uintptr_t addr;
+
+ /* Set Group 1 */
+ addr = GICR_BASE + GICR_IGROUPR0;
+ write_reg(addr, read_reg(addr) | (1U << irq));
+
+ /* Set priority (0xa0) */
+ addr = GICR_BASE + GICR_IPRIORITYR0 + irq;
+ *(volatile uint8_t *)addr = 0xa0;
+
+ /* Enable it */
+ addr = GICR_BASE + GICR_ISENABLER0;
+ write_reg(addr, 1U << irq);
+ } else {
+ /* SPI: not implemented yet */
+ }
+}
diff --git a/tests/tcg/aarch64/system/wfx.c b/tests/tcg/aarch64/system/wfx.c
index 59436c381fd..567d9e59c70 100644
--- a/tests/tcg/aarch64/system/wfx.c
+++ b/tests/tcg/aarch64/system/wfx.c
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <minilib.h>
+#include "gicv3.h"
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
@@ -31,6 +32,9 @@
#define wfit(reg) asm volatile("wfit %0" : : "r" (reg) : "memory")
#define wfet(reg) asm volatile("wfet %0" : : "r" (reg) : "memory")
+#define enable_irq() asm volatile("msr daifclr, #2" : : : "memory")
+#define disable_irq() asm volatile("msr daifset, #2" : : : "memory")
+
static void wait_ticks(uint64_t ticks)
{
uint64_t start = read_sysreg(cntvct_el0);
@@ -44,6 +48,9 @@ int main(void)
uint64_t start, end, elapsed;
uint64_t timeout;
+ gicv3_init();
+ gicv3_enable_irq(27); /* Virtual Timer PPI */
+
ml_printf("WFX Test\n");
/* 1. Test WFI with timer interrupt */
@@ -58,8 +65,13 @@ int main(void)
* We don't have a full interrupt handler, but WFI should wake up
* when the interrupt is pending even if we have it masked at the CPU.
* PSTATE.I is set by boot code.
+ *
+ * We unmask interrupts here to ensure the CPU can take the minimal
+ * exception handler defined in boot.S.
*/
+ enable_irq();
wfi();
+ disable_irq();
end = read_sysreg(cntvct_el0);
elapsed = end - start;
if (elapsed < 100000) {
@@ -76,11 +88,12 @@ int main(void)
wfe(); /* Should return immediately */
end = read_sysreg(cntvct_el0);
elapsed = end - start;
- if (elapsed > 1000) { /* Should be very fast */
+ /* while this should be fast there is some overhead from TCG */
+ if (elapsed > 20000) {
ml_printf("FAILED: WFE slept despite SEV (%ld ticks)\n", elapsed);
return 1;
}
- ml_printf("PASSED\n");
+ ml_printf("PASSED (%ld ticks)\n", elapsed);
/* 3. Test WFIT */
ml_printf("Testing WFIT...");
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index 84342c52cd7..9a5b95de621 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -4,8 +4,9 @@
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
AARCH64_SYSTEM_SRC=$(AARCH64_SRC)/system
+AARCH64_SYSTEM_LIB_SRC=$(AARCH64_SYSTEM_SRC)/lib
-VPATH+=$(AARCH64_SYSTEM_SRC)
+VPATH+=$(AARCH64_SYSTEM_SRC) $(AARCH64_SYSTEM_LIB_SRC)
# These objects provide the basic boot code and helper functions for all tests
CRT_OBJS=boot.o
@@ -24,7 +25,7 @@ LINK_SCRIPT=$(AARCH64_SYSTEM_SRC)/kernel.ld
LDFLAGS=-Wl,-T$(LINK_SCRIPT)
TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
EXTRA_RUNS+=$(MULTIARCH_RUNS)
-CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
+CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC) -I$(AARCH64_SYSTEM_LIB_SRC)
LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
config-cc.mak: Makefile
@@ -102,7 +103,15 @@ run-pauth-3:
$(call skip-test, "RUN of pauth-3", "not built")
endif
+gicv3.o: gicv3.c gicv3.h
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+
wfx: CFLAGS += -march=armv8.7-a
+wfx: LDFLAGS += gicv3.o
+wfx: gicv3.o
+
+QEMU_GICV3_MACHINE=-M virt,gic-version=3 -cpu max -display none
+run-wfx: QEMU_OPTS=$(QEMU_GICV3_MACHINE) $(QEMU_BASE_ARGS) -kernel
ifneq ($(CROSS_CC_HAS_ARMV8_MTE),)
QEMU_MTE_ENABLED_MACHINE=-M virt,mte=on -cpu max -display none
diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
index 8bfa4e4efc7..6a71fc0da5a 100644
--- a/tests/tcg/aarch64/system/boot.S
+++ b/tests/tcg/aarch64/system/boot.S
@@ -60,7 +60,6 @@ curr_sp0_irq:
curr_sp0_fiq:
curr_sp0_serror:
curr_spx_sync:
-curr_spx_irq:
curr_spx_fiq:
curr_spx_serror:
lower_a64_sync:
@@ -248,29 +247,34 @@ at_testel:
msr ttbr0_el1, x0
/*
- * Setup a flat address mapping page-tables. Stage one simply
- * maps RAM to the first Gb. The stage2 tables have two 2mb
- * translation block entries covering a series of adjacent
- * 4k pages.
+ * Setup a flat address mapping page-tables.
+ *
+ * ttb (Level 1):
+ * - Entry 0 [0 - 1GB]: 1GB Device block (for GIC and other H/W)
+ * - Entry 1 [1GB - 2GB]: Table entry pointing to ttb_stage2 (for RAM)
*/
- /* Stage 1 entry: indexed by IA[38:30] */
- adr x1, . /* phys address */
- bic x1, x1, #(1 << 30) - 1 /* 1GB alignment*/
- add x2, x0, x1, lsr #(30 - 3) /* offset in l1 page table */
+ /* Entry 0: 1GB Device block mapping at 0x0 */
+ ldr x1, =0x401 | (1 << 2) /* AF=1, block, AttrIndx=Attr1 (Device) */
+ str x1, [x0]
- /* point to stage 2 table [47:12] */
- adrp x0, ttb_stage2
- orr x1, x0, #3 /* ptr to stage 2 */
- str x1, [x2]
+ /* Entry 1: Table entry pointing to ttb_stage2 */
+ adrp x1, ttb_stage2
+ orr x1, x1, #3 /* ptr to table (type=3) */
+ str x1, [x0, #8]
- /* Stage 2 entries: indexed by IA[29:21] */
+ /* Stage 2 entries: indexed by IA[29:21] (within 1GB-2GB range) */
+ adrp x0, ttb_stage2
+ add x0, x0, :lo12:ttb_stage2
ldr x5, =(((1 << 9) - 1) << 21)
/* First block: .text/RO/execute enabled */
adr x1, . /* phys address */
bic x1, x1, #(1 << 21) - 1 /* 2mb block alignment */
- and x4, x1, x5 /* IA[29:21] */
+ /* Note: we assume RAM is in the 1GB-2GB range, so IA[30] is 1 */
+ mov x4, x1
+ bic x4, x4, #(1 << 30) /* remove 1GB offset for L2 index */
+ and x4, x4, x5 /* IA[29:21] */
add x2, x0, x4, lsr #(21 - 3) /* offset in l2 page table */
ldr x3, =0x401 /* attr(AF, block) */
orr x1, x1, x3
@@ -280,7 +284,9 @@ at_testel:
adrp x1, .data
add x1, x1, :lo12:.data
bic x1, x1, #(1 << 21) - 1 /* 2mb block alignment */
- and x4, x1, x5 /* IA[29:21] */
+ mov x4, x1
+ bic x4, x4, #(1 << 30) /* remove 1GB offset for L2 index */
+ and x4, x4, x5 /* IA[29:21] */
add x2, x0, x4, lsr #(21 - 3) /* offset in l2 page table */
ldr x3, =(3 << 53) | 0x401 /* attr(AF, NX, block) */
orr x1, x1, x3
@@ -290,7 +296,9 @@ at_testel:
adrp x1, mte_page
add x1, x1, :lo12:mte_page
bic x1, x1, #(1 << 21) - 1
- and x4, x1, x5
+ mov x4, x1
+ bic x4, x4, #(1 << 30) /* remove 1GB offset for L2 index */
+ and x4, x4, x5
add x2, x0, x4, lsr #(21 - 3)
/* attr(AF, NX, block, AttrIndx=Attr1) */
ldr x3, =(3 << 53) | 0x401 | (1 << 2)
@@ -317,7 +325,7 @@ at_testel:
ldr x0, = (2 << 32) | 25 | (3 << 10) | (3 << 8)
msr tcr_el1, x0
- mov x0, #0xee /* Inner/outer cacheable WB */
+ ldr x0, =0x04ee /* Attr1: Device-nGnRE, Attr0: Normal WB */
msr mair_el1, x0
isb
@@ -370,6 +378,17 @@ _exit:
semihosting_call
/* never returns */
+ /*
+ * IRQ handler
+ */
+ .global curr_spx_irq
+curr_spx_irq:
+ /* Minimal IRQ handler: just mask the timer and return */
+ mrs x0, cntv_ctl_el0
+ orr x0, x0, #2 /* IMASK=1 */
+ msr cntv_ctl_el0, x0
+ eret
+
/*
* Helper Functions
*/
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 8/8] target/arm: fixes for WFx[T] support
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
` (6 preceding siblings ...)
2026-02-24 12:10 ` [PATCH 7/8] tests/tcg/aarch64: fixes for " Alex Bennée
@ 2026-02-24 12:10 ` Alex Bennée
7 siblings, 0 replies; 14+ messages in thread
From: Alex Bennée @ 2026-02-24 12:10 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennée
These are the bits I needed to fix manually on top of what the model
had done.
- ensure the SEV instruction is enabled for aa64
- remove the FEATURE_M check for aa32
- add an exit block so WFE can fall through
On the last change I see the DISAS_WFI does tcg_gen_exit_tb to ensure
we check for interrupts. However for yield and wfe we should just be
able to roll into the next instruction. We could probably rationalise
DISAS cases for all of these into a common handling.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
target/arm/tcg/a64.decode | 3 +--
target/arm/tcg/translate-a64.c | 10 ++++++++++
target/arm/tcg/translate.c | 4 +---
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 01b1b3e38be..d5b65d79da1 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -237,8 +237,7 @@ ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
YIELD 1101 0101 0000 0011 0010 0000 001 11111
WFE 1101 0101 0000 0011 0010 0000 010 11111
WFI 1101 0101 0000 0011 0010 0000 011 11111
- # We implement WFE to never block, so our SEV/SEVL are NOPs
- # SEV 1101 0101 0000 0011 0010 0000 100 11111
+ SEV 1101 0101 0000 0011 0010 0000 100 11111
# SEVL 1101 0101 0000 0011 0010 0000 101 11111
# Our DGL is a NOP because we don't merge memory accesses anyway.
# DGL 1101 0101 0000 0011 0010 0000 110 11111
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index f76a00d1329..4714bedd01c 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -2032,6 +2032,14 @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
return true;
}
+static bool trans_SEV(DisasContext *s, arg_SEV *a)
+{
+#ifndef CONFIG_USER_ONLY
+ gen_helper_sev(tcg_env);
+#endif
+ return true;
+}
+
static bool trans_WFE(DisasContext *s, arg_WFI *a)
{
/*
@@ -10918,6 +10926,8 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
case DISAS_WFE:
gen_a64_update_pc(dc, 4);
gen_helper_wfe(tcg_env);
+ gen_goto_tb(dc, 1, 4);
+ /* tcg_gen_exit_tb(NULL, 0); */
break;
case DISAS_YIELD:
gen_a64_update_pc(dc, 4);
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index f9d1b8897d2..78ba7d2fde5 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -3248,9 +3248,7 @@ static bool trans_SEV(DisasContext *s, arg_SEV *a)
* For system-mode M-profile, it sets the event register.
*/
#ifndef CONFIG_USER_ONLY
- if (arm_dc_feature(s, ARM_FEATURE_M)) {
- gen_helper_sev(tcg_env);
- }
+ gen_helper_sev(tcg_env);
#endif
return true;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 5/8] target/arm: extend WFX support for A-profile
2026-02-24 12:10 ` [PATCH 5/8] target/arm: extend WFX support for A-profile Alex Bennée
@ 2026-02-24 12:26 ` Peter Maydell
2026-02-25 11:22 ` Alex Bennée
0 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2026-02-24 12:26 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, qemu-arm, eca
On Tue, 24 Feb 2026 at 12:10, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> This commit extends support for WFI, WFE, WFIT, and WFET instructions
> for A-profile ARM CPUs, ensuring proper architectural semantics and
> full ISS (Instruction Specific Syndrome) field support for traps.
>
> Key changes:
> - Update `syn_wfx` in `target/arm/syndrome.h` to include `RN` (register
> number) and `RV` (register valid) fields using `registerfields.h`
> macros.
> - Refactor `HELPER(wfi)` and `HELPER(wfit)` to use correct AArch64
> syndrome values (CV=0, COND=0xf).
> - Implement `HELPER(wfet)` and update `trans_WFET` to support the new
> Wait For Event with Timeout instruction.
> - Update `HELPER(wfe)` to implement proper A-profile semantics,
> including trap checks and event register handling.
> - Extend `event_register` handling to all ARM CPUs (not just M-profile)
> by updating `HELPER(sev)` and `arm_cpu_has_work`.
> - Declare WFxT helpers as `TCG_CALL_NO_WG` as they can raise
> exceptions.
Yeah, no. This all needs to be split out to be anything
close to reviewable. In particular "report the right
syndrome info", "make WFE/SEV not NOPs on A profile like
they are on M-profile" and "do better with WFET" are all
separate things.
Also, this doesn't change any of the places that it needs to
change to implement the places that architecturally set the
event register (see R_XRZRK in the Arm ARM), so it will
break code that uses WFE. Notably for A-profile this includes
generic timer "event streams", which we currently don't implement
at all.
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/8] target/arm: extend WFX support for A-profile
2026-02-24 12:26 ` Peter Maydell
@ 2026-02-25 11:22 ` Alex Bennée
2026-02-25 11:50 ` Peter Maydell
0 siblings, 1 reply; 14+ messages in thread
From: Alex Bennée @ 2026-02-25 11:22 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, qemu-arm
Peter Maydell <peter.maydell@linaro.org> writes:
> On Tue, 24 Feb 2026 at 12:10, Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>> This commit extends support for WFI, WFE, WFIT, and WFET instructions
>> for A-profile ARM CPUs, ensuring proper architectural semantics and
>> full ISS (Instruction Specific Syndrome) field support for traps.
>>
>> Key changes:
>> - Update `syn_wfx` in `target/arm/syndrome.h` to include `RN` (register
>> number) and `RV` (register valid) fields using `registerfields.h`
>> macros.
>> - Refactor `HELPER(wfi)` and `HELPER(wfit)` to use correct AArch64
>> syndrome values (CV=0, COND=0xf).
>> - Implement `HELPER(wfet)` and update `trans_WFET` to support the new
>> Wait For Event with Timeout instruction.
>> - Update `HELPER(wfe)` to implement proper A-profile semantics,
>> including trap checks and event register handling.
>> - Extend `event_register` handling to all ARM CPUs (not just M-profile)
>> by updating `HELPER(sev)` and `arm_cpu_has_work`.
>> - Declare WFxT helpers as `TCG_CALL_NO_WG` as they can raise
>> exceptions.
>
> Yeah, no. This all needs to be split out to be anything
> close to reviewable. In particular "report the right
> syndrome info", "make WFE/SEV not NOPs on A profile like
> they are on M-profile" and "do better with WFET" are all
> separate things.
Yeah it was surprising it didn't follow its own plan which did have a
nice breakdown of patches. When I do my human spin I'll make sure it is
split up better.
> Also, this doesn't change any of the places that it needs to
> change to implement the places that architecturally set the
> event register (see R_XRZRK in the Arm ARM),
I was having trouble finding that but searching for just XRZRK finds the
subscript text:
The Event Register for a PE is set by any of the following:
- A Send Event instruction, SEV, executed by any PE in the system.
- A Send Event Local instruction, SEVL, executed by the PE
- An exception return.
These seem easy enough
- The clearing of the global monitor for the PE
Is this the LSTREX monitor?
- An event from a Generic Timer event stream, see Event streams.
So this looks like sub-timer events that trigger events but aren't timer
expiry events? I shall have a look to see if the kernel uses this.
- An event sent by some IMPLEMENTATION DEFINED mechanism.
I assume we don't need to care about IMPDEF cases for our current CPU models?
> so it will
> break code that uses WFE. Notably for A-profile this includes
> generic timer "event streams", which we currently don't implement
> at all.
>
> thanks
> -- PMM
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/8] target/arm: extend WFX support for A-profile
2026-02-25 11:22 ` Alex Bennée
@ 2026-02-25 11:50 ` Peter Maydell
0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2026-02-25 11:50 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, qemu-arm
On Wed, 25 Feb 2026 at 11:22, Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Peter Maydell <peter.maydell@linaro.org> writes:
> > Also, this doesn't change any of the places that it needs to
> > change to implement the places that architecturally set the
> > event register (see R_XRZRK in the Arm ARM),
>
> I was having trouble finding that but searching for just XRZRK finds the
> subscript text:
>
> The Event Register for a PE is set by any of the following:
> - A Send Event instruction, SEV, executed by any PE in the system.
> - A Send Event Local instruction, SEVL, executed by the PE
> - An exception return.
>
> These seem easy enough
>
> - The clearing of the global monitor for the PE
>
> Is this the LSTREX monitor?
Yes (see Arm ARM section B2.12.2). Note that as "global" implies,
this is cross-CPU, not just internal to this one.
> - An event from a Generic Timer event stream, see Event streams.
>
> So this looks like sub-timer events that trigger events but aren't timer
> expiry events? I shall have a look to see if the kernel uses this.
It will both use it internally and also exposes it to userspace
(in the sense of providing a hwcap that says "we generate an
event stream so you can rely on WFE waking up after a while").
The kernel config symbol is ARM_ARCH_TIMER_EVTSTREAM.
For internal use, see for instance arch/arm64/lib/delay.c :
if the CPU has event streams but not WFIT/WFET then it will
use the event stream to implement the delay.
> - An event sent by some IMPLEMENTATION DEFINED mechanism.
>
> I assume we don't need to care about IMPDEF cases for our current CPU models?
Yes, we don't need to worry about this part.
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU
2026-02-24 12:10 ` [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU Alex Bennée
@ 2026-03-20 16:01 ` Daniel P. Berrangé
2026-03-20 16:55 ` Paolo Bonzini
0 siblings, 1 reply; 14+ messages in thread
From: Daniel P. Berrangé @ 2026-03-20 16:01 UTC (permalink / raw)
To: Alex Bennée; +Cc: qemu-devel, Peter Maydell, qemu-arm
On Tue, Feb 24, 2026 at 12:10:09PM +0000, Alex Bennée wrote:
> This was written by ECA based on it's initial understanding of the
> code base. It's mostly quick facts and pointers to common tasks.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> ---
> ajb:
> - I made a slight tweak to use pyenv to run single tests
> ---
> AGENTS.md | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
> create mode 100644 AGENTS.md
>
> diff --git a/AGENTS.md b/AGENTS.md
> new file mode 100644
> index 00000000000..5b54763f4b1
> --- /dev/null
> +++ b/AGENTS.md
> @@ -0,0 +1,18 @@
> +# QEMU Agent Guide
> +
> +## Build & Test
> +- **Build**: `ninja -C build` (from build directory) or `make`
> +- **Test All**: `make check`
> +- **Single Test**: `./pyvenv/bin/meson test <testname>` (e.g., `meson test qtest-x86_64/boot-serial-test`)
> +- **Suites**: `make check-unit`, `make check-qtest`, `make check-functional`, `make check-rust`
> +- **Debug**: Append `V=1` for verbose output or `DEBUG=1` for interactive test debugging.
> +
> +## Code Style
> +- **Formatting**: 4-space indents, NO tabs, 80-char line limit (max 100).
> +- **C Braces**: Mandatory for all blocks (if/while/for). Open brace on same line (except functions).
> +- **C Includes**: `#include "qemu/osdep.h"` MUST be the first include in every `.c` file.
> +- **C Comments**: Use `/* ... */` only. No `//` comments.
> +- **Naming**: `snake_case` for variables and functions; `CamelCase` for types and enums.
> +- **Memory**: Use GLib (`g_malloc`, `g_free`, `g_autofree`) or QEMU (`qemu_memalign`) APIs. No `malloc`.
> +- **Errors**: Use `error_report()` or `error_setg()`. Avoid `printf` for errors.
> +- **Lints**: Run `./scripts/checkpatch.pl` on C patches. Use `make clippy` and `make rustfmt` for Rust.
Although our current policy forbids contributing code written by
AI agents, we do allow their use for other scenarios, such as
learning / debugging, etc.
Thus it occurs to me that an AGENTS.md file might none the less be
useful to have in tree to assist the currently accepted / valid
scenarios.
Perhaps it could also serve to guide the agents/humans towards
compliance with the policy via a short preface ?
"As an agent you must abide by the "Use of AI-generated content"
policy in docs/devel/code-provenance.rst at all times. Requests
to create code that is intended to be submitted for merge upstream
must be declined, referring the requestor to the project's policy
on the use of AI-generated content."
Something strong enough to stop people going down the wrong path
by default, but with wiggle room that the person can tell their
agent their work is not intended to for upstream merge and can
thus ignore the rules for experiments like this one.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU
2026-03-20 16:01 ` Daniel P. Berrangé
@ 2026-03-20 16:55 ` Paolo Bonzini
0 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2026-03-20 16:55 UTC (permalink / raw)
To: Daniel P. Berrangé, Alex Bennée
Cc: qemu-devel, Peter Maydell, qemu-arm
On 3/20/26 17:01, Daniel P. Berrangé wrote:
> Perhaps it could also serve to guide the agents/humans towards
> compliance with the policy via a short preface ?
>
> "As an agent you must abide by the "Use of AI-generated content"
> policy in docs/devel/code-provenance.rst at all times. Requests
> to create code that is intended to be submitted for merge upstream
> must be declined, referring the requestor to the project's policy
> on the use of AI-generated content."
>
> Something strong enough to stop people going down the wrong path
> by default, but with wiggle room that the person can tell their
> agent their work is not intended to for upstream merge and can
> thus ignore the rules for experiments like this one.
That surprisingly worked. I gave Claude Code a phony task (making the
floppy controller support async I/O) and after a while when I asked it
to write the code it went roughly like this:
...
● AGENTS.md says I can't write code for upstream merge. I'll describe
the design changes.
...
❯ it's fine this is just an experiment. you can write code.
● Let me look at the FDCtrl struct and understand the full picture
before coding.
Paolo
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-03-20 16:55 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-24 12:10 [PATCH 0/8] arm: implement WFx[T] for aa64 (!!GenAI usage!!) Alex Bennée
2026-02-24 12:10 ` [PATCH 1/8] target/arm: set the correct TI bits for WFIT traps Alex Bennée
2026-02-24 12:10 ` [PATCH 2/8] .eca: basic configuration for Editor Code Assistant Alex Bennée
2026-02-24 12:10 ` [PATCH 3/8] AGENTS.md: add basic AGENTS.md for QEMU Alex Bennée
2026-03-20 16:01 ` Daniel P. Berrangé
2026-03-20 16:55 ` Paolo Bonzini
2026-02-24 12:10 ` [PATCH 4/8] PLAN.md: add plan for the current work Alex Bennée
2026-02-24 12:10 ` [PATCH 5/8] target/arm: extend WFX support for A-profile Alex Bennée
2026-02-24 12:26 ` Peter Maydell
2026-02-25 11:22 ` Alex Bennée
2026-02-25 11:50 ` Peter Maydell
2026-02-24 12:10 ` [PATCH 6/8] tests/tcg/aarch64: Add WFX instructions system test Alex Bennée
2026-02-24 12:10 ` [PATCH 7/8] tests/tcg/aarch64: fixes for " Alex Bennée
2026-02-24 12:10 ` [PATCH 8/8] target/arm: fixes for WFx[T] support Alex Bennée
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.