diff --git a/Documentation/devicetree/bindings/display/apple,dcp.yaml b/Documentation/devicetree/bindings/display/apple,dcp.yaml index c67a71b7a169b..38be82bc7d1bd 100644 --- a/Documentation/devicetree/bindings/display/apple,dcp.yaml +++ b/Documentation/devicetree/bindings/display/apple,dcp.yaml @@ -35,7 +35,6 @@ properties: - apple,t6020-dcpext - apple,t6041-dcpext - const: apple,dcpext - - const: apple,t6041-dcpext - items: - const: apple,t8140-dcpext - const: apple,dcp @@ -295,8 +294,6 @@ properties: '#size-cells': const: 2 - ranges: true - piodma: type: object properties: @@ -393,19 +390,10 @@ allOf: pattern: '^(dp-xbar|typec[0-9]+)$' - if: not: - anyOf: - - properties: - compatible: - contains: - const: apple,t8132-dcp - - properties: - compatible: - contains: - const: apple,t6041-dcpext - status: - const: disabled - required: - - status + properties: + compatible: + contains: + const: apple,t8132-dcp then: required: - apple,bw-scratch diff --git a/Documentation/devicetree/bindings/phy/apple,t6040-atcphy.yaml b/Documentation/devicetree/bindings/phy/apple,t6040-atcphy.yaml index 7f24f79264211..04c8907584946 100644 --- a/Documentation/devicetree/bindings/phy/apple,t6040-atcphy.yaml +++ b/Documentation/devicetree/bindings/phy/apple,t6040-atcphy.yaml @@ -106,8 +106,8 @@ properties: port: $ref: /schemas/graph.yaml#/properties/port description: > - Link to the SuperSpeed lanes of the Type-C connector, or to the DCP - DisplayPort output on a fixed DisplayPort PHY. + Link to the SuperSpeed lanes of the Type-C connector. Absent on a fixed + DisplayPort PHY. apple,tunable-axi2af: $ref: "#/$defs/apple,tunable" @@ -174,6 +174,7 @@ allOf: "#reset-cells": false orientation-switch: false mode-switch: false + port: false additionalProperties: false diff --git a/Documentation/devicetree/bindings/sound/apple,t6030-dpaudio.yaml b/Documentation/devicetree/bindings/sound/apple,t6030-dpaudio.yaml index bb92d6a30c428..9b4e9328d9020 100644 --- a/Documentation/devicetree/bindings/sound/apple,t6030-dpaudio.yaml +++ b/Documentation/devicetree/bindings/sound/apple,t6030-dpaudio.yaml @@ -4,36 +4,29 @@ $id: http://devicetree.org/schemas/sound/apple,t6030-dpaudio.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Apple T6030 and T6041 DisplayPort audio +title: Apple T6030 DisplayPort audio maintainers: - Ryan Murray description: | - Each DisplayPort audio interface has no application-processor registers. - Samples arrive through SIO, and the graph connects the interface to port 0 - of the display processor that owns its audio service. An interface without - an assigned display processor has no graph connection and remains disabled. - - T6041 requires a generation-specific SIO firmware backend and a compatible - display audio service before these interfaces can be enabled. + The external display processor provides the HDMI port's audio service. + Its DisplayPort audio interface has no application-processor registers. + Samples arrive through SIO, and the graph connects this interface to + port 0 of the display processor that owns the audio service. select: properties: compatible: contains: - enum: - - apple,t6030-dpaudio - - apple,t6041-dpaudio + const: apple,t6030-dpaudio required: - compatible properties: compatible: items: - - enum: - - apple,t6030-dpaudio - - apple,t6041-dpaudio + - const: apple,t6030-dpaudio - const: apple,dpaudio dmas: @@ -59,26 +52,6 @@ required: - dmas - dma-names - power-domains - -allOf: - - if: - properties: - compatible: - contains: - const: apple,t6030-dpaudio - then: - required: - - ports - - - if: - not: - required: - - ports - then: - properties: - status: - const: disabled - required: - - status + - ports additionalProperties: false diff --git a/Documentation/soc/apple/t8140-pmp-dvfs.rst b/Documentation/soc/apple/t8140-pmp-dvfs.rst deleted file mode 100644 index 7ec4ae7366ed9..0000000000000 --- a/Documentation/soc/apple/t8140-pmp-dvfs.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0-only - -T8140 PMP DVFS diagnostics -========================= - -The existing PMP report provider exposes a read-only ``dvfs`` file under -``/sys/kernel/debug/apple-pmp-/`` on T8140. The provider must be -bound; the file is readable by root. Its output lists ADT report entries -8 through 11 and both raw 64-bit words of each 16-byte entry. Only those four entries -are read. The report aperture is not dumped. - -Reading returns ``EAGAIN`` if the PMP running bit is clear before or after -sampling. Entries are sampled individually, rather than as an atomic -firmware snapshot. A running PMP alone does not establish freshness of -each value. - -The field encoding and conversion to clock rates are not yet established. -Values must not be interpreted as Hz, temperatures, or verified hardware -clock states. This interface changes neither firmware requests nor cache -allocation nor thermal policy. - -CPU temperatures remain available through ``macsmc-hwmon``. CPU cooling -and firmware frequency limits remain under their existing drivers. The -DVFS diagnostic file is not a thermal sensor. diff --git a/MAINTAINERS b/MAINTAINERS index 8b2cc48645bf4..d966b42b5cbe6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2110,7 +2110,6 @@ F: Documentation/devicetree/bindings/sound/apple,t8140-aop-audio.yaml F: Documentation/devicetree/bindings/usb/vialab,vl122.yaml F: Documentation/gpu/apple-dcp-backlight.rst F: Documentation/hid/apple-j700-multitouch.rst -F: Documentation/soc/apple/t8140-pmp-dvfs.rst F: Documentation/networking/device_drivers/wifi/mt7932-neo.rst F: arch/arm64/boot/dts/apple/t8140* F: arch/arm64/configs/j700*.config @@ -2809,13 +2808,6 @@ S: Maintained F: Documentation/devicetree/bindings/spi/apple,qspi.yaml F: drivers/spi/spi-apple-qspi.c -ARM/APPLE QSPIMC DRIVER -M: Ryan Murray -W: https://aurora-silicon.github.io -S: Maintained -F: Documentation/devicetree/bindings/spi/apple,qspi.yaml -F: drivers/spi/spi-apple-qspi.c - ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson M: Lars Persson diff --git a/arch/arm64/boot/dts/apple/t6040-dpaudio.dtsi b/arch/arm64/boot/dts/apple/t6040-dpaudio.dtsi deleted file mode 100644 index 68d346a4e1160..0000000000000 --- a/arch/arm64/boot/dts/apple/t6040-dpaudio.dtsi +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * DPA interfaces are fed by SIO and have no AP-side MMIO registers. - * Keep them disabled until the T6041 SIO firmware and DCP audio services - * are supported. DPA3/4 have no assigned DCP in this SoC's firmware tree. - */ - -/ { - dpaudio0: audio-controller-0 { - compatible = "apple,t6041-dpaudio", "apple,dpaudio"; - dmas = <&sio 0x64>; - dma-names = "tx"; - power-domains = <&ps_dpa0>; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dpaudio0_dcp: endpoint { - remote-endpoint = <&dcp_audio>; - }; - }; - }; - }; - - dpaudio1: audio-controller-1 { - compatible = "apple,t6041-dpaudio", "apple,dpaudio"; - dmas = <&sio 0x66>; - dma-names = "tx"; - power-domains = <&ps_dpa1>; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dpaudio1_dcp: endpoint { - remote-endpoint = <&dcpext0_audio>; - }; - }; - }; - }; - - dpaudio2: audio-controller-2 { - compatible = "apple,t6041-dpaudio", "apple,dpaudio"; - dmas = <&sio 0x68>; - dma-names = "tx"; - power-domains = <&ps_dpa2>; - status = "disabled"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dpaudio2_dcp: endpoint { - remote-endpoint = <&dcpext1_audio>; - }; - }; - }; - }; - - dpaudio3: audio-controller-3 { - compatible = "apple,t6041-dpaudio", "apple,dpaudio"; - dmas = <&sio 0x6a>; - dma-names = "tx"; - power-domains = <&ps_dpa3>; - status = "disabled"; - }; - - dpaudio4: audio-controller-4 { - compatible = "apple,t6041-dpaudio", "apple,dpaudio"; - dmas = <&sio 0x6c>; - dma-names = "tx"; - power-domains = <&ps_dpa4>; - status = "disabled"; - }; -}; - -&dcp { - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dcp_audio: endpoint { - remote-endpoint = <&dpaudio0_dcp>; - }; - }; - }; -}; - -&dcpext0 { - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dcpext0_audio: endpoint { - remote-endpoint = <&dpaudio1_dcp>; - }; - }; - }; -}; - -&dcpext1 { - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dcpext1_audio: endpoint { - remote-endpoint = <&dpaudio2_dcp>; - }; - }; - }; -}; diff --git a/arch/arm64/configs/asahi.config b/arch/arm64/configs/asahi.config index fcf0d27611aae..4422527c3ed65 100644 --- a/arch/arm64/configs/asahi.config +++ b/arch/arm64/configs/asahi.config @@ -3,11 +3,16 @@ # olddefconfig and verify that the requested settings survive resolution. # Device-specific boot, debug and distribution policy stays in the base. CONFIG_RUST=y +CONFIG_ARM64_ACTLR_STATE=y +CONFIG_ARCH_APPLE=y +# CONFIG_ARM64_4K_PAGES is not set CONFIG_ARM64_16K_PAGES=y +# CONFIG_ARM64_64K_PAGES is not set CONFIG_ARM64_VA_BITS_48=y CONFIG_ARM64_USER4K_EXPERIMENTAL=y CONFIG_ARM64_MEMORY_MODEL_CONTROL=y CONFIG_ARM_APPLE_CPUIDLE=y +CONFIG_ARM_APPLE_SOC_CPUFREQ=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y # CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y @@ -15,17 +20,27 @@ CONFIG_BT_BRCMEXT=y CONFIG_BT_HCIBCM4377=m CONFIG_BT_MTK7932_PCIE=m CONFIG_PCIE_APPLE=y +CONFIG_NVME_APPLE=m CONFIG_MMC_SDHCI_PCI=m +CONFIG_BRCMFMAC=m CONFIG_BRCMFMAC_PCIE=y CONFIG_PCIE_APPLE_PIODMA_DIAG=y CONFIG_PCIEASPM=y CONFIG_NET_VENDOR_INTEL=y +CONFIG_IGB=m CONFIG_IGC=m CONFIG_MT7932_FULLMAC=m +CONFIG_TOUCHSCREEN_APPLE_Z2=m CONFIG_INPUT_MACSMC_INPUT=m +CONFIG_I2C_APPLE=m +CONFIG_SPI_APPLE=m CONFIG_SPI_APPLE_QSPI=m CONFIG_SPMI_APPLE=y +CONFIG_PINCTRL_APPLE_GPIO=m +CONFIG_GPIO_MACSMC=m +CONFIG_POWER_RESET_MACSMC=m CONFIG_MACSMC_POWER=m +CONFIG_SENSORS_MACSMC_HWMON=m CONFIG_SENSORS_APPLE_PMP_J613=m CONFIG_THERMAL_NETLINK=y CONFIG_NVME_HWMON=y @@ -37,7 +52,6 @@ CONFIG_VIDEO_APPLE_AVD=m CONFIG_VIDEO_APPLE_ISP=m CONFIG_DRM=y CONFIG_DRM_ASAHI=m -CONFIG_DRM_ASAHI_G15=y CONFIG_DRM_ASAHI_G16=y CONFIG_DRM_ADP=m CONFIG_DRM_APPLE=m @@ -48,53 +62,76 @@ CONFIG_DRM_ACCEL_ANE=m CONFIG_DRM_SIMPLEDRM=y CONFIG_SYSFB_SIMPLEFB=y CONFIG_SND_SOC_APPLE_AOP_AUDIO=m +CONFIG_SND_SOC_APPLE_MCA=m CONFIG_SND_SOC_APPLE_MACAUDIO=m CONFIG_SND_SOC_CS42L83=m CONFIG_SND_SOC_CS42L84=m +CONFIG_SND_SOC_MAX98357A=m CONFIG_SND_SOC_TAS2764=m CONFIG_SND_SOC_TAS2770=m CONFIG_HID_APPLE=m CONFIG_HID_MAGICMOUSE=m CONFIG_HID_APPLE_MTP_HAPTIC=m +CONFIG_SERIAL_SAMSUNG=y +CONFIG_SERIAL_SAMSUNG_CONSOLE=y CONFIG_HID_DOCKCHANNEL=m CONFIG_SPI_HID_APPLE_OF=m +CONFIG_SPI_HID_APPLE_CORE=m CONFIG_USB_DWC3_APPLE=m +CONFIG_TYPEC=m CONFIG_USB4=m CONFIG_USB4_APPLE_SOC=m CONFIG_USB_XHCI_PCI_ASMEDIA=y CONFIG_TYPEC_SN201202X=m CONFIG_RTC_DRV_MACSMC=y CONFIG_RTC_DRV_APPLE_PMU=m +CONFIG_APPLE_ADMAC=m CONFIG_APPLE_SIO=m CONFIG_MFD_MACSMC=y +CONFIG_COMMON_CLK_APPLE_NCO=m CONFIG_APPLE_DART=y CONFIG_APPLE_DART_J713_DCP=y CONFIG_APPLE_DOCKCHANNEL=m CONFIG_SERIAL_APPLE_DOCKCHANNEL=y CONFIG_SERIAL_APPLE_DOCKCHANNEL_EARLYCON=y +CONFIG_APPLE_MAILBOX=y CONFIG_APPLE_PMGR_MISC=y +CONFIG_APPLE_RTKIT=y CONFIG_APPLE_RTKIT_HELPER=m +CONFIG_APPLE_SART=m +CONFIG_RUST_APPLE_RTKIT=y +CONFIG_APPLE_AOP=m +CONFIG_HW_RANDOM=y +CONFIG_KEYS=y CONFIG_TRUSTED_KEYS=y # CONFIG_TRUSTED_KEYS_TPM is not set # CONFIG_TRUSTED_KEYS_TEE is not set CONFIG_APPLE_SEP=m CONFIG_APPLE_PMGR_PWRSTATE=y CONFIG_APPLE_PMP=m +CONFIG_APPLE_PMP_REPORT=y CONFIG_APPLE_PMP_THERMAL=m CONFIG_APPLE_T8132_PLATFORM_HANDOFF=y CONFIG_IIO_AOP_SENSOR_LAS=m CONFIG_IIO_AOP_SENSOR_ALS=m +CONFIG_RUST_FW_LOADER_ABSTRACTIONS=y +CONFIG_PWM_APPLE=m +CONFIG_APPLE_AIC=y CONFIG_PHY_APPLE_ATC=m CONFIG_PHY_APPLE_T6040_USB2=m CONFIG_PHY_APPLE_DPTX=m +CONFIG_APPLE_M1_CPU_PMU=y +CONFIG_NVMEM_APPLE_EFUSES=m CONFIG_NVMEM_APPLE_SPMI=y CONFIG_MUX_APPLE_DPXBAR=m +CONFIG_TYPEC_TPS6598X=m CONFIG_RESET_APPLE_CIO=y CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_RDMA_RXE=m CONFIG_RDMA_SIW=m +CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_UDMABUF=y CONFIG_DETECT_HUNG_TASK=y diff --git a/drivers/gpu/drm/apple/av-lifetime-test.c b/drivers/gpu/drm/apple/av-lifetime-test.c index 7485436cbf595..193358ce2bfba 100644 --- a/drivers/gpu/drm/apple/av-lifetime-test.c +++ b/drivers/gpu/drm/apple/av-lifetime-test.c @@ -156,7 +156,6 @@ static struct av_life_test *av_life_setup(struct kunit *test, work_func_t owner_ dev_set_drvdata(t->dev, t->dcp); spin_lock_init(&t->ep->lock); INIT_LIST_HEAD(&t->ep->compact_cmds); - mutex_init(&t->ep->compact_tx_lock); init_rwsem(&t->asrv->srv_rwsem); INIT_WORK(&t->asrv->start_av_service_wq, owner_fn); INIT_WORK(&t->asrv->terminate_wq, owner_fn); @@ -487,7 +486,6 @@ static struct av_life_test *av_life_group_setup(struct kunit *test, KUNIT_ASSERT_NOT_NULL(test, t->ep); spin_lock_init(&t->ep->lock); INIT_LIST_HEAD(&t->ep->compact_cmds); - mutex_init(&t->ep->compact_tx_lock); t->ep->dcp = t->dcp; t->wq = alloc_ordered_workqueue("av-lifetime-devres", 0); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, t->wq); diff --git a/drivers/gpu/drm/asahi/crashdump.rs b/drivers/gpu/drm/asahi/crashdump.rs deleted file mode 100644 index 148cae7aa9b46..0000000000000 --- a/drivers/gpu/drm/asahi/crashdump.rs +++ /dev/null @@ -1,307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only OR MIT - -//! GPU crash dump formatter -//! -//! Takes a raw dump of firmware/kernel mapped pages from `pgtable` and formats it into -//! an ELF core dump suitable for dumping into userspace. - -use core::mem::size_of; - -use kernel::{ - devcoredump::DevCoreDump, - error::Result, - page::{Page, PAGE_MASK, PAGE_SHIFT, PAGE_SIZE}, - prelude::*, - types::Owned, - uapi, -}; - -use crate::hw; -use crate::pgtable::{self, DumpedPage, Prot, UAT_PGSZ}; -use crate::util::align; - -pub(crate) struct CrashDump { - headers: KVVec, - pages: KVVec>, -} - -const NOTE_NAME_AGX: &str = "AGX"; -const NOTE_AGX_DUMP_INFO: u32 = 1; - -const NOTE_NAME_RTKIT: &str = "RTKIT"; -const NOTE_RTKIT_CRASHLOG: u32 = 1; - -#[repr(C)] -pub(crate) struct AGXDumpInfo { - initdata_address: u64, - chip_id: u32, - gpu_gen: hw::GpuGen, - gpu_variant: hw::GpuVariant, - gpu_rev: hw::GpuRevision, - total_active_cores: u32, - firmware_version: [u32; 6], - reserved: u32, -} - -struct ELFNote { - name: &'static str, - ty: u32, - data: KVVec, -} - -pub(crate) struct CrashDumpBuilder { - page_dump: KVVec, - notes: KVec, -} - -/// Helper to convert ELF headers into byte slices -/// TODO: Hook this up into kernel::AsBytes somehow -/// -/// # Safety -/// -/// Types implementing this trait must have no padding bytes. -unsafe trait AsBytes: Sized { - fn as_bytes(&self) -> &[u8] { - // SAFETY: This trait is only implemented for types with no padding bytes - unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, size_of::()) } - } - fn slice_as_bytes(slice: &[Self]) -> &[u8] { - // SAFETY: This trait is only implemented for types with no padding bytes - unsafe { - core::slice::from_raw_parts(slice.as_ptr() as *const u8, core::mem::size_of_val(slice)) - } - } -} - -// SAFETY: This type has no padding -unsafe impl AsBytes for uapi::Elf64_Ehdr {} -// SAFETY: This type has no padding -unsafe impl AsBytes for uapi::Elf64_Phdr {} -// SAFETY: This type has no padding -unsafe impl AsBytes for uapi::Elf64_Nhdr {} -// SAFETY: This type has no padding -unsafe impl AsBytes for AGXDumpInfo {} - -const FIRMWARE_ENTRYPOINT: u64 = 0xFFFFFF8000000000u64; - -impl CrashDumpBuilder { - pub(crate) fn new(page_dump: KVVec) -> Result { - Ok(CrashDumpBuilder { - page_dump, - notes: KVec::new(), - }) - } - - pub(crate) fn add_agx_info( - &mut self, - cfg: &hw::HwConfig, - dyncfg: &hw::DynConfig, - initdata_address: u64, - ) -> Result { - let mut info = AGXDumpInfo { - chip_id: cfg.chip_id, - gpu_gen: dyncfg.id.gpu_gen, - gpu_variant: dyncfg.id.gpu_variant, - gpu_rev: dyncfg.id.gpu_rev, - total_active_cores: dyncfg.id.total_active_cores, - firmware_version: [0; 6], - reserved: 0, - initdata_address, - }; - info.firmware_version[..dyncfg.firmware_version.len().min(6)] - .copy_from_slice(&dyncfg.firmware_version); - - let mut data = KVVec::new(); - data.extend_from_slice(info.as_bytes(), GFP_KERNEL)?; - - self.notes.push( - ELFNote { - name: NOTE_NAME_AGX, - ty: NOTE_AGX_DUMP_INFO, - data, - }, - GFP_KERNEL, - )?; - Ok(()) - } - - pub(crate) fn add_crashlog(&mut self, crashlog: &[u8]) -> Result { - let mut data = KVVec::new(); - data.extend_from_slice(crashlog, GFP_KERNEL)?; - - self.notes.push( - ELFNote { - name: NOTE_NAME_RTKIT, - ty: NOTE_RTKIT_CRASHLOG, - data, - }, - GFP_KERNEL, - )?; - - Ok(()) - } - - pub(crate) fn finalize(self) -> Result { - let CrashDumpBuilder { page_dump, notes } = self; - - let mut ehdr: uapi::Elf64_Ehdr = Default::default(); - - ehdr.e_ident[uapi::EI_MAG0 as usize..=uapi::EI_MAG3 as usize].copy_from_slice(b"\x7fELF"); - ehdr.e_ident[uapi::EI_CLASS as usize] = uapi::ELFCLASS64 as u8; - ehdr.e_ident[uapi::EI_DATA as usize] = uapi::ELFDATA2LSB as u8; - ehdr.e_ident[uapi::EI_VERSION as usize] = uapi::EV_CURRENT as u8; - ehdr.e_type = uapi::ET_CORE as u16; - ehdr.e_machine = uapi::EM_AARCH64 as u16; - ehdr.e_version = uapi::EV_CURRENT; - ehdr.e_entry = FIRMWARE_ENTRYPOINT; - ehdr.e_ehsize = core::mem::size_of::() as u16; - ehdr.e_phentsize = core::mem::size_of::() as u16; - - let phdr_offset = core::mem::size_of::(); - - // PHDRs come after the ELF header - ehdr.e_phoff = phdr_offset as u64; - - let mut phdrs = KVVec::new(); - - // First PHDR is the NOTE section - phdrs.push( - uapi::Elf64_Phdr { - p_type: uapi::PT_NOTE, - p_flags: uapi::PF_R, - p_align: 1, - ..Default::default() - }, - GFP_KERNEL, - )?; - - // Generate the page phdrs. The offset will be fixed up later. - let mut off: usize = 0; - let mut next = None; - let mut pages: KVVec> = KVVec::new(); - - for mut page in page_dump { - let vaddr = page.iova; - let paddr = page.pte & pgtable::PTE_ADDR_BITS; - let flags = Prot::from_pte(page.pte).elf_flags(); - let valid = page.data.is_some(); - let cur = (vaddr, paddr, flags, valid); - if Some(cur) != next { - phdrs.push( - uapi::Elf64_Phdr { - p_type: uapi::PT_LOAD, - p_offset: if valid { off as u64 } else { 0 }, - p_vaddr: vaddr, - p_paddr: paddr, - p_filesz: if valid { UAT_PGSZ as u64 } else { 0 }, - p_memsz: UAT_PGSZ as u64, - p_flags: flags, - p_align: UAT_PGSZ as u64, - }, - GFP_KERNEL, - )?; - if valid { - off += UAT_PGSZ; - } - } else { - let ph = phdrs.last_mut().unwrap(); - ph.p_memsz += UAT_PGSZ as u64; - if valid { - ph.p_filesz += UAT_PGSZ as u64; - off += UAT_PGSZ; - } - } - if let Some(data_page) = page.data.take() { - pages.push(data_page, GFP_KERNEL)?; - } - next = Some(( - vaddr + UAT_PGSZ as u64, - paddr + UAT_PGSZ as u64, - flags, - valid, - )); - } - - ehdr.e_phnum = phdrs.len() as u16; - - let note_offset = phdr_offset + size_of::() * phdrs.len(); - - let mut note_data: KVVec = KVVec::new(); - - for note in notes { - let hdr = uapi::Elf64_Nhdr { - n_namesz: note.name.len() as u32 + 1, - n_descsz: note.data.len() as u32, - n_type: note.ty, - }; - note_data.extend_from_slice(hdr.as_bytes(), GFP_KERNEL)?; - note_data.extend_from_slice(note.name.as_bytes(), GFP_KERNEL)?; - note_data.push(0, GFP_KERNEL)?; - while note_data.len() & 3 != 0 { - note_data.push(0, GFP_KERNEL)?; - } - note_data.extend_from_slice(¬e.data, GFP_KERNEL)?; - while note_data.len() & 3 != 0 { - note_data.push(0, GFP_KERNEL)?; - } - } - - // NOTE section comes after the PHDRs - phdrs[0].p_offset = note_offset as u64; - phdrs[0].p_filesz = note_data.len() as u64; - - // Align data section to the page size - let data_offset = align(note_offset + note_data.len(), UAT_PGSZ); - - // Fix up data PHDR offsets - for phdr in &mut phdrs[1..] { - phdr.p_offset += data_offset as u64; - } - - // Build ELF header buffer - let mut headers: KVVec = KVVec::from_elem(0, data_offset, GFP_KERNEL)?; - - headers[0..size_of::()].copy_from_slice(ehdr.as_bytes()); - headers[phdr_offset..phdr_offset + phdrs.len() * size_of::()] - .copy_from_slice(AsBytes::slice_as_bytes(&phdrs)); - headers[note_offset..note_offset + note_data.len()].copy_from_slice(¬e_data); - - Ok(CrashDump { headers, pages }) - } -} - -impl DevCoreDump for CrashDump { - fn read(&self, buf: &mut [u8], mut offset: usize) -> Result { - let mut read = 0; - let mut left = buf.len(); - if offset < self.headers.len() { - let block = left.min(self.headers.len() - offset); - buf[..block].copy_from_slice(&self.headers[offset..offset + block]); - read += block; - offset += block; - left -= block; - } - if left == 0 { - return Ok(read); - } - offset -= self.headers.len(); // Offset from the page area - - while left > 0 { - let page_index = offset >> PAGE_SHIFT; - let page_offset = offset & !PAGE_MASK; - let block = left.min(PAGE_SIZE - page_offset); - let Some(page) = self.pages.get(page_index) else { - break; - }; - let slice = &mut buf[read..read + block]; - // SAFETY: We own the page, and the slice guarantees the - // dst length is sufficient. - unsafe { page.read_raw(slice.as_mut_ptr(), page_offset, slice.len())? }; - read += block; - offset += block; - left -= block; - } - - Ok(read) - } -} diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c index 09b2f86cff0a3..84cef035e0865 100644 --- a/drivers/phy/apple/atc.c +++ b/drivers/phy/apple/atc.c @@ -4326,9 +4326,6 @@ static int atcphy_usb3_set_mode(struct phy *phy, enum phy_mode mode, int submode mode == PHY_MODE_USB_DEVICE) return -EOPNOTSUPP; - if (atcphy->usb_off_pending) - return -EBUSY; - switch (mode) { case PHY_MODE_USB_HOST: atcphy->host_active = true; diff --git a/tools/asahi/apple-dart-range-tests.py b/tools/asahi/apple-dart-range-tests.py index d389d95be5920..5d311fef0813d 100644 --- a/tools/asahi/apple-dart-range-tests.py +++ b/tools/asahi/apple-dart-range-tests.py @@ -43,34 +43,36 @@ def main(): struct apple_dart; struct apple_dart_stream_map { struct apple_dart *dart; unsigned long sidmap[1]; }; struct apple_dart_hw { int (*invalidate_tlb)(struct apple_dart_stream_map *); }; -struct apple_dart { int num_streams, locked, version; void *dev; struct apple_dart_hw *hw; }; +struct apple_dart { int num_streams, locked, version; bool fw_mirror, fw_handoff, managed_sids; void *dev; struct apple_dart_hw *hw; }; struct apple_dart_atomic_stream_map { struct apple_dart *dart; unsigned long sidmap[1]; }; struct apple_dart_domain { - void *pgtbl_ops, *dcp; struct apple_dart_atomic_stream_map streams[2]; int count; + void *pgtbl_ops; bool dcp; struct apple_dart_atomic_stream_map streams[2]; int count; u64 dma_offset, mask; }; #define for_each_stream_map(i,d,m) for ((i)=0; (i)<(d)->count && ((m)=&(d)->streams[i],1); (i)++) -static int powered, power_error, sync_error, range_error, syncs, ranges, fulls; +static int powered, power_error, sync_error, range_error, syncs, ranges, fulls, firmware_flushes, quarantines, dcp_flushes; static u64 seen_first, seen_last; -static int pm_runtime_resume_and_get(void *dev) { if (power_error) return power_error; powered++; return 0; } +static int pm_runtime_resume_and_get(void *dev) { if (power_error && !dev) return power_error; powered++; return 0; } static void pm_runtime_put(void *dev) { assert(powered>0); powered--; } -static int apple_dart_dcp_domain_flush(struct apple_dart_domain *domain) { - (void)domain; assert(!"unexpected DCP dispatch in range fixture"); return -EINVAL; -} -static int apple_dart_hw_sync_locked(struct io_pgtable_cfg *cfg, struct apple_dart_stream_map *stream, bool sync) { - assert(sync); syncs++; return sync_error; +static int apple_dart_hw_sync_locked(struct io_pgtable_cfg *cfg, struct apple_dart_stream_map *stream, bool invalidate) { + assert(invalidate); syncs++; return sync_error; } static int apple_dart_t8110_hw_tlb_command_range(struct apple_dart_stream_map *stream, int command, bool range, u64 first, u64 last) { assert(command==1 && range); ranges++; seen_first=first; seen_last=last; return range_error; } +static int apple_dart_dcp_domain_flush(struct apple_dart_domain *domain) { assert(domain->dcp); dcp_flushes++; return -EAGAIN; } +static void apple_dart_managed_quarantine(struct apple_dart *dart) { assert(dart->managed_sids); quarantines++; } +static int apple_dart_fw_invalidate(struct apple_dart_stream_map *stream, u64 first, u64 last) { + firmware_flushes++; seen_first=first; seen_last=last; return range_error; +} static int full(struct apple_dart_stream_map *stream) { fulls++; return 0; } ''' source += production source += r''' static void reset(void) { assert(powered==0); power_error=sync_error=range_error=syncs=ranges=fulls=0; - seen_first=seen_last=0; + seen_first=seen_last=0; firmware_flushes=quarantines=dcp_flushes=0; } int main(void) { struct apple_dart_hw hw={.invalidate_tlb=full}; @@ -92,14 +94,35 @@ def main(): assert(fulls==1 && ranges==0 && syncs==0); reset(); dart.locked=1; sync_error=-EBUSY; assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-EBUSY); - assert(ranges==0 && fulls==0 && powered==0); + assert(ranges==1 && fulls==0 && powered==0); reset(); power_error=-EHOSTDOWN; assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-EHOSTDOWN); assert(syncs==0 && ranges==0 && fulls==0 && powered==0); reset(); range_error=-ETIMEDOUT; assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-ETIMEDOUT); assert(ranges==1 && powered==0); - reset(); domain.streams[0].sidmap[0]=0; + reset(); dart.managed_sids=true; range_error=-ETIMEDOUT; + assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-ETIMEDOUT); + assert(ranges==1 && quarantines==1 && powered==0); + reset(); sync_error=-EBUSY; range_error=-ETIMEDOUT; + assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-EBUSY); + assert(ranges==1 && quarantines==1 && powered==0); + reset(); dart.fw_mirror=true; + assert(!apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)); + assert(firmware_flushes==1 && ranges==0 && syncs==1); + reset(); dart.fw_mirror=false; dart.fw_handoff=true; + assert(!apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)); + assert(firmware_flushes==1 && ranges==0); + reset(); dart.fw_handoff=false; domain.dcp=true; + assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-EAGAIN); + assert(dcp_flushes==1 && ranges==0 && syncs==0); + reset(); domain.dcp=false; + struct apple_dart second=dart; second.dev=(void *)1; + domain.streams[1].dart=&second; domain.streams[1].sidmap[0]=1; domain.count=2; + power_error=-EHOSTDOWN; + assert(apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)==-EHOSTDOWN); + assert(ranges==1 && syncs==1 && powered==0); + reset(); domain.count=1; domain.streams[0].sidmap[0]=0; assert(!apple_dart_domain_flush_tlb_range(&domain,true,0x4000,0x7fff)); assert(syncs==0 && ranges==0 && fulls==0 && powered==0); puts("PASS: device DVA, low window, legacy/unlocked fallback, sync/power/command errors and empty stream"); diff --git a/tools/asahi/atc-usb3-tests.py b/tools/asahi/atc-usb3-tests.py index 5e45e11c3c46d..af585383ed33e 100644 --- a/tools/asahi/atc-usb3-tests.py +++ b/tools/asahi/atc-usb3-tests.py @@ -74,7 +74,7 @@ def block(source, marker): STUBS = r''' struct atcphy_hw { enum atcphy_generation gen; - bool has_t8140_dp, dp_t8122, has_usb4, park_pipe_unlocked, park_dummy_phy; }; + bool has_t8140_dp, dp_t8122, has_usb4, park_pipe_unlocked, park_dummy_phy, usb2_only; }; struct device_node { const char *const *compatible; unsigned int count; }; static bool of_device_is_compatible(const struct device_node *root, const char *compatible) { if (!root) return false; @@ -95,6 +95,9 @@ def block(source, marker): enum atcphy_mode typec_mode; bool pipe_pending, t8103_dummy_pending, t8103_usb3_retry, t8103_usb3_workaround, mode_dirty, usb_off_pending; bool host_active, usb3_port_off, dp_only, ss_tunables, fixed_usb2, t8140_dp_tunables, dp_tunables; + /* T8132 state: the modeled machines never select that generation. */ + bool t8132_ss, t8132_common_owned, t8132_failed; + struct { void *usb3_dp; } tunables; }; struct phy { struct apple_atcphy *data; }; struct typec_mux_dev { struct apple_atcphy *data; }; @@ -169,6 +172,16 @@ def block(source, marker): static int atcphy_usb2_power_off(struct apple_atcphy *a) { (void)a; usb2_power_off_calls++; return 0; } +/* T8132 back ends: out of scope, and never reached by the modeled generations. */ +static int atcphy_configure_t8132(struct apple_atcphy *a, enum atcphy_mode mode) { + (void)a; (void)mode; assert(!"T8132 lane setup reached"); return -EINVAL; +} +static int atcphy_configure_pipehandler_usb3_host_t8132(struct apple_atcphy *a) { + (void)a; assert(!"T8132 PIPE setup reached"); return -EINVAL; +} +static void atcphy_usb2_power_on(struct apple_atcphy *a) { + (void)a; assert(!"USB2-only power restore reached"); +} static int atcphy_configure(struct apple_atcphy *atcphy, enum atcphy_mode mode) { /* ACTUAL_CONFIGURE_ENTRY */ struct apple_atcphy *a = atcphy; @@ -619,6 +632,7 @@ def harness(source): end = source.index("\n};", source.index("} atcphy_modes[] = {", start)) + 3 table = source[start:end] function_specs = [ + ("int", "atcphy_pipehandler_lock_timeout"), ("int", "atcphy_pipehandler_lock"), ("int", "atcphy_pipehandler_lock_live"), ("int", "atcphy_configure_pipehandler_usb3"), @@ -662,7 +676,7 @@ def harness(source): MUTATIONS = {'no-live-retry': ('atcphy_pipehandler_lock_live', '? 10 : 1;', '? 1 : 1;'), 'retry-later-generations': ('atcphy_pipehandler_lock_live', '? 10 : 1;', '? 10 : 10;'), 'sleep-after-last': ('atcphy_pipehandler_lock_live', 'if (attempt + 1 < attempts)', 'if (true)'), - 'missing-ack-check': ('atcphy_pipehandler_lock', + 'missing-ack-check': ('atcphy_pipehandler_lock_timeout', 'if (requested & PIPEHANDLER_LOCK_EN) {', 'if (requested & PIPEHANDLER_LOCK_EN) return 0;\n' '\tif (requested & PIPEHANDLER_LOCK_EN) {'), diff --git a/tools/asahi/rtkit-oslog-tests.py b/tools/asahi/rtkit-oslog-tests.py index 9d8fcf3c9bd83..5f8eb290ebde5 100644 --- a/tools/asahi/rtkit-oslog-tests.py +++ b/tools/asahi/rtkit-oslog-tests.py @@ -45,14 +45,14 @@ def function(source, name): void *dev, *wq; struct mailbox *mbox; struct apple_rtkit_shmem oslog_buffer, syslog_buffer, ioreport_buffer, crashlog_buffer; - struct apple_rtkit_shmem kdebug_buffer0, kdebug_buffer1, coreanalytics_buffer; + struct apple_rtkit_shmem kdebug_buffer0, kdebug_buffer1; int sync_ack_fifo; bool sync_syslog_ack, oslog_inherited, syslog_inherited, crashlog_inherited, crashed, shutting_down; unsigned iop_power_state, ap_power_state; unsigned long endpoints[4]; char *syslog_msg_buffer; size_t syslog_n_entries, syslog_msg_size; - int epmap_completion, iop_pwr_ack_completion, ap_pwr_ack_completion, coreanalytics_completion; + int epmap_completion, iop_pwr_ack_completion, ap_pwr_ack_completion; }; static unsigned sent, warnings, errors, requests, detachments, flushes, freed, checks; static int send_error, setup_error, start_error; @@ -125,7 +125,7 @@ def function(source, name): detachments=flushes=freed=0;start_error=fail?-5:0; assert(apple_rtkit_reinit(&r)==start_error); assert(!r.oslog_inherited && !r.syslog_inherited && !r.crashlog_inherited); - assert(!r.oslog_buffer.size && !r.crashed && !r.syslog_msg_size && freed==7); + assert(!r.oslog_buffer.size && !r.crashed && !r.syslog_msg_size && freed==6); assert(r.endpoints[0]==(1UL< - 1-10 +- Add the Linux-lane orphan identity list and delete tool + * Wed Oct 28 2026 Ryan Murray - 1-9 - Start the login screen without waiting for Touch ID, and show it again once Touch ID is ready if nobody has logged in yet @@ -163,7 +166,6 @@ fi the record a boot policy change makes the enclave rewrite - aurora-sep-policy-change: back up the gigalocker and allow that one rewrite on the next boot, so Touch ID survives a boot policy change -- Add the Linux-lane orphan identity list and delete tool * Mon Oct 19 2026 Ryan Murray - 1-7 - XART-SAFETY.md: what the xART guard allows for restore, use, setup and diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py b/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py index 60ed9b365d099..9b949a1a6ff1d 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/edid.py @@ -855,7 +855,7 @@ def function(text, signature): }; struct afk_receive_message_work { struct apple_dcp_afkep *ep; u64 message; struct work_struct work; }; struct apple_rtkit_ops { void (*recv_message)(void *,u8,u64); }; -struct apple_rtkit { bool shutting_down, sync_syslog_ack; const struct apple_rtkit_ops *ops; void *cookie,*dev; }; +struct apple_rtkit { bool shutting_down, sync_syslog_ack, pmp_registry_v2; const struct apple_rtkit_ops *ops; void *cookie,*dev; }; struct apple_rtkit_rx_work { struct apple_rtkit *rtk; u8 ep; u64 msg; struct work_struct work; }; #define current ((void *)1) static pthread_mutex_t reply_lock=PTHREAD_MUTEX_INITIALIZER; diff --git a/tools/testing/selftests/drivers/gpu/apple-dcp/run.py b/tools/testing/selftests/drivers/gpu/apple-dcp/run.py index efc79d1345f7a..f836743f2fc8d 100644 --- a/tools/testing/selftests/drivers/gpu/apple-dcp/run.py +++ b/tools/testing/selftests/drivers/gpu/apple-dcp/run.py @@ -156,6 +156,9 @@ def main(): prefix += ('#define APPLE_RTKIT_EP_COREANALYTICS ' + endpoint + '\n' '#define apple_rtkit_coreanalytics_rx(...) ' 'assert(!"CoreAnalytics is outside this ordered-display fixture")\n') + # The T6050 PMP registry-v2 buffer shares endpoint 7. + prefix += ('#define apple_rtkit_pmp_aux_rx(...) ' + 'assert(!"The PMP auxiliary buffer is outside this ordered-display fixture")\n') unit = prefix + unit if unit is not None: result['translation_unit_sha256'] = run_unit(name, unit, output, cases, includes if name == 'service-rebind' else (), flags) diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/abi.py b/tools/testing/selftests/drivers/gpu/asahi-m4/abi.py index 2f1d78a9e962d..38c6d7806eabd 100644 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/abi.py +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/abi.py @@ -62,15 +62,13 @@ def run_measurements(command, source, binary): def c_layout(header, bindings, output, tag): keys, _ = expressions(bindings) capacity_tail = 'client_memory_limit;' in header.read_text() - # Bindings frozen after the capacity tail landed already describe all of it. - frozen_tail = 'client_memory_limit' in bindings.read_text() # Linux 7.2 folds the historical extension structs into the base payloads. # Compare the same wire prefixes and offsets while keeping the C oracle frozen. if 'struct drm_asahi_cmd_render_with_prior {' not in header.read_text(): translated = [] for key, expr in keys: kind, _, field = key.partition(':') - if capacity_tail and not frozen_tail and key == 'drm_asahi_params_global:size': + if capacity_tail and key == 'drm_asahi_params_global:size': # Compare the frozen reply prefix; validate the entire known additive tail below. expr = 'offsetof(struct drm_asahi_params_global, memory_limit)' if key == "drm_asahi_vm_create:pad": diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/check-channels.rs b/tools/testing/selftests/drivers/gpu/asahi-m4/check-channels.rs index fccab550c6f29..925fb72a49931 100644 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/check-channels.rs +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/check-channels.rs @@ -5,7 +5,7 @@ mod channels; #[path = "@KERNEL@/drivers/gpu/drm/asahi/g16/fw/graph.rs"] mod graph; mod fwid { -@FIRMWARE_BUILD@ +@FWID_BUILD@ } mod hw {pub enum GpuVariant {G}} struct Config { diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/ABI-EXTENSIONS.md b/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/ABI-EXTENSIONS.md deleted file mode 100644 index f61ded1b37ddc..0000000000000 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/ABI-EXTENSIONS.md +++ /dev/null @@ -1,11 +0,0 @@ -SPDX-License-Identifier: GPL-2.0-only OR MIT - -The public-uapi.rs declaration snapshot includes the optional memory_limit and -client_memory_limit tail fields from the public MIT C UAPI at kernel commit -a1b269f79e35844660892b9779adb2f68abc38b7 (include/uapi/drm/asahi_drm.h). -The preceding layout remains the legacy 600-byte reply prefix; the full struct -is 616 bytes. test-uapi.py compiles the C and Rust declarations and compares -their sizes, offsets and constants, including the paired Mesa header. - -The independent C-generated encoder and VM byte fixtures were not regenerated -or changed. Their original provenance and hashes remain in manifest.json. diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/manifest.json b/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/manifest.json index 9ad503ae03eee..f33da77aa1795 100644 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/manifest.json +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/manifest.json @@ -136,19 +136,8 @@ "sha256_before_spdx_notice": "e3ba6fa572ed16636c9b6d7428e921cf1d81930429e4610738f5a86e906bc7fe" }, "public-uapi.rs": { - "sha256": "33eb92306ec7b088f14847c2cd974eebad88e5b75ac37fcc18a523c171edd0c6", - "sha256_before_spdx_notice": "e9f1ebf957d800bd1ed6fb372a4f8890fb1f1d8ff30e2fd436134de8c998cc76", - "abi_tail_extension": { - "reference_kernel_commit": "a1b269f79e35844660892b9779adb2f68abc38b7", - "reference_header_blob": "66396f89cc33393b774b99ace0945794215e2131", - "reference_header_sha256": "697f494b0e4c4719959bc73b4b4731c540b9b058b694ec8ccd7abd24b1b3dd21", - "previous_bindings_sha256": "1cb62b5c57600855b38ffff960d59b35cd5f306d35cfe77a47ed3d60ee29e601", - "fields": [ - "memory_limit", - "client_memory_limit" - ], - "reference": "Public MIT C UAPI declarations; checked by compiled C/Rust layout comparison. Encoder byte fixtures are unchanged." - } + "sha256": "1cb62b5c57600855b38ffff960d59b35cd5f306d35cfe77a47ed3d60ee29e601", + "sha256_before_spdx_notice": "e9f1ebf957d800bd1ed6fb372a4f8890fb1f1d8ff30e2fd436134de8c998cc76" }, "vm-case-0.bin.gz": { "sha256": "2758f69e5813fa2f7f08f2008217de05c2482af4ff706125025d39b42c40be36", diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/public-uapi.rs b/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/public-uapi.rs index 8dbdd1451fb7f..786446c4f7206 100644 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/public-uapi.rs +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/fixtures/public-uapi.rs @@ -77,10 +77,6 @@ pub struct drm_asahi_params_global { pub usc_generation: __u32, #[doc = " @gpu_hal_generation: Apple GPU HAL/command-stream generation.\n\n This is DRM_ASAHI_GPU_HAL_LEGACY for G13-G15,\n DRM_ASAHI_GPU_HAL_200 for G16 and G17P/G17A, and\n DRM_ASAHI_GPU_HAL_300 for G17G/G17S/G17C."] pub gpu_hal_generation: __u32, - /// Optional device-wide committed/resident-byte capacity; zero means no limit. - pub memory_limit: __u64, - /// Optional per-DRM-file committed-byte capacity; zero means no limit. - pub client_memory_limit: __u64, } impl Default for drm_asahi_params_global { fn default() -> Self { diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/run-golden-tests.py b/tools/testing/selftests/drivers/gpu/asahi-m4/run-golden-tests.py index d751e9c93f255..962713941338b 100644 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/run-golden-tests.py +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/run-golden-tests.py @@ -15,21 +15,14 @@ def main(): manifest = unpack_fixtures(golden) (out / 'public-uapi.rs').write_bytes(frozen_bindings().read_bytes()) backend = root / 'drivers/gpu/drm/asahi/g16' - # The hardware catalog now imports its data-only declaration from shared - # fwid. Compile that exact production declaration; firmware measurement is - # outside this wire-encoder harness. Independent byte fixtures stay frozen. - fwid = root / 'drivers/gpu/drm/asahi/fwid.rs' - declaration = '' - if fwid.exists(): - identity = fwid.read_text() - begin = identity.index('pub(crate) struct FirmwareBuild {') - end = identity.index('\n}', begin) + 2 - declaration = identity[begin:end] + identity = (root / 'drivers/gpu/drm/asahi/fwid.rs').read_text() + first = identity.index('pub(crate) struct FirmwareBuild {') + build_type = identity[first:identity.index('\n}', first) + 2] logs = [] for name in ['initdata', 'compute', 'render', 'channels', 'initdata-bounds']: source = (HERE / f'check-{name}.rs').read_text() source = source.replace('@KERNEL@', str(root)).replace('@OUTPUT@', str(out)) - source = source.replace('@FIRMWARE_BUILD@', declaration) + source = source.replace('@FWID_BUILD@', build_type) test = out / f'check-{name}.rs' test.write_text(source) binary = out / f'check-{name}' @@ -44,9 +37,7 @@ def main(): report = {'passed': True, 'scope': 'Production Rust encoder output versus frozen independent C fixtures; CPU-only, no hardware acceptance.', 'reference_kernel_commit': manifest['reference_kernel_commit'], 'fixture_manifest_sha256': sha(HERE / 'fixtures/manifest.json'), 'seconds': round(time.monotonic()-start, 3), 'compared_encoder_bytes': 3736988, - 'source_sha256': {str(p.relative_to(root)): sha(p) for p in sorted(backend.rglob('*.rs'))}, - 'firmware_declaration_source_sha256': sha(fwid) if fwid.exists() else None, - 'firmware_declaration_scope': 'Shared FirmwareBuild data declaration only; identity measurement is not executed by this harness.'} + 'source_sha256': {str(p.relative_to(root)): sha(p) for p in sorted(backend.rglob('*.rs'))}} (out / 'golden-tests.json').write_text(json.dumps(report, indent=2)+'\n') return 0 diff --git a/tools/testing/selftests/drivers/gpu/asahi-m4/test-mmu-retention.py b/tools/testing/selftests/drivers/gpu/asahi-m4/test-mmu-retention.py index 92ed7670812a3..787992e9b4c24 100755 --- a/tools/testing/selftests/drivers/gpu/asahi-m4/test-mmu-retention.py +++ b/tools/testing/selftests/drivers/gpu/asahi-m4/test-mmu-retention.py @@ -29,6 +29,7 @@ def body(source,marker): struct MutexBackend;struct Mutex(StdMutex);implMutex{fn new(v:T)->Self{Self(StdMutex::new(v))}fn lock(&self)->Guard<'_,T,MutexBackend>{Guard(self.0.lock().unwrap(),std::marker::PhantomData)}} struct Guard<'a,T,M>(std::sync::MutexGuard<'a,T>,std::marker::PhantomData);implDeref for Guard<'_,T,M>{type Target=T;fn deref(&self)->&T{&self.0}}implDerefMut for Guard<'_,T,M>{fn deref_mut(&mut self)->&mut T{&mut self.0}} struct Monotonic;struct Delta;impl Delta{fn from_millis(n:u64)->u64{n}}struct Instant{n:std::cell::Cell,p:std::marker::PhantomData}implInstant{fn now()->Self{Self{n:std::cell::Cell::new(0),p:std::marker::PhantomData}}fn elapsed(&self)->u64{let n=self.n.get();self.n.set(n+1);n}} +mod pgtable{pub fn clean_poc(_p:*const u8,_n:usize){super::BARRIERS.fetch_add(1,super::Ordering::Relaxed);}pub fn poc_barrier(){super::BARRIERS.fetch_add(1,super::Ordering::Relaxed);}} mod mem{pub fn sync(){super::BARRIERS.fetch_add(1,super::Ordering::Relaxed);}pub fn tlbi_asid(_:u8){}} #[derive(Clone,Copy,PartialEq,Eq)]enum UatFirmware{Handoff,PublishedRoots} struct Handoff{lock_ap:AtomicU8,lock_fw:AtomicU8,turn:AtomicU32,cur_slot:AtomicU32}impl Handoff{fn new()->Self{Self{lock_ap:AtomicU8::new(0),lock_fw:AtomicU8::new(0),turn:AtomicU32::new(0),cur_slot:AtomicU32::new(0xffff)}} @@ -36,23 +37,19 @@ def body(source,marker): handoff='\n'.join(body(mm,m) for m in ['fn lock(&self) {\n self.lock_ap', 'fn unlock(&self) {\n self.turn', 'fn current_slot(']) mid=r''' } -struct SlotTTBS{ttb0:AtomicU64,ttb1:AtomicU64}struct UatShared{quirks:UatQuirks,handoff:Handoff,ttbs:[SlotTTBS;64],map_kernel_to_user:bool,kernel_ttb1:u64,binding_generations:[u64;64],binding_published:[bool;64],owned_user_roots:[u64;64]} +struct Quirks{handoff_lock:bool,clean_tables:bool} +struct SlotTTBS{ttb0:AtomicU64,ttb1:AtomicU64}struct UatShared{handoff:Handoff,ttbs:[SlotTTBS;64],map_kernel_to_user:bool,kernel_ttb1:u64,binding_generations:[u64;64],binding_published:[bool;64],owned_user_roots:[u64;64],quirks:Quirks} impl UatShared{fn handoff(&self)->&Handoff{&self.handoff}fn ttbs(&self)->&[SlotTTBS;64]{&self.ttbs}} struct UatInner{firmware:UatFirmware,m4_adopted:bool,failed:AtomicBool,shared:Mutex} ''' -# Read quirk policy and wrappers from production rather than copying their behavior. -quirks=body(mm,'pub(crate) struct UatQuirks {')+'\n'+body(mm,'impl UatQuirks {') -pre=pre.replace('struct Handoff{',quirks+'\nstruct Handoff{',1) -pre=pre.replace('mod mem{', 'mod pgtable{pub fn clean_poc(_p:*const u8,_n:usize){panic!("cache-clean profile is outside this fixture");}pub fn poc_barrier(){panic!("cache-clean profile is outside this fixture");}}\nmod mem{',1) -shared_methods='\n'.join(body(mm,m) for m in ['fn handoff_lock(', 'fn handoff_unlock(', 'fn publish_slot(']) -mid=mid.replace('impl UatShared{','impl UatShared{'+shared_methods+'\n',1) +mid=mid.replace('impl UatShared{','impl UatShared{'+''.join(body(mm,m) for m in ['fn handoff_lock(', 'fn handoff_unlock(', 'fn publish_slot('])) raii='#[path="'+str(ROOT/'drivers/gpu/drm/asahi/mmu/ppl.rs')+'"]mod ppl;\n'+'\n'.join(body(mm,m) for m in [ 'struct M4Transport<', 'impl ppl::Memory for M4Transport', 'enum HandoffGuard<', 'impl HandoffGuard<', 'impl Drop for HandoffGuard<' ]) inner='impl UatInner{\n'+'\n'.join(body(mm,m) for m in ['fn lock(&self) -> Guard', 'fn check_m4(', 'fn lock_handoff(', 'fn lock_m4_upper('])+'\n}\n' models=r''' -fn uat(m4:bool,firmware:UatFirmware)->Rc{Rc::new(UatInner{firmware,m4_adopted:m4,failed:AtomicBool::new(false),shared:Mutex::new(UatShared{quirks:UatQuirks::DEFAULT,handoff:Handoff::new(),ttbs:std::array::from_fn(|_|SlotTTBS{ttb0:AtomicU64::new(0),ttb1:AtomicU64::new(0)}),map_kernel_to_user:!m4,kernel_ttb1:0x800000000,binding_generations:[0;64],binding_published:[false;64],owned_user_roots:[0;64]})})} +fn uat(m4:bool,firmware:UatFirmware)->Rc{Rc::new(UatInner{firmware,m4_adopted:m4,failed:AtomicBool::new(false),shared:Mutex::new(UatShared{handoff:Handoff::new(),ttbs:std::array::from_fn(|_|SlotTTBS{ttb0:AtomicU64::new(0),ttb1:AtomicU64::new(0)}),map_kernel_to_user:!m4,kernel_ttb1:0x800000000,binding_generations:[0;64],binding_published:[false;64],owned_user_roots:[0;64],quirks:Quirks{handoff_lock:true,clean_tables:false}})})} #[derive(Clone,Copy)]struct Prot{cached:bool}impl Prot{fn is_cached_noncoherent(&self)->bool{self.cached}} struct Mutation;impl Drop for Mutation{fn drop(&mut self){MUTATIONS.fetch_sub(1,Ordering::Relaxed);}} struct MapTable{fail:bool}impl MapTable{fn unmap_pages(&mut self,_r:Range)->Result{LEAF_CLEARS.fetch_add(1,Ordering::Relaxed);if self.fail{Err(EIO)}else{Ok(())}}}