Skip to content
Closed
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
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
<dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> <dikshita@codeaurora.org>
Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> <quic_dikshita@quicinc.com>
Dj <hey@djdev.me> <43033058+DjDeveloperr@users.noreply.github.com>
Dmitry Baryshkov <lumag@kernel.org> <dbaryshkov@gmail.com>
Dmitry Baryshkov <lumag@kernel.org> <[dbaryshkov@gmail.com]>
Dmitry Baryshkov <lumag@kernel.org> <dmitry_baryshkov@mentor.com>
Expand Down
36 changes: 36 additions & 0 deletions Documentation/devicetree/bindings/firmware/aurora,apif-mmio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/firmware/aurora,apif-mmio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Aurora Platform Interface over Memory-Mapped I/O

maintainers:
- Dj <hey@djdev.me>

description: |
Synthetic MMIO transport supplied by Aura's EL2-resident monitor. Version 2
forwards native SPTM selectors and arguments and provides memory-ownership
services. Peripheral policy belongs to consumers, which reference this node
through the aurora,apif phandle. The register page must be absent from the
guest stage-2 mappings so accesses reach Aura.

properties:
compatible:
const: aurora,apif-mmio
reg:
maxItems: 1

required:
- compatible
- reg

additionalProperties: false

examples:
- |
apif: firmware@61ff0000 {
compatible = "aurora,apif-mmio";
reg = <0x61ff0000 0x4000>;
};
78 changes: 78 additions & 0 deletions Documentation/devicetree/bindings/iommu/apple,dart-apif.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/iommu/apple,dart-apif.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple DART mediated through Aura APIF

maintainers:
- Dj <hey@djdev.me>

description: |
A DART instance accessed through native SPTM calls rather than guest MMIO.
Linux owns stream grouping, table setup, mapping rollback and DMA apertures.
Firmware-owned streams are adopted without replacing their roots or replaying
retained mappings. Unit identifiers are firmware metadata, not chip IDs.

properties:
compatible:
const: apple,dart-apif
'#iommu-cells':
const: 1
description: Stream identifier.
aurora,apif:
$ref: /schemas/types.yaml#/definitions/phandle
description: APIF version-2 transport provider.
apple,apif-dart-id:
$ref: /schemas/types.yaml#/definitions/uint32
maximum: 255
description: Native SPTM DART unit identifier.
apple,apif-num-streams:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 1
maximum: 256
default: 256
description: Number of streams supported by this unit.
apple,apif-retained-sids:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 256
uniqueItems: true
items:
maximum: 255
description: Firmware-owned stream IDs which Aura adopted at bootstrap.
apple,apif-iova-force:
$ref: /schemas/types.yaml#/definitions/uint64
enum: [0, 1099511627776]
description: |
Optional native bit-40 force mask for a low-address device DMA view.
Must not overlap apple,dma-range. Omit for a native DVA aperture.
apple,apif-reserve-last-page:
type: boolean
description: Native aperture forbids allocating its final 16 KiB granule.
apple,dma-range:
$ref: /schemas/types.yaml#/definitions/uint64-array
minItems: 2
maxItems: 2
description: |
Device-visible DMA aperture base and size, aligned to 16 KiB and within
42 bits. Defaults to the low 4 GiB. This is not a CPU mapping.

required:
- compatible
- '#iommu-cells'
- aurora,apif
- apple,apif-dart-id

additionalProperties: false

examples:
- |
iommu {
compatible = "apple,dart-apif";
#iommu-cells = <1>;
aurora,apif = <&apif>;
apple,apif-dart-id = <5>;
apple,apif-num-streams = <16>;
};
35 changes: 35 additions & 0 deletions Documentation/devicetree/bindings/soc/apple/apple,sart-apif.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/apple/apple,sart-apif.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple SART mediated through Aura APIF

maintainers:
- Dj <hey@djdev.me>

description: |
SART provider using native SPTM table-5 calls. Existing consumers reference
this provider through their apple,sart phandle. Linux tracks only its own
regions; unknown firmware grants are not reported as inherited regions.

properties:
compatible:
const: apple,sart-apif
aurora,apif:
$ref: /schemas/types.yaml#/definitions/phandle
description: APIF version-2 transport provider.

required:
- compatible
- aurora,apif

additionalProperties: false

examples:
- |
sart {
compatible = "apple,sart-apif";
aurora,apif = <&apif>;
};
100 changes: 100 additions & 0 deletions Documentation/driver-api/firmware/aurora-apif.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.. SPDX-License-Identifier: GPL-2.0-only

===============================================
Aurora Platform Interface over Memory-Mapped I/O
===============================================

Aura is Aurora's EL2-resident monitor for Apple Silicon, providing SPTM
mediation and nested virtualization. APIF is a synchronous, trusted-kernel
transport. Linux supplies native selectors and endpoint arguments; Aura
forwards them unchanged. Invalid native calls can stop the machine. This
interface does not isolate an untrusted kernel.

Wire contract
=============

