Skip to content

Commit

Permalink
Silicon/RK3588: Fix MCFG when CFG0 TLPs are being correctly filtered
Browse files Browse the repository at this point in the history
Some devices (either single or multi-function) manage to appear only once, so we
must expose the original ECAM base in this case, starting from dev 0.
  • Loading branch information
mariobalanica committed Oct 11, 2023
1 parent 105f7b9 commit 98e1008
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 29 deletions.
18 changes: 3 additions & 15 deletions edk2-rockchip/Silicon/Rockchip/RK3588/AcpiTables/Mcfg.aslc
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,17 @@
*
**/

#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
#include "AcpiTables.h"

#pragma pack(push, 1)

//
// The root port config is not part of ECAM.
// OSes can parse additional config spaces in MCFG, but we'll hide it for now.
// MCFG may get patched by AcpiPlatformDxe.
//

typedef struct {
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER Header;
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Entry[5];
} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE;

EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE Mcfg = {
RK3588_MCFG_TABLE Mcfg = {
{
ACPI_HEADER (
EFI_ACPI_6_4_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE,
RK3588_MCFG_TABLE,
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION
),
},
Expand Down Expand Up @@ -72,6 +62,4 @@ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE Mcfg = {
}
};

#pragma pack(pop)

VOID* CONST ReferenceAcpiTable = &Mcfg;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <Library/AcpiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <AcpiTables.h>
#include <VarStoreData.h>

STATIC CONST EFI_GUID mAcpiTableFile = {
Expand Down Expand Up @@ -153,12 +155,26 @@ AcpiVerifyUpdateTable (
return Result;
}

//
// Monitor the ACPI tables being installed and when
// a DSDT/SSDT is detected validate that we want to
// install it, and if so update any "NameOp" defined
// variables contained in the table from PCD values
//
STATIC
BOOLEAN
AcpiFixupMcfg (
IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader
)
{
RK3588_MCFG_TABLE *Table;
UINT32 Seg;

Table = (RK3588_MCFG_TABLE *) AcpiHeader;

for (Seg = 0; Seg < ARRAY_SIZE (Table->Entry); Seg++) {
if ((PcdGet32 (PcdPcieEcamCompliantSegmentsMask) & (1 << Seg)) != 0) {
Table->Entry[Seg].BaseAddress -= 0x8000;
}
}

return TRUE;
}

STATIC
BOOLEAN
AcpiHandleDynamicNamespace (
Expand All @@ -169,11 +185,30 @@ AcpiHandleDynamicNamespace (
case SIGNATURE_32 ('D', 'S', 'D', 'T'):
case SIGNATURE_32 ('S', 'S', 'D', 'T'):
return AcpiVerifyUpdateTable (AcpiHeader);
case SIGNATURE_32 ('M', 'C', 'F', 'G'):
return AcpiFixupMcfg (AcpiHeader);
}

return TRUE;
}

STATIC
VOID
EFIAPI
NotifyEndOfDxeEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;

Status = LocateAndInstallAcpiFromFvConditional (&mAcpiTableFile, &AcpiHandleDynamicNamespace);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "AcpiPlatform: Failed to install firmware ACPI as config table. Status=%r\n",
Status));
}
}

EFI_STATUS
EFIAPI
AcpiPlatformDxeInitialize (
Expand All @@ -182,18 +217,22 @@ AcpiPlatformDxeInitialize (
)
{
EFI_STATUS Status;
EFI_EVENT Event;

if ((PcdGet32 (PcdConfigTableMode) & CONFIG_TABLE_MODE_ACPI) == 0) {
DEBUG ((DEBUG_WARN, "AcpiPlatform: ACPI support is disabled by the settings.\n"));
return EFI_UNSUPPORTED;
}

Status = LocateAndInstallAcpiFromFvConditional (&mAcpiTableFile, &AcpiHandleDynamicNamespace);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "AcpiPlatform: Failed to install firmware ACPI as config table. Status=%r\n",
Status));
return Status;
}
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL, // Type
TPL_CALLBACK, // NotifyTpl
NotifyEndOfDxeEvent, // NotifyFunction
NULL, // NotifyContext
&gEfiEndOfDxeEventGroupGuid, // EventGroup
&Event // Event
);
ASSERT_EFI_ERROR (Status);

