Skip to content

Commit

Permalink
Add options for S3 Resume script and bar size mask override
Browse files Browse the repository at this point in the history
Move S3 Resume script functions to new source and header file.
Add user option to enable / disable the S3 Resume script, default
enabled.

Add user option to enable / disable override for PCIe ReBAR capability
bitmask of possible BAR sizes. Update text output to indicate with a
signle-quote ' character when bitmask override is enabled.

Fix unexpected status for missing ReBAR capability for pre-Turring GPUs.
  • Loading branch information
terminatorul committed Mar 8, 2024
1 parent bda2f65 commit 477ec9b
Show file tree
Hide file tree
Showing 17 changed files with 731 additions and 451 deletions.
97 changes: 78 additions & 19 deletions ReBarDxe/NvStrapsConfig.c
Expand Up @@ -41,9 +41,10 @@ static void GPUSelector_unpack(BYTE const *buffer, NvStraps_GPUSelector *selecto

uint_least8_t busPos = unpack_BYTE(buffer); buffer += BYTE_SIZE;

selector->device = selector->bus == 0xFFu && busPos == 0xFFu ? 0xFFu : busPos >> 3u & 0b0001'1111u;
selector->function = selector->bus == 0xFFu && busPos == 0xFFu ? 0xFFu : busPos & 0b0111u;
selector->barSizeSelector = unpack_BYTE(buffer), buffer += BYTE_SIZE;
selector->device = selector->bus == 0xFFu && busPos == 0xFFu ? 0xFFu : busPos >> 3u & 0b0001'1111u;
selector->function = selector->bus == 0xFFu && busPos == 0xFFu ? 0xFFu : busPos & 0b0111u;
selector->barSizeSelector = unpack_BYTE(buffer), buffer += BYTE_SIZE;
selector->overrideBarSizeMask = unpack_BYTE(buffer), buffer += BYTE_SIZE;
}

