Skip to content

Commit

Permalink
ACPI: Prepare SD controller support for Windows
Browse files Browse the repository at this point in the history
Signed-off-by: Mario Bălănică <[email protected]>
  • Loading branch information
mariobalanica committed Jun 18, 2024
1 parent dd0b22f commit 053cf71
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 11 deletions.
50 changes: 40 additions & 10 deletions edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Sdhc.asl
Original file line number Diff line number Diff line change
@@ -1,31 +1,61 @@
/** @file
*
* Copyright (c) 2021, ARM Limited. All rights reserved.
* Copyright (c) 2024, Mario Bălănică <[email protected]>
*
* 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

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)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@

#include <IndustryStandard/AcpiAml.h>
#include <IndustryStandard/PeImage.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/NonDiscoverableDevice.h>
#include <Library/AcpiLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <AcpiTables.h>
#include <VarStoreData.h>

Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 (
Expand All @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# ACPI platform driver
#
# Copyright (c) 2023, Mario Bălănică <[email protected]>
# Copyright (c) 2024, Mario Bălănică <[email protected]>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
Expand Down Expand Up @@ -31,15 +31,21 @@
BaseLib
BaseMemoryLib
DebugLib
DevicePathLib
MemoryAllocationLib
PeCoffGetEntryPointLib
UefiBootServicesTableLib
UefiLib
UefiDriverEntryPoint

[Guids]
gEfiEndOfDxeEventGroupGuid
gEfiEventReadyToBootGuid

[Protocols]
gEdkiiNonDiscoverableDeviceProtocolGuid
gEfiAcpiSdtProtocolGuid
gEfiLoadedImageProtocolGuid

[Pcd]
gRK3588TokenSpaceGuid.PcdConfigTableMode
Expand All @@ -50,6 +56,7 @@
gRK3588TokenSpaceGuid.PcdPcie30Supported
gRK3588TokenSpaceGuid.PcdPcie30State
gRK3588TokenSpaceGuid.PcdPcieEcamCompliantSegmentsMask
gRockchipTokenSpaceGuid.PcdRkSdmmcBaseAddress

[Depex]
gRockchipPlatformConfigAppliedProtocolGuid

0 comments on commit 053cf71

Please sign in to comment.