13 Commits
v1.1 ... master

Author SHA1 Message Date
Mario Bălănică
824e6c1216 Switch devicetree-rebasing to kernel.googlesource.com mirror
CI builds have been failing lately with:
Error: fatal: unable to access
'https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/':
Failed to connect to git.kernel.org port 443 after
134198 ms: Couldn't connect to server

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 19:59:02 +02:00
Mario Bălănică
cb0d358be3 build: Improve patchset application
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 18:36:27 +02:00
Mario Bălănică
49dbee8d7c OhciDxe: Fix excessive stalls and debug prints
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 14:10:53 +02:00
Mario Bălănică
dd1aa689f3 OhciDxe: Port to EFI_USB2_HC_PROTOCOL
EFI_USB_HC_PROTOCOL support has been removed in recent EDK2.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 12:39:39 +02:00
Mario Bălănică
a4cc8fe021 Convert to new FdtLib wrapper API
There are a few missing wrappers for which I've submitted a patch
upstream. The patch is pending, so include it under edk2-patches for
now.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 11:58:55 +02:00
Mario Bălănică
630ebc9181 Misc fixes after EDK2 update
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 11:13:45 +02:00
Mario Bălănică
4dc1930d05 Update to latest EDK2
edk2-stable202511

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 10:49:03 +02:00
Mario Bălănică
35d9b8f25d build: Support submodule patchsets
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-07 10:48:59 +02:00
Mario Bălănică
b89f436f73 Improve PCIe resource assignment
- The PCIe MMIO regions on this SoC are absurdly small. Some demanding
devices (like NVIDIA GPUs) need more than 16 MB of 32-bit
non-prefetchable memory. To address this, carve out 256 MB at the top of
MMIO64 for ECAM (128 MB), followed by MEM32 (128 MB, with 32-bit
translation). MEM64 takes up the remaining space (768 MB), starting at
the bottom of MMIO64 (to preserve the alignment). This should be enough
to cover most use cases and allows for even a larger 512 MB prefetchable
BAR.

- Since all RCs share the same SMMU and ITS blocks, segments need
distinct bus numbers so that Requester IDs don't overlap. With 128 MB of
ECAM and 5 segments, this gives a spacing of 25 buses. Ideally, we
would've encoded the segment number instead, but that doesn't seem
possible here.

- Sync ACPI and FDT with the updated resources.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-01 13:36:21 +02:00
Mario Bălănică
dd994400c5 AcpiPlatform: Unify auto ECAM compatibility modes
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-01 12:35:01 +02:00
Mario Bălănică
904ae9ca19 Add AArch64 AMD GOP drivers
The x64 driver in the GPU's Option ROM does not work properly on
non-coherent hardware through the emulator (framebuffer gets corrupted).

We also need to install EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL on the
native driver's handle in order to override the Option ROM version.

Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-01 12:35:00 +02:00
Mario Bălănică
101b780f8c Add X86EmulatorDxe for PCI Option ROMs
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
2025-12-01 12:34:37 +02:00
Chen Jiali
d4627ada03 Platforms: Radxa: use the latest Radxa logo
Signed-off-by: Chen Jiali <chenjiali@radxa.com>
2025-05-21 03:59:40 +00:00
45 changed files with 1859 additions and 1124 deletions

2
.gitmodules vendored
View File

@@ -13,7 +13,7 @@
branch = rk3588
[submodule "devicetree/mainline/upstream"]
path = devicetree/mainline/upstream
url = https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git
url = https://kernel.googlesource.com/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git
[submodule "edk2-platforms"]
path = edk2-platforms
url = https://github.com/tianocore/edk2-platforms.git

View File

