From 477ec9bdffd67b8a3f5f95ba66bf7168a2369f9f Mon Sep 17 00:00:00 2001 From: Timothy Madden Date: Fri, 8 Mar 2024 15:55:34 +0200 Subject: [PATCH] Add options for S3 Resume script and bar size mask override 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. --- ReBarDxe/NvStrapsConfig.c | 97 ++++++++-- ReBarDxe/PciConfig.c | 178 ++++++++--------- ReBarDxe/ReBar.c | 71 ++----- ReBarDxe/ReBarDxe.inf | 2 + ReBarDxe/S3ResumeScript.c | 79 ++++++++ ReBarDxe/SetupNvStraps.c | 300 ++++++++--------------------- ReBarDxe/include/NvStrapsConfig.h | 121 +++++++++++- ReBarDxe/include/PciConfig.h | 1 + ReBarDxe/include/ReBar.h | 1 - ReBarDxe/include/S3ResumeScript.h | 15 ++ ReBarDxe/include/StatusVar.h | 2 +- ReBarState/ConfigManagerError.ixx | 2 + ReBarState/ConfigurationWizard.ixx | 93 ++++++++- ReBarState/NvStrapsConfig.hh | 49 ++++- ReBarState/NvStrapsConfig.ixx | 23 ++- ReBarState/TextWizardMenu.ixx | 92 ++++++++- ReBarState/TextWizardPage.ixx | 56 ++++-- 17 files changed, 731 insertions(+), 451 deletions(-) create mode 100644 ReBarDxe/S3ResumeScript.c create mode 100644 ReBarDxe/include/S3ResumeScript.h diff --git a/ReBarDxe/NvStrapsConfig.c b/ReBarDxe/NvStrapsConfig.c index f3b586b..a1f89ca 100644 --- a/ReBarDxe/NvStrapsConfig.c +++ b/ReBarDxe/NvStrapsConfig.c @@ -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) @@ -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; } @@ -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; @@ -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) @@ -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++) @@ -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 }; @@ -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++) diff --git a/ReBarDxe/PciConfig.c b/ReBarDxe/PciConfig.c index b8a6a27..65f65bb 100644 --- a/ReBarDxe/PciConfig.c +++ b/ReBarDxe/PciConfig.c @@ -4,12 +4,12 @@ #include #include #include -#include #include #include #include #include "pciRegs.h" +#include "S3ResumeScript.h" #include "LocalAppConfig.h" #include "StatusVar.h" #include "SetupNvStraps.h" @@ -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) @@ -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) diff --git a/ReBarDxe/ReBar.c b/ReBarDxe/ReBar.c index eeafa74..457649c 100644 --- a/ReBarDxe/ReBar.c +++ b/ReBarDxe/ReBar.c @@ -14,9 +14,6 @@ SPDX-License-Identifier: MIT #include #include -#include -#include - #if defined(_ASSERT) # undef _ASSERT #endif @@ -26,6 +23,7 @@ SPDX-License-Identifier: MIT #include "LocalAppConfig.h" #include "StatusVar.h" #include "PciConfig.h" +#include "S3ResumeScript.h" #include "NvStrapsConfig.h" #include "SetupNvStraps.h" @@ -35,7 +33,9 @@ SPDX-License-Identifier: MIT static unsigned const BUILD_YEAR = 2024u; // for quirk -static uint_least16_t const PCI_VENDOR_ID_ATI = 0x1002u; +static uint_least16_t const + PCI_VENDOR_ID_ATI = 0x1002u, + PCI_DEVICE_Sapphire_RX_5600_XT_Pulse = 0x731Fu; // 0: disabled // >0: maximum BAR size (2^x) set to value. 32 for unlimited, 64 for selected GPU only @@ -48,7 +48,7 @@ static EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER o_ EFI_HANDLE reBarImageHandle = NULL; NvStrapsConfig *config = NULL; -// find last set bit and return the index of it +// find highest-order bit set and return the bit index static inline uint_least8_t highestBitIndex(uint_least32_t val) { uint_least8_t bitIndex = (uint_least8_t)(sizeof val * BYTE_BITSIZE - 1u); @@ -70,11 +70,11 @@ uint_least32_t getReBarSizeMask(UINTN pciAddress, uint_least16_t capabilityOffse uint_least32_t barSizeMask = pciRebarGetPossibleSizes(pciAddress, capabilityOffset, vid, did, barIndex); /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ - if (vid == PCI_VENDOR_ID_ATI && did == 0x731fu && barIndex == PCI_BAR_IDX0 && barSizeMask == 0x7000u) - barSizeMask = 0x3f000u; -// else -// if (NvStraps_CheckBARSizeListAdjust(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex)) -// barSizeMask = NvStraps_AdjustBARSizeList(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex, barSizeMask); + if (vid == PCI_VENDOR_ID_ATI && did == PCI_DEVICE_Sapphire_RX_5600_XT_Pulse && barIndex == PCI_BAR_IDX0 && barSizeMask == 0x7000u) + barSizeMask = 0x3'F000u; + else + if (NvStraps_CheckBARSizeListAdjust(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex)) + barSizeMask = NvStraps_AdjustBARSizeList(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex, barSizeMask); return barSizeMask; } @@ -114,7 +114,7 @@ static void reBarSetupDevice(EFI_HANDLE handle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ bool resized = pciRebarSetSize(pciAddress, capOffset, barIndex, barSizeBitIndex); if (isSelectedGpu && resized) - SetStatusVar(StatusVar_GpuReBarConfigured); + SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarConfigured); break; } @@ -124,7 +124,7 @@ static void reBarSetupDevice(EFI_HANDLE handle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ static EFI_STATUS EFIAPI PreprocessControllerOverride ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, + IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, IN EFI_HANDLE RootBridgeHandle, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase @@ -198,53 +198,10 @@ static bool IsCMOSClear() return time.Year < BUILD_YEAR; } -EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState = NULL; -EFI_EVENT evS3SaveStateInstalled; -void *Registration = NULL; - -static void EFIAPI OnS3SaveStateInstalled(EFI_EVENT event, void *context) -{ - SetStatusVar(StatusVar_ParseError); - - if (event == evS3SaveStateInstalled) - gBS->CloseEvent(evS3SaveStateInstalled); -} - -static void RegisterS3SaveStateInstallNotification() -{ - - EFI_STATUS status = gBS->LocateProtocol(&gEfiS3SaveStateProtocolGuid, NULL, (void **)&S3SaveState); - - if (EFI_ERROR(status)) - { - SetEFIError(EFIError_LocateS3SaveStateProtocol, status); - return; - } - - status = gBS->CreateEvent(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnS3SaveStateInstalled, NULL, &evS3SaveStateInstalled); - - if (EFI_ERROR(status)) - { - SetEFIError(EFIError_CreateTimer, status); - return; - } - - status = gBS->RegisterProtocolNotify(&gEfiS3SaveStateProtocolGuid, evS3SaveStateInstalled, &Registration); - - if (EFI_ERROR(status)) - { - SetEFIError(EFIError_SetupTimer, status); - gBS->CloseEvent(evS3SaveStateInstalled); - return; - } -} - EFI_STATUS EFIAPI rebarInit(IN EFI_HANDLE imageHandle, IN EFI_SYSTEM_TABLE *systemTable) { DEBUG((DEBUG_INFO, "ReBarDXE: Loaded\n")); - RegisterS3SaveStateInstallNotification(); - reBarImageHandle = imageHandle; config = GetNvStrapsConfig(false, NULL); // attempts to overflow EFI variable data should result in EFI_BUFFER_TOO_SMALL nPciBarSizeSelector = NvStrapsConfig_TargetPciBarSizeSelector(config); @@ -269,6 +226,8 @@ EFI_STATUS EFIAPI rebarInit(IN EFI_HANDLE imageHandle, IN EFI_SYSTEM_TABLE *syst } SetStatusVar(StatusVar_Configured); + + S3ResumeScript_Init(NvStrapsConfig_IsGpuConfigured(config)); pciHostBridgeResourceAllocationProtocolHook(); // For overriding PciHostBridgeResourceAllocationProtocol } else @@ -276,3 +235,5 @@ EFI_STATUS EFIAPI rebarInit(IN EFI_HANDLE imageHandle, IN EFI_SYSTEM_TABLE *syst return EFI_SUCCESS; } + +// vim:ft=cpp diff --git a/ReBarDxe/ReBarDxe.inf b/ReBarDxe/ReBarDxe.inf index b220cd9..1ed2f83 100644 --- a/ReBarDxe/ReBarDxe.inf +++ b/ReBarDxe/ReBarDxe.inf @@ -10,6 +10,7 @@ include/pciRegs.h include/LocalAppConfig.h include/PciConfig.h + include/S3ResumeScript.h include/DeviceRegistry.h include/SetupNvStraps.h include/EfiVariable.h @@ -17,6 +18,7 @@ include/StatusVar.h include/ReBar.h PciConfig.c + S3ResumeScript.c DeviceRegistry.c SetupNvStraps.c EfiVariable.c diff --git a/ReBarDxe/S3ResumeScript.c b/ReBarDxe/S3ResumeScript.c new file mode 100644 index 0000000..b5c3e28 --- /dev/null +++ b/ReBarDxe/S3ResumeScript.c @@ -0,0 +1,79 @@ + +#include +#include + +#include +#include +#include +#include + +#include "ReBar.h" +#include "PciConfig.h" +#include "StatusVar.h" +#include "S3ResumeScript.h" + +EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState = NULL; + +static void LoadS3SaveStateProtocol() +{ + EFI_STATUS status = gBS->LocateProtocol(&gEfiS3SaveStateProtocolGuid, NULL, (void **)&S3SaveState); + + if (EFI_ERROR(status)) + SetEFIError(EFIError_LocateS3SaveStateProtocol, status); +} + +void S3ResumeScript_Init(bool enabled) +{ + if (enabled && !NvStrapsConfig_SkipS3Resume(config)) + LoadS3SaveStateProtocol(); +} + +// EFI_STATUS S3ResumeScript_MemWrite_DWORD(uintptr_t address, uint_least32_t data); + +EFI_STATUS S3ResumeScript_MemReadWrite_DWORD(uintptr_t address, uint_least32_t data, uint_least32_t dataMask) +{ + if (S3SaveState) + return S3SaveState->Write + ( + S3SaveState, + (UINT16)EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, + (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, + (UINT64)address, + (void *)&data, + (void *)&dataMask + ); + + return EFI_SUCCESS; +} + +EFI_STATUS S3ResumeScript_PciConfigWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data) +{ + if (S3SaveState) + return S3SaveState->Write + ( + S3SaveState, + (UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE, + (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, + (UINT64)pciAddrOffset(pciAddress, offset), + (UINTN)1u, + (void *)&data + ); + + return EFI_SUCCESS; +} + +EFI_STATUS S3ResumeScript_PciConfigReadWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data, uint_least32_t dataMask) +{ + if (S3SaveState) + return S3SaveState->Write + ( + S3SaveState, + (UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, + (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, + (UINT64)pciAddrOffset(pciAddress, offset), + (void *)&data, + (void *)&dataMask + ); + + return EFI_SUCCESS; +} diff --git a/ReBarDxe/SetupNvStraps.c b/ReBarDxe/SetupNvStraps.c index c274344..5711a0a 100644 --- a/ReBarDxe/SetupNvStraps.c +++ b/ReBarDxe/SetupNvStraps.c @@ -12,6 +12,7 @@ #include "StatusVar.h" #include "PciConfig.h" +#include "S3ResumeScript.h" #include "DeviceRegistry.h" #include "NvStrapsConfig.h" #include "ReBar.h" @@ -32,155 +33,6 @@ static uint_least32_t const BAR1_SIZE_PART2_SHIFT = 20u, BAR1_SIZE_PART2_BITSIZE = 3u; -static struct GpuUpdate -{ - uint_least8_t sizeSelector; - uint_least16_t pciLocation; -} - updatedGPUs[ARRAY_SIZE(config->gpuConfig)] = { 0, }; - -static uint_least8_t updatedGPUsCount = 0u; - -EFI_S3_SAVE_STATE_PROTOCOL s3SaveState; -EFI_EVENT eventBeforeExitBootServices; - -void EFIAPI PreExitBootServices(EFI_EVENT event, void *context) -{ - UINT32 - BAR1_SIZE_PART1_MASK = ~(UINT32)(((UINT64_C(1) << BAR1_SIZE_PART1_BITSIZE) - 1u) << BAR1_SIZE_PART1_SHIFT), - BAR1_SIZE_PART2_MASK = ~(UINT32)(((UINT64_C(1) << BAR1_SIZE_PART2_BITSIZE) - 1u) << BAR1_SIZE_PART2_SHIFT); - - EFI_STATUS status; - - for (uint_least8_t i = 0u; i < updatedGPUsCount; i++) - { - uint_least8_t - bus = updatedGPUs[i].pciLocation >> BYTE_BITSIZE & BYTE_BITMASK, - dev = updatedGPUs[i].pciLocation >> 3u & 0b0001'1111u, - func = updatedGPUs[i].pciLocation & 0b0000'0111u; - - UINTN pciAddress = EFI_PCI_ADDRESS(bus, dev, func, 0u); - - uint_least32_t - baseAddress0 = pciDeviceBAR0(pciAddress, &status); - - if (baseAddress0 == UINT32_C(0xFFFF'FFFF)) - { - SetDeviceEFIError(pciAddress, EFIError_ReadBaseAddress0, status); - continue; - } - - uint_least8_t sizeSelector = updatedGPUs[i].sizeSelector; - - UINT32 - bar1SizePart1 = sizeSelector < 3u ? sizeSelector : sizeSelector < 10u ? 2u : 3u, - bar1SizePart2 = sizeSelector < 3u ? 0u : sizeSelector < 10u ? sizeSelector - 2u : 7u; - - bar1SizePart1 <<= BAR1_SIZE_PART1_SHIFT; - bar1SizePart2 <<= BAR1_SIZE_PART2_SHIFT; - - s3SaveState.Write - ( - &s3SaveState, - EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, - EfiBootScriptWidthUint32, - baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET0_OFFSET, - &bar1SizePart1, - &BAR1_SIZE_PART1_MASK - ); - - s3SaveState.Write - ( - &s3SaveState, - EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, - EfiBootScriptWidthUint32, - baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET1_OFFSET, - &bar1SizePart2, - &BAR1_SIZE_PART2_MASK - ); - } - - if (updatedGPUsCount) - SetStatusVar(StatusVar_BootScriptWritten); - -// status = gBS->CloseEvent(eventBeforeExitBootServices); -// -// if (EFI_ERROR(status)) -// SetEFIError(EFIError_CloseEvent, status); -} - -EFI_EXIT_BOOT_SERVICES ExitBootServices = NULL; - -EFI_STATUS EFIAPI ExitBootServicesOverride(EFI_HANDLE imageHandle, UINTN systemMap) -{ - //PreExitBootServices(NULL, NULL); - - if (ExitBootServices) - { - gBS->ExitBootServices = ExitBootServices; - ExitBootServices = NULL; - return gBS->ExitBootServices(imageHandle, systemMap); - } - - return RETURN_NOT_STARTED; -} - -void RecordUpdateGPU(uint_least8_t bus, uint_least8_t device, uint_least8_t func, uint_least8_t barSize) -{ - if (updatedGPUsCount < ARRAY_SIZE(updatedGPUs)) - { - struct GpuUpdate *gpuUpdate = updatedGPUs + updatedGPUsCount++; - - gpuUpdate->sizeSelector = barSize; - gpuUpdate->pciLocation = pciPackLocation(bus, device, func); - - if (updatedGPUsCount == 1u) - { - EFI_STATUS status; - // UINTN handleCount; - // EFI_HANDLE *handleBuffer = NULL; - - status = gBS->LocateProtocol(&gEfiS3SaveStateProtocolGuid, NULL, (void **)&s3SaveState); - - // status = gBS->LocateHandleBuffer( - // ByProtocol, - // &gEfiS3SaveStateProtocolGuid, - // NULL, - // &handleCount, - // &handleBuffer); - - // if (EFI_ERROR(status)) - // { - // SetEFIError(EFIError_LocateS3SaveStateProtocol, status); - // return; - // } - - // status = gBS->OpenProtocol( - // *handleBuffer, - // &gEfiS3SaveStateProtocolGuid, - // (VOID **)&s3SaveState, - // gImageHandle, - // NULL, - // EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (EFI_ERROR(status)) - { - SetEFIError(EFIError_LoadS3SaveStateProtocol, status); - return; - } - - PreExitBootServices(NULL, NULL); - // ExitBootServices = gBS->ExitBootServices; - // gBS->ExitBootServices = ExitBootServicesOverride; - - // status = gBS->CreateEventEx(EVT_NOTIFY_SIGNAL, TPL_APPLICATION, &PreExitBootServices, NULL, &gEfiEventReadyToBootGuid, &eventBeforeExitBootServices); - - // if (EFI_ERROR(status)) - // SetEFIError(EFIError_CreateEvent, status); - } - } -} - static uint_least16_t enumeratedBridges[ARRAY_SIZE(config->bridge)] = { 0, }; static uint_least8_t enumeratedBridgeCount = 0u; @@ -264,23 +116,15 @@ static bool ConfigureNvStrapsBAR1Size(EFI_PHYSICAL_ADDRESS baseAddress0, UINT8 b CopyMem(pSTRAPS0, &STRAPS0, sizeof STRAPS0); - if (S3SaveState) - { - EFI_STATUS status = S3SaveState->Write - ( - S3SaveState, - (UINT16)EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, - (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, - (UINT64)((UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET0_OFFSET), - (UINTN)1u, - (void *)&STRAPS0 - ); - - if (EFI_ERROR(status)) - SetEFIError(EFIError_WriteS3SaveStateProtocol, status); - } - else - SetEFIError(EFIError_LoadS3SaveStateProtocol, EFI_NOT_FOUND); + EFI_STATUS status = S3ResumeScript_MemReadWrite_DWORD + ( + (UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET0_OFFSET, + (UINT32)targetBarSize_Part1 << BAR1_SIZE_PART1_SHIFT | UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u), + (UINT32) ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART1_BITSIZE) - 1u) << BAR1_SIZE_PART1_SHIFT) + ); + + if (EFI_ERROR(status)) + SetEFIError(EFIError_WriteS3SaveStateProtocol, status); } if (barSize_Part2 != targetBarSize_Part2) @@ -291,23 +135,15 @@ static bool ConfigureNvStrapsBAR1Size(EFI_PHYSICAL_ADDRESS baseAddress0, UINT8 b CopyMem(pSTRAPS1, &STRAPS1, sizeof STRAPS1); - if (S3SaveState) - { - EFI_STATUS status = S3SaveState->Write - ( - S3SaveState, - (UINT16)EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE, - (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, - (UINT64)((UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET1_OFFSET), - (UINTN)1u, - (void *)&STRAPS1 - ); - - if (EFI_ERROR(status)) - SetEFIError(EFIError_WriteS3SaveStateProtocol, status); - } - else - SetEFIError(EFIError_LoadS3SaveStateProtocol, EFI_NOT_FOUND); + EFI_STATUS status = S3ResumeScript_MemReadWrite_DWORD + ( + (UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET1_OFFSET, + (UINT32)targetBarSize_Part2 << BAR1_SIZE_PART2_SHIFT | UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u), + (UINT32) ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART2_BITSIZE) - 1u) << BAR1_SIZE_PART2_SHIFT) + ); + + if (EFI_ERROR(status)) + SetEFIError(EFIError_WriteS3SaveStateProtocol, status); } return barSize_Part1 + barSize_Part2 != targetBarSize_Part1 + targetBarSize_Part2; @@ -325,6 +161,8 @@ void NvStraps_Setup(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t de if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) return; + NvStraps_BarSizeMaskOverride sizeMaskOverride = NvStrapsConfig_LookupBarSizeMaskOverride(config, deviceId, subsysVenID, subsysDevID, bus, device, func); + NvStraps_GPUConfig const *gpuConfig = NvStrapsConfig_LookupGPUConfig(config, bus, device, func); if (!gpuConfig) @@ -409,12 +247,19 @@ void NvStraps_Setup(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t de SetDeviceStatusVar(pciAddress, StatusVar_GpuStrapsNoConfirm); } else - SetStatusVar(StatusVar_GpuNoReBarCapability); + if (isTuringGPU(deviceId)) + SetDeviceStatusVar(pciAddress, StatusVar_GpuNoReBarCapability); - if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_GPU_ONLY && capabilityOffset) + if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_GPU_ONLY) { - if (pciRebarSetSize(pciAddress, capabilityOffset, PCI_BAR_IDX1, (uint_least8_t)(barSizeSelector.barSizeSelector + 6u))) - SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarConfigured); + if (capabilityOffset && (barSizeMask & UINT32_C(0x0000'0001) << (barSizeSelector.barSizeSelector + 6u) || sizeMaskOverride.sizeMaskOverride)) + { + if ((barSizeMask & UINT32_C(0x0000'0001) << (barSizeSelector.barSizeSelector + 6u)) == 0) + SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarSizeOverride); + + if (pciRebarSetSize(pciAddress, capabilityOffset, PCI_BAR_IDX1, (uint_least8_t)(barSizeSelector.barSizeSelector + 6u))) + SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarConfigured); + } } else if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_GPU_STRAPS_ONLY) @@ -451,43 +296,48 @@ void NvStraps_Setup(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t de // SetStatusVar(StatusVar_EFIAllocationError); } -// bool NvStraps_CheckBARSizeListAdjust(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t barIndex) -// { -// if (vid == TARGET_GPU_VENDOR_ID && subsysVenID != WORD_BITMASK && subsysDevID != WORD_BITMASK && barIndex == PCI_BAR_IDX1) -// { -// uint_least8_t bus, device, func; -// pciUnpackAddress(pciAddress, &bus, &device, &func); -// -// NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); -// -// if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) -// return false; -// -// NvStraps_BridgeConfig const *bridgeConfig = NvStrapsConfig_LookupBridgeConfig(config, bus); -// -// return isBridgeEnumerated(pciPackLocation(bridgeConfig->bridgeBus, bridgeConfig->bridgeDevice, bridgeConfig->bridgeFunction)); -// } -// -// return false; -// } -// -// uint_least32_t NvStraps_AdjustBARSizeList(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t barIndex, uint_least32_t barSizeMask) -// { -// uint_least8_t bus, device, func; -// -// pciUnpackAddress(pciAddress, &bus, &device, &func); -// -// NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); -// -// if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) -// return barSizeMask; -// else -// if (barSizeMask >> 9u) // any BAR sizes over 256 MB -// SetStatusVar(StatusVar_GpuReBarConfigured); -// -// -// return barSizeMask | UINT32_C(0x00000001) << (6u + (unsigned)barSizeSelector.barSizeSelector); -// } -// +bool NvStraps_CheckBARSizeListAdjust(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t barIndex) +{ + if (vid == TARGET_GPU_VENDOR_ID && subsysVenID != WORD_BITMASK && subsysDevID != WORD_BITMASK && barIndex == PCI_BAR_IDX1) + { + uint_least8_t bus, device, func; + pciUnpackAddress(pciAddress, &bus, &device, &func); + + NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); + + if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) + return false; + + NvStraps_BarSizeMaskOverride sizeMaskOverride = NvStrapsConfig_LookupBarSizeMaskOverride(config, did, subsysVenID, subsysDevID, bus, device, func); + + if (sizeMaskOverride.sizeMaskOverride) + { + NvStraps_BridgeConfig const *bridgeConfig = NvStrapsConfig_LookupBridgeConfig(config, bus); + + return isBridgeEnumerated(pciPackLocation(bridgeConfig->bridgeBus, bridgeConfig->bridgeDevice, bridgeConfig->bridgeFunction)); + } + + return false; + } + + return false; +} + +uint_least32_t NvStraps_AdjustBARSizeList(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t barIndex, uint_least32_t barSizeMask) +{ + uint_least8_t bus, device, func; + + pciUnpackAddress(pciAddress, &bus, &device, &func); + + NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); + + if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) + return barSizeMask; + + if ((barSizeMask & UINT32_C(0x00000001) << (6u + (unsigned)barSizeSelector.barSizeSelector)) == 0u) + SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarSizeOverride); + + return barSizeMask | UINT32_C(0x00000001) << (6u + (unsigned)barSizeSelector.barSizeSelector); +} // vim: ft=cpp diff --git a/ReBarDxe/include/NvStrapsConfig.h b/ReBarDxe/include/NvStrapsConfig.h index ea865fd..c859736 100644 --- a/ReBarDxe/include/NvStrapsConfig.h +++ b/ReBarDxe/include/NvStrapsConfig.h @@ -1,7 +1,6 @@ #if !defined(NV_STRAPS_REBAR_CONFIG_H) #define NV_STRAPS_REBAR_CONFIG_H -// Some test to check if compiling UEFI code #if defined(UEFI_SOURCE) # include #else @@ -72,6 +71,7 @@ typedef struct NvStraps_GPUSelector uint_least8_t device; uint_least8_t function; uint_least8_t barSizeSelector; + uint_least8_t overrideBarSizeMask; #if defined(__cplusplus) bool operator ==(NvStraps_GPUSelector const &other) const = default; @@ -85,7 +85,7 @@ typedef struct NvStraps_GPUSelector enum { - GPU_SELECTOR_SIZE = WORD_SIZE * 3u + BYTE_SIZE * 3u, + GPU_SELECTOR_SIZE = WORD_SIZE * 3u + BYTE_SIZE * 4u, }; typedef struct NvStraps_GPUConfig @@ -144,11 +144,18 @@ typedef struct NvStraps_BarSize } NvStraps_BarSize; +typedef struct NvStraps_BarSizeMaskOverride +{ + ConfigPriority priority; + bool sizeMaskOverride; +} + NvStraps_BarSizeMaskOverride; + typedef struct NvStrapsConfig { bool dirty; uint_least8_t nPciBarSize; - uint_least8_t nGlobalEnable; + uint_least8_t nOptionFlags; uint_least8_t nGPUSelector; NvStraps_GPUSelector GPUs[NvStraps_GPU_MAX_COUNT]; @@ -164,6 +171,10 @@ typedef struct NvStrapsConfig bool isDirty(bool fDirty); uint_least8_t isGlobalEnable() const; uint_least8_t setGlobalEnable(uint_least8_t val); + bool skipS3Resume() const; + bool skipS3Resume(bool fSkip); + bool overrideBarSizeMask() const; + bool overrideBarSizeMask(bool overrideSizeMask); uint_least8_t targetPciBarSizeSelector() const; uint_least8_t targetPciBarSizeSelector(uint_least8_t barSizeSelector); @@ -171,6 +182,9 @@ typedef struct NvStrapsConfig bool setGPUSelector(uint_least8_t barSizeSelector, uint_least16_t deviceID); bool setGPUSelector(uint_least8_t barSizeSelector, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID); bool setGPUSelector(uint_least8_t barSizeSelector, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn); + bool setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID); + bool setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID); + bool setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn); bool setGPUConfig(NvStraps_GPUConfig const &config); bool setBridgeConfig(NvStraps_BridgeConfig const &config); @@ -182,6 +196,7 @@ typedef struct NvStrapsConfig bool clearGPUSelectors(); NvStraps_BarSize lookupBarSize(uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) const; + NvStraps_BarSizeMaskOverride lookupBarSizeMaskOverride(uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) const; std::tuple hasBridgeDevice(uint_least8_t bridgeBus, uint_least8_t bridgeDevice, uint_least8_t bridgeFunction) const; NvStraps_BridgeConfig const *lookupBridgeConfig(uint_least8_t bridgeSecondaryBus) const; NvStraps_GPUConfig const *lookupGPUConfig(uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) const; @@ -222,12 +237,17 @@ bool NvStrapsConfig_SetGPUConfig(NvStrapsConfig *config, NvStraps_GPUConfig cons bool NvStrapsConfig_SetBridgeConfig(NvStrapsConfig *config, NvStraps_BridgeConfig const *bridgeConfig); bool NvStrapsConfig_IsDirty(NvStrapsConfig const *config); bool NvStrapsConfig_SetIsDirty(NvStrapsConfig *config, bool dirtyFlag); +bool NvStrapsConfig_SkipS3Resume(NvStrapsConfig const *config); +bool NvStrapsConfig_SetSkipS3Resume(NvStrapsConfig *config, bool fSkipS3Resume); +bool NvStrapsConfig_OverrideBarSizeMask(NvStrapsConfig const *config); +bool NvStrapsConfig_SetOverrideBarSizeMask(NvStrapsConfig *config, bool fOverrideSizeMask); bool NvStrapsConfig_IsGpuConfigured(NvStrapsConfig const *config); bool NvStrapsConfig_IsDriverConfigured(NvStrapsConfig const *config); bool NvStrapsConfig_ResetConfig(NvStrapsConfig *config); void NvStrapsConfig_Clear(NvStrapsConfig *config); NvStraps_BarSize NvStrapsConfig_LookupBarSize(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); +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); NvStraps_GPUConfig const *NvStrapsConfig_LookupGPUConfig(NvStrapsConfig const *config, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn); NvStraps_BridgeConfig const *NvStrapsConfig_LookupBridgeConfig(NvStrapsConfig const *config, uint_least8_t secondaryBus); uint_least32_t NvStrapsConfig_HasBridgeDevice(NvStrapsConfig const *config, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn); @@ -243,22 +263,29 @@ inline uint_least8_t NvStrapsConfig_TargetPciBarSizeSelector(NvStrapsConfig cons inline uint_least8_t NvStrapsConfig_SetTargetPciBarSizeSelector(NvStrapsConfig *config, uint_least8_t barSizeSelector) { uint_least8_t pciBarSize = config->nPciBarSize; - config->dirty = barSizeSelector != config->nPciBarSize; + config->dirty = config->dirty || barSizeSelector != config->nPciBarSize; return config->nPciBarSize = barSizeSelector, pciBarSize; } inline uint_least8_t NvStrapsConfig_IsGlobalEnable(NvStrapsConfig const *config) { - return config->nGlobalEnable; + return config->nOptionFlags & 0x03u; } inline uint_least8_t NvStrapsConfig_SetGlobalEnable(NvStrapsConfig *config, uint_least8_t globalEnable) { - uint_least8_t oldGlobalEnable = config->nGlobalEnable; - config->dirty = globalEnable != config->nGlobalEnable; + uint_least8_t previousGlobalEnable = NvStrapsConfig_IsGlobalEnable(config); + + if (previousGlobalEnable != globalEnable) + { + config->dirty = true; - return config->nGlobalEnable = globalEnable, oldGlobalEnable; + config->nOptionFlags &= ~(uint_least8_t)0x03u; + config->nOptionFlags |= globalEnable & 0x03u; + } + + return previousGlobalEnable; } inline bool NvStrapsConfig_IsDirty(NvStrapsConfig const *config) @@ -272,9 +299,47 @@ inline bool NvStrapsConfig_SetIsDirty(NvStrapsConfig *config, bool dirtyFlag) return config->dirty = dirtyFlag, oldFlag; } +inline bool NvStrapsConfig_SkipS3Resume(NvStrapsConfig const *config) +{ + return !!(config->nOptionFlags & 0x04u); +} + +inline bool NvStrapsConfig_SetSkipS3Resume(NvStrapsConfig *config, bool fSkipS3Resume) +{ + bool previousFlag = NvStrapsConfig_SkipS3Resume(config); + + config->dirty = config->dirty || fSkipS3Resume != previousFlag; + + if (fSkipS3Resume) + config->nOptionFlags |= 0x04u; + else + config->nOptionFlags &= (uint_least8_t) ~(uint_least8_t)0x04u; + + return previousFlag; +} + +inline bool NvStrapsConfig_OverrideBarSizeMask(NvStrapsConfig const *config) +{ + return !!(config->nOptionFlags & 0x08u); +} + +inline bool NvStrapsConfig_SetOverrideBarSizeMask(NvStrapsConfig *config, bool fOverrideSizeMask) +{ + bool previousFlag = NvStrapsConfig_OverrideBarSizeMask(config); + + config->dirty = config->dirty || fOverrideSizeMask != previousFlag; + + if (fOverrideSizeMask) + config->nOptionFlags |= 0x08u; + else + config->nOptionFlags &= (uint_least8_t) ~(uint_least8_t)0x08u; + + return previousFlag; +} + inline bool NvStrapsConfig_IsGpuConfigured(NvStrapsConfig const *config) { - return config->nGlobalEnable || config->nGPUSelector; + return NvStrapsConfig_IsGlobalEnable(config) || config->nGPUSelector; } inline bool NvStrapsConfig_IsDriverConfigured(NvStrapsConfig const *config) @@ -332,6 +397,16 @@ inline bool NvStrapsConfig::setGPUSelector(uint_least8_t barSizeSelector, uint_l return setGPUSelector(barSizeSelector, deviceID, subsysVenID, subsysDevID, MAX_UINT8, MAX_UINT8, MAX_UINT8); } +inline bool NvStrapsConfig::setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID) +{ + return setBarSizeMaskOverride(sizeMaskOverride, deviceID, MAX_UINT16, MAX_UINT16); +} + +inline bool NvStrapsConfig::setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID) +{ + return setBarSizeMaskOverride(sizeMaskOverride, deviceID, subsysVenID, subsysDevID, MAX_UINT8, MAX_UINT8, MAX_UINT8); +} + inline bool NvStrapsConfig::setGPUConfig(NvStraps_GPUConfig const &config) { return NvStrapsConfig_SetGPUConfig(this, &config); @@ -394,7 +469,7 @@ inline bool NvStrapsConfig::resetConfig() inline bool NvStrapsConfig::clearGPUSelectors() { - return dirty = !!nGPUSelector, !!std::exchange(nGPUSelector, 0u); + return dirty = dirty || !!nGPUSelector, !!std::exchange(nGPUSelector, 0u); } inline bool NvStrapsConfig::isDirty() const @@ -407,6 +482,26 @@ inline bool NvStrapsConfig::isDirty(bool fDirty) return NvStrapsConfig_SetIsDirty(this, fDirty); } +inline bool NvStrapsConfig::skipS3Resume() const +{ + return NvStrapsConfig_SkipS3Resume(this); +} + +inline bool NvStrapsConfig::skipS3Resume(bool fSkip) +{ + return NvStrapsConfig_SetSkipS3Resume(this, fSkip); +} + +inline bool NvStrapsConfig::overrideBarSizeMask() const +{ + return NvStrapsConfig_OverrideBarSizeMask(this); +} + +inline bool NvStrapsConfig::overrideBarSizeMask(bool overrideSizeMask) +{ + return NvStrapsConfig_SetOverrideBarSizeMask(this, overrideSizeMask); +} + inline uint_least8_t NvStrapsConfig::isGlobalEnable() const { return NvStrapsConfig_IsGlobalEnable(this); @@ -432,6 +527,12 @@ inline NvStraps_BarSize NvStrapsConfig::lookupBarSize(uint_least16_t deviceID, u return NvStrapsConfig_LookupBarSize(this, deviceID, subsysVenID, subsysDevID, bus, dev, fn); } + +inline NvStraps_BarSizeMaskOverride NvStrapsConfig::lookupBarSizeMaskOverride(uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) const +{ + return NvStrapsConfig_LookupBarSizeMaskOverride(this, deviceID, subsysVenID, subsysDevID, bus, dev, fn); +} + inline std::tuple NvStrapsConfig::hasBridgeDevice(uint_least8_t bridgeBus, uint_least8_t bridgeDevice, uint_least8_t bridgeFunction) const { auto deviceID = uint_least32_t { NvStrapsConfig_HasBridgeDevice(this, bridgeBus, bridgeDevice, bridgeFunction) }; diff --git a/ReBarDxe/include/PciConfig.h b/ReBarDxe/include/PciConfig.h index b848556..6f9b00b 100644 --- a/ReBarDxe/include/PciConfig.h +++ b/ReBarDxe/include/PciConfig.h @@ -12,6 +12,7 @@ #include "LocalAppConfig.h" #if defined(UEFI_SOURCE) +UINT64 pciAddrOffset(UINTN pciAddress, INTN offset); UINTN pciLocateDevice(EFI_HANDLE RootBridgeHandle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS addressInfo, uint_least16_t *venID, uint_least16_t *devID, uint_least8_t *headerType); uint_least16_t pciFindExtCapability(UINTN pciAddress, uint_least32_t cap); uint_least32_t pciRebarGetPossibleSizes(UINTN pciAddress, uint_least16_t capabilityOffset, UINT16 vid, UINT16 did, uint_least8_t barIndex); diff --git a/ReBarDxe/include/ReBar.h b/ReBarDxe/include/ReBar.h index 1a43620..cbdfdf8 100644 --- a/ReBarDxe/include/ReBar.h +++ b/ReBarDxe/include/ReBar.h @@ -8,6 +8,5 @@ extern EFI_HANDLE reBarImageHandle; extern NvStrapsConfig *config; -extern EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState; #endif // !defined(REBAR_UEFI_REBAR_H) diff --git a/ReBarDxe/include/S3ResumeScript.h b/ReBarDxe/include/S3ResumeScript.h new file mode 100644 index 0000000..95ede68 --- /dev/null +++ b/ReBarDxe/include/S3ResumeScript.h @@ -0,0 +1,15 @@ +#if !defined(NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H) +#define NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H + +#include +#include + +#include + +void S3ResumeScript_Init(bool enabled); +// EFI_STATUS S3ResumeScript_MemWrite_DWORD(uintptr_t address, uint_least32_t data); +EFI_STATUS S3ResumeScript_MemReadWrite_DWORD(uintptr_t address, uint_least32_t data, uint_least32_t dataMask); +EFI_STATUS S3ResumeScript_PciConfigWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data); +EFI_STATUS S3ResumeScript_PciConfigReadWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data, uint_least32_t dataMask); + +#endif // !defined(NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H) diff --git a/ReBarDxe/include/StatusVar.h b/ReBarDxe/include/StatusVar.h index 9cd2aa3..4cee1af 100644 --- a/ReBarDxe/include/StatusVar.h +++ b/ReBarDxe/include/StatusVar.h @@ -34,9 +34,9 @@ typedef enum StatusVar StatusVar_GpuDelayElapsed = 110u, StatusVar_GpuReBarConfigured = 120u, StatusVar_GpuStrapsNoConfirm = 130u, + StatusVar_GpuReBarSizeOverride = 135u, StatusVar_GpuNoReBarCapability = 140u, StatusVar_GpuExcluded = 150u, - StatusVar_BootScriptWritten = 151u, StatusVar_NoBridgeConfig = 159u, StatusVar_BadBridgeConfig = 160u, diff --git a/ReBarState/ConfigManagerError.ixx b/ReBarState/ConfigManagerError.ixx index 90c2f7e..7b0a92d 100644 --- a/ReBarState/ConfigManagerError.ixx +++ b/ReBarState/ConfigManagerError.ixx @@ -310,3 +310,5 @@ inline string ConfigManagerErrorCategory::message(int error) const { return "PnP Configuration Manager error code " + to_string(error) + ": " + configurationManagerErrorMessage(error); } + +// vim: ft=cpp diff --git a/ReBarState/ConfigurationWizard.ixx b/ReBarState/ConfigurationWizard.ixx index d233e7d..e8017e9 100644 --- a/ReBarState/ConfigurationWizard.ixx +++ b/ReBarState/ConfigurationWizard.ixx @@ -20,6 +20,8 @@ using std::uint_least8_t; using std::uint_least32_t; using std::uint_least64_t; using std::span; +using std::begin; +using std::end; using std::tuple; using std::tie; using std::vector; @@ -59,6 +61,8 @@ static vector buildConfigurationMenu(NvStrapsConfig &nvStrapsConfig MenuCommand::GlobalEnable, MenuCommand::PerGPUConfig, MenuCommand::PerGPUConfigClear, + MenuCommand::SkipS3Resume, + MenuCommand::OverrideBarSizeMask, MenuCommand::UEFIConfiguration, MenuCommand::ShowConfiguration }; @@ -77,9 +81,10 @@ static vector buildConfigurationMenu(NvStrapsConfig &nvStrapsConfig return configMenu; } -static span selectCurrentMenu(MenuType menuType, NvStrapsConfig &nvStrapsConfig) +static span selectCurrentMenu(MenuType menuType, NvStrapsConfig &nvStrapsConfig, unsigned selectedDevice, vector const &deviceList) { static auto mainMenu = vector { }; + static auto barSizeMenu = vector { begin(GPUBarSizePrompt), end(GPUBarSizePrompt) }; switch (menuType) { @@ -91,7 +96,16 @@ static span selectCurrentMenu(MenuType menuType, NvStrapsConfig &nv return GPUConfigMenu; case MenuType::GPUBARSize: - return GPUBarSizePrompt; + if (isTuringGPU(deviceList[selectedDevice].deviceID)) + if (barSizeMenu[2u] != MenuCommand::OverrideBarSizeMask) + barSizeMenu.insert(barSizeMenu.begin() + 2u, MenuCommand::OverrideBarSizeMask); + else + ; + else + if (barSizeMenu[2u] == MenuCommand::OverrideBarSizeMask) + barSizeMenu.erase(barSizeMenu.begin() + 2u); + + return barSizeMenu; case MenuType::PCIBARSize: return ReBarUEFIMenu; @@ -116,7 +130,7 @@ static tuple getDefaultCommand(MenuType menuType, NvStrap return { MenuCommand::DefaultChoice, 0u }; } -static bool setGPUBarSize(NvStrapsConfig &nvStrapsConfig, UINT8 barSizeSelector, unsigned selectedDevice, MenuCommand deviceSelector, vector const &deviceList) +static bool setGPUBarSize(NvStrapsConfig &nvStrapsConfig, uint_least8_t barSizeSelector, unsigned selectedDevice, MenuCommand deviceSelector, vector const &deviceList) { auto configured = false; auto const &device = deviceList[selectedDevice]; @@ -142,6 +156,32 @@ static bool setGPUBarSize(NvStrapsConfig &nvStrapsConfig, UINT8 barSizeSelector, return configured; } +static bool setGPUBarSizeMaskOverride(NvStrapsConfig &nvStrapsConfig, bool maskOverride, unsigned selectedDevice, MenuCommand deviceSelector, vector const &deviceList) +{ + auto configured = false; + auto const &device = deviceList[selectedDevice]; + + switch (deviceSelector) + { + case MenuCommand::GPUSelectorByPCIID: + configured = nvStrapsConfig.setBarSizeMaskOverride(maskOverride, device.deviceID); + break; + + case MenuCommand::GPUSelectorByPCISubsystem: + configured = nvStrapsConfig.setBarSizeMaskOverride(maskOverride, device.deviceID, device.subsystemVendorID, device.subsystemDeviceID); + break; + + case MenuCommand::GPUSelectorByPCILocation: + configured = nvStrapsConfig.setBarSizeMaskOverride(maskOverride, device.deviceID, device.subsystemVendorID, device.subsystemDeviceID, device.bus, device.device, device.function); + break; + } + + if (!configured) + showError(L"Cannot configure GPU. Too many GPU configurations ? Clear existing configurations and re-configure.\n"s); + + return configured; +} + static bool clearGPUBarSize(NvStrapsConfig &nvStrapsConfig, unsigned selectedDevice, MenuCommand deviceSelector, vector const &deviceList) { auto configured = false; @@ -302,7 +342,7 @@ void runConfigurationWizard() auto [menuCommand, value] = showMenuPrompt ( - selectCurrentMenu(menuType, nvStrapsConfig), + selectCurrentMenu(menuType, nvStrapsConfig, selectedDevice, deviceList), defaultCommand, defaultValue, nvStrapsConfig.isGlobalEnable(), @@ -314,6 +354,13 @@ void runConfigurationWizard() switch (menuCommand) { case MenuCommand::DiscardQuit: + if (runConfirmationPrompt(MenuCommand::DiscardQuit)) + runMenuLoop = false; + else + showConfig(); + + break; + case MenuCommand::Quit: runMenuLoop = false; break; @@ -323,6 +370,44 @@ void runConfigurationWizard() showConfig(); break; + case MenuCommand::SkipS3Resume: + if (nvStrapsConfig.skipS3Resume() || runConfirmationPrompt(MenuCommand::SkipS3Resume)) + nvStrapsConfig.skipS3Resume(!nvStrapsConfig.skipS3Resume()); + + showConfig(); + break; + + case MenuCommand::OverrideBarSizeMask: + switch (menuType) + { + case MenuType::Main: + nvStrapsConfig.overrideBarSizeMask(!nvStrapsConfig.overrideBarSizeMask()); + break; + + case MenuType::GPUBARSize: + { + auto &&deviceInfo = deviceList[selectedDevice]; + auto barSizeMaskOverride = + nvStrapsConfig.lookupBarSizeMaskOverride + ( + deviceInfo.deviceID, + deviceInfo.subsystemVendorID, + deviceInfo.subsystemDeviceID, + deviceInfo.bus, + deviceInfo.device, + deviceInfo.function + ) + .sizeMaskOverride; + setGPUBarSizeMaskOverride(nvStrapsConfig, !barSizeMaskOverride, selectedDevice, deviceSelector, deviceList); + } + + break; + } + + showConfig(); + menuType = MenuType::Main; + break; + case MenuCommand::PerGPUConfigClear: nvStrapsConfig.clearGPUSelectors(); showConfig(); diff --git a/ReBarState/NvStrapsConfig.hh b/ReBarState/NvStrapsConfig.hh index 5eb484f..621bb5b 100644 --- a/ReBarState/NvStrapsConfig.hh +++ b/ReBarState/NvStrapsConfig.hh @@ -16,7 +16,7 @@ namespace views = std::ranges::views; namespace execution = std::execution; using namespace std::literals::string_literals; -bool NvStrapsConfig::setGPUSelector(UINT8 barSizeSelector, UINT16 deviceID, UINT16 subsysVenID, UINT16 subsysDevID, UINT8 bus, UINT8 dev, UINT8 fn) +bool NvStrapsConfig::setGPUSelector(uint_least8_t barSizeSelector, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) { NvStraps_GPUSelector gpuSelector { @@ -26,7 +26,8 @@ bool NvStrapsConfig::setGPUSelector(UINT8 barSizeSelector, UINT16 deviceID, UINT .bus = bus, .device = dev, .function = fn, - .barSizeSelector = barSizeSelector + .barSizeSelector = barSizeSelector, + .overrideBarSizeMask = 0u }; auto end_it = begin(GPUs) + nGPUSelector; @@ -46,10 +47,50 @@ bool NvStrapsConfig::setGPUSelector(UINT8 barSizeSelector, UINT16 deviceID, UINT GPUs[nGPUSelector++] = gpuSelector; } else - if (*it != gpuSelector) + if (it->barSizeSelector != barSizeSelector) { dirty = true; - *it = gpuSelector; + it->barSizeSelector = barSizeSelector; + } + + return true; +} + +bool NvStrapsConfig::setBarSizeMaskOverride(bool sizeMaskOverride, uint_least16_t deviceID, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t bus, uint_least8_t dev, uint_least8_t fn) +{ + NvStraps_GPUSelector gpuSelector + { + .deviceID = deviceID, + .subsysVendorID = subsysVenID, + .subsysDeviceID = subsysDevID, + .bus = bus, + .device = dev, + .function = fn, + .barSizeSelector = BarSizeSelector_None, + .overrideBarSizeMask = sizeMaskOverride ? (uint_least8_t)0x01u : (uint_least8_t)0xFFu + }; + + auto end_it = begin(GPUs) + nGPUSelector; + auto it = find_if(execution::par_unseq, begin(GPUs), end_it, [&gpuSelector](auto const &selector) + { + return selector.deviceMatch(gpuSelector.deviceID) + && selector.subsystemMatch(gpuSelector.subsysVendorID, gpuSelector.subsysDeviceID) + && selector.busLocationMatch(gpuSelector.bus, gpuSelector.device, gpuSelector.function); + }); + + if (it == end_it) + if (nGPUSelector >= size(GPUs)) + return false; + else + { + dirty = true; + GPUs[nGPUSelector++] = gpuSelector; + } + else + if (it->overrideBarSizeMask != gpuSelector.overrideBarSizeMask) + { + dirty = true; + it->overrideBarSizeMask = gpuSelector.overrideBarSizeMask; } return true; diff --git a/ReBarState/NvStrapsConfig.ixx b/ReBarState/NvStrapsConfig.ixx index 9d4d164..53b9c3b 100644 --- a/ReBarState/NvStrapsConfig.ixx +++ b/ReBarState/NvStrapsConfig.ixx @@ -96,23 +96,24 @@ void ShowNvStrapsConfig(function show) show(L"DXE Driver configuration:\n"s); show(L"\tisDirty: "s + to_wstring(config.dirty) + L'\n'); - show(L"\tnGlobalEnable: "s + to_wstring(config.nGlobalEnable) + L'\n'); + show(L"\tOptionFlags: "s + L"0x"s + formatHexByte(config.nOptionFlags) + L'\n'); show(L"\tnPciBarSize: "s + to_wstring(config.nPciBarSize) + L'\n'); show(L"\tnGPUSelectorCount: "s + to_wstring(config.nGPUSelector) + L'\n'); for (auto const &&[i, gpuSelector]: config.GPUs | views::enumerate | views::take(config.nGPUSelector)) { - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": deviceID: "s + formatPCI_ID(gpuSelector.deviceID) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysVendorID: "s + formatPCI_ID(gpuSelector.subsysVendorID) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysDeviceID: "s + formatPCI_ID(gpuSelector.subsysDeviceID) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": bus: "s + formatHexByte(gpuSelector.bus) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": device: "s + formatHexByte(gpuSelector.device) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": function: "s + formatHexNibble(gpuSelector.function) + L'\n'); - show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": barSizeSelector: "s + to_wstring(gpuSelector.barSizeSelector) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": deviceID: "s + formatPCI_ID(gpuSelector.deviceID) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysVendorID: "s + formatPCI_ID(gpuSelector.subsysVendorID) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysDeviceID: "s + formatPCI_ID(gpuSelector.subsysDeviceID) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": bus: "s + formatHexByte(gpuSelector.bus) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": device: "s + formatHexByte(gpuSelector.device) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": function: "s + formatHexNibble(gpuSelector.function) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": barSizeSelector: "s + to_wstring(gpuSelector.barSizeSelector) + L'\n'); + show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": overridebarSizeMask: "s + to_wstring(gpuSelector.overrideBarSizeMask) + L'\n'); show(L"\n"s); } - show(L"\tnGPUConfigCount: " + to_wstring(config.nGPUConfig) + L'\n'); + show(L"\tnGPUConfigCount: "s + to_wstring(config.nGPUConfig) + L'\n'); for (auto const &&[i, gpuConfig]: config.gpuConfig | views::enumerate | views::take(config.nGPUConfig)) { @@ -127,7 +128,7 @@ void ShowNvStrapsConfig(function show) show(L"\n"s); } - show(L"\tnBridgeCount: "s + to_wstring(config.nBridgeConfig) + L'\n'); + show(L"\tnBridgeCount: "s + to_wstring(config.nBridgeConfig) + L'\n'); for (auto const &&[i, bridgeConfig]: config.bridge | views::enumerate | views::take(config.nBridgeConfig)) { @@ -140,3 +141,5 @@ void ShowNvStrapsConfig(function show) show(L"\n"s); } } + +// vim:ft=cpp diff --git a/ReBarState/TextWizardMenu.ixx b/ReBarState/TextWizardMenu.ixx index 7905761..f7a9d2f 100644 --- a/ReBarState/TextWizardMenu.ixx +++ b/ReBarState/TextWizardMenu.ixx @@ -3,6 +3,7 @@ export module TextWizardMenu; import std; import LocalAppConfig; import NvStrapsConfig; +import DeviceRegistry; import DeviceList; using std::tuple; @@ -20,6 +21,8 @@ export enum class MenuCommand DiscardPrompt, GlobalEnable, GlobalFallbackEnable, + SkipS3Resume, + OverrideBarSizeMask, UEFIConfiguration, UEFIBARSizePrompt, PerGPUConfigClear, @@ -53,6 +56,8 @@ export tuple showMenuPrompt NvStrapsConfig const &config ); +export bool runConfirmationPrompt(MenuCommand menuCommand); + module: private; using std::optional; @@ -87,11 +92,12 @@ namespace execution = std::execution; namespace views = std::ranges::views; using namespace std::literals::string_view_literals; - static auto const mainMenuShortcuts = map { { L'E', MenuCommand::GlobalEnable }, { L'D', MenuCommand::GlobalEnable }, + { L'K', MenuCommand::SkipS3Resume }, + { L'O', MenuCommand::OverrideBarSizeMask }, // { L'G', MenuCommand::PerGPUConfig }, { L'C', MenuCommand::PerGPUConfigClear }, { L'P', MenuCommand::UEFIConfiguration }, @@ -111,7 +117,8 @@ static auto const gpuMenuShortcuts = map static auto const barSizeMenuShortcuts = map { { L'C', MenuCommand::GPUSelectorClear }, - { L'X', MenuCommand::GPUSelectorExclude } + { L'X', MenuCommand::GPUSelectorExclude }, + { L'O', MenuCommand::OverrideBarSizeMask } }; static wchar_t FindMenuShortcut(map const &menuShortcuts, MenuCommand menuCommand) @@ -140,6 +147,24 @@ static wstring showMainMenuEntry(MenuCommand menuCommand, bool isGlobalEnable, v return wstring(1u, isGlobalEnable ? L'D' : L'E'); + case MenuCommand::SkipS3Resume: + if (config.skipS3Resume()) + wcout << L"\t(" << chShortcut << L") Configure BAR size during resume from S3 (sleep)\n"sv; + else + wcout << L"\t(" << chShortcut << L") Skip BAR size configuration during resume from S3 (sleep)\n"sv; + + return wstring(1u, chShortcut); + + case MenuCommand::OverrideBarSizeMask: + if (config.overrideBarSizeMask()) + wcout << L"\t(" << chShortcut << L") Disable"sv; + else + wcout << L"\t(" << chShortcut << L") Enable"sv; + + wcout << L" override for BAR size mask for PCI ReBAR capability\n"sv; + + return wstring(1u, chShortcut); + case MenuCommand::PerGPUConfig: if (devices | all) { @@ -279,7 +304,7 @@ static wstring showUEFIReBarMenuEntry(MenuCommand menuCommand) return { }; } -static wstring showBarSizeMenuEntry(MenuCommand menuCommand) +static wstring showBarSizeMenuEntry(MenuCommand menuCommand, unsigned short device, vector const &devices, NvStrapsConfig const &config) { auto chShortcut = FindMenuShortcut(barSizeMenuShortcuts, menuCommand); @@ -293,6 +318,21 @@ static wstring showBarSizeMenuEntry(MenuCommand menuCommand) wcout << L"\t("sv << chShortcut << L"): Add exclusion for the GPU from auto-selected configuration.\n"sv; return wstring(1u, chShortcut); + case MenuCommand::OverrideBarSizeMask: + if (isTuringGPU(devices[device].deviceID)) + { + auto &&deviceInfo = devices[device]; + + if (config.lookupBarSizeMaskOverride(deviceInfo.deviceID, deviceInfo.subsystemVendorID, deviceInfo.subsystemDeviceID, deviceInfo.bus, deviceInfo.device, deviceInfo.function).sizeMaskOverride) + wcout << L"\t("sv << chShortcut << L"): Disable"sv; + else + wcout << L"\t("sv << chShortcut << L"): Enable"sv; + + wcout << L" override for BAR size mask for PCIe ReBAR capability\n"sv; + + return wstring(1u, chShortcut); + } + case MenuCommand::GPUVRAMSize: wcout << L"\t 0): 64 MiB\n"sv; wcout << L"\t 1): 128 MiB\n"sv; @@ -371,7 +411,7 @@ static wstring showMenuEntry return showGPUConfigurationMenuEntry(menuCommand, device, devices); case MenuType::GPUBARSize: - return showBarSizeMenuEntry(menuCommand); + return showBarSizeMenuEntry(menuCommand, device, devices, config); case MenuType::PCIBARSize: return showUEFIReBarMenuEntry(menuCommand); @@ -455,11 +495,9 @@ static tuple, unsigned> translateInput(MenuType menuType, if (isNumeric(inputValue)) return { MenuCommand::GPUVRAMSize, stoul(inputValue) }; - if (inputValue | all && toupper(*inputValue.cbegin(), wcin.getloc()) == L'C' && commands.find(L'C') != commands.npos) - return { MenuCommand::GPUSelectorClear, 0u }; - - if (inputValue | all && toupper(*inputValue.cbegin(), wcin.getloc()) == L'X' && commands.find(L'X') != commands.npos) - return { MenuCommand::GPUSelectorExclude, 0u }; + if (inputValue.length() == 1u && hasShortcut(*inputValue.cbegin(), commands)) + if (auto it = barSizeMenuShortcuts.find(toupper(*inputValue.cbegin(), wcin.getloc())); it != barSizeMenuShortcuts.end()) + return { it->second, 0u }; return { nullopt, 0u }; @@ -617,3 +655,39 @@ tuple showMenuPrompt showMenuHeader(menuType, device, devices); return showMenu(menuType, menu, defaultCommand, defaultValue, isGlobalEnable, device, devices, config); } + +bool runConfirmationPrompt(MenuCommand menuCommand) +{ + wstring input; + + switch (menuCommand) + { + case MenuCommand::SkipS3Resume: + wcout << L"WARNING: Only skip S3 Resume if the system does not support S3 sleep or the DXE driver status shows an S3 EFI error !\n"sv; + wcout << L"Skip BAR size configuration during S3 Resume ? (y/N) "sv; + break; + + case MenuCommand::DiscardQuit: + wcout << L"Quit without saving ? (y/N) "sv; + break; + + default: + wcout << L"Confirmation to continue (y/N) "sv; + break; + } + + getline(wcin, input); + + while (input | all && isspace(*input.begin())) + input.erase(input.begin()); + + while (input | all && isspace(*input.rbegin())) + input.resize(input.size() - 1u); + + for (auto &ch: input) + ch = toupper(ch, wcin.getloc()); + + return input | all && L"YES"sv.starts_with(input); +} + +// vim:ft=cpp diff --git a/ReBarState/TextWizardPage.ixx b/ReBarState/TextWizardPage.ixx index bb4ccd5..b56e129 100644 --- a/ReBarState/TextWizardPage.ixx +++ b/ReBarState/TextWizardPage.ixx @@ -128,6 +128,23 @@ static wstring_view formatBarSizeSelector(uint_least8_t barSizeSelector) return L" "sv; } +static wchar_t locationMarker(ConfigPriority location, ConfigPriority barSizePriority, ConfigPriority sizeMaskOverridePriority, bool bridgeMismatch) +{ + if (bridgeMismatch && location == ConfigPriority::EXPLICIT_PCI_LOCATION) + return L'!'; + + if (barSizePriority >= location) + if (sizeMaskOverridePriority >= location) + return L'+'; + else + return L'*'; + else + if (sizeMaskOverridePriority >= location) + return L'\''; + else + return L' '; +} + static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig const &nvStrapsConfig) { #if defined(NDEBUG) @@ -154,10 +171,10 @@ static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig co nMaxNameSize = max(nMaxNameSize, deviceInfo.productName.size()); } - wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+-"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n"sv; - wcout << L"| Nr | PCI ID | subsystem | "sv << left << setw(nMaxLocationSize) << L"Bridge + GPU"sv << L" | "sv << left << setw(nMaxTargetBarSize) << " Target " << L" | "sv << setw(nMaxTargetBarSize) << left << "Current" << L" | "sv << setw(nMaxVRAMSize) << L"VRAM"sv << L" | "sv << setw(nMaxNameSize) << L"Product Name"sv << L" |\n"sv; - wcout << L"| | VID:DID | VID:DID | "sv << setw(nMaxLocationSize) << left << "bus:dev.fn" << L" | "sv << setw(nMaxTargetBarSize) << L"BAR size"sv << L" | "sv << setw(nMaxCurrentBarSize) << L"BAR size"sv << L" | "sv << setw(nMaxVRAMSize) << L"size"sv << L" | "sv << wstring(nMaxNameSize, L' ') << L" |\n"sv; - wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+-"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n"sv; + wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+--"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n"sv; + wcout << L"| Nr | PCI ID | subsystem | "sv << left << setw(nMaxLocationSize) << L"Bridge + GPU"sv << L" | "sv << left << setw(nMaxTargetBarSize) << " Target " << L" | "sv << setw(nMaxTargetBarSize) << left << "Current" << L" | "sv << setw(nMaxVRAMSize) << L"VRAM"sv << L" | "sv << setw(nMaxNameSize) << L"Product Name"sv << L" |\n"sv; + wcout << L"| | VID:DID | VID:DID | "sv << setw(nMaxLocationSize) << left << "bus:dev.fn" << L" | "sv << setw(nMaxTargetBarSize) << L"BAR size"sv << L" | "sv << setw(nMaxCurrentBarSize) << L"BAR size"sv << L" | "sv << setw(nMaxVRAMSize) << L"size"sv << L" | "sv << wstring(nMaxNameSize, L' ') << L" |\n"sv; + wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+--"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n"sv; for (auto const &&[deviceIndex, deviceInfo]: deviceSet | views::enumerate) { @@ -173,6 +190,16 @@ static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig co deviceInfo.function ); + auto [sizeMaskOverridePriority, sizeMaskOverride] = nvStrapsConfig.lookupBarSizeMaskOverride + ( + deviceInfo.deviceID, + deviceInfo.subsystemVendorID, + deviceInfo.subsystemDeviceID, + deviceInfo.bus, + deviceInfo.device, + deviceInfo.function + ); + auto bridgeMismatch = bool { !!configPriority && barSizeSelector < BarSizeSelector_Excluded @@ -184,20 +211,22 @@ static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig co ) }; + wchar_t marker; + // GPU number wcout << L"| "sv << dec << right << setw(2u) << setfill(L' ') << deviceIndex + 1u; // PCI ID - wcout << L" | "sv << (configPriority < ConfigPriority::EXPLICIT_PCI_ID ? L' ' : L'*') << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.vendorID << L':' << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << deviceInfo.deviceID; + wcout << L" | "sv << locationMarker(ConfigPriority::EXPLICIT_PCI_ID, configPriority, sizeMaskOverridePriority, bridgeMismatch) << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.vendorID << L':' << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << deviceInfo.deviceID; // PCI subsystem ID - wcout << L" | "sv << (configPriority < ConfigPriority::EXPLICIT_SUBSYSTEM_ID ? L' ' : L'*') << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.subsystemVendorID << L':' << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.subsystemDeviceID; + wcout << L" | "sv << locationMarker(ConfigPriority::EXPLICIT_SUBSYSTEM_ID, configPriority, sizeMaskOverridePriority, bridgeMismatch) << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.subsystemVendorID << L':' << hex << setw(WORD_SIZE * 2u) << setfill(L'0') << uppercase << deviceInfo.subsystemDeviceID; // PCI bus location - wcout << L" | "sv << (bridgeMismatch ? L'!' : configPriority < ConfigPriority::EXPLICIT_PCI_LOCATION ? L' ' : L'*') << right << setw(nMaxLocationSize) << setfill(L' ') << left << formatLocation(deviceInfo); + wcout << L" | "sv << locationMarker(ConfigPriority::EXPLICIT_PCI_LOCATION, configPriority, sizeMaskOverridePriority, bridgeMismatch) << right << setw(nMaxLocationSize) << setfill(L' ') << left << formatLocation(deviceInfo); // Target BAR1 size - wcout << L" | "sv << dec << setw(nMaxTargetBarSize) << right << setfill(L' ') << formatBarSizeSelector(barSizeSelector); + wcout << L" | "sv << (sizeMaskOverride ? isTuringGPU(deviceInfo.deviceID) ? L'\'' : L' ' : L' ') << dec << setw(nMaxTargetBarSize) << right << setfill(L' ') << formatBarSizeSelector(barSizeSelector); // Current BAR size wcout << L" | "sv << dec << setw(nMaxCurrentBarSize) << right << setfill(L' ') << formatDirectBARSize(deviceInfo.currentBARSize); @@ -211,7 +240,7 @@ static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig co wcout << L" |\n"sv; } - wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+-"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n\n"sv; + wcout << L"+----+------------+------------+--"sv << wstring(nMaxLocationSize, L'-') << L"-+--"sv << wstring(nMaxTargetBarSize, L'-') << L"-+-"sv << wstring(nMaxCurrentBarSize, L'-') << L"-+-"sv << wstring(nMaxVRAMSize, L'-') << L"-+-"sv << wstring(nMaxNameSize, L'-') << L"-+\n\n"sv; } static wstring_view driverStatusString(uint_least64_t driverStatus) @@ -257,15 +286,15 @@ static wstring_view driverStatusString(uint_least64_t driverStatus) case StatusVar_GpuStrapsNoConfirm: return L"GPU-side ReBAR Configured without PCI confirm"sv; + case StatusVar_GpuReBarSizeOverride: + return L"GPU-side ReABR Configured with PCI ReBAR size override"sv; + case StatusVar_GpuNoReBarCapability: return L"ReBAR capability not advertised"sv; case StatusVar_GpuExcluded: return L"GPU excluded"sv; - case StatusVar_BootScriptWritten: - return L"Boot script written"sv; - case StatusVar_NoBridgeConfig: return L"Missing bridge configuration"sv; @@ -385,6 +414,9 @@ static void showDriverStatus(uint_least64_t driverStatus) wcout << L"UEFI DXE driver status: "sv << driverStatusString(status) << (status == StatusVar_Internal_EFIError ? driverErrorString(static_cast(driverStatus >> (DWORD_BITSIZE + BYTE_BITSIZE) & BYTE_BITMASK)) : L""sv) << L" (0x"sv << hex << right << setfill(L'0') << setw(QWORD_SIZE * 2u) << driverStatus << dec << setfill(L' ') << L")\n"sv; + + if (status == StatusVar_GpuStrapsNoConfirm) + wcout << L"(use Overide BAR Size Mask option)\n"sv; } static wstring formatPciBarSize(unsigned sizeSelector)