static BYTE *GPUSelector_pack(BYTE *buffer, NvStraps_GPUSelector const *selector)
Expand All @@ -54,6 +55,7 @@ static BYTE *GPUSelector_pack(BYTE *buffer, NvStraps_GPUSelector const *selector
buffer = pack_BYTE(buffer, selector->bus);
buffer = pack_BYTE(buffer, (uint_least8_t)((unsigned)selector->device << 3u & 0b1111'1000u | (unsigned)selector->function & 0b0111u));
buffer = pack_BYTE(buffer, selector->barSizeSelector);
buffer = pack_BYTE(buffer, selector->overrideBarSizeMask);

return buffer;
}
Expand Down Expand Up @@ -128,7 +130,7 @@ void NvStrapsConfig_Clear(NvStrapsConfig *config)
{
config->dirty = false;
config->nPciBarSize = 0u;
config->nGlobalEnable = 0u;
config->nOptionFlags = 0u;
config->nGPUSelector = 0u;
config->nGPUConfig = 0u;
config->nBridgeConfig = 0u;
Expand All @@ -150,7 +152,7 @@ static void NvStrapsConfig_Load(BYTE const *buffer, unsigned size, NvStrapsConfi
break;

config->nPciBarSize = unpack_BYTE(buffer), buffer += BYTE_SIZE;
config->nGlobalEnable = unpack_BYTE(buffer), buffer += BYTE_SIZE;
config->nOptionFlags = unpack_BYTE(buffer), buffer += BYTE_SIZE;
config->nGPUSelector = unpack_BYTE(buffer), buffer += BYTE_SIZE;

if (config->nGPUSelector > ARRAY_SIZE(config->GPUs) || size < (unsigned)NV_STRAPS_HEADER_SIZE + BYTE_SIZE + config->nGPUSelector * GPU_SELECTOR_SIZE + BYTE_SIZE)
Expand Down Expand Up @@ -201,7 +203,7 @@ static unsigned NvStrapsConfig_Save(BYTE *buffer, unsigned size, NvStrapsConfig
&& size >= BUFFER_SIZE)
{
buffer = pack_BYTE(buffer, config->nPciBarSize);
buffer = pack_BYTE(buffer, config->nGlobalEnable);
buffer = pack_BYTE(buffer, config->nOptionFlags);
buffer = pack_BYTE(buffer, config->nGPUSelector);

for (unsigned i = 0u; i < config->nGPUSelector; i++)
Expand Down Expand Up @@ -244,30 +246,39 @@ NvStraps_BarSize NvStrapsConfig_LookupBarSize(NvStrapsConfig const *config, uint
if (NvStrapsConfig_GPUSelector_SubsystemMatch(config->GPUs + iGPU, subsysVenID, subsysDevID))
if (NvStrapsConfig_GPUSelector_HasBusLocation(config->GPUs + iGPU))
if (NvStrapsConfig_GPUSelector_BusLocationMatch(config->GPUs + iGPU, bus, dev, fn))
{
NvStraps_BarSize sizeSelector = { .priority = EXPLICIT_PCI_LOCATION, .barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector };

return sizeSelector;
}
if (config->GPUs[iGPU].barSizeSelector != BarSizeSelector_None)
{
NvStraps_BarSize sizeSelector = { .priority = EXPLICIT_PCI_LOCATION, .barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector };

return sizeSelector;
}
else
;
else
;
else
configPriority = EXPLICIT_SUBSYSTEM_ID, barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector;
if (config->GPUs[iGPU].barSizeSelector != BarSizeSelector_None)
configPriority = EXPLICIT_SUBSYSTEM_ID, barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector;
else
;
else
;
else
{
if (configPriority < EXPLICIT_SUBSYSTEM_ID)
configPriority = EXPLICIT_PCI_ID, barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector;
}

if (configPriority == UNCONFIGURED && config->nGlobalEnable)
if (config->GPUs[iGPU].barSizeSelector != BarSizeSelector_None)
{
if (configPriority < EXPLICIT_SUBSYSTEM_ID)
configPriority = EXPLICIT_PCI_ID, barSizeSelector = (BarSizeSelector)config->GPUs[iGPU].barSizeSelector;
}
else
;

if (configPriority == UNCONFIGURED && NvStrapsConfig_IsGlobalEnable(config))
{
barSizeSelector = lookupBarSizeInRegistry(deviceID);

if (barSizeSelector == BarSizeSelector_None)
{
if (config->nGlobalEnable > 1u && isTuringGPU(deviceID))
if (NvStrapsConfig_IsGlobalEnable(config) > 1u && isTuringGPU(deviceID))
{
NvStraps_BarSize sizeSelector = { .priority = IMPLIED_GLOBAL, .barSizeSelector = BarSizeSelector_2G };

Expand All @@ -283,6 +294,54 @@ NvStraps_BarSize NvStrapsConfig_LookupBarSize(NvStrapsConfig const *config, uint
return sizeSelector;
}

NvStraps_BarSizeMaskOverride NvStrapsConfig_LookupBarSizeMaskOverride(NvStrapsConfig const *config, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn)
{
ConfigPriority configPriority = UNCONFIGURED;
bool barSizeMaskOverride = false;

for (unsigned iGPU = 0u; iGPU < config->nGPUSelector; iGPU++)
if (NvStrapsConfig_GPUSelector_DeviceMatch(config->GPUs + iGPU, deviceID))
if (NvStrapsConfig_GPUSelector_HasSubsystem(config->GPUs + iGPU))
if (NvStrapsConfig_GPUSelector_SubsystemMatch(config->GPUs + iGPU, subsysVenID, subsysDevID))
if (NvStrapsConfig_GPUSelector_HasBusLocation(config->GPUs + iGPU))
if (NvStrapsConfig_GPUSelector_BusLocationMatch(config->GPUs + iGPU, bus, dev, fn))
if (config->GPUs[iGPU].overrideBarSizeMask)
{
NvStraps_BarSizeMaskOverride maskOverride = { .priority = EXPLICIT_PCI_LOCATION, .sizeMaskOverride = config->GPUs[iGPU].overrideBarSizeMask != 0xFFu };

return maskOverride;
}
else
;
else
;
else
if (config->GPUs[iGPU].overrideBarSizeMask)
configPriority = EXPLICIT_SUBSYSTEM_ID, barSizeMaskOverride = config->GPUs[iGPU].overrideBarSizeMask != 0xFFu;
else
;
else
;
else
if (config->GPUs[iGPU].overrideBarSizeMask)
{
if (configPriority < EXPLICIT_SUBSYSTEM_ID)
configPriority = EXPLICIT_PCI_ID, barSizeMaskOverride = config->GPUs[iGPU].overrideBarSizeMask != 0xFFu;
}
else
;

if (configPriority == UNCONFIGURED)
{
configPriority = FOUND_GLOBAL;
barSizeMaskOverride = NvStrapsConfig_OverrideBarSizeMask(config);
}

NvStraps_BarSizeMaskOverride maskOverride = { .priority = configPriority, .sizeMaskOverride = barSizeMaskOverride };

return maskOverride;
}

static unsigned NvStrapsConfig_FindGPUConfig(NvStrapsConfig const *config, uint_least8_t busNr, uint_least8_t dev, uint_least8_t fun)
{
for (unsigned i = 0u; i < config->nGPUConfig; i++)
Expand Down
178 changes: 77 additions & 101 deletions ReBarDxe/PciConfig.c
Expand Up @@ -4,12 +4,12 @@
#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/S3SaveState.h>
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/Pci22.h>
#include <IndustryStandard/PciExpress21.h>

#include "pciRegs.h"
#include "S3ResumeScript.h"
#include "LocalAppConfig.h"
#include "StatusVar.h"
#include "SetupNvStraps.h"
Expand Down Expand Up @@ -310,74 +310,60 @@ void pciSaveAndRemapBridgeConfig(UINTN bridgePciAddress, UINT32 bridgeSaveArea[3
efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_IO_BASE, &bridgeIoBaseLimit)));
efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_COMMAND_OFFSET, &bridgeCommand)));

if (S3SaveState)
if (!efiError)
{
if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(bridgePciAddress, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET),
(UINTN)1u,
(void *)&configReg
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(bridgePciAddress, PCI_MEMORY_BASE),
(UINTN)1u,
(void *)&bridgeMemoryBaseLimit
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(bridgePciAddress, PCI_IO_BASE),
(UINTN)1u,
(void *)&bridgeIoBaseLimit
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(bridgePciAddress, PCI_COMMAND_OFFSET),
(UINTN)1u,
(void *)&bridgeCommand
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}
status = S3ResumeScript_PciConfigReadWrite_DWORD
(
bridgePciAddress,
PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
configReg & UINT32_C(0x00FF'FFFF), // primary bus, secondary bus, subsidiary bus
UINT32_C(0xFF00'0000)
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3ResumeScript_PciConfigWrite_DWORD
(
bridgePciAddress,
PCI_MEMORY_BASE,
bridgeMemoryBaseLimit
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3ResumeScript_PciConfigReadWrite_DWORD
(
bridgePciAddress,
PCI_IO_BASE,
bridgeIoBaseLimit & UINT32_C(0x0000'FFFF),
UINT32_C(0xFFFF'0000)
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3ResumeScript_PciConfigReadWrite_DWORD
(
bridgePciAddress,
PCI_COMMAND_OFFSET,
EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER,
(UINT32) ~(UINT32)(EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER)
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}
else
SetEFIError(EFIError_LoadS3SaveStateProtocol, EFI_NOT_FOUND);
}

if (efiError)
Expand Down Expand Up @@ -420,42 +406,32 @@ void pciSaveAndRemapDeviceBAR0(UINTN pciAddress, UINT32 gpuSaveArea[2u], EFI_PHY
efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_BASE_ADDRESS_0, &gpuBaseAddress)));
efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_COMMAND_OFFSET, &gpuCommand)));

if (S3SaveState)
if (!efiError)
{
if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(pciAddress, PCI_BASE_ADDRESS_0),
(UINTN)1u,
(void *)&gpuBaseAddress
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3SaveState->Write
(
S3SaveState,
(UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
(EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32,
(UINT64)pciAddrOffset(pciAddress, PCI_COMMAND_OFFSET),
(UINTN)1u,
(void *)&gpuCommand
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}
status = S3ResumeScript_PciConfigWrite_DWORD
(
pciAddress,
PCI_BASE_ADDRESS_0,
gpuBaseAddress
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}

if (!efiError)
{
status = S3ResumeScript_PciConfigReadWrite_DWORD
(
pciAddress,
PCI_COMMAND_OFFSET,
EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER,
(uint_least32_t) ~(uint_least32_t)(EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER)
);

efiError = efiError || EFI_ERROR(status);
s3SaveStateError = s3SaveStateError || EFI_ERROR(status);
}
else
SetEFIError(EFIError_LoadS3SaveStateProtocol, EFI_NOT_FOUND);
}

if (efiError)
Expand Down

0 comments on commit 477ec9b

Please sign in to comment.