@@ -11,10 +11,11 @@ function _help(){
echo " -r, --release MODE Release mode for building, default is 'DEBUG', 'RELEASE' alternatively."
echo " -t, --toolchain TOOLCHAIN Set toolchain, default is 'GCC'."
echo " --open-tfa ENABLE Use open-source TF-A submodule. Default: ${OPEN_TFA}"
echo " -C, --clean Clean workspace and output."
echo " -D, --distclean Clean up all files that are not in repo."
echo " --tfa-flags \"FLAGS\" Flags appended to open TF-A build process."
echo " --edk2-flags \"FLAGS\" Flags appended to the EDK2 build process."
echo " --skip-patchsets Skip applying upstream submodule patchsets during development."
echo " -C, --clean Clean workspace and output."
echo " -D, --distclean Clean up all files that are not in repo."
echo " -h, --help Show this help."
echo
exit "${1}"
@@ -22,6 +23,59 @@ function _help(){
function _error() { echo "${@}" >&2; exit 1; }
function apply_patchset() {
${SKIP_PATCHSETS} && return 0
local patches_dir="$1"
local target_dir="$2"
[ ! -d "${patches_dir}" ] && return 0
if [ ! -d "${target_dir}" ]; then
echo "Patchset target directory does not exist: ${target_dir}"
return 1
fi
echo "Checking patchset ${patches_dir} for ${target_dir}"
local patchset_name=$(basename "${patches_dir}")
local patchset_marker="${target_dir}/.patchset_${patchset_name}"
if [ ! -f "${patchset_marker}" ] || [ "${patches_dir}" -nt "${patchset_marker}" ]; then
echo "Patchset needs to be (re)applied"
if ! git -C "${target_dir}" reset --hard || ! git -C "${target_dir}" clean -xfd; then
echo "Failed to reset git repository - aborting"
return 1
fi
else
echo "Patchset already applied - skipping"
return 0
fi
local patch_file
local patch_count=0
for patch_file in "${patches_dir}"/*.patch; do
[ -f "${patch_file}" ] || continue
local patch_name=$(basename "${patch_file}")
echo "Patch ${patch_count}: ${patch_name}"
if patch -p1 -d "${target_dir}" < "${patch_file}"; then
echo " Successfully applied"
((patch_count++))
else
echo " Failed to apply - aborting"
return 1
fi
done
touch "${patchset_marker}"
echo "Patchset summary: ${patch_count} applied"
return 0
}
function _build_idblock() {
echo " => Building idblock.bin"
pushd ${WORKSPACE}
@@ -58,7 +112,7 @@ function _build_fit() {
BL31="${ROOTDIR}/misc/rkbin/${BL31_RKBIN}"
BL32="${ROOTDIR}/misc/rkbin/${BL32_RKBIN}"
if [ ${OPEN_TFA} == 1 ]; then
if ${OPEN_TFA}; then
BL31="${ROOTDIR}/arm-trusted-firmware/build/${TFA_PLAT}/${RELEASE_TYPE,,}/bl31/bl31.elf"
fi
@@ -117,7 +171,9 @@ function _build(){
#
# Build TF-A
#
if [ ${OPEN_TFA} == 1 ]; then
if ${OPEN_TFA}; then
apply_patchset "${ROOTDIR}/arm-trusted-firmware-patches" "${ROOTDIR}/arm-trusted-firmware" || exit 1
pushd arm-trusted-firmware
if [ ${RELEASE_TYPE} == "DEBUG" ]; then
@@ -134,11 +190,21 @@ function _build(){
#
# Build EDK2
#
apply_patchset "${ROOTDIR}/edk2-patches" "${ROOTDIR}/edk2" || exit 1
apply_patchset "${ROOTDIR}/devicetree/mainline/patches" "${ROOTDIR}/devicetree/mainline/upstream" || exit 1
[ -d "${WORKSPACE}/Conf" ] || mkdir -p "${WORKSPACE}/Conf"
export GCC_AARCH64_PREFIX="${CROSS_COMPILE}"
export CLANG38_AARCH64_PREFIX="${CROSS_COMPILE}"
export PACKAGES_PATH="${ROOTDIR}/edk2:${ROOTDIR}/edk2-rockchip:${ROOTDIR}/devicetree:${ROOTDIR}/edk2-non-osi:${ROOTDIR}/edk2-platforms:${ROOTDIR}"
PACKAGES_PATH="${ROOTDIR}"
PACKAGES_PATH+=":${ROOTDIR}/devicetree"
PACKAGES_PATH+=":${ROOTDIR}/edk2"
PACKAGES_PATH+=":${ROOTDIR}/edk2-non-osi"
PACKAGES_PATH+=":${ROOTDIR}/edk2-platforms"
PACKAGES_PATH+=":${ROOTDIR}/edk2-rockchip"
PACKAGES_PATH+=":${ROOTDIR}/edk2-rockchip-non-osi"
export PACKAGES_PATH
make -C "${ROOTDIR}/edk2/BaseTools"
source "${ROOTDIR}/edk2/edksetup.sh"
@@ -176,9 +242,10 @@ typeset -u RELEASE_TYPE
DEVICE=""
RELEASE_TYPE=DEBUG
TOOLCHAIN=GCC
OPEN_TFA=1
OPEN_TFA=true
TFA_FLAGS=""
EDK2_FLAGS=""
SKIP_PATCHSETS=false
CLEAN=false
DISTCLEAN=false
OUTDIR="${PWD}"
@@ -186,7 +253,7 @@ OUTDIR="${PWD}"
#
# Get options
#
OPTS=$(getopt -o "d:r:t:CDh" -l "device:,release:,toolchain:,open-tfa:,tfa-flags:,edk2-flags:,clean,distclean,help" -n build.sh -- "${@}") || _help $?
OPTS=$(getopt -o "d:r:t:CDh" -l "device:,release:,toolchain:,open-tfa:,tfa-flags:,edk2-flags:,skip-patchsets,clean,distclean,help" -n build.sh -- "${@}") || _help $?
eval set -- "${OPTS}"
while true; do
case "${1}" in
@@ -196,6 +263,7 @@ while true; do
--open-tfa) OPEN_TFA="${2}"; shift 2 ;;
--tfa-flags) TFA_FLAGS="${2}"; shift 2 ;;
--edk2-flags) EDK2_FLAGS="${2}"; shift 2 ;;
--skip-patchsets) SKIP_PATCHSETS=true; shift ;;
-C|--clean) CLEAN=true; shift ;;
-D|--distclean) DISTCLEAN=true; shift ;;
-h|--help) _help 0; shift ;;

2
edk2

Submodule edk2 updated: fbe0805b20...46548b1ada

View File

@@ -0,0 +1,103 @@
From 7f9f0713b06cadff7071271c76d10a2091c8823d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?=
<mariobalanica02@gmail.com>
Date: Fri, 5 Dec 2025 14:02:15 +0200
Subject: [PATCH] MdePkg/BaseFdtLib: Add more wrappers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add FDT_HEADER field accessors and FdtOverlayApply() wrapper.
Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
---
MdePkg/Include/Library/FdtLib.h | 29 ++++++++++++++++++++++++++++-
MdePkg/Library/BaseFdtLib/FdtLib.c | 18 ++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLib.h
index a7f63f3d5a..16e8179af4 100644
--- a/MdePkg/Include/Library/FdtLib.h
+++ b/MdePkg/Include/Library/FdtLib.h
@@ -181,7 +181,16 @@ typedef struct {
#define FdtGetHeader(Fdt, Field) \
(Fdt32ToCpu (((const FDT_HEADER *)(Fdt))->Field))
-#define FdtTotalSize(Fdt) (FdtGetHeader ((Fdt), TotalSize))
+#define FdtMagic(Fdt) (FdtGetHeader ((Fdt), Magic))
+#define FdtTotalSize(Fdt) (FdtGetHeader ((Fdt), TotalSize))
+#define FdtOffsetDtStruct(Fdt) (FdtGetHeader ((Fdt), OffsetDtStruct))
+#define FdtOffsetDtStrings(Fdt) (FdtGetHeader ((Fdt), OffsetDtStrings))
+#define FdtOffsetMemRsvmap(Fdt) (FdtGetHeader ((Fdt), OffsetMemRsvmap))
+#define FdtVersion(Fdt) (FdtGetHeader ((Fdt), Version))
+#define FdtLastCompVersion(Fdt) (FdtGetHeader ((Fdt), LastCompVersion))
+#define FdtBootCpuidPhys(Fdt) (FdtGetHeader ((Fdt), BootCpuidPhys))
+#define FdtSizeDtStrings(Fdt) (FdtGetHeader ((Fdt), SizeDtStrings))
+#define FdtSizeDtStruct(Fdt) (FdtGetHeader ((Fdt), SizeDtStruct))
#define FdtForEachSubnode(Node, Fdt, Parent) \
for (Node = FdtFirstSubnode (Fdt, Parent); \
@@ -191,6 +200,9 @@ typedef struct {
#define FdtSetPropString(Fdt, NodeOffset, Name, String) \
FdtSetProp ((Fdt), (NodeOffset), (Name), (String), AsciiStrLen (String) + 1)
+#define FdtSetPropEmpty(Fdt, NodeOffset, Name) \
+ FdtSetProp ((Fdt), (NodeOffset), (Name), NULL, 0)
+
/**
Convert UINT16 data of the FDT blob to little-endian
@@ -960,6 +972,21 @@ FdtGetPhandle (
IN INT32 NodeOffset
);
+/**
+ Applies a DT overlay on a base DT.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Fdto The pointer to FDT overlay blob.
+
+ @return 0 on success, or negative error code.
+**/
+INT32
+EFIAPI
+FdtOverlayApply (
+ IN VOID *Fdt,
+ IN VOID *Fdto
+ );
+
/* Debug functions. */
CONST
CHAR8
diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib/FdtLib.c
index 3dacfbee45..8c986650dc 100644
--- a/MdePkg/Library/BaseFdtLib/FdtLib.c
+++ b/MdePkg/Library/BaseFdtLib/FdtLib.c
@@ -918,6 +918,24 @@ FdtGetPhandle (
return fdt_get_phandle (Fdt, NodeOffset);
}
+/**
+ Applies a DT overlay on a base DT.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Fdto The pointer to FDT overlay blob.
+
+ @return 0 on success, or negative error code.
+**/
+INT32
+EFIAPI
+FdtOverlayApply (
+ IN VOID *Fdt,
+ IN VOID *Fdto
+ )
+{
+ return fdt_overlay_apply (Fdt, Fdto);
+}
+
/* Debug functions. */
CONST
CHAR8
--
2.39.1.windows.1

View File

@@ -0,0 +1,213 @@
/** @file
*
* AMD GOP OpROM override
*
* Copyright (c) 2025, Mario Bălănică <mariobalanica02@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#include <Protocol/DriverFamilyOverride.h>
#include <Protocol/LoadedImage.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
STATIC CONST EFI_GUID mAmdGopDriverGuids[] = {
{ 0x62c34cea, 0xa08d, 0x4676, { 0x81, 0xe5, 0xf1, 0x6b, 0x0e, 0xe2, 0x2f, 0x22 }
}, // AmdGopPreSoc15Dxe.inf
{ 0x92f10585, 0xfb63, 0x430f, { 0x81, 0x88, 0x71, 0xfe, 0xeb, 0x2d, 0xda, 0x5b }
}, // AmdGopPostSoc15Dxe.inf
};
STATIC
UINT32
AmdGopDriverFamilyOverrideGetVersion (
IN EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *This
)
{
return MAX_UINT32;
}
STATIC EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL mAmdGopDriverFamilyOverride = {
AmdGopDriverFamilyOverrideGetVersion
};
STATIC
EFI_STATUS
EFIAPI
AmdGopUnloadImage (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_IMAGE_UNLOAD OriginalUnload;
Status = gBS->HandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
Status = gBS->HandleProtocol (
ImageHandle,
&gEfiCallerIdGuid,
(VOID **)&OriginalUnload
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
&gEfiDriverFamilyOverrideProtocolGuid,
&mAmdGopDriverFamilyOverride,
&gEfiCallerIdGuid,
OriginalUnload,
NULL
);
LoadedImage->Unload = OriginalUnload;
return LoadedImage->Unload (ImageHandle);
}
STATIC
EFI_GUID *
GetLoadedImageGuid (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage
)
{
EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
EFI_GUID *NameGuid;
if ((LoadedImage == NULL) || (LoadedImage->FilePath == NULL)) {
return NULL;
}
DevPathNode = LoadedImage->FilePath;
while (!IsDevicePathEnd (DevPathNode)) {
NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (
(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode
);
if (NameGuid != NULL) {
return NameGuid;
}
DevPathNode = NextDevicePathNode (DevPathNode);
}
return NULL;
}
STATIC VOID *mDriverBindingEventRegistration;
STATIC
VOID
EFIAPI
NotifyDriverBinding (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN BufferSize;
EFI_HANDLE Handle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_GUID *LoadedImageGuid;
UINTN Index;
while (TRUE) {
BufferSize = sizeof (EFI_HANDLE);
Status = gBS->LocateHandle (
ByRegisterNotify,
NULL,
mDriverBindingEventRegistration,
&BufferSize,
&Handle
);
if (EFI_ERROR (Status)) {
if (Status != EFI_NOT_FOUND) {
ASSERT_EFI_ERROR (Status);
}
break;
}
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
);
if (EFI_ERROR (Status)) {
continue;
}
LoadedImageGuid = GetLoadedImageGuid (LoadedImage);
if (LoadedImageGuid == NULL) {
continue;
}
for (Index = 0; Index < ARRAY_SIZE (mAmdGopDriverGuids); Index++) {
if (!CompareGuid (LoadedImageGuid, &mAmdGopDriverGuids[Index])) {
continue;
}
DEBUG ((DEBUG_INFO, "%a: %g\n", gEfiCallerBaseName, LoadedImageGuid));
Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gEfiDriverFamilyOverrideProtocolGuid,
&mAmdGopDriverFamilyOverride,
NULL
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
break;
}
if (LoadedImage->Unload != NULL) {
Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gEfiCallerIdGuid,
LoadedImage->Unload,
NULL
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
break;
}
LoadedImage->Unload = AmdGopUnloadImage;
}
}
}
}
EFI_STATUS
EFIAPI
AmdGopOpRomOverrideInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EfiCreateProtocolNotifyEvent (
&gEfiDriverBindingProtocolGuid,
TPL_CALLBACK,
NotifyDriverBinding,
NULL,
&mDriverBindingEventRegistration
);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,40 @@
#/** @file
#
# AMD GOP OpROM override
#
# Copyright (c) 2025, Mario Bălănică <mariobalanica02@gmail.com>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x0001001A
BASE_NAME = AmdGopOpRomOverrideDxe
FILE_GUID = 261d0e39-4663-4f0f-94ad-2903b7bb31e1
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = AmdGopOpRomOverrideInitialize
[Sources]
AmdGopOpRomOverride.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseMemoryLib
DebugLib
DevicePathLib
UefiBootServicesTableLib
UefiLib
UefiDriverEntryPoint
[Protocols]
gEfiDriverBindingProtocolGuid
gEfiDriverFamilyOverrideProtocolGuid
gEfiLoadedImageProtocolGuid
[Depex]
TRUE

View File

@@ -0,0 +1,9 @@
[Defines]
INF_VERSION = 0x0001001A
BASE_NAME = AMDGopPostSoc15Dxe
FILE_GUID = 92f10585-fb63-430f-8188-71feeb2dda5b
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
[Binaries.AARCH64]
PE32|AArch64/ARM64Gop_2_10.efi|*

View File

@@ -0,0 +1,9 @@
[Defines]
INF_VERSION = 0x0001001A
BASE_NAME = AMDGopPreSoc15Dxe
FILE_GUID = 62c34cea-a08d-4676-81e5-f16b0ee22f22
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
[Binaries.AARCH64]
PE32|AArch64/Arm64Gop_1_68.efi|*

View File

@@ -0,0 +1,19 @@
# AMD AARCH64 Gop Driver
## Important Notes
- This driver should be considered "as is" and may not be supported with further updates, upgrades or bug fixes.
- Contact info: James Huang (James.Huang@amd.com), Plamen Belomorski (Plamen.Belomorski@amd.com).
- When a headless GPU ROM image is found, return “unsupported” from Supported.
## Pre-SOC15 Gop Driver
**Supported Asic Device ID ranges:**
(0x6880, 0x689f), (0x68A0, 0x68Bf), (0x68C0, 0x68Df), (0x68E0, 0x68FF), (0x9640, 0x964f), (0x9800, 0x980f), (0x9990, 0x99Af), (0x6700, 0x671f), (0x6720, 0x673f), (0x6740, 0x675f), (0x6840, 0x685f), (0x6760, 0x677f), (0x6780, 0x679f), (0x6800, 0x681f), (0x6820, 0x683f), (0x6600, 0x663f), (0x6660, 0x667f), (0x1304, 0x131d), (0x6640, 0x665f), (0x67a0, 0x67bf), (0x9830, 0x983f), (0x98b0, 0x98bf), (0x6900, 0x691f), (0x6920, 0x693f), (0x6960, 0x697f), (0x7300, 0x7304), (0x67C0, 0x67DF), (0x67E0, 0x67Ff), (0x6980, 0x699f), (0x6940, 0x695f), (0x9850, 0x985f), (0x9870, 0x988f), (0x98e0, 0x98ff), (0x9890, 0x98af), (0x98c0, 0x98df)
## Post-SOC15 Gop Driver
For the DIDs that are not supported in pre-SoC15 GOP, please use this Post-SoC15 GOP driver.
https://www.amd.com/en/resources/support-articles/release-notes/RN-AAR.html

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 768 KiB

View File

@@ -1,6 +1,7 @@
/** @file
UEFI Component Name and Name2 protocol for OHCI driver.
Copyright (c) 2025, Mario Bălănică <mariobalanica02@gmail.com>
Copyright (c) 2013-2015 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -166,9 +167,9 @@ OhciComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
USB_OHCI_HC_DEV *OhciDev;
EFI_USB_HC_PROTOCOL *UsbHc;
EFI_STATUS Status;
USB_OHCI_HC_DEV *OhciDev;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
//
// This is a device driver, so ChildHandle must be NULL.
@@ -194,8 +195,8 @@ OhciComponentNameGetControllerName (
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUsbHcProtocolGuid,
(VOID **)&UsbHc,
&gEfiUsb2HcProtocolGuid,
(VOID **)&Usb2Hc,
gOhciDriverBinding.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
@@ -204,7 +205,7 @@ OhciComponentNameGetControllerName (
return Status;
}
OhciDev = USB_OHCI_HC_DEV_FROM_THIS (UsbHc);
OhciDev = USB_OHCI_HC_DEV_FROM_THIS (Usb2Hc);
return LookupUnicodeString2 (
Language,

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
Provides the definition of Usb Hc Protocol and OHCI controller
private data structure.
Copyright (c) 2025, Mario Bălănică <mariobalanica02@gmail.com>
Copyright (c) 2013-2016 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Uefi.h>
#include <Protocol/UsbHostController.h>
#include <Protocol/Usb2HostController.h>
#include <Library/DmaLib.h>
#include <Guid/EventGroup.h>
@@ -62,7 +63,6 @@ typedef struct {
struct _USB_OHCI_HC_DEV {
UINTN Signature;
EFI_USB_HC_PROTOCOL UsbHc;
EFI_USB2_HC_PROTOCOL Usb2Hc;
UINT32 UsbHcBaseAddress;
HCCA_MEMORY_BLOCK *HccaMemoryBlock;
@@ -87,174 +87,189 @@ struct _USB_OHCI_HC_DEV {
OHCI_DEVICE_PROTOCOL *Protocol;
};
#define USB_OHCI_HC_DEV_FROM_THIS(a) CR(a, USB_OHCI_HC_DEV, UsbHc, USB_OHCI_HC_DEV_SIGNATURE)
#define USB_OHCI_HC_DEV_FROM_THIS(a) CR(a, USB_OHCI_HC_DEV, Usb2Hc, USB_OHCI_HC_DEV_SIGNATURE)
//
// Func List
//
/**
Retrieves the Host Controller capabilities.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param MaxSpeed Host controller data transfer speed.
@param PortNumber Number of the root hub ports.
@param Is64BitCapable TRUE if controller supports 64-bit memory addressing,
FALSE otherwise.
@retval EFI_SUCCESS The host controller capabilities were retrieved successfully.
@retval EFI_INVALID_PARAMETER One of the input args was NULL.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to
retrieve the capabilities.
**/
EFI_STATUS
EFIAPI
OhciGetCapability (
IN EFI_USB2_HC_PROTOCOL *This,
OUT UINT8 *MaxSpeed,
OUT UINT8 *PortNumber,
OUT UINT8 *Is64BitCapable
);
/**
Provides software reset for the USB host controller.
@param This This EFI_USB_HC_PROTOCOL instance.
@param Attributes A bit mask of the reset operation to perform.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param Attributes A bit mask of the reset operation to perform.
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
@retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
not currently supported by the host controller.
@retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
@retval EFI_UNSUPPORTED The type of reset specified by Attributes is not currently
supported by the host controller hardware.
@retval EFI_ACCESS_DENIED Reset operation is rejected due to the debug port being configured
and active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Attributes can be used to
perform reset operation for this host controller.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to
retrieve the capabilities.
**/
EFI_STATUS
EFIAPI
OhciReset (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT16 Attributes
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT16 Attributes
);
/**
Retrieve the current state of the USB host controller.
Retrieves current state of the USB host controller.
@param This This EFI_USB_HC_PROTOCOL instance.
@param State Variable to return the current host controller
state.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param State A pointer to the EFI_USB_HC_STATE data structure that
indicates current state of the USB host controller.
@retval EFI_SUCCESS Host controller state was returned in State.
@retval EFI_SUCCESS The state information of the host controller was returned in State.
@retval EFI_INVALID_PARAMETER State is NULL.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to
retrieve the host controller's current state.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the
host controller's current state.
**/
EFI_STATUS
EFIAPI
OhciGetState (
IN EFI_USB_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
IN EFI_USB2_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
);
/**
Sets the USB host controller to a specific state.
@param This This EFI_USB_HC_PROTOCOL instance.
@param State The state of the host controller that will be set.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param State Indicates the state of the host controller that will be set.
@retval EFI_SUCCESS The USB host controller was successfully placed
in the state specified by State.
@retval EFI_INVALID_PARAMETER State is invalid.
@retval EFI_DEVICE_ERROR Failed to set the state due to device error.
@retval EFI_SUCCESS The USB host controller was successfully placed in the state
specified by State.
@retval EFI_INVALID_PARAMETER State is not valid.
@retval EFI_DEVICE_ERROR Failed to set the state specified by State due to device error.
**/
EFI_STATUS
EFIAPI
OhciSetState (
IN EFI_USB_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
IN EFI_USB2_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
);
/**
Submits control transfer to a target USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPaketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
sending or receiving.
@param Request A pointer to the USB device request that will be sent
to the USB device.
@param TransferDirection Specifies the data direction for the transfer.
There are three values available, DataIn, DataOut
and NoData.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength Indicates the size, in bytes, of the data buffer
specified by Data.
@param TimeOut Indicates the maximum time, in microseconds,
which the transfer is allowed to complete.
@param TransferResult A pointer to the detailed result information generated
by this control transfer.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Indicates the maximum packet size that the default control transfer
endpoint is capable of sending or receiving.
@param Request A pointer to the USB device request that will be sent to the USB device.
@param TransferDirection Specifies the data direction for the transfer. There are three values
available, EfiUsbDataIn, EfiUsbDataOut and EfiUsbNoData.
@param Data A pointer to the buffer of data that will be transmitted to USB device or
received from USB device.
@param DataLength On input, indicates the size, in bytes, of the data buffer specified by Data.
On output, indicates the amount of data actually transferred.
@param TimeOut Indicates the maximum time, in milliseconds, which the transfer is
allowed to complete.
@param Translator A pointer to the transaction translator data.
@param TransferResult A pointer to the detailed result information generated by this control
transfer.
@retval EFI_SUCCESS The control transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The control transfer could not be completed due to a lack of resources.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The control transfer could not be completed due to a lack of resources.
@retval EFI_TIMEOUT The control transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The control transfer failed due to host controller or device error.
Caller should check TranferResult for detailed error information.
--*/
Caller should check TransferResult for detailed error information.
**/
EFI_STATUS
EFIAPI
OhciControlTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data OPTIONAL,
IN OUT UINTN *DataLength OPTIONAL,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data OPTIONAL,
IN OUT UINTN *DataLength OPTIONAL,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits bulk transfer to a bulk endpoint of a USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an
endpoint direction of the target USB device.
Each endpoint address supports data transfer in
one direction except the control endpoint
(whose default endpoint address is 0).
It is the caller's responsibility to make sure that
the EndPointAddress represents a bulk endpoint.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength When input, indicates the size, in bytes, of the data buffer
specified by Data. When output, indicates the actually
transferred data size.
@param DataToggle A pointer to the data toggle value. On input, it indicates
the initial data toggle value the bulk transfer should adopt;
on output, it is updated to indicate the data toggle value
of the subsequent bulk transfer.
@param TimeOut Indicates the maximum time, in microseconds, which the
transfer is allowed to complete.
TransferResult A pointer to the detailed result information of the
bulk transfer.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param EndPointAddress The combination of an endpoint number and an endpoint direction of the
target USB device.
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
sending or receiving.
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data that will be transmitted to USB
device or received from USB device.
@param DataLength When input, indicates the size, in bytes, of the data buffers specified by
Data. When output, indicates the actually transferred data size.
@param DataToggle A pointer to the data toggle value.
@param TimeOut Indicates the maximum time, in milliseconds, which the transfer is
allowed to complete.
@param Translator A pointer to the transaction translator data.
@param TransferResult A pointer to the detailed result information of the bulk transfer.
@retval EFI_SUCCESS The bulk transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The bulk transfer could not be submitted due to lack of resource.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The bulk transfer could not be submitted due to a lack of resources.
@retval EFI_TIMEOUT The bulk transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The bulk transfer failed due to host controller or device error.
Caller should check TranferResult for detailed error information.
Caller should check TransferResult for detailed error information.
**/
EFI_STATUS
EFIAPI
OhciBulkTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaxPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
@@ -272,7 +287,7 @@ OhciBulkTransfer (
the EndPointAddress represents an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPacketLength Indicates the maximum packet size the target endpoint
@param MaximumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
the host and the target interrupt endpoint.
@@ -309,14 +324,13 @@ OhciBulkTransfer (
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
OhciInterruptTransfer (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN UINT8 MaximumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle OPTIONAL,
IN UINTN PollingInterval OPTIONAL,
@@ -330,45 +344,30 @@ OhciInterruptTransfer (
);
/**
Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an endpoint
direction of the target USB device. Each endpoint address
supports data transfer in one direction except the
control endpoint (whose default endpoint address is 0).
It is the caller's responsibility to make sure that
the EndPointAddress represents an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxiumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
the host and the target interrupt endpoint.
If FALSE, the specified asynchronous interrupt pipe
is canceled.
@param DataToggle A pointer to the data toggle value. On input, it is valid
when IsNewTransfer is TRUE, and it indicates the initial
data toggle value the asynchronous interrupt transfer
should adopt.
On output, it is valid when IsNewTransfer is FALSE,
and it is updated to indicate the data toggle value of
the subsequent asynchronous interrupt transfer.
@param PollingInterval Indicates the interval, in milliseconds, that the
asynchronous interrupt transfer is polled.
This parameter is required when IsNewTransfer is TRUE.
@param DataLength Indicates the length of data to be received at the
rate specified by PollingInterval from the target
asynchronous interrupt endpoint. This parameter
is only required when IsNewTransfer is TRUE.
@param CallBackFunction The Callback function.This function is called at the
rate specified by PollingInterval.This parameter is
only required when IsNewTransfer is TRUE.
@param Context The context that is passed to the CallBackFunction.
This is an optional parameter and may be NULL.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param EndPointAddress The combination of an endpoint number and an endpoint direction of the
target USB device.
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
sending or receiving.
@param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between the host and the
target interrupt endpoint. If FALSE, the specified asynchronous interrupt
pipe is canceled. If TRUE, and an interrupt transfer exists for the target
end point, then EFI_INVALID_PARAMETER is returned.
@param DataToggle A pointer to the data toggle value.
@param PollingInterval Indicates the interval, in milliseconds, that the asynchronous interrupt
transfer is polled.
@param DataLength Indicates the length of data to be received at the rate specified by
PollingInterval from the target asynchronous interrupt endpoint.
@param Translator A pointr to the transaction translator data.
@param CallBackFunction The Callback function. This function is called at the rate specified by
PollingInterval.
@param Context The context that is passed to the CallBackFunction. This is an
optional parameter and may be NULL.
@retval EFI_SUCCESS The asynchronous interrupt transfer request has been successfully
submitted or canceled.
@@ -376,228 +375,276 @@ OhciInterruptTransfer (
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
OhciAsyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle OPTIONAL,
IN UINTN PollingInterval OPTIONAL,
IN UINTN DataLength OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaxiumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval OPTIONAL,
IN UINTN DataLength OPTIONAL,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL
);
/**
Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.
Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated in the following specification version.
Submits synchronous interrupt transfer to an interrupt endpoint
of a USB device.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param EndPointAddress The combination of an endpoint number and an endpoint direction of the
target USB device.
@param DeviceSpeed Indicates device speed.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted to USB device or
received from USB device.
@param DataLength On input, the size, in bytes, of the data buffer specified by Data. On
output, the number of bytes transferred.
@param DataToggle A pointer to the data toggle value.
@param TimeOut Indicates the maximum time, in milliseconds, which the transfer is
allowed to complete.
@param Translator A pointr to the transaction translator data.
@param TransferResult A pointer to the detailed result information from the synchronous
interrupt transfer.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an endpoint
direction of the target USB device. Each endpoint
address supports data transfer in one direction
except the control endpoint (whose default
endpoint address is 0). It is the caller's responsibility
to make sure that the EndPointAddress represents
an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength On input, the size, in bytes, of the data buffer specified
by Data. On output, the number of bytes transferred.
@param DataToggle A pointer to the data toggle value. On input, it indicates
the initial data toggle value the synchronous interrupt
transfer should adopt;
on output, it is updated to indicate the data toggle value
of the subsequent synchronous interrupt transfer.
@param TimeOut Indicates the maximum time, in microseconds, which the
transfer is allowed to complete.
@param TransferResult A pointer to the detailed result information from
the synchronous interrupt transfer.
@retval EFI_UNSUPPORTED This interface not available.
@retval EFI_INVALID_PARAMETER Parameters not follow spec
@retval EFI_SUCCESS The synchronous interrupt transfer was completed successfully.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The synchronous interrupt transfer could not be submitted due to a lack of resources.
@retval EFI_TIMEOUT The synchronous interrupt transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The synchronous interrupt transfer failed due to host controller or device error.
Caller should check TransferResult for detailed error information.
**/
EFI_STATUS
EFIAPI
OhciSyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits isochronous transfer to an isochronous endpoint of a USB device.
Submits isochronous transfer to a target USB device.
This function is used to submit isochronous transfer to a target endpoint of a USB device.
The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers are
used when working with isochronous date. It provides periodic, continuous communication between
the host and a device. Isochronous transfers can beused only by full-speed, high-speed, and
super-speed devices.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress End point address
@param MaximumPacketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
High-speed isochronous transfers can be performed using multiple data buffers. The number of
buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For
full-speed isochronous transfers this value is ignored.
Data represents a list of pointers to the data buffers. For full-speed isochronous transfers
only the data pointed by Data[0]shall be used. For high-speed isochronous transfers and for
the split transactions depending on DataLengththere several data buffers canbe used. For the
high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM.
For split transactions performed on full-speed device by high-speed host controller the total
number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1.
If the isochronous transfer is successful, then EFI_SUCCESSis returned. The isochronous transfer
is designed to be completed within one USB frame time, if it cannot be completed, EFI_TIMEOUT
is returned. If an error other than timeout occurs during the USB transfer, then EFI_DEVICE_ERROR
is returned and the detailed status code will be returned in TransferResult.
EFI_INVALID_PARAMETERis returned if one of the following conditionsis satisfied:
- Data is NULL.
- DataLength is 0.
- DeviceSpeed is not one of the supported values listed above.
- MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed devices,
and 1024 or less for high-speed and super-speed devices.
- TransferResult is NULL.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param EndPointAddress The combination of an endpoint number and an endpoint direction of the
target USB device.
@param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL,
EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength Indicates the size, in bytes, of the data buffer
specified by Data.
@param TransferResult A pointer to the detailed result information generated
by this control transfer.
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data that will be transmitted to USB
device or received from USB device.
@param DataLength Specifies the length, in bytes, of the data to be sent to or received from
the USB device.
@param Translator A pointer to the transaction translator data.
@param TransferResult A pointer to the detailed result information of the isochronous transfer.
@retval EFI_UNSUPPORTED This interface not available
@retval EFI_INVALID_PARAMETER Data is NULL or DataLength is 0 or TransferResult is NULL
@retval EFI_SUCCESS The isochronous transfer was completed successfully.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The isochronous transfer could not be submitted due to a lack of resources.
@retval EFI_TIMEOUT The isochronous transfer cannot be completed within the one USB frame time.
@retval EFI_DEVICE_ERROR The isochronous transfer failed due to host controller or device error.
Caller should check TransferResult for detailed error information.
**/
EFI_STATUS
EFIAPI
OhciIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN DataLength,
OUT UINT32 *TransferResult
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *TransferResult
);
/**
Submits nonblocking isochronous transfer to an isochronous endpoint of a USB device.
Submits Async isochronous transfer to a target USB device.
This is an asynchronous type of USB isochronous transfer. If the caller submits a USB
isochronous transfer request through this function, this function will return immediately.
@param his A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress End point address
@param MaximumPacketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
When the isochronous transfer completes, the IsochronousCallbackfunction will be triggered,
the caller can know the transfer results. If the transfer is successful, the caller can get
the data received or sent in this callback function.
The target endpoint is specified by DeviceAddressand EndpointAddress. Isochronous transfers
are used when working with isochronous date. It provides periodic, continuous communication
between the host and a device. Isochronous transfers can be used only by full-speed, high-speed,
and super-speed devices.
High-speed isochronous transfers can be performed using multiple data buffers. The number of
buffers that are actually prepared for the transfer is specified by DataBuffersNumber. For
full-speed isochronous transfers this value is ignored.
Data represents a list of pointers to the data buffers. For full-speed isochronous transfers
only the data pointed by Data[0] shall be used. For high-speed isochronous transfers and for
the split transactions depending on DataLength there several data buffers can be used. For
the high-speed isochronous transfers the total number of buffers must not exceed EFI_USB_MAX_ISO_BUFFER_NUM.
For split transactions performed on full-speed device by high-speed host controller the total
number of buffers is limited to EFI_USB_MAX_ISO_BUFFER_NUM1.
EFI_INVALID_PARAMETER is returned if one of the following conditionsis satisfied:
- Data is NULL.
- DataLength is 0.
- DeviceSpeed is not one of the supported values listed above.
- MaximumPacketLength is invalid. MaximumPacketLength must be 1023 or less for full-speed
devices and 1024 or less for high-speed and super-speed devices.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB.
@param EndPointAddress The combination of an endpoint number and an endpoint direction of the
target USB device.
@param DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL,
EFI_USB_SPEED_HIGH, or EFI_USB_SPEED_SUPER.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint is capable of
sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param IsochronousCallBack When the transfer complete, the call back function will be called
@param Context Pass to the call back function as parameter
@param DataBuffersNumber Number of data buffers prepared for the transfer.
@param Data Array of pointers to the buffers of data that will be transmitted to USB
device or received from USB device.
@param DataLength Specifies the length, in bytes, of the data to be sent to or received from
the USB device.
@param Translator A pointer to the transaction translator data.
@param IsochronousCallback The Callback function. This function is called if the requested
isochronous transfer is completed.
@param Context Data passed to the IsochronousCallback function. This is an
optional parameter and may be NULL.
@retval EFI_UNSUPPORTED This interface not available
@retval EFI_INVALID_PARAMETER Data is NULL or Datalength is 0
@retval EFI_SUCCESS The asynchronous isochronous transfer request has been successfully
submitted or canceled.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The asynchronous isochronous transfer could not be submitted due to
a lack of resources.
**/
EFI_STATUS
EFIAPI
OhciAsyncIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN DataLength,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
IN VOID *Context OPTIONAL
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 DeviceSpeed,
IN UINTN MaximumPacketLength,
IN UINT8 DataBuffersNumber,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
IN VOID *Context OPTIONAL
);
/**
Retrieves the number of root hub ports.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param NumOfPorts A pointer to the number of the root hub ports.
@retval EFI_SUCCESS The port number was retrieved successfully.
**/
EFI_STATUS
EFIAPI
OhciGetRootHubNumOfPorts (
IN EFI_USB_HC_PROTOCOL *This,
OUT UINT8 *NumOfPorts
);
/**
Retrieves the current status of a USB root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL.
@param PortNumber Specifies the root hub port from which the status
is to be retrieved. This value is zero-based. For example,
if a root hub has two ports, then the first port is numbered 0,
and the second port is numbered 1.
@param PortStatus A pointer to the current port status bits and
port status change bits.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param PortNumber Specifies the root hub port from which the status is to be retrieved.
This value is zero based.
@param PortStatus A pointer to the current port status bits and port status change bits.
@retval EFI_SUCCESS The status of the USB root hub port specified by PortNumber
was returned in PortStatus.
@retval EFI_INVALID_PARAMETER Port number not valid
**/
@retval EFI_INVALID_PARAMETER PortNumber is invalid.
**/
EFI_STATUS
EFIAPI
OhciGetRootHubPortStatus (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
);
/**
Sets a feature for the specified root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL.
@param PortNumber Specifies the root hub port whose feature
is requested to be set.
@param PortFeature Indicates the feature selector associated
with the feature set request.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param PortNumber Specifies the root hub port whose feature is requested to be set. This
value is zero based.
@param PortFeature Indicates the feature selector associated with the feature set request.
@retval EFI_SUCCESS The feature specified by PortFeature was set for the USB
root hub port specified by PortNumber.
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
@retval EFI_SUCCESS The feature specified by PortFeature was set for the
USB root hub port specified by PortNumber.
@retval EFI_DEVICE_ERROR Set feature failed because of hardware issue
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
**/
EFI_STATUS
EFIAPI
OhciSetRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
/**
Clears a feature for the specified root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param PortNumber Specifies the root hub port whose feature
is requested to be cleared.
@param PortFeature Indicates the feature selector associated with the
feature clear request.
@param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
@param PortNumber Specifies the root hub port whose feature is requested to be cleared. This
value is zero based.
@param PortFeature Indicates the feature selector associated with the feature clear request.
@retval EFI_SUCCESS The feature specified by PortFeature was cleared for the USB
root hub port specified by PortNumber.
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid for this function.
@retval EFI_SUCCESS The feature specified by PortFeature was cleared for the
USB root hub port specified by PortNumber.
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
@retval EFI_DEVICE_ERROR Some error happened when clearing feature
**/
EFI_STATUS
EFIAPI
OhciClearRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
@@ -616,7 +663,6 @@ OhciClearRootHubPortFeature (
**/
EFI_STATUS
EFIAPI
OHCIDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,

View File

@@ -1,6 +1,7 @@
## @file
# OHCI USB Host Controller UEFI Driver
#
# Copyright (c) 2025, Mario Bălănică <mariobalanica02@gmail.com>
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -62,8 +63,8 @@
gEfiEndOfDxeEventGroupGuid
[Protocols]
gOhciDeviceProtocolGuid ## TO_START
gEfiUsbHcProtocolGuid ## BY_START
gOhciDeviceProtocolGuid ## TO_START
gEfiUsb2HcProtocolGuid ## BY_START
[Depex]
TRUE

View File

@@ -24,7 +24,7 @@ struct _INTERRUPT_CONTEXT_ENTRY {
ED_DESCRIPTOR *Ed;
TD_DESCRIPTOR *DataTd;
BOOLEAN IsSlowDevice;
UINT8 MaxPacketLength;
UINT8 MaximumPacketLength;
UINTN PollingInterval;
EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction;
VOID *Context;

View File

@@ -272,14 +272,13 @@ CHAR8 *mEnclosureInfoType3Strings[] = {
SMBIOS data definition TYPE4 Processor Information
************************************************************************/
SMBIOS_TABLE_TYPE4 mProcessorInfoType4 = {
{ EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE4), 0 },
{ EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE4), 0 },
1, // Socket String
CentralProcessor, // ProcessorType; ///< The enumeration value from PROCESSOR_TYPE_DATA.
ProcessorFamilyIndicatorFamily2, // ProcessorFamily; ///< The enumeration value from PROCESSOR_FAMILY2_DATA.
2, // ProcessorManufacture String;
{ // ProcessorId;
{ 0x00, 0x00, 0x00, 0x00},
{ 0x00, 0x00, 0x00, 0x00}
0x00, 0x00, 0x00, 0x00
},
3, // ProcessorVersion String;
{ // Voltage;
@@ -344,8 +343,8 @@ SMBIOS_TABLE_TYPE7 mCacheInfoType7_L1I = {
// Enabled/Disabled :1 (Enabled)
// Operational Mode :2 (Unknown)
// Reserved :6
0x0020, // Maximum Size (32KB)
0x0020, // Install Size (32KB)
{ 0x0020, 0 }, // Maximum Size (32KB)
{ 0x0020, 0 }, // Install Size (32KB)
{ // Supported SRAM Type
0, // Other :1
0, // Unknown :1
@@ -387,8 +386,8 @@ SMBIOS_TABLE_TYPE7 mCacheInfoType7_L1D = {
// Enabled/Disabled :1 (Enabled)
// Operational Mode :2 (WB)
// Reserved :6
0x0020, // Maximum Size (32KB)
0x0020, // Install Size (32KB)
{ 0x0020, 0 }, // Maximum Size (32KB)
{ 0x0020, 0 }, // Install Size (32KB)
{ // Supported SRAM Type
0, // Other :1
0, // Unknown :1
@@ -430,8 +429,8 @@ SMBIOS_TABLE_TYPE7 mCacheInfoType7_L2 = {
// Enabled/Disabled :1 (Enabled)
// Operational Mode :2 (WB)
// Reserved :6
0x0200, // Maximum Size (512KB)
0x0200, // Install Size (512KB)
{ 0x0200, 0 }, // Maximum Size (512KB)
{ 0x0200, 0 }, // Install Size (512KB)
{ // Supported SRAM Type
0, // Other :1
0, // Unknown :1

View File

@@ -17,15 +17,16 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/FdtLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/RkAtagsLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeLib.h>
#include <Library/DevicePathLib.h>
#include <Library/RkAtagsLib.h>
#include <Protocol/DiskIo.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/NonDiscoverableDevice.h>
@@ -34,7 +35,6 @@
#include <Guid/SystemNvDataGuid.h>
#include <Guid/VariableFormat.h>
#include <Guid/EventGroup.h>
#include <libfdt.h>
#include "RkFvbDxe.h"
@@ -1349,7 +1349,7 @@ FvbCheckBootDiskDeviceHasFirmware (
EFI_DISK_IO_PROTOCOL *DiskIo;
UINT64 Offset;
UINTN Size;
struct fdt_header FdtHeader;
FDT_HEADER FdtHeader;
VOID *Fdt = NULL;
INT32 Ret;
INT32 Node;
@@ -1378,19 +1378,19 @@ FvbCheckBootDiskDeviceHasFirmware (
goto Exit;
}
Ret = fdt_check_header (&FdtHeader);
Ret = FdtCheckHeader (&FdtHeader);
if (Ret) {
DEBUG ((
DEBUG_ERROR,
"%a: [%s] FIT has an invalid header! Ret=%a\n",
__FUNCTION__,
DevicePathText,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
goto Exit;
}
Size = fdt_totalsize (&FdtHeader);
Size = FdtTotalSize (&FdtHeader);
Fdt = AllocatePool (Size);
Status = DiskIo->ReadDisk (DiskIo, MediaId, Offset, Size, Fdt);
@@ -1407,14 +1407,14 @@ FvbCheckBootDiskDeviceHasFirmware (
goto Exit;
}
Node = fdt_path_offset (Fdt, "/images/edk2");
Node = FdtPathOffset (Fdt, "/images/edk2");
if (Node < 0) {
DEBUG ((
DEBUG_ERROR,
"%a: [%s] FIT: Couldn't locate '/images/edk2' node! Ret=%a\n",
__FUNCTION__,
DevicePathText,
fdt_strerror (Node)
FdtStrerror (Node)
));
goto Exit;
}

View File

@@ -31,21 +31,20 @@
Silicon/Rockchip/RockchipPkg.dec
[LibraryClasses]
IoLib
BaseLib
DebugLib
HobLib
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiRuntimeLib
BaseMemoryLib
DebugLib
DevicePathLib
DxeServicesTableLib
MemoryAllocationLib
UefiRuntimeServicesTableLib
RkAtagsLib
FdtLib
HobLib
MemoryAllocationLib
PcdLib
RkAtagsLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
UefiRuntimeLib
[Guids]
gEdkiiNvVarStoreFormattedGuid

View File

@@ -127,6 +127,12 @@
INF Silicon/Rockchip/Library/DisplayLib/DwMipiDsi2Lib.inf
INF Silicon/Rockchip/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
!if $(RK_AMD_GOP_ENABLE) == TRUE
INF Drivers/AMD/Gop/AmdGopOpRomOverrideDxe.inf
INF Drivers/AMD/Gop/AmdGopPreSoc15Dxe.inf
INF Drivers/AMD/Gop/AmdGopPostSoc15Dxe.inf
!endif
#
# USB Support
#
@@ -222,6 +228,13 @@
#
INF EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
#
# x64 Binary Compatibility Support
#
!if $(RK_X86_EMULATOR_ENABLE) == TRUE
INF Emulator/X86EmulatorDxe/X86EmulatorDxe.inf
!endif
#
# Bds
#

View File

@@ -20,6 +20,7 @@
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
Silicon/Rockchip/Library/Pcf8563RealTimeClockLib/Pcf8563RealTimeClockLib.dec

View File

@@ -53,9 +53,6 @@
UefiLib
UefiRuntimeServicesTableLib
[FeaturePcd]
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString

View File

@@ -23,80 +23,6 @@ RK3588_MCFG_TABLE Mcfg = {
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION
),
},
{ // Main config space
{
PCIE_CFG_BASE (0),
0, // PciSegmentNumber
1, // PciBusMin
1, // PciBusMax
0 // Reserved
},
{
PCIE_CFG_BASE (1),
1, // PciSegmentNumber
1, // PciBusMin
1, // PciBusMax
0 // Reserved
},
{
PCIE_CFG_BASE (2),
2, // PciSegmentNumber
1, // PciBusMin
1, // PciBusMax
0 // Reserved
},
{
PCIE_CFG_BASE (3),
3, // PciSegmentNumber
1, // PciBusMin
1, // PciBusMax
0 // Reserved
},
{
PCIE_CFG_BASE (4),
4, // PciSegmentNumber
1, // PciBusMin
1, // PciBusMax
0 // Reserved
}
},
{ // Root Port DBI config space (for Windows)
{
PCIE_DBI_BASE (0),
0, // PciSegmentNumber
0, // PciBusMin
0, // PciBusMax
0 // Reserved
},
{
PCIE_DBI_BASE (1),
1, // PciSegmentNumber
0, // PciBusMin
0, // PciBusMax
0 // Reserved
},
{
PCIE_DBI_BASE (2),
2, // PciSegmentNumber
0, // PciBusMin
0, // PciBusMax
0 // Reserved
},
{
PCIE_DBI_BASE (3),
3, // PciSegmentNumber
0, // PciBusMin
0, // PciBusMax
0 // Reserved
},
{
PCIE_DBI_BASE (4),
4, // PciSegmentNumber
0, // PciBusMin
0, // PciBusMax
0 // Reserved
}
}
};
VOID *CONST ReferenceAcpiTable = &Mcfg;

View File

@@ -16,7 +16,11 @@
Name (_UID, Segment) \
Name (_SEG, Segment) \
Method (_BBN) { \
Return (PBMI) \
If (PBOF) { \
Return (PCIE_BUS_BASE (Segment) + PBMI) \
} Else { \
Return (PBMI) \
} \
} \
Name (_STA, 0xF) \
\
@@ -30,14 +34,34 @@
Method (_CRS, 0, Serialized) { \
Name (RBUF, ResourceTemplate () { \
WORDBUSNUMBER_BUF (00, ResourceProducer) \
DWORDMEMORY_BUF (01, ResourceProducer) \
QWORDMEMORY_BUF (01, ResourceProducer) \
QWORDMEMORY_BUF (02, ResourceProducer) \
QWORDIO_BUF (03, ResourceProducer) \
}) \
WORD_SET (00, PBMI, PBMA - PBMI + 1, 0) \
DWORD_SET (01, PCIE_MEM_BASE (Segment), PCIE_MEM_SIZE, 0) \
QWORD_SET (02, PCIE_MEM64_BASE (Segment), PCIE_MEM64_SIZE, 0) \
QWORD_SET (03, PCIE_IO_BASE, PCIE_IO_SIZE, PCIE_IO_XLATE (Segment)) \
WORD_SET ( \
00, \
_BBN, \
PBMA - PBMI + 1, \
0 \
) \
QWORD_SET ( \
01, \
PCIE_MEM32_BUS_BASE, \
PCIE_MEM32_SIZE, \
PCIE_MEM32_TRANSLATION (Segment) \
) \
QWORD_SET ( \
02, \
PCIE_MEM64_BASE (Segment), \
PCIE_MEM64_SIZE, \
0 \
) \
QWORD_SET ( \
03, \
PCIE_IO_BUS_BASE, \
PCIE_IO_SIZE, \
PCIE_IO_TRANSLATION (Segment) \
) \
Return (RBUF) \
} \
\
@@ -61,7 +85,7 @@
Name (RBUF, ResourceTemplate () { \
QWORDMEMORY_BUF (00, ResourceProducer) \
}) \
QWORD_SET (00, PCIE_CFG_BASE (Segment), SIZE_256MB, 0) \
QWORD_SET (00, PCIE_CFG_BASE (Segment), PCIE_CFG_SIZE , 0) \
Return (RBUF) \
} \
} \
@@ -111,6 +135,7 @@
Scope (\_SB_) {
Name (PBMI, 0xABCD) // PCI Bus Minimum
Name (PBMA, 0xABCD) // PCI Bus Maximum
Name (PBOF, 1) // PCI Bus Offset
PCIE_ROOT_COMPLEX (0, 292)
PCIE_ROOT_COMPLEX (1, 287)

View File

@@ -218,9 +218,9 @@ AcpiFixupPcieEcam (
UINT32 PcieEcamMode;
UINT8 PcieBusMin;
UINT8 PcieBusMax;
UINT8 McfgMainBusMin;
BOOLEAN McfgSplitRootPort;
BOOLEAN McfgSingleDevQuirk;
BOOLEAN PcieBusOffset;
BOOLEAN McfgDeviceFiltering;
BOOLEAN McfgSplitConfigSpaces;
Index = 0;
Status = AcpiLocateTableBySignature (
@@ -241,23 +241,37 @@ AcpiFixupPcieEcam (
PcieEcamMode = PcdGet32 (PcdAcpiPcieEcamCompatMode);
if ((PcieEcamMode == ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV) ||
(PcieEcamMode == ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON))
{
if (OsType == ExitBootServicesOsWindows) {
PcieEcamMode = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6;
} else {
PcieEcamMode &= ~ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6;
if (PcieEcamMode == ACPI_PCIE_ECAM_COMPAT_MODE_AUTO) {
switch (OsType) {
case ExitBootServicesOsWindows:
PcieEcamMode = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6;
break;
case ExitBootServicesOsLinux:
PcieEcamMode = ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON;
break;
default:
PcieEcamMode = ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV;
break;
}
}
switch (PcieEcamMode) {
case ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6:
PcieBusMin = 0;
PcieBusMax = PCIE_BUS_LIMIT;
McfgMainBusMin = 1;
McfgSplitRootPort = TRUE;
McfgSingleDevQuirk = FALSE;
//
// This workaround ought to filter duplicate devices on the primary
// and secondary buses, but it appears that recent Windows versions
// only do so for bus numbers 0 and 1.
// Not all segments start at bus 0 anymore, since they need to be made
// distinct to the SMMU & ITS (see Rk3588Pcie.h). However, these features
// can't be enabled in Windows anyway, so we'll disable the bus offset and
// let it reassign bus numbers from 0.
// It's possible to enable PcieBusOffset by disabling McfgDeviceFiltering,
// but this will hide the root port and may cause the system to lock-up
// with certain endpoints that have broken CFG0 filtering.
//
PcieBusOffset = FALSE;
McfgDeviceFiltering = !PcieBusOffset;
McfgSplitConfigSpaces = TRUE;
Index = 0;
Status = AcpiLocateTableBySignature (
@@ -281,44 +295,97 @@ AcpiFixupPcieEcam (
break;
case ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON:
PcieBusMin = 0;
PcieBusMax = PCIE_BUS_LIMIT;
McfgMainBusMin = 0;
McfgSplitRootPort = FALSE;
McfgSingleDevQuirk = FALSE;
PcieBusOffset = TRUE;
McfgDeviceFiltering = TRUE;
McfgSplitConfigSpaces = FALSE;
CopyMem (McfgTable->Header.Header.OemId, "AMAZON", sizeof (McfgTable->Header.Header.OemId));
McfgTable->Header.Header.OemTableId = SIGNATURE_64 ('G', 'R', 'A', 'V', 'I', 'T', 'O', 'N');
break;
default: // ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV
PcieBusMin = 1;
PcieBusMax = 1;
McfgMainBusMin = 1;
McfgSplitRootPort = FALSE;
McfgSingleDevQuirk = TRUE;
PcieBusOffset = TRUE;
McfgDeviceFiltering = FALSE;
McfgSplitConfigSpaces = FALSE;
break;
}
for (Index = 0; Index < ARRAY_SIZE (McfgTable->MainEntries); Index++) {
if (McfgSingleDevQuirk) {
if ((PcdGet32 (PcdPcieEcamCompliantSegmentsMask) & (1 << Index)) == 0) {
McfgTable->MainEntries[Index].BaseAddress += 0x8000;
PcieBusMin = 0;
PcieBusMax = PCIE_BUS_COUNT - 1;
if (!McfgDeviceFiltering) {
//
// Skip the primary bus as it only spans a single function (root port)
// and the remaining DBI region has to be filtered out.
//
PcieBusMin = 1;
if (!McfgSplitConfigSpaces) {
//
// It's not possible to have more than a single bus due to the
// the device offset workaround below.
//
PcieBusMax = PcieBusMin;
}
}
for (Index = 0; Index < NUM_PCIE_CONTROLLER; Index++) {
McfgTable->ConfigSpaces[0][Index].PciSegmentGroupNumber = Index;
McfgTable->ConfigSpaces[0][Index].BaseAddress = PCIE_CFG_BASE (Index) + PCIE_BUS_BASE_OFFSET (Index);
McfgTable->ConfigSpaces[0][Index].StartBusNumber = PcieBusMin;
McfgTable->ConfigSpaces[0][Index].EndBusNumber = PcieBusMax;
if (PcieBusOffset) {
McfgTable->ConfigSpaces[0][Index].BaseAddress -= PCIE_BUS_BASE_OFFSET (Index);
McfgTable->ConfigSpaces[0][Index].StartBusNumber += PCIE_BUS_BASE (Index);
McfgTable->ConfigSpaces[0][Index].EndBusNumber += PCIE_BUS_BASE (Index);
}
if (McfgSplitConfigSpaces) {
McfgTable->ConfigSpaces[1][Index].PciSegmentGroupNumber = McfgTable->ConfigSpaces[0][Index].PciSegmentGroupNumber;
McfgTable->ConfigSpaces[1][Index].StartBusNumber = McfgTable->ConfigSpaces[0][Index].StartBusNumber;
if (McfgDeviceFiltering) {
//
// The OS is expected to filter devices on the primary and secondary
// buses, so we can expose the root port in this entry (primary bus)
// and remaining buses in the first entry.
//
McfgTable->ConfigSpaces[1][Index].BaseAddress = PCIE_DBI_BASE (Index);
McfgTable->ConfigSpaces[1][Index].EndBusNumber = McfgTable->ConfigSpaces[1][Index].StartBusNumber;
McfgTable->ConfigSpaces[0][Index].StartBusNumber += 1;
} else {
//
// The OS will not filter devices on any bus, so we can't expose
// the root port. Use this entry for buses following secondary and
// limit the first entry to the secondary bus only, so the device
// offset workaround below can work.
//
McfgTable->ConfigSpaces[1][Index].BaseAddress = McfgTable->ConfigSpaces[0][Index].BaseAddress;
McfgTable->ConfigSpaces[1][Index].StartBusNumber += 1;
McfgTable->ConfigSpaces[1][Index].EndBusNumber = McfgTable->ConfigSpaces[0][Index].EndBusNumber;
McfgTable->ConfigSpaces[0][Index].EndBusNumber = McfgTable->ConfigSpaces[0][Index].StartBusNumber;
}
}
McfgTable->MainEntries[Index].StartBusNumber = McfgMainBusMin;
McfgTable->MainEntries[Index].EndBusNumber = PcieBusMax;
if (!McfgDeviceFiltering &&
((PcdGet32 (PcdPcieEcamCompliantSegmentsMask) & (1 << Index)) == 0))
{
McfgTable->ConfigSpaces[0][Index].BaseAddress += 0x8000;
}
}
if (McfgSplitRootPort == FALSE) {
McfgTable->Header.Header.Length -= sizeof (McfgTable->RootPortEntries);
if (!McfgSplitConfigSpaces) {
McfgTable->Header.Header.Length = OFFSET_OF (RK3588_MCFG_TABLE, ConfigSpaces[1]);
}
AcpiUpdateChecksum ((UINT8 *)McfgTable, McfgTable->Header.Header.Length);
AcpiUpdateSdtNameInteger (mDsdtTable, "PBMI", PcieBusMin);
AcpiUpdateSdtNameInteger (mDsdtTable, "PBMA", PcieBusMax);
AcpiUpdateSdtNameInteger (mDsdtTable, "PBOF", PcieBusOffset);
return EFI_SUCCESS;
}

View File

@@ -12,15 +12,17 @@
#include <Protocol/SimpleFileSystem.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PrintLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/FdtLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/Rk3588Pcie.h>
#include <Library/RockchipPlatformLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <libfdt.h>
#include <Guid/Fdt.h>
#include <Guid/FileInfo.h>
@@ -79,9 +81,9 @@ STATIC
EFI_STATUS
EFIAPI
FdtOpenIntoAlloc (
IN OUT VOID **Fdt,
IN OUT VOID **DestinationFdt, OPTIONAL
IN UINTN Size
IN OUT VOID **Fdt,
IN OUT VOID **DestinationFdt OPTIONAL,
IN UINTN Size
)
{
VOID *NewFdt;
@@ -97,9 +99,9 @@ FdtOpenIntoAlloc (
return EFI_OUT_OF_RESOURCES;
}
Ret = fdt_open_into (*Fdt, NewFdt, Size);
Ret = FdtOpenInto (*Fdt, NewFdt, Size);
if (Ret) {
DEBUG ((DEBUG_ERROR, "FdtPlatform: Failed to copy FDT. Ret=%a\n", fdt_strerror (Ret)));
DEBUG ((DEBUG_ERROR, "FdtPlatform: Failed to copy FDT. Ret=%a\n", FdtStrerror (Ret)));
FreePool (NewFdt);
return EFI_LOAD_ERROR;
}
@@ -127,26 +129,26 @@ FdtEnableNode (
INT32 Ret;
CHAR8 *NodeStatus;
Node = fdt_path_offset (Fdt, NodePath);
Node = FdtPathOffset (Fdt, NodePath);
if (Node < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Couldn't locate FDT node path '%a'. Ret=%a\n",
NodePath,
fdt_strerror (Node)
FdtStrerror (Node)
));
return EFI_NOT_FOUND;
}
NodeStatus = Enable ? "okay" : "disabled";
Ret = fdt_setprop_string (Fdt, Node, "status", NodeStatus);
Ret = FdtSetPropString (Fdt, Node, "status", NodeStatus);
if (Ret) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set '%a' status to '%a'. Ret=%a\n",
NodePath,
NodeStatus,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return EFI_UNSUPPORTED;
}
@@ -220,30 +222,30 @@ FdtFixupComboPhyDevices (
// turning it off.
//
if (Phys[Index].Mode == COMBO_PHY_MODE_SATA) {
Node = fdt_path_offset (Fdt, Phys[Index].PcieNodePath);
Node = FdtPathOffset (Fdt, Phys[Index].PcieNodePath);
if (Node < 0) {
continue;
}
Property = fdt_getprop (Fdt, Node, "vpcie3v3-supply", &Length);
Property = FdtGetProp (Fdt, Node, "vpcie3v3-supply", &Length);
if (Property == NULL) {
continue;
}
ASSERT (Length == sizeof (UINT32));
Node = fdt_path_offset (Fdt, Phys[Index].SataNodePath);
Node = FdtPathOffset (Fdt, Phys[Index].SataNodePath);
if (Node < 0) {
continue;
}
Ret = fdt_setprop (Fdt, Node, "phy-supply", Property, Length);
Ret = FdtSetProp (Fdt, Node, "phy-supply", Property, Length);
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'phy-supply' property for '%a'. Ret=%a\n",
Phys[Index].SataNodePath,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
continue;
}
@@ -279,6 +281,121 @@ FdtFixupPcie3Devices (
);
}
STATIC
VOID
EFIAPI
FdtFixupPcieResources (
IN VOID *Fdt
)
{
STATIC CHAR8 *PcieNodes[] = {
[PCIE_SEGMENT_PCIE30X4] = "/pcie@fe150000",
[PCIE_SEGMENT_PCIE30X2] = "/pcie@fe160000",
[PCIE_SEGMENT_PCIE20L0] = "/pcie@fe170000",
[PCIE_SEGMENT_PCIE20L1] = "/pcie@fe180000",
[PCIE_SEGMENT_PCIE20L2] = "/pcie@fe190000",
};
UINT32 Segment;
CHAR8 *NodePath;
INT32 Node;
INT32 Ret;
DEBUG ((DEBUG_INFO, "FdtPlatform: Fixing up PCIe resources\n"));
for (Segment = 0; Segment < ARRAY_SIZE (PcieNodes); Segment++) {
NodePath = PcieNodes[Segment];
Node = FdtPathOffset (Fdt, NodePath);
if (Node < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Couldn't locate '%a' node. Ret=%a\n",
NodePath,
FdtStrerror (Node)
));
continue;
}
UINT32 Ranges[][7] = {
{
CpuToFdt32 (0x01000000), // I/O space
CpuToFdt32 ((UINT32)((UINT64)PCIE_IO_BUS_BASE >> 32)),
CpuToFdt32 ((UINT32)(PCIE_IO_BUS_BASE)),
CpuToFdt32 ((UINT32)((UINT64)PCIE_IO_BASE (Segment) >> 32)),
CpuToFdt32 ((UINT32)(PCIE_IO_BASE (Segment))),
CpuToFdt32 ((UINT32)((UINT64)PCIE_IO_SIZE >> 32)),
CpuToFdt32 ((UINT32)(PCIE_IO_SIZE))
},
{
CpuToFdt32 (0x02000000), // 32-bit non-prefetchable memory
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM32_BUS_BASE >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM32_BUS_BASE)),
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM32_BASE (Segment) >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM32_BASE (Segment))),
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM32_SIZE >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM32_SIZE))
},
{
CpuToFdt32 (0x43000000), // 64-bit prefetchable memory
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM64_BASE (Segment) >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM64_BASE (Segment))),
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM64_BASE (Segment) >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM64_BASE (Segment))),
CpuToFdt32 ((UINT32)((UINT64)PCIE_MEM64_SIZE >> 32)),
CpuToFdt32 ((UINT32)(PCIE_MEM64_SIZE))
},
};
Ret = FdtSetProp (Fdt, Node, "ranges", Ranges, sizeof (Ranges));
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'ranges' property for '%a'. Ret=%a\n",
NodePath,
FdtStrerror (Ret)
));
continue;
}
UINT32 BusRange[] = {
CpuToFdt32 (PCIE_BUS_BASE (Segment)),
CpuToFdt32 (PCIE_BUS_LIMIT (Segment))
};
Ret = FdtSetProp (Fdt, Node, "bus-range", BusRange, sizeof (BusRange));
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'bus-range' property for '%a'. Ret=%a\n",
NodePath,
FdtStrerror (Ret)
));
continue;
}
CHAR8 *RidMapProps[] = { "msi-map", "iommu-map" };
for (UINT32 RidMapIndex = 0; RidMapIndex < ARRAY_SIZE (RidMapProps); RidMapIndex++) {
UINT32 *RidMap;
INT32 RidMapLength;
RidMap = (UINT32 *)FdtGetProp (Fdt, Node, RidMapProps[RidMapIndex], &RidMapLength);
if ((RidMap == NULL) || (RidMapLength != sizeof (UINT32) * 4)) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to get '%a' property for '%a'. Ret=%a\n",
RidMapProps[RidMapIndex],
NodePath,
FdtStrerror ((RidMapLength < 0) ? RidMapLength : -FDT_ERR_BADVALUE)
));
continue;
}
RidMap[0] = CpuToFdt32 (PCIE_BUS_BASE (Segment) << 8);
RidMap[2] = RidMap[0];
RidMap[3] = CpuToFdt32 (PCIE_BUS_COUNT << 8);
}
}
}
STATIC
VOID
EFIAPI
@@ -344,20 +461,20 @@ FdtFixupVopDevices (
FdtEnableNode (Fdt, VopNodesToDisable[Index], FALSE);
}
Root = fdt_path_offset (Fdt, "/");
Root = FdtPathOffset (Fdt, "/");
ASSERT (Root >= 0);
if (Root < 0) {
DEBUG ((DEBUG_ERROR, "FdtPlatform: Couldn't locate FDT root. Ret=%a\n", fdt_strerror (Root)));
DEBUG ((DEBUG_ERROR, "FdtPlatform: Couldn't locate FDT root. Ret=%a\n", FdtStrerror (Root)));
return;
}
Node = fdt_path_offset (Fdt, "/clock-controller@fd7c0000");
Node = FdtPathOffset (Fdt, "/clock-controller@fd7c0000");
if (Node < 0) {
DEBUG ((DEBUG_ERROR, "FdtPlatform: Couldn't locate CRU node. Ret=%a\n", fdt_strerror (Node)));
DEBUG ((DEBUG_ERROR, "FdtPlatform: Couldn't locate CRU node. Ret=%a\n", FdtStrerror (Node)));
return;
}
CruPhandle = fdt_get_phandle (Fdt, Node);
CruPhandle = FdtGetPhandle (Fdt, Node);
if (CruPhandle <= 0) {
DEBUG ((DEBUG_ERROR, "FdtPlatform: Failed to get CRU phandle.\n"));
return;
@@ -369,58 +486,58 @@ FdtFixupVopDevices (
CHAR8 NodeName[34];
AsciiSPrint (NodeName, sizeof (NodeName), "clk-cru-%d-keep-alive-reg", ClockId);
Node = fdt_add_subnode (Fdt, Root, NodeName);
Node = FdtAddSubnode (Fdt, Root, NodeName);
if (Node < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Couldn't create FDT node '%a'. Ret=%a\n",
NodeName,
fdt_strerror (Node)
FdtStrerror (Node)
));
return;
}
Ret = fdt_setprop_string (Fdt, Node, "compatible", "regulator-fixed-clock");
Ret = FdtSetPropString (Fdt, Node, "compatible", "regulator-fixed-clock");
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'compatible' property for '%a'. Ret=%a\n",
NodeName,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return;
}
Ret = fdt_setprop_string (Fdt, Node, "regulator-name", NodeName);
Ret = FdtSetPropString (Fdt, Node, "regulator-name", NodeName);
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'regulator-name' property for '%a'. Ret=%a\n",
NodeName,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return;
}
Ret = fdt_setprop_empty (Fdt, Node, "regulator-always-on");
Ret = FdtSetPropEmpty (Fdt, Node, "regulator-always-on");
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'regulator-always-on' property for '%a'. Ret=%a\n",
NodeName,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return;
}
UINT32 ClockPair[] = { cpu_to_fdt32 (CruPhandle), cpu_to_fdt32 (ClockId) };
Ret = fdt_setprop (Fdt, Node, "clocks", ClockPair, sizeof (ClockPair));
UINT32 ClockPair[] = { CpuToFdt32 (CruPhandle), CpuToFdt32 (ClockId) };
Ret = FdtSetProp (Fdt, Node, "clocks", ClockPair, sizeof (ClockPair));
if (Ret < 0) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Failed to set 'clocks' property for '%a'. Ret=%a\n",
NodeName,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return;
}
@@ -437,13 +554,14 @@ ApplyPlatformFdtFixups (
EFI_STATUS Status;
// Expand the FDT a bit to give room for any additions.
Status = FdtOpenIntoAlloc (Fdt, NULL, fdt_totalsize (*Fdt) + SIZE_4KB);
Status = FdtOpenIntoAlloc (Fdt, NULL, FdtTotalSize (*Fdt) + SIZE_4KB);
if (EFI_ERROR (Status)) {
return Status;
}
FdtFixupComboPhyDevices (*Fdt);
FdtFixupPcie3Devices (*Fdt);
FdtFixupPcieResources (*Fdt);
FdtFixupVopDevices (*Fdt);
return EFI_SUCCESS;
@@ -453,10 +571,10 @@ STATIC
EFI_STATUS
EFIAPI
ReadFdtFromFilePath (
IN EFI_FILE_PROTOCOL *Root,
IN CHAR16 *Path,
IN OUT UINTN *FileSize, OPTIONAL
IN OUT VOID **Fdt
IN EFI_FILE_PROTOCOL *Root,
IN CHAR16 *Path,
IN OUT UINTN *FileSize OPTIONAL,
IN OUT VOID **Fdt
)
{
EFI_STATUS Status;
@@ -546,13 +664,13 @@ ReadFdtFromFilePath (
goto Exit;
}
Ret = fdt_check_header (*Fdt);
Ret = FdtCheckHeader (*Fdt);
if (Ret) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: '%s' has an invalid header! Ret=%a\n",
Path,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
Status = EFI_LOAD_ERROR;
goto Exit;
@@ -572,9 +690,11 @@ Exit:
return Status;
}
#define FDT_GET_USED_SIZE(Fdt) (fdt_off_dt_struct (Fdt) \
+ fdt_size_dt_struct (Fdt) \
+ fdt_size_dt_strings (Fdt))
//
// Assume the FDT ends with a strings block.
// See https://devicetree-specification.readthedocs.io/en/stable/flattened-format.html
//
#define FdtUsedSize(Fdt) (FdtOffsetDtStrings (Fdt) + FdtSizeDtStrings (Fdt))
STATIC
EFI_STATUS
@@ -592,7 +712,6 @@ InstallOverlaysFromDirectoryPath (
UINTN CurrentInfoSize;
EFI_FILE_INFO *DirEntryInfo;
VOID *FdtOverlay;
UINTN FdtSize;
INT32 Ret;
Status = Root->Open (Root, &Dir, Path, EFI_FILE_MODE_READ, 0);
@@ -658,21 +777,23 @@ InstallOverlaysFromDirectoryPath (
continue;
}
FdtSize = FDT_GET_USED_SIZE (*Fdt);
if (FdtSize + DirEntryInfo->FileSize >= fdt_totalsize (*Fdt)) {
if (FdtUsedSize (*Fdt) + DirEntryInfo->FileSize >= FdtTotalSize (*Fdt)) {
//
// Expand the buffer by at least 8 KB, so we don't end up
// reallocating for every small overlay.
//
FdtSize = fdt_totalsize (*Fdt) + MAX (DirEntryInfo->FileSize, SIZE_8KB);
Status = FdtOpenIntoAlloc (Fdt, NULL, FdtSize);
Status = FdtOpenIntoAlloc (
Fdt,
NULL,
FdtTotalSize (*Fdt) + MAX (DirEntryInfo->FileSize, SIZE_8KB)
);
if (EFI_ERROR (Status)) {
FreePool (FdtOverlay);
break;
}
}
Ret = fdt_overlay_apply (*Fdt, FdtOverlay);
Ret = FdtOverlayApply (*Fdt, FdtOverlay);
FreePool (FdtOverlay);
if (Ret) {
DEBUG ((
@@ -680,15 +801,15 @@ InstallOverlaysFromDirectoryPath (
"FdtPlatform: Failed to apply overlay '%s' (%d bytes). Ret=%a\n",
DirEntryInfo->FileName,
DirEntryInfo->FileSize,
fdt_strerror (Ret)
FdtStrerror (Ret)
));
if (Ret == -FDT_ERR_NOSPACE) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: FDT bytes used: %d, total: %d\n",
FDT_GET_USED_SIZE (*Fdt),
fdt_totalsize (*Fdt)
FdtUsedSize (*Fdt),
FdtTotalSize (*Fdt)
));
}
@@ -862,7 +983,7 @@ FdtPlatformProcessFileSystem (
// Clone the FDT so that we can restore the original one
// in case it gets damaged.
//
Status = FdtOpenIntoAlloc (&Fdt, &NewFdt, fdt_totalsize (Fdt));
Status = FdtOpenIntoAlloc (&Fdt, &NewFdt, FdtTotalSize (Fdt));
if (EFI_ERROR (Status)) {
return Status;
}
@@ -897,7 +1018,7 @@ FdtPlatformProcessFileSystem (
// overlays installed.
//
if (!EFI_ERROR (Status)) {
Ret = fdt_check_header (NewFdt);
Ret = FdtCheckHeader (NewFdt);
if (Ret == 0) {
if ((Fdt != mPlatformFdt) || (OverlaysCount > 0)) {
FdtToInstall = NewFdt;
@@ -907,7 +1028,7 @@ FdtPlatformProcessFileSystem (
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: New FDT has an invalid header! Ret=%a\n",
fdt_strerror (Ret)
FdtStrerror (Ret)
));
}
}
@@ -1154,7 +1275,7 @@ NotifyExitBootServices (
Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);
if (EFI_ERROR (Status) || (Dtb == NULL)) {
DEBUG ((DEBUG_WARN, "FdtPlatform: No FDT installed!\n"));
} else if (fdt_totalsize (Dtb) <= SIZE_4KB) {
} else if (FdtTotalSize (Dtb) <= SIZE_4KB) {
// Some loaders may install a dummy table, warn in this case too.
DEBUG ((DEBUG_WARN, "FdtPlatform: No usable FDT installed!\n"));
}
@@ -1208,12 +1329,12 @@ LoadPlatformFdt (
return EFI_NOT_FOUND;
}
Ret = fdt_check_header (Fdt);
Ret = FdtCheckHeader (Fdt);
if (Ret) {
DEBUG ((
DEBUG_ERROR,
"FdtPlatform: Firmware FDT has an invalid header! Ret=%a\n",
fdt_strerror (Ret)
FdtStrerror (Ret)
));
return EFI_NOT_FOUND;
}

View File

@@ -28,16 +28,17 @@
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
DevicePathLib
PrintLib
DxeServicesLib
FdtLib
MemoryAllocationLib
PrintLib
RockchipPlatformLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
FdtLib
[Guids]
gFdtTableGuid

View File

@@ -35,6 +35,23 @@ IsFdtCompatModeSupported (
return PlatformGetDtbFileGuid (CompatMode) != NULL;
}
STATIC
BOOLEAN
IsAcpiPcieEcamCompatModeSupported (
IN UINT32 CompatMode
)
{
switch (CompatMode) {
case ACPI_PCIE_ECAM_COMPAT_MODE_AUTO:
case ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV:
case ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6:
case ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON:
return TRUE;
}
return FALSE;
}
VOID
EFIAPI
ApplyConfigTableVariables (
@@ -79,7 +96,7 @@ SetupConfigTableVariables (
&Size,
&Var32
);
if (EFI_ERROR (Status)) {
if (EFI_ERROR (Status) || !IsAcpiPcieEcamCompatModeSupported (Var32)) {
Status = PcdSet32S (PcdAcpiPcieEcamCompatMode, FixedPcdGet32 (PcdAcpiPcieEcamCompatModeDefault));
ASSERT_EFI_ERROR (Status);
}

View File

@@ -239,11 +239,10 @@
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_PROMPT #language en-US "PCIe ECAM Compatibility Mode"
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_HELP #language en-US "Choose how to expose the non-standard PCIe configuration space to the OS.\n\n"
"Single Device - compatible with all OSes. Allows usage of a single or multi-function device. Switches are not supported.\n\n"
"NXPMX6 - compatible with Windows. Exposes the full bus topology and supports switches.\n\n"
"AMAZON GRAVITON - compatible with Linux. Exposes the full bus topology and supports switches.\n\n"
"The Auto modes select NXPMX6 for Windows and fall back to the second option when booting other OSes."
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV #language en-US "Auto (NXPMX6 + Single Device)"
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON #language en-US "Auto (NXPMX6 + AMAZON GRAVITON)"
"NXPMX6 - compatible with Windows. Switches are supported.\n\n"
"AMAZON GRAVITON - compatible with Linux. Switches are supported.\n\n"
"The Auto mode selects NXPMX6 for Windows, AMAZON GRAVTION for Linux or Single Device for other OSes."
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_AUTO #language en-US "Auto"
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV #language en-US "Single Device"
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6 #language en-US "NXPMX6"
#string STR_ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON #language en-US "AMAZON GRAVITON"

View File

@@ -821,8 +821,7 @@ formset
help = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_HELP),
flags = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
default = FixedPcdGet32 (PcdAcpiPcieEcamCompatModeDefault),
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV, flags = 0;
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON, flags = 0;
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_AUTO), value = ACPI_PCIE_ECAM_COMPAT_MODE_AUTO, flags = 0;
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV), value = ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV, flags = 0;
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6, flags = 0;
option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON), value = ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON, flags = 0;

View File

@@ -118,8 +118,7 @@
#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 MainEntries[NUM_PCIE_CONTROLLER];
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE RootPortEntries[NUM_PCIE_CONTROLLER];
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE ConfigSpaces[2][NUM_PCIE_CONTROLLER];
} RK3588_MCFG_TABLE;
#pragma pack(pop)