return EFI_SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
AcpiLib
BaseMemoryLib
DebugLib
UefiBootServicesTableLib
UefiDriverEntryPoint

[Guids]
gEfiEndOfDxeEventGroupGuid

[Protocols]

Expand All @@ -44,6 +46,7 @@
gRK3588TokenSpaceGuid.PcdComboPhy2Mode
gRK3588TokenSpaceGuid.PcdPcie30Supported
gRK3588TokenSpaceGuid.PcdPcie30State
gRK3588TokenSpaceGuid.PcdPcieEcamCompliantSegmentsMask

[Depex]
gRockchipPlatformConfigAppliedProtocolGuid
8 changes: 8 additions & 0 deletions edk2-rockchip/Silicon/Rockchip/RK3588/Include/AcpiTables.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define __ACPITABLES_H__

#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>

#define EFI_ACPI_OEM_ID {'R','K','C','P',' ',' '}

Expand Down Expand Up @@ -58,4 +59,11 @@
0 \
}

#pragma pack(push, 1)
typedef struct {
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER Header;
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Entry[5];
} RK3588_MCFG_TABLE;
#pragma pack(pop)

#endif // __ACPITABLES_H__
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ PciePinmuxInit(
ASSERT(MuxNum < 2);
GpioSetIomuxConfig(&mPcie20x1_2_IomuxConfigs[MuxNum][0], 3);
break;

default:
return;
}
Expand Down Expand Up @@ -255,7 +255,7 @@ PciSetupClocks (
default:
break;
}

}

STATIC
Expand Down Expand Up @@ -448,6 +448,29 @@ PciSetupAtu (
gBS->Stall (10000);
}

STATIC
VOID
PciValidateCfg0 (
IN UINT32 Segment,
IN EFI_PHYSICAL_ADDRESS Cfg0Base
)
{
EFI_STATUS Status;

//
// If the downstream device doesn't appear mirrored, config accesses
// must not be shifted by 0x8000 anymore.
//
if (MmioRead32 (Cfg0Base) != 0xffffffff
&& MmioRead32 (Cfg0Base + 0x8000) == 0xffffffff) {
Status = PcdSet32S (PcdPcieEcamCompliantSegmentsMask,
PcdGet32 (PcdPcieEcamCompliantSegmentsMask) | (1 << Segment));
ASSERT_EFI_ERROR (Status);

DEBUG((DEBUG_INFO, "PCIe: Working CFG0 TLP filtering for connected device!\n"));
}
}

EFI_STATUS
InitializePciHost (
UINT32 Segment
Expand Down Expand Up @@ -564,5 +587,7 @@ InitializePciHost (
PciGetLinkSpeedWidth (DbiBase, &LinkSpeed, &LinkWidth);
PciPrintLinkSpeedWidth (LinkSpeed, LinkWidth);

PciValidateCfg0 (Segment, PcieBase + Cfg0Base);

return EFI_SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@
gRK3588TokenSpaceGuid.PcdComboPhy2Mode

gRK3588TokenSpaceGuid.PcdPcie30State

gRK3588TokenSpaceGuid.PcdPcieEcamCompliantSegmentsMask
3 changes: 3 additions & 0 deletions edk2-rockchip/Silicon/Rockchip/RK3588/RK3588.dec
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@

gRK3588TokenSpaceGuid.PcdUsbDpPhy0Usb3State|0|UINT32|0x00000501
gRK3588TokenSpaceGuid.PcdUsbDpPhy1Usb3State|0|UINT32|0x00000502

[PcdsDynamicEx]
gRK3588TokenSpaceGuid.PcdPcieEcamCompliantSegmentsMask|0|UINT32|0x20000001

0 comments on commit 98e1008

Please sign in to comment.