The version-2 synthetic register page occupies 16 KiB at guest IPA 0x61ff0000.
Registers are little-endian 64-bit fields: magic at 0x000 is
0x4f494d4d46495041 (APIFMMIO), version at 0x008 is 2, maximum operations at
0x010, and feature flags at 0x018 (bit 0 native, bit 1 memory, bit 2 I/O).
A 64-bit write at 0x100 supplies a 16-byte-aligned guest IPA for the batch.
The entire buffer must fit within one guest RAM bank. The register page is
unmapped at guest stage 2; Aura handles its data aborts.

A batch has a 16-byte header (u32 count, u32 flags, s32 status, u32 done),
then count 64-byte operations (u64 selector, u64 arg[6], u64 ret). Flags are
zero. Selector upper/lower halves give native table/endpoint (x16); arguments
are native x0-x5 and ret is native x0, unchanged. Transport status does not
interpret native results. Void and boolean endpoints need different caller
handling. A failed Aura service stops the batch; done is the completed prefix.

Each client owns a physically contiguous buffer and serializes its submissions
with IRQs masked. The transport orders memory around the trapping store and
preserves the Linux stack in x9 across the synchronous redispatch contract.
Device links order supplier lifetime; client revocation drains submissions and
subsequent calls return ENODEV. It is safe to call from atomic context. Provider
and consumers must be described together in the guest DT; this series does not
rewrite existing board DTs or enable the backend on an existing boot.

Ownership services
==================

Table 0xffffffff supplies Aura services (other tables are native selectors):

* 1 TRANSLATE(guest IPA, size): native PA for a contiguous guest range.
* 2 ALLOC_FRAME(owner, address): zeroed 16 KiB native frame, CPU alias removed.
* 3 FREE_FRAME(PA): restore Aura's alias after detachment and retype to type 11.
* 4 MAP_IO(guest IPA, PA, size, readonly): map bounded page-aligned device I/O.
* 5 GUEST_ROOT(): guest stage-2 root PA.
* 6 BOOT_IOMMU(kind, unit, SID, index, output IPA, size): bootstrap snapshot.
* 7 BOOT_TABLE(kind, unit, SID, address, level): existing bootstrap table PA.
* 8 FIND_FRAME(owner, address): registered lent frame PA or zero.
* 9 TAG_FRAME(PA, owner, address): register a unique opaque key after attachment.

Unused arguments are zero. Frame keys are bookkeeping, not an ownership
transition. The pool is capped at 1024 frames. Never free attached or uncertain
frames. MAP_IO does not roll back a partially successful mapping; a failed
mapping requires recovery before its address range can be reused. Initialize
batch status to EINPROGRESS so a missing completion cannot be mistaken for
success. Lost table-operation completion stops further DART transactions.

BOOT_IOMMU kind 0 means DART. Index U64_MAX returns root level, run count and
DVA aperture; another index returns a retained mapping. The 64-byte output is
u64 level, count, base, size, pa, ipa, attrs, reserved. An unavailable IPA is
U64_MAX. BOOT_TABLE levels 0-2 return existing bootstrap tables, while U64_MAX
returns the bootstrap initialized flag. Bootstrap queries never replay maps.

DART and SART providers
=======================

APPLE_DART_APIF supplies an IOMMU provider for apple,dart-apif. It preserves
stream groups, shared IOVA allocation, retained mappings, bounded batches and
partial-prefix rollback. Linux builds native physical page lists, complements
IOMMU allow bits into native deny bits, and sets up typed tables. Both DMA
backing and list-buffer pointers are translated before native calls. Retained
streams remain reserved and are excluded from ordinary power-down.

APPLE_SART_APIF supplies apple,sart-apif through the existing apple_sart API.
The raw MMIO provider continues using its current operations. The APIF provider
tracks Linux-owned regions and respects endpoint-specific return semantics;
unknown firmware grants are not advertised as inherited. Neither provider
prints routine successful calls or runs probe-time mapping self-tests.

The existing arm64 TSO task interface discovers guest ACTLR support through
its toggle/readback probe; APIF does not add a second TSO protocol. The Apple
WFI preservation quirk also covers captured T6050 parts 0x064/0x065 and uses
the same CPU predicate to avoid unsafe timed waits in arbitrary delay callers.
Existing CPU ranges are preserved. This does not claim future Ultra support.

Validation
==========

Build the providers and run the production-function host tests with::

make ARCH=arm64 LLVM=1 Image
make -C tools/testing/selftests/aurora-apif run_tests

Host tests exercise framing, prefix completion, ownership ordering, list
translation and endpoint return handling. Hardware validation of this cleaned
version-2 integration is pending. GPU backend changes are outside this series;
legacy version-1 Aura aliases remain available to existing clients.
1 change: 1 addition & 0 deletions Documentation/driver-api/firmware/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Linux Firmware API

.. toctree::

aurora-apif
introduction
core
efi/index
Expand Down
15 changes: 15 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4359,6 +4359,21 @@ F: rust/helpers/auxiliary.c
F: rust/kernel/auxiliary.rs
F: samples/rust/rust_driver_auxiliary.rs