View File

@@ -1,10 +1,11 @@
/** @file
*
* Copyright (c) 2023, Molly Sophia <mollysophia379@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
*
* Copyright (c) 2023-2025, Mario Bălănică <mariobalanica02@gmail.com>
* Copyright (c) 2023, Molly Sophia <mollysophia379@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/
#ifndef RK3588PCIE_H
#define RK3588PCIE_H
@@ -21,47 +22,72 @@ PciePinmuxInit (
);
//
// PCIe 3x4 is the first PCIe controller in memory, the others
// immediately follow it in the order of the segments below.
// Hardware mapping
//
// PCIe 3x4 is the first PCIe controller in memory, immediately followed
// by the others in the order of the segments below.
//
#define NUM_PCIE_CONTROLLER 5
/*
* All pcie controllers supports PCIe 3.0
* Here we name them using their device tree name in the linux kernel source
*/
#define PCIE_SEGMENT_PCIE30X4 0
#define PCIE_SEGMENT_PCIE30X2 1
#define PCIE_SEGMENT_PCIE20L0 2
#define PCIE_SEGMENT_PCIE20L1 3
#define PCIE_SEGMENT_PCIE20L2 4
#define PCIE_3X4_APB_BASE 0xfe150000
#define PCIE_3X4_DBI_BASE 0xa40000000ULL
#define PCIE_3X4_CFG_BASE 0x900000000ULL
#define PCIE_3X4_MEM_BASE 0xf0000000
#define PCIE_3X4_APB_BASE 0xfe150000
#define PCIE_3X4_DBI_BASE 0xa40000000ULL
#define PCIE_3X4_MMIO32_BASE 0xf0000000
#define PCIE_3X4_MMIO64_BASE 0x900000000ULL
#define PCIE_APB_SIZE SIZE_64KB
#define PCIE_DBI_SIZE SIZE_4MB
#define PCIE_CFG_SIZE SIZE_1GB
#define PCIE_MEM_SIZE SIZE_16MB
#define PCIE_APB_SIZE SIZE_64KB
#define PCIE_DBI_SIZE SIZE_4MB
#define PCIE_MMIO32_SIZE SIZE_16MB
#define PCIE_MMIO64_SIZE SIZE_1GB
#define PCIE_MEM64_OFFSET 0x10000000ULL
#define PCIE_APB_BASE(Segment) (PCIE_3X4_APB_BASE + (Segment * PCIE_APB_SIZE))
#define PCIE_DBI_BASE(Segment) (PCIE_3X4_DBI_BASE + (Segment * 1ULL * PCIE_DBI_SIZE))
#define PCIE_MMIO32_BASE(Segment) (PCIE_3X4_MMIO32_BASE + (Segment * PCIE_MMIO32_SIZE))
#define PCIE_MMIO64_BASE(Segment) (PCIE_3X4_MMIO64_BASE + (Segment * 1ULL * PCIE_MMIO64_SIZE))
#define PCIE_APB_BASE(Segment) (PCIE_3X4_APB_BASE + (Segment * PCIE_APB_SIZE))
#define PCIE_DBI_BASE(Segment) (PCIE_3X4_DBI_BASE + (Segment * 1ULL * PCIE_DBI_SIZE))
#define PCIE_CFG_BASE(Segment) (PCIE_3X4_CFG_BASE + (Segment * 1ULL * PCIE_CFG_SIZE))
//
// Software mapping
//
// Since the MMIO32 space is absurdly small, we only use it for I/O.
// ECAM and MEM32 go at the top of the MMIO64 space. This preserves
// the MEM64 alignment and allows EDK2 to allocate up to a single
// large 512 MB BAR + remaining space until the ECAM base.
//
#define PCIE_MEM32_SIZE SIZE_128MB
#define PCIE_MEM32_BASE(Segment) (PCIE_MMIO64_BASE (Segment) + PCIE_MMIO64_SIZE - PCIE_MEM32_SIZE)
//
// Likely not an issue here, but let's play it safe and ensure the bus
// address does not overlap inbound system RAM, since I've seen DMA
// corruption on a different IP due to this.
//
#define PCIE_MEM32_BUS_BASE PCIE_MMIO32_BASE (0)
#define PCIE_MEM32_TRANSLATION(Segment) (PCIE_MEM32_BASE (Segment) - PCIE_MEM32_BUS_BASE)
#define PCIE_MEM_BASE(Segment) (PCIE_3X4_MEM_BASE + (Segment * PCIE_MEM_SIZE))
#define PCIE_MEM64_BASE(Segment) (PCIE_CFG_BASE(Segment) + PCIE_MEM64_OFFSET)
// ECAM must start on a 256 MB boundary (28-bit B/D/F addressing).
#define PCIE_CFG_SIZE (SIZE_256MB - PCIE_MEM32_SIZE)
#define PCIE_CFG_BASE(Segment) (PCIE_MMIO64_BASE (Segment) + PCIE_MMIO64_SIZE - SIZE_256MB)
#define PCIE_IO_BASE 0x0000
#define PCIE_IO_SIZE SIZE_64KB
#define PCIE_IO_XLATE(Segment) (PCIE_CFG_BASE(Segment) + PCIE_CFG_SIZE - PCIE_IO_SIZE)
#define PCIE_MEM64_SIZE (PCIE_MMIO64_SIZE - PCIE_MEM32_SIZE - PCIE_CFG_SIZE)
#define PCIE_MEM64_BASE(Segment) PCIE_MMIO64_BASE (Segment)
#define PCIE_MEM64_SIZE (PCIE_CFG_SIZE - PCIE_IO_SIZE - PCIE_MEM64_OFFSET)
#define PCIE_IO_SIZE SIZE_64KB
#define PCIE_IO_BASE(Segment) (PCIE_MMIO32_BASE (Segment) + SIZE_1MB)
#define PCIE_IO_BUS_BASE 0x0000
#define PCIE_IO_TRANSLATION(Segment) (PCIE_IO_BASE (Segment) - PCIE_IO_BUS_BASE)
#define PCIE_BUS_LIMIT 252 // limited by CFG1 iATU window size
//
// All RCs share a single SMMU and two ITS blocks. To prevent overlapping
// Requester IDs, we need to space segments by <PCIE_BUS_COUNT> bus numbers.
// It doesn't seem possible to encode the segment number instead.
//
#define PCIE_BUS_COUNT (PCIE_CFG_SIZE / SIZE_1MB / NUM_PCIE_CONTROLLER)
#define PCIE_BUS_BASE(Segment) (Segment * PCIE_BUS_COUNT)
#define PCIE_BUS_LIMIT(Segment) (PCIE_BUS_BASE (Segment) + PCIE_BUS_COUNT - 1)
#define PCIE_BUS_BASE_OFFSET(Segment) (PCIE_BUS_BASE (Segment) * SIZE_1MB)
#endif

