From 053cf714a7479951dcaf2d43bc61d1ae71f5d715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?= Date: Tue, 18 Jun 2024 21:17:17 +0300 Subject: [PATCH] ACPI: Prepare SD controller support for Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mario Bălănică --- .../Rockchip/RK3588/AcpiTables/Sdhc.asl | 50 ++++-- .../Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c | 143 ++++++++++++++++++ .../AcpiPlatformDxe/AcpiPlatformDxe.inf | 9 +- 3 files changed, 191 insertions(+), 11 deletions(-) diff --git a/edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Sdhc.asl b/edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Sdhc.asl index fb691b43f..2f5da8371 100644 --- a/edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Sdhc.asl +++ b/edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Sdhc.asl @@ -1,31 +1,61 @@ /** @file * - * Copyright (c) 2021, ARM Limited. All rights reserved. + * Copyright (c) 2024, Mario Bălănică * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ + #include "AcpiTables.h" +Scope (\_SB_) { + Name (SDRM, 1) // SD slot is removable - Device (SDHC) - { + Device (SDHC) { Name (_HID, "RKCPFE2C") - Name (_UID, 0x1) + Name (_UID, 0x0) Name (_CCA, 0x0) Name (_S1D, 0x1) Name (_S2D, 0x1) Name (_S3D, 0x1) Name (_S4D, 0x1) - Method (_STA) - { - Return(0xf) - } + Name (_STA, 0xf) + Method (_CRS, 0x0, Serialized) { - Name (RBUF, ResourceTemplate() { + Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0xfe2c0000, 0x4000) Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 235 } + + // SDMMC_DET + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GPI0") { GPIO_PIN_PA4 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GPI0") { GPIO_PIN_PA4 } }) Return (RBUF) } - } //SDHC \ No newline at end of file + + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "compatible", Package () { "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc" } }, + Package () { "fifo-depth", 0x100 }, + Package () { "max-frequency", 200000000 }, + Package () { "bus-width", 4 }, + Package () { "cap-sd-highspeed", 1 }, + Package () { "sd-uhs-ddr50", 1 }, + Package () { "sd-uhs-sdr50", 1 }, + Package () { "sd-uhs-sdr104", 1 }, + } + }) + + // + // A child device that represents the SD card. + // + Device (SDMM) { + Name (_ADR, 0x0) + + Method (_RMV) { + Return (SDRM) + } + } + } +} diff --git a/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c b/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c index ebf26d6eb..ad9b1ae4d 100644 --- a/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c +++ b/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c @@ -11,12 +11,17 @@ #include #include +#include +#include #include #include #include #include +#include +#include #include #include +#include #include #include @@ -29,6 +34,8 @@ STATIC EFI_EXIT_BOOT_SERVICES mOriginalExitBootServices; STATIC EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol; STATIC EFI_ACPI_DESCRIPTION_HEADER *mDsdtTable; +STATIC BOOLEAN mIsSdmmcBoot = FALSE; + typedef enum { AcpiOsUnknown = 0, AcpiOsWindows, @@ -318,6 +325,14 @@ AcpiPlatformOsBootHandler ( AcpiUpdateSdtNameInteger (mDsdtTable, "EHID", 0); } + // + // If the boot device is SDMMC, mark the slot as non-removable. + // This allows Windows to create a page file on it. + // + if (mIsSdmmcBoot) { + AcpiUpdateSdtNameInteger (mDsdtTable, "SDRM", 0); + } + AcpiFixupPcieEcam (OsType); AcpiUpdateChecksum ((UINT8 *)mDsdtTable, mDsdtTable->Length); @@ -406,6 +421,124 @@ AcpiPlatformExitBootServicesHook ( return gBS->ExitBootServices (ImageHandle, MapKey); } +STATIC +BOOLEAN +IsDeviceSdmmc ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_HANDLE DeviceHandle; + NON_DISCOVERABLE_DEVICE *Device; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; + + DevicePath = DevicePathFromHandle (Handle); + + if (DevicePath == NULL + || DevicePath->Type != HARDWARE_DEVICE_PATH + || DevicePath->SubType != HW_VENDOR_DP) { + return FALSE; + } + + Status = gBS->LocateDevicePath (&gEdkiiNonDiscoverableDeviceProtocolGuid, + &DevicePath, &DeviceHandle); + if (EFI_ERROR (Status)) { + return FALSE; + } + + Status = gBS->HandleProtocol (DeviceHandle, + &gEdkiiNonDiscoverableDeviceProtocolGuid, (VOID **) &Device); + if (EFI_ERROR (Status)) { + return FALSE; + } + + Descriptor = &Device->Resources[0]; + + if (Descriptor->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR || + Descriptor->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) { + return FALSE; + } + + return Descriptor->AddrRangeMin == PcdGet32 (PcdRkSdmmcBaseAddress); +} + + +STATIC VOID *mLoadedImageEventRegistration; + +STATIC +VOID +EFIAPI +NotifyLoadedImage ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN HandleCount; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + + while (TRUE) { + Status = gBS->LocateHandleBuffer ( + ByRegisterNotify, + NULL, + mLoadedImageEventRegistration, + &HandleCount, + &Handles + ); + if (EFI_ERROR (Status)) { + if (Status != EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, "AcpiPlatform: Failed to locate gEfiLoadedImageProtocolGuid. Status=%r\n", + Status)); + } + break; + } + ASSERT (HandleCount == 1); + + Status = gBS->HandleProtocol ( + Handles[0], + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + FreePool (Handles); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "AcpiPlatform: Failed to get gEfiLoadedImageProtocolGuid. Status=%r\n", + Status)); + break; + } + + if (LoadedImage->DeviceHandle == NULL) { + continue; + } + + // + // If the last image was loaded from SDMMC, then assume that's + // the boot device. + // + mIsSdmmcBoot = IsDeviceSdmmc (LoadedImage->DeviceHandle); + } +} + +STATIC +VOID +EFIAPI +NotifyReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gBS->CloseEvent (Event); + + EfiCreateProtocolNotifyEvent ( + &gEfiLoadedImageProtocolGuid, + TPL_CALLBACK, + NotifyLoadedImage, + NULL, + &mLoadedImageEventRegistration + ); +} + EFI_STATUS EFIAPI AcpiPlatformDxeInitialize ( @@ -431,6 +564,16 @@ AcpiPlatformDxeInitialize ( ); ASSERT_EFI_ERROR (Status); + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, // Type + TPL_CALLBACK, // NotifyTpl + NotifyReadyToBoot, // NotifyFunction + NULL, // NotifyContext + &gEfiEventReadyToBootGuid, // EventGroup + &Event // Event + ); + ASSERT_EFI_ERROR (Status); + mOriginalExitBootServices = gBS->ExitBootServices; gBS->ExitBootServices = AcpiPlatformExitBootServicesHook; diff --git a/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf index c7aa4646c..8253ccda5 100644 --- a/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/edk2-rockchip/Silicon/Rockchip/RK3588/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -2,7 +2,7 @@ # # ACPI platform driver # -# Copyright (c) 2023, Mario Bălănică +# Copyright (c) 2024, Mario Bălănică # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -31,15 +31,21 @@ BaseLib BaseMemoryLib DebugLib + DevicePathLib + MemoryAllocationLib PeCoffGetEntryPointLib UefiBootServicesTableLib + UefiLib UefiDriverEntryPoint [Guids] gEfiEndOfDxeEventGroupGuid + gEfiEventReadyToBootGuid [Protocols] + gEdkiiNonDiscoverableDeviceProtocolGuid gEfiAcpiSdtProtocolGuid + gEfiLoadedImageProtocolGuid [Pcd] gRK3588TokenSpaceGuid.PcdConfigTableMode @@ -50,6 +56,7 @@ gRK3588TokenSpaceGuid.PcdPcie30Supported gRK3588TokenSpaceGuid.PcdPcie30State gRK3588TokenSpaceGuid.PcdPcieEcamCompliantSegmentsMask + gRockchipTokenSpaceGuid.PcdRkSdmmcBaseAddress [Depex] gRockchipPlatformConfigAppliedProtocolGuid