Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions docs/common/acs_smc_porting_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# ACS EL3 SMC porting guide

This guide describes how to enable the ACS EL3 services on a platform other
than the current RDV3 reference implementation, or with an EL3 firmware
implementation other than TF-A.

## 1. Confirm the EL3 dispatch interface

The ACS client invokes SMC64 FID `0xC7000030`. EL3 must reserve this FID and
route it to the ACS handler with the following arguments:

```text
x0 = 0xC7000030
x1 = ACS service selector
x2 = service argument 0
x3 = service argument 1
x4 = service argument 2
```

On success, return status `0` in `x0` and the service value in `x1`. For an
unknown FID or selector, return the SMCCC unknown-function value, observed by
ACS as all ones. TF-A defines this value as `SMC_UNK`.

### TF-A requirement

Use TF-A v2.14 or newer. The required support was introduced by commit
[`f69f551`](https://github.com/ARM-software/arm-trusted-firmware/commit/f69f551269f1d126877889a1cab27cc1692316ea)
and includes:

- the `0xC7000030` ACS allocation in the vendor-specific EL3 service range;
- `ENABLE_ACS_SMC` and `PLAT_ARM_ACS_SMC_HANDLER` build controls;
- dispatch from the vendor EL3 runtime service to `plat_arm_acs_smc_handler()`; and
- a default platform ACS handler symbol.

## 2. Add the platform configuration

Copy the RDV3 reference configuration for the target platform:

```sh
cp -r services/acs_smc/platform/rdv3 services/acs_smc/platform/<platform name>
```

When TF-A is used, no changes to `platform_el3.h` are required; it maps the
override to TF-A's `ARM_SYS_CNTCTL_BASE`. For non-TF-A firmware, update the
copied header with the platform-specific system counter control base:

```c
#define PLATFORM_OVERRIDE_SYS_COUNTER_CNTCTL_BASE <system counter control base>
```

## 3. Integrate the handler into TF-A

This section applies only when TF-A is used as the EL3 firmware.

`acs_smc.mk` adds the C and AArch64 sources to `VENDOR_EL3_SRCS`, adds the
required include paths, and passes this linker option:

```text
-Wl,--wrap=plat_arm_acs_smc_handler
```

The provided script performs the integration automatically:

```sh
./tools/scripts/build_acs_smc.sh \
TFA_PATH=/path/to/arm-trusted-firmware \
PLAT=<plat> \
CC=aarch64-linux-gnu-gcc \
<platform TF-A flags>
```

The script enables `ENABLE_ACS_SMC=1`, copies `services/acs_smc` under
`TF_A/plat/arm/common/acs_smc` when that directory is absent, removes stale
BL31 objects, and runs the requested TF-A build target (`bl31` by default or
`all` with `--all`).

If the copied ACS directory already exists, the script leaves it in place.
Remove or update a stale copy before relying on it in a platform-specific TF-A
integration.

## 4. Port to another EL3 implementation

This section applies only when the EL3 firmware is not TF-A.

The supplied build script cannot build non-TF-A firmware. Integrate these
sources into the firmware's EL3 image using its native build system:

```text
services/acs_smc/src/acs_el3_handler.c
services/acs_smc/src/AArch64/PlatAcsSysreg.S
services/acs_smc/include/acs_el3_handler.h
services/acs_smc/platform/<plat>/platform_el3.h
```

Then adapt the TF-A-specific interfaces used by `acs_el3_handler.c`:

| TF-A interface | Required equivalent |
| --- | --- |
| `SMC_RET1(handle, value)` | Return `value` in `x0` from the active SMC context |
| `SMC_RET2(handle, status, value)` | Return `status` in `x0` and `value` in `x1` |
| `SMC_UNK` | TF-A macro for the SMCCC unknown-function return value |
| `mmio_read_32()` / `mmio_write_32()` | EL3 32-bit MMIO accessors |
| `read_cntpct_el0()` | Ordered read of the physical count register |
| `INFO()` / `WARN()` | Firmware logging, or suitable no-op definitions |

Register an SMC64 handler for `0xC7000030` in the firmware's runtime service
dispatcher. Preserve the selector numbers, argument registers, status values,
and result registers documented in the README. The sysarch-acs VAL wrappers depend on that exact ABI.

## 5. Integrate stack packaging

Without `STACK_PATH`, the requested build outputs remain in the TF-A build
directory. With `STACK_PATH`, Step 6 of `tools/scripts/build_acs_smc.sh`
assumes the RDV3 stack convention:

```text
BL31 destination: STACK_PATH/output/PLAT/tf-bl31.bin
Packaging command: STACK_PATH/build-scripts/rdinfra/build-test-acs.sh -p PLAT package
```

For another stack, choose one of these approaches:

1. Provide `PACKAGE_SCRIPT` in the environment with a script accepting
`-p <plat> package` and retain the expected stack output layout.
2. Modify Step 6 to copy the required TF-A build outputs to the platform's
required destinations and call its native packaging command.

Keep `ACS_BL31_REPACKAGE_ACTIVE` or an equivalent guard if the packaging
script can invoke the ACS build script recursively.

## 6. Validate the port

1. Confirm the generated `bl31.bin` is installed in the image that the
platform actually boots.
2. Check the EL3 log for `ACS/EL3: handler entered` when an SMC-dependent test
runs.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| `Platform '<plat>' is not supported by ACS SMC` | Add `services/acs_smc/platform/<plat>/platform_el3.h` and match the `PLAT` spelling exactly |
| ACS tests report that the EL3 handler is absent | Verify TF-A v2.14+ ACS dispatch support, `ENABLE_ACS_SMC=1`, the linker wrapper, and the deployed BL31 |
| Base-frequency test returns zero or an implausible value | Verify the counter-control physical base and the `CNTFID0` implementation |

## License

The ACS EL3 SMC service is distributed under the Apache License 2.0.

--------------

*Copyright (c) 2026, Arm Limited or its affiliates. All rights reserved.*
117 changes: 117 additions & 0 deletions services/acs_smc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# ACS EL3 SMC service

The ACS EL3 SMC service gives sysarch-acs tests controlled access to information that is not available from the non-secure ACS execution environment. It is intended only for ACS validation firmware.

Trusted Firmware-A (TF-A) reserves a vendor-specific SMC FIDs for ACS. This integration uses that reserved interface to include the ACS EL3 handler in BL31 so that ACS can perform validation that requires secure-world support. The build script integrates the ACS SMC handler with TF-A and builds either a standalone BL31 binary or the complete TF-A build.

We currently provide RDV3 as the reference implementation. To support a new platform or a non-TF-A EL3 implementation, see the
[porting guide](../../docs/common/acs_smc_porting_guide.md).

## Supported rules

| Rule | Requirement | EL3 service dependency |
| --- | --- | --- |
| B_PPI_03 | Secure EL2 physical timer (CNTHPS) PPI mapping | `ACS_SMC_GET_CNTHPS_INTID` |
| B_PPI_03 | Secure EL2 virtual timer (CNTHVS) PPI mapping | `ACS_SMC_GET_CNTHVS_INTID` |
| B_TIME_02 | System counter frequency is at least 10 MHz | `ACS_SMC_READ_BASE_CNTFREQ` |
| S_L8TI_01 | System counter frequency is at least 50 MHz | `ACS_SMC_READ_BASE_CNTFREQ` |

If EL3 does not implement the ACS FID, rules that depend on the SMC service are
skipped when the call returns the SMCCC unknown-function value (`SMC_UNK` in
TF-A).

## SMC interface

ACS uses the vendor-specific SMC64 FID `0xC7000030`.

## TF-A compatibility

TF-A must reserve the ACS FID and dispatch it through `plat_arm_acs_smc_handler()`. This support was introduced by TF-A commit
[`f69f551`](https://github.com/ARM-software/arm-trusted-firmware/commit/f69f551269f1d126877889a1cab27cc1692316ea)
and is present from TF-A v2.14. The TF-A build must set `ENABLE_ACS_SMC=1` to enable the dispatch path; the supplied
[build script](../../tools/scripts/build_acs_smc.sh) sets this flag automatically.

## Prerequisites

- AArch64 GCC compiler (or cross compiler) and binutils
- GNU Make
- Python 3
- Device Tree Compiler (`dtc`)
- OpenSSL
- A TF-A v2.14-or-newer source tree, or a TF-A fork containing the ACS FID reservation and dispatch support
- The Mbed TLS version required by the selected TF-A/platform configuration
- Any images and build flags normally required by the target TF-A platform

The script checks these inputs before starting the build.

## Standalone BL31 build

Run the script from the sysarch-acs root:

```sh
./tools/scripts/build_acs_smc.sh \
TFA_PATH=/path/to/arm-trusted-firmware \
PLAT=$PLAT \
CC=aarch64-linux-gnu-gcc \
DEBUG=1
```

The default target is `bl31`. Pass `--all` to request the TF-A `all` target.
Other `NAME=value` arguments are passed to TF-A. The generated image is under the platform's TF-A build directory, for example:

```text
/path/to/arm-trusted-firmware/build/$PLAT/debug/bl31.bin
```

`TFA_PATH` and `PLAT` are required. `ACS_PATH`, `CC`, and `MBEDTLS_DIR` can be set explicitly when automatic detection is unsuitable. Add any other flags
required by the target platform and TF-A revision.

## RDV3 software-stack build and packaging

The following command shape has been used with a RDV3 software stack (2025/26 version). Replace every path with the corresponding path in the local stack:

```sh
./tools/scripts/build_acs_smc.sh \
TFA_PATH=/path/to/rdv3-stack/tf-a \
PLAT=rdv3 \
CC=aarch64-linux-gnu-gcc \
STACK_PATH=/path/to/rdv3-stack \
NRD_PLATFORM_VARIANT=0 \
DEBUG=1 \
ENABLE_RME=1 \
RME_GPT_BITLOCK_BLOCK=0 \
RMM=/path/to/rdv3-stack/rmm/build/Debug/rmm.img \
SPD=spmd \
SPMD_SPM_AT_SEL2=1 \
BL32=1 \
SP_LAYOUT_FILE=/path/to/rdv3-stack/build-scripts/sp_metadata/rdv3/rdv3_sp_layout.json \
ENABLE_PMF=1 \
SEPARATE_CODE_AND_RODATA=1
```

When `STACK_PATH` is present, the script:

1. Copies `bl31.bin` to `STACK_PATH/output/PLAT/tf-bl31.bin`.
2. Invokes `STACK_PATH/build-scripts/rdinfra/build-test-acs.sh -p PLAT package`.

## Implementation layout

```text
services/acs_smc/
|-- acs_smc.mk TF-A build integration
|-- include/acs_el3_handler.h FID, selectors, status, and prototypes
|-- platform/rdv3/platform_el3.h Platform specific details (for RDV3)
`-- src/
|-- acs_el3_handler.c EL3 service implementation
`-- AArch64/PlatAcsSysreg.S Secure EL2 timer register accessors
```

The non-secure System ACS wrappers and tests are in `val/` and `test_pool/`.

## License

The ACS EL3 SMC service is distributed under the Apache License 2.0.

--------------

*Copyright (c) 2026, Arm Limited or its affiliates. All rights reserved.*
Loading