View File

@@ -65,11 +65,10 @@ typedef struct {
UINT32 Mode;
} CONFIG_TABLE_MODE_VARSTORE_DATA;
#define ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV 0x00000001
#define ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6 0x00000002
#define ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON 0x00000004
#define ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV 0x00000003
#define ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON 0x00000006
#define ACPI_PCIE_ECAM_COMPAT_MODE_AUTO 0x00000000
#define ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV 0x00000001
#define ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6 0x00000002
#define ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON 0x00000004
typedef struct {
UINT32 Mode;
} ACPI_PCIE_ECAM_COMPAT_MODE_VARSTORE_DATA;

View File

@@ -24,6 +24,7 @@
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
Silicon/Rockchip/RK3588/RK3588.dec
UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
DebugLib

View File

@@ -26,11 +26,11 @@
ArmPlatformPkg/ArmPlatformPkg.dec
Silicon/Rockchip/RK3588/RK3588.dec
Silicon/Rockchip/RockchipPkg.dec
UefiCpuPkg/UefiCpuPkg.dec
[LibraryClasses]
ArmLib
BaseVariableLib
FdtLib
IoLib
MemoryAllocationLib
PcdLib

View File

@@ -574,19 +574,14 @@ InitializePciHost (
UINT32 Segment
)
{
EFI_PHYSICAL_ADDRESS ApbBase = PCIE_APB_BASE (Segment);
EFI_PHYSICAL_ADDRESS DbiBase = PCIE_DBI_BASE (Segment);
EFI_PHYSICAL_ADDRESS PcieBase = PCIE_CFG_BASE (Segment);
EFI_PHYSICAL_ADDRESS ApbBase = PCIE_APB_BASE (Segment);
EFI_PHYSICAL_ADDRESS DbiBase = PCIE_DBI_BASE (Segment);
EFI_PHYSICAL_ADDRESS CfgBase;
EFI_PHYSICAL_ADDRESS CfgSize;
EFI_STATUS Status;
UINTN Retry;
UINT32 LinkSpeed;
UINT32 LinkWidth;
UINT64 Cfg0Base;
UINT64 Cfg0Size;
UINT64 Cfg1Base;
UINT64 Cfg1Size;
UINT64 PciIoBase;
UINT64 PciIoSize;
UINT8 Pcie30PhyMode;
Pcie30PhyMode = PcdGet8 (PcdPcie30PhyMode);
@@ -611,7 +606,6 @@ InitializePciHost (
/* Log settings */
DEBUG ((DEBUG_INIT, "\nPCIe: Segment %u\n", Segment));
DEBUG ((DEBUG_INIT, "PCIe: PciExpressBaseAddress 0x%lx\n", PcieBase));
DEBUG ((DEBUG_INIT, "PCIe: ApbBase 0x%lx\n", ApbBase));
DEBUG ((DEBUG_INIT, "PCIe: DbiBase 0x%lx\n", DbiBase));
DEBUG ((DEBUG_INIT, "PCIe: NumLanes %u\n", LinkWidth));
@@ -645,16 +639,41 @@ InitializePciHost (
PciSetupBars (DbiBase);
DEBUG ((DEBUG_INIT, "PCIe: Setup iATU\n"));
Cfg0Base = SIZE_1MB;
Cfg0Size = SIZE_64KB;
Cfg1Base = SIZE_2MB;
Cfg1Size = 0x10000000UL - (SIZE_2MB + SIZE_64KB);
PciIoBase = 0x2FFF0000UL;
PciIoSize = SIZE_64KB;
CfgBase = PCIE_CFG_BASE (Segment) + PCIE_BUS_BASE_OFFSET (Segment);
CfgSize = PCIE_BUS_COUNT * SIZE_1MB;
PciSetupAtu (DbiBase, 0, IATU_TYPE_CFG0, PcieBase + Cfg0Base, Cfg0Base, Cfg0Size);
PciSetupAtu (DbiBase, 1, IATU_TYPE_CFG1, PcieBase + Cfg1Base, Cfg1Base, Cfg1Size);
PciSetupAtu (DbiBase, 2, IATU_TYPE_IO, PcieBase + PciIoBase, 0, PciIoSize);
PciSetupAtu (
DbiBase,
0,
IATU_TYPE_CFG0,
CfgBase + SIZE_1MB, // Bus 1
SIZE_1MB,
SIZE_64KB // Should be 32KB but granule is 64KB (see PciValidateCfg0())
);
PciSetupAtu (
DbiBase,
1,
IATU_TYPE_CFG1,
CfgBase + SIZE_2MB, // Bus 2 and above
SIZE_2MB,
CfgSize - SIZE_2MB
);
PciSetupAtu (
DbiBase,
2,
IATU_TYPE_IO,
PCIE_IO_BASE (Segment),
PCIE_IO_BUS_BASE,
PCIE_IO_SIZE
);
PciSetupAtu (
DbiBase,
3,
IATU_TYPE_MEM,
PCIE_MEM32_BASE (Segment),
PCIE_MEM32_BUS_BASE,
PCIE_MEM32_SIZE
);
DEBUG ((DEBUG_INIT, "PCIe: Set link speed\n"));
PciSetupLinkSpeed (DbiBase, LinkSpeed, LinkWidth);
@@ -692,7 +711,7 @@ InitializePciHost (
PciGetLinkSpeedWidth (DbiBase, &LinkSpeed, &LinkWidth);
PciPrintLinkSpeedWidth (LinkSpeed, LinkWidth);
PciValidateCfg0 (Segment, PcieBase + Cfg0Base);
PciValidateCfg0 (Segment, CfgBase + SIZE_1MB);
return EFI_SUCCESS;
}

View File

@@ -1,6 +1,7 @@
/** @file
PCI Host Bridge Library instance for Rockchip Rk3588
Copyright (c) 2023-2025, Mario Bălănică <mariobalanica02@gmail.com>
Copyright (c) 2023, Molly Sophia <mollysophia379@gmail.com>
Copyright (c) 2021, Jared McNeill <jmcneill@invisible.ca>
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
@@ -192,15 +193,16 @@ PciHostBridgeGetRootBridges (
mPciRootBridges[Loop].AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
mPciRootBridges[Loop].Bus.Base = 0;
mPciRootBridges[Loop].Bus.Limit = PCIE_BUS_LIMIT;
mPciRootBridges[Loop].Bus.Base = PCIE_BUS_BASE (Idx);
mPciRootBridges[Loop].Bus.Limit = PCIE_BUS_LIMIT (Idx);
mPciRootBridges[Loop].Io.Base = PCIE_IO_BASE;
mPciRootBridges[Loop].Io.Base = PCIE_IO_BUS_BASE;
mPciRootBridges[Loop].Io.Limit = mPciRootBridges[Loop].Io.Base + PCIE_IO_SIZE - 1;
mPciRootBridges[Loop].Io.Translation = MAX_UINT64 - PCIE_IO_XLATE (Idx) + 1;
mPciRootBridges[Loop].Io.Translation = MAX_UINT64 - PCIE_IO_TRANSLATION (Idx) + 1;
mPciRootBridges[Loop].Mem.Base = PCIE_MEM_BASE (Idx);
mPciRootBridges[Loop].Mem.Limit = mPciRootBridges[Loop].Mem.Base + PCIE_MEM_SIZE - 1;
mPciRootBridges[Loop].Mem.Base = PCIE_MEM32_BUS_BASE;
mPciRootBridges[Loop].Mem.Limit = mPciRootBridges[Loop].Mem.Base + PCIE_MEM32_SIZE - 1;
mPciRootBridges[Loop].Mem.Translation = MAX_UINT64 - PCIE_MEM32_TRANSLATION (Idx) + 1;
mPciRootBridges[Loop].MemAbove4G.Base = PCIE_MEM64_BASE (Idx);
mPciRootBridges[Loop].MemAbove4G.Limit = mPciRootBridges[Loop].MemAbove4G.Base + PCIE_MEM64_SIZE - 1;
@@ -211,7 +213,6 @@ PciHostBridgeGetRootBridges (
mPciRootBridges[Loop].PMemAbove4G.Limit = 0;
mPciRootBridges[Loop].DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Idx];
DEBUG ((DEBUG_INFO, "0x%llx 0x%llx 0x%llx\n", mPciRootBridges[Loop].Mem.Base, mPciRootBridges[Loop].MemAbove4G.Base, mPciRootBridges[Loop].Io.Translation));
Loop++;
}

View File

@@ -1,6 +1,7 @@
/** @file
PCI Segment Library for Rockchip RK356x
Copyright (c) 2023-2025, Mario Bălănică <mariobalanica02@gmail.com>
Copyright (c) 2023, Molly Sophia <mollysophia379@gmail.com>
Copyright (c) 2021, Jared McNeill <jmcneill@invisible.ca>
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
@@ -36,6 +37,8 @@ typedef enum {
#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A, M) \
ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)
#define INVALID_PCI_ADDRESS 0xffffffff
#define GET_SEG_NUM(Address) ((Address >> 32) & 0xFFFF)
#define GET_BUS_NUM(Address) ((Address >> 20) & 0xFF)
#define GET_DEV_NUM(Address) ((Address >> 15) & 0x1F)
@@ -48,31 +51,42 @@ PciSegmentLibGetConfigBase (
IN UINT64 Address
)
{
UINT64 Base;
UINT16 Segment;
UINT8 Bus;
UINT16 Device;
UINT8 Device;
UINT8 Function;
Segment = GET_SEG_NUM (Address);
Bus = GET_BUS_NUM (Address);
Device = GET_DEV_NUM (Address);
Segment = GET_SEG_NUM (Address);
Bus = GET_BUS_NUM (Address);
Device = GET_DEV_NUM (Address);
Function = GET_FUNC_NUM (Address);
ASSERT (Segment < NUM_PCIE_CONTROLLER);
// DEBUG ((DEBUG_ERROR, "PciSegmentLibGetConfigBase: Address=0x%lX, Bus=%d, Segment=%d\n",
// Address, Bus, Segment));
// Ignore more than one device on bus 0 and 1 to hide duplicates/ghosts.
if ((Device > 0) && ((Bus == 0) || (Bus == 1))) {
return 0xffffffff;
if (Segment >= NUM_PCIE_CONTROLLER) {
ASSERT (FALSE);
return INVALID_PCI_ADDRESS;
}
// The root port is not part of the main config space.
if (Bus == 0) {
return PCIE_DBI_BASE (Segment);
//
// The primary bus can only contain a single function (the root port).
// The secondary bus can only contain a single device.
//
if (((Bus == PCIE_BUS_BASE (Segment)) && (Device + Function > 0)) ||
((Bus == PCIE_BUS_BASE (Segment) + 1) && (Device > 0)))
{
return INVALID_PCI_ADDRESS;
}
// Here starts the not-quite-compliant ECAM space.
return PCIE_CFG_BASE (Segment);
if (Bus == PCIE_BUS_BASE (Segment)) {
// The root port is not part of the main config space.
Base = PCIE_DBI_BASE (Segment);
Address -= PCIE_BUS_BASE_OFFSET (Segment);
} else {
// Here starts the almost-compliant ECAM space.
Base = PCIE_CFG_BASE (Segment);
}
return Base + (UINT32)Address;
}
/**
@@ -95,21 +109,17 @@ PciSegmentLibReadWorker (
UINT64 Base;
Base = PciSegmentLibGetConfigBase (Address);
if (Base == 0xFFFFFFFF) {
if (Base == INVALID_PCI_ADDRESS) {
return Base;
}
// DEBUG ((DEBUG_ERROR, "PciSegmentLibReadWorker: Address=0x%lX, Base=0x%lX, Width=%u\n",
// Address, Base, Width));
switch (Width) {
case PciCfgWidthUint8:
return MmioRead8 (Base + (UINT32)Address);
return MmioRead8 (Base);
case PciCfgWidthUint16:
return MmioRead16 (Base + (UINT32)Address);
return MmioRead16 (Base);
case PciCfgWidthUint32:
return MmioRead32 (Base + (UINT32)Address);
return MmioRead32 (Base);
default:
ASSERT (FALSE);
}
@@ -139,23 +149,19 @@ PciSegmentLibWriteWorker (
UINT64 Base;
Base = PciSegmentLibGetConfigBase (Address);
if (Base == 0xFFFFFFFF) {
if (Base == INVALID_PCI_ADDRESS) {
return Base;
}
// DEBUG ((DEBUG_ERROR, "PciSegmentLibWriteWorker: Address=0x%lX, Base=0x%lX, Width=%u\n",
// Address, Base, Width));
switch (Width) {
case PciCfgWidthUint8:
MmioWrite8 (Base + (UINT32)Address, Data);
MmioWrite8 (Base, Data);
break;
case PciCfgWidthUint16:
MmioWrite16 (Base + (UINT32)Address, Data);
MmioWrite16 (Base, Data);
break;
case PciCfgWidthUint32:
MmioWrite32 (Base + (UINT32)Address, Data);
MmioWrite32 (Base, Data);
break;
default:
ASSERT (FALSE);

View File

@@ -51,11 +51,10 @@
DEFINE CONFIG_TABLE_MODE_FDT = 0x00000002
DEFINE CONFIG_TABLE_MODE_ACPI_FDT = 0x00000003
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV = 0x00000001
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6 = 0x00000002
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON = 0x00000004
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV = 0x00000003
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON = 0x00000006
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_AUTO = 0x00000000
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV = 0x00000001
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6 = 0x00000002
DEFINE ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON = 0x00000004
DEFINE FDT_COMPAT_MODE_UNSUPPORTED = 0
DEFINE FDT_COMPAT_MODE_VENDOR = 1
@@ -282,7 +281,7 @@
# ACPI / Device Tree support flags and default values
#
gRK3588TokenSpaceGuid.PcdConfigTableModeDefault|$(CONFIG_TABLE_MODE_ACPI_FDT)
gRK3588TokenSpaceGuid.PcdAcpiPcieEcamCompatModeDefault|$(ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV)
gRK3588TokenSpaceGuid.PcdAcpiPcieEcamCompatModeDefault|$(ACPI_PCIE_ECAM_COMPAT_MODE_AUTO)
gRK3588TokenSpaceGuid.PcdFdtCompatModeDefault|$(FDT_COMPAT_MODE_MAINLINE)
gRK3588TokenSpaceGuid.PcdFdtForceGopDefault|FALSE
gRK3588TokenSpaceGuid.PcdFdtSupportOverridesDefault|FALSE

View File

@@ -66,6 +66,16 @@
DEFINE DEBUG_PROPERTY_MASK = 0x0f
!endif
#
# Default support flags
#
!ifndef RK_X86_EMULATOR_ENABLE
DEFINE RK_X86_EMULATOR_ENABLE = TRUE
!endif
!ifndef RK_AMD_GOP_ENABLE
DEFINE RK_AMD_GOP_ENABLE = TRUE
!endif
################################################################################
#
# Library Class section - list of all common Library Classes needed by Rockchip platforms.
@@ -127,11 +137,6 @@
# SCMI Mailbox Transport Layer
ArmMtlLib|Silicon/Rockchip/Library/RkMtlLib/RkMtlLib.inf
# SMC/HVC dependencies
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf
ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
#
# Secure Boot dependencies
#
@@ -168,9 +173,11 @@
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
ArmSmcLib|MdePkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
ArmMmuLib|UefiCpuPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
# UART libraries
@@ -196,7 +203,7 @@
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
# Flattened Device Tree (FDT) access library
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
@@ -284,10 +291,8 @@
PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
## Fixed compile error after upgrade to 14.10
PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
[LibraryClasses.common.DXE_CORE]
@@ -434,7 +439,6 @@ FspiLib|Silicon/Rockchip/Library/FspiLib/FspiLib.inf
# Set timer interrupt to be triggerred in 1ms to avoid missing
# serial terminal input characters.
gEmbeddedTokenSpaceGuid.PcdTimerPeriod|10000
gArmTokenSpaceGuid.PcdVFPEnabled|1
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|32
#
@@ -478,6 +482,7 @@ FspiLib|Silicon/Rockchip/Library/FspiLib/FspiLib.inf
ArmPlatformPkg/PeilessSec/PeilessSec.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PeilessSecMeasureLib|SecurityPkg/Library/PeilessSecMeasureLib/PeilessSecMeasureLibNull.inf
}
#
@@ -629,6 +634,12 @@ FspiLib|Silicon/Rockchip/Library/FspiLib/FspiLib.inf
Silicon/Rockchip/Library/DisplayLib/DwMipiDsi2Lib.inf
Silicon/Rockchip/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
!if $(RK_AMD_GOP_ENABLE) == TRUE
Drivers/AMD/Gop/AmdGopOpRomOverrideDxe.inf
Drivers/AMD/Gop/AmdGopPreSoc15Dxe.inf
Drivers/AMD/Gop/AmdGopPostSoc15Dxe.inf
!endif
#
# USB Support
#
@@ -782,6 +793,13 @@ FspiLib|Silicon/Rockchip/Library/FspiLib/FspiLib.inf
#
EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
#
# x64 Binary Compatibility Support
#
!if $(RK_X86_EMULATOR_ENABLE) == TRUE
Emulator/X86EmulatorDxe/X86EmulatorDxe.inf
!endif
#
# Bds
#

View File

@@ -18,7 +18,6 @@
#include <Protocol/ComponentName.h>
#include <Protocol/ComponentName2.h>
#include <Protocol/DeviceIo.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/SdMmcPassThru.h>

View File

@@ -991,11 +991,11 @@ DwMmcCreateTrb (
IN EFI_EVENT Event
)
{
DW_MMC_HC_TRB *Trb;
EFI_STATUS Status;
EFI_TPL OldTpl;
EFI_IO_OPERATION_TYPE Flag;
UINTN MapLength;
DW_MMC_HC_TRB *Trb;
EFI_STATUS Status;
EFI_TPL OldTpl;
DMA_MAP_OPERATION MapOperation;
UINTN MapLength;
Trb = AllocateZeroPool (sizeof (DW_MMC_HC_TRB));
if (Trb == NULL) {
@@ -1035,9 +1035,9 @@ DwMmcCreateTrb (
Trb->Mode = SdMmcPioMode;
} else {
if (Trb->Read) {
Flag = EfiBusMasterWrite;
MapOperation = MapOperationBusMasterWrite;
} else {
Flag = EfiBusMasterRead;
MapOperation = MapOperationBusMasterRead;
}
if (Private->Slot[Trb->Slot].CardType == SdCardType) {
@@ -1046,7 +1046,7 @@ DwMmcCreateTrb (
Trb->UseFifo = FALSE;
if (Trb->DataLen) {
MapLength = Trb->DataLen;
Status = DmaMap (Flag, Trb->Data, &MapLength, &Trb->DataPhy, &Trb->DataMap);
Status = DmaMap (MapOperation, Trb->Data, &MapLength, &Trb->DataPhy, &Trb->DataMap);
/* Status = DevIo->Map (
DevIo,