AURORA PLATFORM MMIO INTERFACE
M: Dj <hey@djdev.me>
S: Maintained
F: Documentation/devicetree/bindings/firmware/aurora,apif-mmio.yaml
F: Documentation/devicetree/bindings/iommu/apple,dart-apif.yaml
F: Documentation/devicetree/bindings/soc/apple/apple,sart-apif.yaml
F: Documentation/driver-api/firmware/aurora-apif.rst
F: drivers/firmware/aurora-apif-mmio.c
F: drivers/iommu/apple-dart-apif.c
F: drivers/soc/apple/apple-sart-apif.c
F: drivers/soc/apple/sart-backend.h
F: include/linux/apple-dart-apif.h
F: include/linux/soc/aurora/apif-mmio.h
F: tools/testing/selftests/aurora-apif/

AUXILIARY DISPLAY DRIVERS
M: Andy Shevchenko <andy@kernel.org>
R: Geert Uytterhoeven <geert@linux-m68k.org>
Expand Down
17 changes: 16 additions & 1 deletion arch/arm64/include/asm/apple-idle.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,22 @@
#ifndef __ASM_APPLE_IDLE_H
#define __ASM_APPLE_IDLE_H

/* WFI that preserves x18-x30 on affected Apple cores (T8140 and T8152). */
#include <linux/jump_label.h>

#ifdef CONFIG_ARCH_APPLE
extern struct static_key_false apple_wfi_loses_regs;
static __always_inline bool apple_wfi_needs_save(void)
{
return static_branch_unlikely(&apple_wfi_loses_regs);
}
#else
static __always_inline bool apple_wfi_needs_save(void)
{
return false;
}
#endif

/* WFI that preserves x18-x30 on cores selected by the idle quirk. */
void apple_cpu_wfi(void);

#endif
4 changes: 4 additions & 0 deletions arch/arm64/include/asm/cputype.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@
#define APPLE_CPU_PART_TAHITI_P 0x061
#define APPLE_CPU_PART_T8142_E 0x062
#define APPLE_CPU_PART_T8142_P 0x063
#define APPLE_CPU_PART_T6050_064 0x064
#define APPLE_CPU_PART_T6050_065 0x065
#define APPLE_CPU_PART_T8152_E 0x072
#define APPLE_CPU_PART_T8152_P 0x073

Expand Down Expand Up @@ -256,6 +258,8 @@
#define MIDR_APPLE_TAHITI_P MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_TAHITI_P)
#define MIDR_APPLE_T8142_E MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T8142_E)
#define MIDR_APPLE_T8142_P MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T8142_P)
#define MIDR_APPLE_T6050_064 MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T6050_064)
#define MIDR_APPLE_T6050_065 MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T6050_065)
#define MIDR_APPLE_T8152_E MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T8152_E)
#define MIDR_APPLE_T8152_P MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_T8152_P)
#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
Expand Down
18 changes: 5 additions & 13 deletions arch/arm64/kernel/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,20 @@ early_param("idle", setup_idle);

#ifdef CONFIG_ARCH_APPLE
/*
* Apple T8140 (A18 Pro), T8142 (M5), and T8152 (M6) CPUs can return from
* Apple T8140 (A18 Pro), T8142 (M5), T6050, and T8152 (M6) CPUs can return from
* WFI with general-purpose registers cleared. T8140 also loses FP/SIMD
* state; conservatively preserve it on all three parts. The key is enabled once
* state; conservatively preserve it on these parts. The key is enabled once
* at boot on those parts; everywhere else the check is a patched-out branch.
*/
static DEFINE_STATIC_KEY_FALSE(apple_wfi_loses_regs);
DEFINE_STATIC_KEY_FALSE(apple_wfi_loses_regs);

static const struct midr_range apple_wfi_loses_regs_cpus[] __initconst = {
MIDR_ALL_VERSIONS(MIDR_APPLE_TAHITI_E),
MIDR_ALL_VERSIONS(MIDR_APPLE_TAHITI_P),
MIDR_ALL_VERSIONS(MIDR_APPLE_T8142_E),
MIDR_ALL_VERSIONS(MIDR_APPLE_T8142_P),
MIDR_ALL_VERSIONS(MIDR_APPLE_T6050_064),
MIDR_ALL_VERSIONS(MIDR_APPLE_T6050_065),
MIDR_ALL_VERSIONS(MIDR_APPLE_T8152_E),
MIDR_ALL_VERSIONS(MIDR_APPLE_T8152_P),
{}
Expand All @@ -67,16 +69,6 @@ static int __init apple_wfi_quirk_init(void)
return 0;
}
early_initcall(apple_wfi_quirk_init);

static __always_inline bool apple_wfi_needs_save(void)
{
return static_branch_unlikely(&apple_wfi_loses_regs);
}
#else
static __always_inline bool apple_wfi_needs_save(void)
{
return false;
}
#endif

/*
Expand Down
Loading