├── .clangd ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── bug-report.md └── workflows │ ├── ReBarDxe.yml │ ├── ReBarState.yml │ ├── buildffs.bat │ └── buildffs.sh ├── .gitignore ├── LICENSE ├── README.md ├── ReBarDxe ├── CheckSetupVar.c ├── DeviceRegistry.c ├── EfiVariable.c ├── NvStrapsConfig.c ├── PciConfig.c ├── ReBar.c ├── ReBar.dsc ├── ReBarDxe.inf ├── S3ResumeScript.c ├── SetupNvStraps.c ├── StatusVar.c ├── buildffs.py └── include │ ├── CheckSetupVar.h │ ├── DeviceRegistry.h │ ├── EfiVariable.h │ ├── LocalAppConfig.h │ ├── NvStrapsConfig.h │ ├── PciConfig.h │ ├── ReBar.h │ ├── S3ResumeScript.h │ ├── SetupNvStraps.h │ ├── StatusVar.h │ └── pciRegs.h ├── ReBarState ├── CMakeLists.txt ├── ConfigManagerError.ixx ├── ConfigurationWizard.ixx ├── DeviceList.ixx ├── DeviceRegistry.ixx ├── LocalAppConfig.ixx ├── NvStrapsConfig.hh ├── NvStrapsConfig.ixx ├── NvStrapsDXGI.ixx ├── NvStrapsWinAPI.ixx ├── ReBarState.cc ├── StatusVar.ixx ├── TextWizardMenu.ixx ├── TextWizardPage.ixx ├── WinApiError.ixx ├── cmake │ ├── CxxStdModule.cmake │ └── LocalModulePath.cmake ├── compile_commands.template.json ├── cxx_std_lib.hh ├── cxx_std_lib.modulemap └── test │ ├── CMakeLists.txt │ └── TestNvStrapsConfig.cc ├── UEFIPatch ├── BdwUSB3.txt ├── HswUSB3.txt ├── IvyUSB3.txt └── patches.txt ├── compile_commands.template.json ├── rebar.png └── tools └── uuidconv.py /.clangd: -------------------------------------------------------------------------------- 1 | Diagnostics: 2 | Suppress: unused-includes 3 | Suppress: pch-langopt-mismatch 4 | Suppress: pch_langopt_mismatch 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | root=true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_size=4 7 | tab_width=8 8 | intent_style="tab" 9 | trim_trailling_whitespace="true" 10 | insert_final_newline="true" 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve RebarUEFI 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **System** 11 | - Motherboard: 12 | - BIOS Version: 13 | - GPU: 14 | - [ ] CSM is turned off. **Make sure to confirm this in the BIOS and not with GPU-Z or similar since it can be inaccurate** 15 | - [ ] 4G decoding is enabled. **Make sure to confirm this in the BIOS and not with GPU-Z or similar since it can be inaccurate** 16 | - [ ] UEFIPatch is applied (see [Using UEFIPatch](https://github.com/xCuri0/ReBarUEFI/wiki/Using-UEFIPatch) for more information). On some motherboards [DSDT Patching](https://github.com/xCuri0/ReBarUEFI/wiki/DSDT-Patching) is also needed 17 | - [ ] I have read [Common issues (and fixes)](https://github.com/xCuri0/ReBarUEFI/wiki/Common-issues-(and-fixes)) 18 | 19 | **Description** 20 | 21 | Describe the issue here. 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/ReBarDxe.yml: -------------------------------------------------------------------------------- 1 | name: ReBarDxe EDK2 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | env: 9 | TARGET: RELEASE 10 | TARGET_ARCH: X64 11 | 12 | jobs: 13 | rebardxe-windows: 14 | runs-on: windows-2019 15 | 16 | env: 17 | TOOL_CHAIN_TAG: VS2019 18 | 19 | steps: 20 | - uses: actions/setup-python@v4.3.0 21 | - run: pip install pefile 22 | 23 | - name: Support long filenames 24 | run: git config --system core.longpaths true 25 | 26 | # save nasm 27 | - name: cache nasm 28 | id: cache-nasm 29 | uses: actions/cache@v3 30 | with: 31 | path: C:\nasm 32 | key: nasm-path 33 | 34 | # edk2's setup script checks for nasm only at 'C:\nasm' so install it there 35 | - name: install nasm 36 | if: steps.cache-nasm.outputs.cache-hit != 'true' 37 | shell: powershell 38 | run: | 39 | md C:\nasm 40 | Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win64/nasm-2.15.05-win64.zip" -OutFile "C:\nasm\nasm.zip" 41 | cd C:\nasm 42 | 7z e nasm.zip 43 | 44 | - name: Download edk2 45 | uses: actions/checkout@v3 46 | with: 47 | repository: 'tianocore/edk2' 48 | ref: 'edk2-stable202208' 49 | submodules: 'recursive' 50 | 51 | - name: Download RebarUEFI 52 | uses: actions/checkout@v3 53 | with: 54 | path: '.\ReBarUEFI\' 55 | 56 | - name: Setup EDK2 57 | run: .\edksetup.bat Rebuild 58 | 59 | - name: Build RebarDxe 60 | run: .\ReBarUEFI\.github\workflows\buildffs.bat 61 | 62 | - name: Upload ReBarDxe artifact 63 | uses: actions/upload-artifact@master 64 | with: 65 | name: ReBarDxe (built on Windows) 66 | path: ${{github.workspace}}/Build/ReBarUEFI/RELEASE_VS2019/X64/ReBarDxe.ffs 67 | 68 | 69 | rebardxe-linux: 70 | runs-on: ubuntu-22.04 71 | 72 | env: 73 | TOOL_CHAIN_TAG: GCC5 74 | 75 | steps: 76 | - uses: actions/setup-python@v4.3.0 77 | - run: pip install pefile 78 | 79 | - name: Download edk2 80 | uses: actions/checkout@v3 81 | with: 82 | repository: 'tianocore/edk2' 83 | ref: 'edk2-stable202208' 84 | submodules: 'recursive' 85 | path: '.' 86 | 87 | - name: Download RebarUEFI 88 | uses: actions/checkout@v3 89 | with: 90 | path: './ReBarUEFI/' 91 | 92 | - name: Install dependencies 93 | run: sudo apt install build-essential uuid-dev iasl git nasm python-is-python3 94 | 95 | - name: Build Base Tools 96 | run: make -C ./BaseTools/ 97 | 98 | - name: Setup EDK2 99 | run: bash -c "source edksetup.sh" 100 | 101 | - name: Build RebarDxe 102 | run: ./ReBarUEFI/.github/workflows/buildffs.sh 103 | 104 | - name: Upload ReBarDxe artifact 105 | uses: actions/upload-artifact@master 106 | with: 107 | name: ReBarDxe (built on Linux) 108 | path: ${{github.workspace}}/Build/ReBarUEFI/RELEASE_GCC5/X64/ReBarDxe.ffs 109 | -------------------------------------------------------------------------------- /.github/workflows/ReBarState.yml: -------------------------------------------------------------------------------- 1 | name: ReBarState CMake 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 | BUILD_TYPE: Release 12 | 13 | jobs: 14 | rebarstate-ubuntu: 15 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 16 | # You can convert this to a matrix build if you need cross-platform coverage. 17 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - name: Configure CMake 24 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 25 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 26 | working-directory: ./ReBarState 27 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 28 | 29 | - name: Build 30 | # Build your program with the given configuration 31 | working-directory: ./ReBarState 32 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 33 | 34 | - name: Upload Ubuntu artifact 35 | uses: actions/upload-artifact@master 36 | with: 37 | name: ReBarState Linux 38 | path: ${{github.workspace}}/build/ReBarState 39 | 40 | rebarstate-windows: 41 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 42 | # You can convert this to a matrix build if you need cross-platform coverage. 43 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 44 | runs-on: windows-latest 45 | 46 | steps: 47 | - uses: actions/checkout@v3 48 | 49 | - name: Configure CMake 50 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 51 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 52 | working-directory: ./ReBarState 53 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 54 | 55 | - name: Build 56 | # Build your program with the given configuration 57 | working-directory: ./ReBarState 58 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 59 | 60 | - name: Upload Windows artifact 61 | uses: actions/upload-artifact@master 62 | with: 63 | name: ReBarState Windows 64 | path: ${{github.workspace}}/build/Release/ReBarState.exe 65 | 66 | -------------------------------------------------------------------------------- /.github/workflows/buildffs.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | .\edksetup.bat && python .\ReBarUEFI\ReBarDxe\buildffs.py RELEASE B -------------------------------------------------------------------------------- /.github/workflows/buildffs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source ./edksetup.sh 3 | python ./ReBarUEFI/ReBarDxe/buildffs.py RELEASE B 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | .vscode/ 3 | !.vscode/settings.json 4 | !.vscode/tasks.json 5 | !.vscode/launch.json 6 | !.vscode/extensions.json 7 | !.vscode/*.code-snippets 8 | 9 | # Local History for Visual Studio Code 10 | .history/ 11 | 12 | # Built Visual Studio Code Extensions 13 | *.vsix 14 | 15 | uefimount/ 16 | vc140.pdb 17 | NvVars 18 | *.efi 19 | *.iso 20 | *.log 21 | .cache/ 22 | .tags/ 23 | tags 24 | .cscope/ 25 | cscope.out 26 | cscope.out.* 27 | out/ 28 | build/ 29 | build-*/ 30 | compile_commands.json 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Timothy Madden (@terminatorul) 4 | Copyright (c) 2022-2023 xCuri0 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

NvStrapsReBar

2 |

UEFI driver to enable and test Resizable BAR on Turing graphics cards (GTX 1600, RTX 2000).

3 |

This is a copy of the rather popular ReBarUEFI DXE driver. ReBarUEFI enables Resizable BAR for older motherboards and chipsets without ReBAR support from the manufacturer. NvStrapsReBar was created to test Resizable BAR support for GPUs from the RTX 2000 (and GTX 1600, Turing architecture) line. For the GTX 1000 cards (Pascal architecture) and older the tool can also enable a large BAR on the PCI bus, but it is fixed size and not resizable, so it is not the same as ReBAR. But then the NVIDIA driver for Windows shows a blue screen or resets the computer during boot if the BAR size has been changed. So GTX 1000 cards still can not enable ReBAR. The proprietary Linux driver does not crash, but does not pick up the new BAR size either (NVIDIA, could you please help fixing the Pascal driver ?)

4 | 5 | ### Do I need to flash a new UEFI image on the motherboard, to enable ReBAR on the GPU ? 6 | Yes, this is how it works for Turing GPUs (GTX 1600 / RTX 2000). 7 | 9 | 10 | It's ususally the video BIOS (vBIOS) that should enable ReBAR, but the vBIOS is digitally signed (NVIDIA vBIOS is also encrypted) and can not be modified by modders and end-users (is locked-down). The motherboard UEFI image can also be signed or have integrity checks, but in general it is thankfully not as locked down, and users and UEFI modders often still have a way to modify it. 11 | 12 | For older boards without ReBAR, adding ReBAR functionality depends on the Above 4G Decoding option in your UEFI setup, which must be turned on in advance, and CSM must be disabled. 13 | 14 | ### Usage 15 | Download latest release from the [Releases](https://github.com/terminatorul/NvStrapsReBar/releases) page, or build the project using the [build](https://github.com/terminatorul/NvStrapsReBar/wiki/Building-(Windows-only)) instructions. This should produce two files: 16 | * `NvStrapsReBar.ffs` UEFI DXE driver 17 | * `NvStrapsReBar.exe` Windows executable 18 | 19 | After download or build you need to go through the following steps: 20 | * update the motherbord UEFI image to add the new `NvStrapsReBar.ffs` driver (see below) 21 | * enable ReBAR in UEFI Setup if the motherboard supports it. Otherwise enable "Above 4G Decoding" and disable CSM 22 | * run `NvStrapsReBar.exe` as Administrator to enable the new BAR size, by following the text-mode menus. If you have a recent motherboard, you only need to input `E` to Enable ReBAR for Turing GPUs, then input `S` to save the new driver configuration to EFI variable. For older motherboards without ReBAR, you also need to input `P` and set BAR size on the PCI side (motherboard side). 23 | * reboot after saving the menu options. 24 | * if you make changes in UEFI Setup, `NvStrapsReBar` will be disabled automatically and you need to re-enable it. Same if you manually set back the current year in UEFI Setup (can be used to disable NvStrapsReBar without booting to Windows). 25 | * if you make hardware changes like adding or changing a GPU: you have to disable ReBAR first. The reason is NvStrapsReBar depends on the GPU BAR0 address to enable ReBAR, and system firmware changes the allocated address for BAR0 when hardware is changed or settings in UEFI Setup are changed. 26 | 27 | ### Warning 28 | * Disable NvStrapsReBar before making hardware changes like adding a second GPU. 29 | * NvStrapsReBar will be disabled automatically if you make changes in UEFI Setup. Re-enable it afterwards. 30 | 31 | ![image](https://github.com/terminatorul/NvStrapsReBar/assets/378924/21da2dc9-82be-4ac6-8e60-2f61bd619f0a) 32 | 33 | 34 | Credits go to the bellow github users, as I integrated and coded their findings and results: 35 | * [envytools](https://github.com/envytools/envytools) project for the original effort on reverse-engineering the register interface for the GPUs, a very long time ago, for use by the [nouveau](https://nouveau.freedesktop.org/) open-source driver in Linux. Amazing how this old documentation could still help us today ! 36 | * [@mupuf](https://github.com/mupuf) from [envytools](https://github.com/envytools/envytools) project for bringing up the idea and the exact (low level) registers from the documentation, that enable resizable BAR 37 | * [@Xelafic](https://github.com/Xelafic) for the first code samples (written in assembly!) and the first test for using the GPU STRAPS bits, documented by envytools, to select the BAR size during PCIe bring-up in UEFI code. 38 | * [@xCuri0](https://github.com/xCuri0/ReBARUEFI") for great support and for the ReBarUEFI DXE driver that enables ReBAR on the motherboard side, and allows intercepting and hooking into the PCIe enumeration phases in UEFI code on the motherboard. 39 | 40 | ## Working GPUs 41 | Check issue https://github.com/terminatorul/NvStrapsReBar/issues/1 for a list of known working GPUs (and motherboards). 42 | 62 | 63 | ## Updating UEFI image 64 | 65 | You can download the latest release of NvStrapsReBar from the [Releases](https://github.com/terminatorul/NvStrapsReBar/releases) page, or build the UEFI DXE driver and the Windows executable using the instructions on the [building](https://github.com/terminatorul/NvStrapsReBar/wiki/Building-(Windows-only)) page. 66 | 67 | The resulting `NvStrapsReBar.ffs` file needs to be included in the motherboard UEFI image (downloaded from the montherboard manufacturer, usually under "BIOS update"), and the resulting image should be flashed onto the motherboard as if it were a new firmware version for that board. 68 | See the original project [ReBarUEFI](https://github.com/xCuri0/ReBarUEFI/) for the instructions to update motherboard UEFI. Replace "ReBarUEFI.ffs" with "NvStrapsReBar.ffs" where appropriate. 69 | 70 |

So you will still have to check the README page from the original project:

for all the details and instructions on working with the UEFI image, and patching it if necessary (for older motherboards and chipsets).

71 | 72 | ## Enable ReBAR and choose BAR size 73 | After flashing the motherboard with the new UEFI image, you need to enable ReBAR in UEFI Setup. For older motherboards without ReBAR, enable "Above 4G Decoding" and disable CSM. Then you need to run `NvStrapsReBar.exe` as Administrator. 74 | 75 | `NvStrapsReBar.exe` prompts you with a small text-based menu. You can configure 2 values for the BAR size with this tool: 76 | * GPU-side BAR size 77 | * PCI BAR size (for older motherboards without ReBAR) 78 | 79 | Newer boards with ReBAR support from the manufacturer can auto-configure PCI BAR size, so you only need to set the GPU-side value for the BAR size. If not, you should try and experiment with both of them, as needed. 80 | 81 | ### Warning 82 | * Disable NvStrapsReBar before making hardware changes like adding a second GPU. 83 | * NvStrapsReBar will be disabled automatically if you make changes in UEFI Setup. Re-enable it afterwards. 84 | 85 | ![image](https://github.com/terminatorul/NvStrapsReBar/assets/378924/a960adff-665f-4fbb-92ba-a8a4114996ca) 86 | 87 | 88 | Most people should choose the first menu option and press `E` to Enable auto-settings BAR size for Turing GPUs. Depending on your board, you may need to also input `P` at the menu prompt, to choose Target PCI BAR size, and select value 64 (for the option to configure PCI BAR for selected GPUs only). Before quitting the menu, input `S` to save the changes you made to the EFI variable store, for the UEFI DXE driver to read them. 89 | 90 | If you choose a GPU BAR size of 8 GiB for example, and a Target PCI BAR size of 4 GiB, you will get a 4 GiB BAR. 91 | 92 | For older boards without ReBAR support from the manufacturer, you can select other values for Target PCI BAR size, to also configure other GPUs for example. Or to limit the BAR size to smaller values even if the GPU supports higher values. Depending on the motherboard UEFI, for some boards you may need to use lower values, to limit BAR size to 4 GB or 2GB for example. Even a 2 GB BAR size still gives you the benefits of Resizable BAR in most titles, and NVIDIA tends to use 1.5 GB as the default size in the Profile Inspector. There are exceptions to this 'though (for some titles that can still see improvements with the higher BAR sizes). 93 | 94 | If later you want to make further changes in UEFI Setup, or hardware changes like adding a new GPU, you have to disable NvStrapsReBar first. Because NvStrapsReBar depends on the GPU BAR0 address allocated by system firmware, and that changes with UEFI Setup changes or with hardware changes. 95 | 96 | ## Using large BAR sizes 97 | Remember you need to use the [Profile Inspector](https://github.com/Orbmu2k/nvidiaProfileInspector) because it enables ReBAR per-application, and that overrides the global value reported by the PCI bus. There appears to be a fake site for the Profile Inspector, so always downloaded it from github, or use the link above. 98 | -------------------------------------------------------------------------------- /ReBarDxe/CheckSetupVar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "LocalAppConfig.h" 8 | #include "EfiVariable.h" 9 | #include "NvStrapsConfig.h" 10 | #include "StatusVar.h" 11 | #include "CheckSetupVar.h" 12 | 13 | static CHAR16 const SETUP_VAR_NAME[] = L"Setup"; 14 | static CHAR16 const CUSTOM_VAR_NAME[] = L"Custom"; 15 | 16 | static uint_least64_t const ECMA_128_CRC_POLY = UINT64_C(0xC96C'5795'D787'0F42); 17 | 18 | static uint_least64_t ecma128_crc64(BYTE const *buffer, BYTE const *bufferEnd, uint_least64_t crcValue) 19 | { 20 | crcValue = ~crcValue & (uint_least64_t)UINT64_C(0xFFFF'FFFF'FFFF'FFFF); 21 | 22 | while (buffer != bufferEnd) 23 | { 24 | crcValue ^= unpack_QWORD(buffer), buffer += QWORD_SIZE; 25 | 26 | for (unsigned char bitIndex = 0u; bitIndex < QWORD_BITSIZE; bitIndex++) 27 | if (crcValue & UINT64_C(1) << (QWORD_BITSIZE - 1u)) 28 | crcValue <<= 1u, crcValue ^= ECMA_128_CRC_POLY; 29 | else 30 | crcValue <<= 1u; 31 | } 32 | 33 | return ~crcValue & (uint_least64_t)UINT64_C(0xFFFF'FFFF'FFFF'FFFF); 34 | } 35 | 36 | static BYTE *LoadSetupVariable(CHAR16 const *name, EFI_GUID *guid, UINTN *dataLength) 37 | { 38 | UINT32 attributes = 0u; 39 | *dataLength = 0u; 40 | BYTE *data = NULL; 41 | 42 | EFI_STATUS status = gRT->GetVariable((CHAR16 *)name, guid, &attributes, dataLength, NULL); 43 | 44 | if (status != EFI_BUFFER_TOO_SMALL) 45 | { 46 | SetEFIError(EFIError_ReadSetupVarSize, status); 47 | return NULL; 48 | } 49 | 50 | uint_least8_t paddingLength = 8u - *dataLength & 0b0000'0111u; 51 | 52 | status = gBS->AllocatePool(EfiBootServicesData, *dataLength + paddingLength, (VOID **)&data); 53 | 54 | if (EFI_ERROR(status)) 55 | { 56 | SetEFIError(EFIError_AllocateSetupVarData, status); 57 | 58 | return NULL; 59 | } 60 | 61 | for (unsigned i = 0u; i < paddingLength; i++) 62 | data[*dataLength + i] = paddingLength; 63 | 64 | status = gRT->GetVariable((CHAR16 *)name, guid, &attributes, dataLength, data); 65 | 66 | if (EFI_ERROR(status)) 67 | { 68 | gBS->FreePool(data), data = NULL; 69 | SetEFIError(EFIError_ReadSetupVar, status); 70 | 71 | return NULL; 72 | } 73 | 74 | if ( (attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)) != (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) 75 | || (attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)) 76 | { 77 | gBS->FreePool(data), data = NULL; 78 | SetStatusVar(StatusVar_BadSetupVarAttributes); 79 | 80 | return NULL; 81 | } 82 | 83 | *dataLength += paddingLength; 84 | 85 | return data; 86 | } 87 | 88 | static bool FreeSetupVariable(BYTE *data) 89 | { 90 | if (data) 91 | { 92 | EFI_STATUS status = gBS->FreePool(data); 93 | 94 | if (EFI_ERROR(status)) 95 | { 96 | SetEFIError(EFIError_AllocateSetupVarData, status); 97 | 98 | return false; 99 | } 100 | } 101 | 102 | return true; 103 | } 104 | 105 | static void LStringCopy(CHAR16 *newVarName, CHAR16 const *varName, size_t len) 106 | { 107 | CHAR16 const *varNameLimit = varName + len; 108 | 109 | while (varName < varNameLimit) 110 | *newVarName++ = *varName++; 111 | 112 | *newVarName = L'\0'; 113 | } 114 | 115 | static UINTN LStringLength(CHAR16 const *str, UINTN stringCapacity) 116 | { 117 | if (stringCapacity) 118 | { 119 | CHAR16 const *ptr = str, *endPtr = str + stringCapacity - 1u; 120 | 121 | while (ptr != endPtr && *ptr) 122 | ptr++; 123 | 124 | return *ptr ? 0u : ptr - str; 125 | } 126 | 127 | return 0u; 128 | } 129 | 130 | typedef struct UefiString 131 | { 132 | CHAR16 *ptr; 133 | UINTN capacity; 134 | UINTN length; 135 | } 136 | UefiString; 137 | 138 | static bool AllocateUefiString(UefiString *str, size_t stringCapacity) 139 | { 140 | EFI_STATUS status = gBS->AllocatePool(EfiBootServicesData, stringCapacity * sizeof *str->ptr, (VOID **)&str->ptr); 141 | 142 | if (EFI_ERROR(status)) 143 | { 144 | SetEFIError(EFIError_AllocateSetupVarName, status); 145 | return false; 146 | } 147 | 148 | str->capacity = stringCapacity; 149 | str->length = 0u; 150 | str->ptr[0u] = L'\0'; 151 | 152 | return true; 153 | } 154 | 155 | static bool DeallocateUefiString(UefiString *str) 156 | { 157 | if (str->ptr) 158 | { 159 | EFI_STATUS status = gBS->FreePool(str->ptr); 160 | 161 | if (EFI_ERROR(status)) 162 | { 163 | SetEFIError(EFIError_AllocateSetupVarName, status); 164 | return false; 165 | } 166 | else 167 | { 168 | str->length = 0u; 169 | str->capacity = 0u; 170 | str->ptr = NULL; 171 | } 172 | } 173 | 174 | return true; 175 | } 176 | 177 | static bool ReallocateUefiString(UefiString *str, size_t stringCapacity) 178 | { 179 | CHAR16 *newStr = NULL; 180 | EFI_STATUS status = gBS->AllocatePool(EfiBootServicesData, stringCapacity * sizeof *newStr, (VOID **)&newStr); 181 | 182 | if (EFI_ERROR(status)) 183 | { 184 | SetEFIError(EFIError_AllocateSetupVarName, status); 185 | return false; 186 | } 187 | 188 | UINTN length = str->length < stringCapacity ? str->length : stringCapacity ? stringCapacity - 1u : 0u; 189 | 190 | LStringCopy(newStr, str->ptr, str->length); 191 | 192 | if (DeallocateUefiString(str)) 193 | { 194 | str->ptr = newStr; 195 | str->capacity = stringCapacity; 196 | str->length = length; 197 | 198 | return true; 199 | } 200 | else 201 | gBS->FreePool(newStr); 202 | 203 | return false; 204 | } 205 | 206 | static char CompareUefiString(UefiString *str, CHAR16 const *val) 207 | { 208 | CHAR16 const *ptr = str->ptr; 209 | 210 | while (*ptr && *ptr == *val) 211 | ptr++, val++; 212 | 213 | return *ptr < *val ? -1 : *ptr == *val ? 0 : 1; 214 | } 215 | 216 | static bool NextUefiVariableName(UefiString *str, EFI_GUID *efiGUID) 217 | { 218 | UINTN length = str->capacity; 219 | EFI_STATUS status = gRT->GetNextVariableName(&length, str->ptr, efiGUID); 220 | 221 | if (EFI_ERROR(status) && status == EFI_BUFFER_TOO_SMALL) 222 | if (ReallocateUefiString(str, ++length)) 223 | status = gRT->GetNextVariableName(&length, str->ptr, efiGUID); 224 | else 225 | return false; 226 | 227 | if (EFI_ERROR(status)) 228 | if (status == EFI_NOT_FOUND) 229 | length = 0u; 230 | else 231 | { 232 | SetEFIError(EFIError_EnumVar, status); 233 | return false; 234 | } 235 | 236 | str->length = LStringLength(str->ptr, str->capacity); 237 | 238 | return true; 239 | } 240 | 241 | static CHAR16 const *FindSetupVariable(EFI_GUID *efiGUID) 242 | { 243 | enum SetupVarName 244 | { 245 | SetupVar_None, 246 | SetupVar_Custom, 247 | SetupVar_Setup 248 | } 249 | setupVarName = SetupVar_None; 250 | 251 | bool multipleCustomVariables = false; 252 | 253 | UefiString varName = { .ptr = NULL, .capacity = 0u, .length = 0u }; 254 | EFI_GUID varGuid = { }; 255 | 256 | if (!AllocateUefiString(&varName, 64u)) 257 | return NULL; 258 | 259 | bool enumerationCompleted = false; 260 | 261 | while (NextUefiVariableName(&varName, efiGUID)) 262 | { 263 | if (varName.length) 264 | { 265 | if (varName.length == ARRAY_SIZE(CUSTOM_VAR_NAME) - 1u && CompareUefiString(&varName, CUSTOM_VAR_NAME) == 0) 266 | if (setupVarName < SetupVar_Custom) 267 | { 268 | setupVarName = SetupVar_Custom; 269 | varGuid = *efiGUID; 270 | } 271 | else 272 | if (setupVarName == SetupVar_Custom) 273 | multipleCustomVariables = true; // "Custom" variable found twice 274 | else 275 | ; // "Setup" variable has precedence over "Custom" 276 | else 277 | if (varName.length == ARRAY_SIZE(SETUP_VAR_NAME) - 1u && CompareUefiString(&varName, SETUP_VAR_NAME) == 0) 278 | { 279 | UINTN varSize = 0u; 280 | 281 | EFI_STATUS status = gRT->GetVariable(varName.ptr, efiGUID, NULL, &varSize, NULL); 282 | 283 | if (status != EFI_BUFFER_TOO_SMALL) 284 | { 285 | SetEFIError(EFIError_EnumSetupVarSize, status); 286 | return NULL; 287 | } 288 | 289 | if (varSize >= 16u /* && !!(attributes & EFI_VARIABLE_NON_VOLATILE) && !!(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) */) 290 | if (setupVarName < SetupVar_Setup) 291 | { 292 | setupVarName = SetupVar_Setup; 293 | varGuid = *efiGUID; 294 | } 295 | else 296 | { 297 | // "Setup" variable found twice 298 | setupVarName = SetupVar_None; 299 | multipleCustomVariables = true; 300 | enumerationCompleted = true; 301 | break; 302 | } 303 | } 304 | } 305 | else 306 | { 307 | enumerationCompleted = true; 308 | break; 309 | } 310 | } 311 | 312 | if (DeallocateUefiString(&varName)) 313 | { 314 | if (enumerationCompleted) 315 | switch (setupVarName) 316 | { 317 | case SetupVar_Custom: 318 | if (multipleCustomVariables) 319 | { 320 | SetStatusVar(StatusVar_AmbiguousSetupVariable); 321 | return NULL; 322 | } 323 | 324 | *efiGUID = varGuid; 325 | return CUSTOM_VAR_NAME; 326 | 327 | case SetupVar_Setup: 328 | *efiGUID = varGuid; 329 | return SETUP_VAR_NAME; 330 | 331 | default: 332 | SetStatusVar(multipleCustomVariables ? StatusVar_AmbiguousSetupVariable : StatusVar_MissingSetupVariable); 333 | return NULL; 334 | } 335 | } 336 | 337 | return NULL; 338 | } 339 | 340 | bool IsSetupVariableChanged() 341 | { 342 | ERROR_CODE errorCode; 343 | NvStrapsConfig *config = GetNvStrapsConfig(false, &errorCode); 344 | 345 | if (errorCode) 346 | return true; 347 | 348 | EFI_GUID setupVarGuid = { .Data1 = 0u, .Data2 = 0u, .Data3 = 0u, }; 349 | CHAR16 const *varName = FindSetupVariable(&setupVarGuid); 350 | 351 | if (!varName) 352 | return true; 353 | 354 | UINTN length; 355 | BYTE *data = LoadSetupVariable(varName, &setupVarGuid, &length); 356 | 357 | if (!data) 358 | return true; 359 | 360 | uint_least64_t crc64 = ecma128_crc64(data, data + length, 0u); 361 | 362 | if (FreeSetupVariable(data)) 363 | { 364 | data = NULL; 365 | 366 | if (NvStrapsConfig_HasSetupVarCRC(config)) 367 | return NvStrapsConfig_SetupVarCRC(config) != crc64; 368 | 369 | NvStrapsConfig_SetSetupVarCRC(config, crc64); 370 | NvStrapsConfig_SetHasSetupVarCRC(config, true); 371 | 372 | SaveNvStrapsConfig(&errorCode); 373 | 374 | if (EFI_ERROR(errorCode)) 375 | SetEFIError(EFIError_WriteConfigVar, errorCode); 376 | 377 | return false; 378 | } 379 | 380 | return true; 381 | } 382 | 383 | // vim:ft=cpp 384 | -------------------------------------------------------------------------------- /ReBarDxe/DeviceRegistry.c: -------------------------------------------------------------------------------- 1 | #if !defined(UEFI_SOURCE) && !defined(EFIAPI) 2 | # if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 3 | # if defined(_M_AMD64) && !defined(_AMD64_) 4 | # define _AMD64_ 5 | # endif 6 | # endif 7 | #else 8 | # include 9 | #endif 10 | 11 | #include 12 | #include 13 | 14 | #include "LocalAppConfig.h" 15 | #include "DeviceRegistry.h" 16 | 17 | typedef struct IDRange 18 | { 19 | UINT16 first; 20 | UINT16 last; 21 | } 22 | IDRange; 23 | 24 | // See envytools documentation at: 25 | // https://envytools.readthedocs.io/en/latest/hw/pciid.html#introduction 26 | static IDRange const 27 | PCI_ID_RANGE_TU102 = { .first = 0x1E00u, .last = 0x1E7Fu }, 28 | PCI_ID_RANGE_TU104 = { .first = 0x1E80u, .last = 0x1EFFu }, 29 | PCI_ID_RANGE_TU106 = { .first = 0x1F00u, .last = 0x1F7Fu }, 30 | PCI_ID_RANGE_TU116 = { .first = 0x2180u, .last = 0x21FFu }, 31 | PCI_ID_RANGE_TU117 = { .first = 0x1F80u, .last = 0x1FFFu }; 32 | 33 | // See: 34 | // - https://admin.pci-ids.ucw.cz/read/PC/10de 35 | // - https://www.techpowerup.com/gpu-specs/?architecture=Turing&sort=name 36 | // 37 | static UINT16 Turing_Device_List_Skip[] = 38 | { 39 | // Tesla GPUs have some virtual memory with large BARs 40 | // Some Quadro GPUs already have resizable BAR 41 | 42 | UINT16_C(0x1E30), // TU102GL [Quadro RTX 6000/8000] 24GB / 48GB 43 | UINT16_C(0x1E36), // TU102GL [Quadro RTX 6000] 24GB 44 | UINT16_C(0x1E37), // TU102GL [Tesla T10 16GB / GRID RTX T10-2/T10-4/T10-8] 45 | UINT16_C(0x1E38), // TU102GL [Tesla T40 24GB] 46 | UINT16_C(0x1E3C), // TU102GL 47 | UINT16_C(0x1E3D), // TU102GL 48 | UINT16_C(0x1E3E), // TU102GL 49 | UINT16_C(0x1E78), // TU102GL [Quadro RTX 6000/8000] 24GB / 48GB 50 | 51 | UINT16_C(0x1EB9), // TU104GL [T4 32GB] 52 | UINT16_C(0x1EBA), // TU104GL [PG189 SKU600] 53 | UINT16_C(0x1EBE), // TU104GL 54 | }, 55 | Turing_Device_List_2GB[] = 56 | { 57 | UINT16_C(0x1F97), // TU117M [GeForce MX450] 2GB 58 | UINT16_C(0x1F98), // TU117M [GeForce MX450] 2GB 59 | UINT16_C(0x1F9C), // TU117M [GeForce MX450] 2GB 60 | UINT16_C(0x1F9F), // TU117M [GeForce MX550] 2GB 61 | UINT16_C(0x1FA0), // TU117M [GeForce MX550] 2GB 62 | }, 63 | Turing_Device_List_4GB[] = 64 | { 65 | UINT16_C(0x1F0A), // TU106 [GeForce GTX 1650] 4GB 66 | 67 | // UINT16_C(0x1F81), // TU117 68 | UINT16_C(0x1F82), // TU117 [GeForce GTX 1650] 4GB 69 | UINT16_C(0x1F83), // TU117 [GeForce GTX 1630] 4GB 70 | UINT16_C(0x1F91), // TU117M [GeForce GTX 1650 Mobile / Max-Q] 4GB 71 | UINT16_C(0x1F92), // TU117M [GeForce GTX 1650 Mobile] 4GB 72 | UINT16_C(0x1F94), // TU117M [GeForce GTX 1650 Mobile] 4GB 73 | UINT16_C(0x1F95), // TU117M [GeForce GTX 1650 Ti Mobile] 4GB 74 | UINT16_C(0x1F96), // TU117M [GeForce GTX 1650 Mobile / Max-Q] 4GB 75 | UINT16_C(0x1F99), // TU117M [GeForce GTX 1650 Mobile / Max-Q] 4GB 76 | UINT16_C(0x1F9D), // TU117M [GeForce GTX 1650 Mobile / Max-Q] 4GB 77 | //UINT16_C(0x1F9E), 78 | //UINT16_C(0x1FA1), // TU117M 79 | 80 | //UINT16_C(0x1FAE), // TU117GL 81 | UINT16_C(0x1FB0), // TU117GLM [Quadro T1000 Mobile] 4GB 82 | UINT16_C(0x1FB1), // TU117GL [T600] 4GB 83 | UINT16_C(0x1FB2), // TU117GLM [Quadro T400 Mobile] 4GB ?? 84 | UINT16_C(0x1FB6), // TU117GLM [T600 Laptop GPU] 4GB 85 | UINT16_C(0x1FB7), // TU117GLM [T550 Laptop GPU] 4GB 86 | UINT16_C(0x1FB8), // TU117GLM [Quadro T2000 Mobile / Max-Q] 4GB 87 | UINT16_C(0x1FB9), // TU117GLM [Quadro T1000 Mobile] 4GB 88 | UINT16_C(0x1FBa), // TU117GLM [T600 Mobile] 4GB 89 | UINT16_C(0x1FBB), // TU117GLM [Quadro T500 Mobile] 4GB 90 | UINT16_C(0x1FBC), // TU117GLM [T1200 Laptop GPU] 4GB 91 | //UINT16_C(0x1FBF), // TU117GL 92 | 93 | UINT16_C(0x1FD9), // TU117BM [GeForce GTX 1650 Mobile Refresh] 4GB 94 | UINT16_C(0x1FDD), // TU117BM [GeForce GTX 1650 Mobile Refresh] 4GB 95 | 96 | UINT16_C(0x1FF2), // TU117GL [T400 4GB] 97 | UINT16_C(0x1FF9), // TU117GLM [Quadro T1000 Mobile] 4GB 98 | 99 | UINT16_C(0x2187), // TU116 [GeForce GTX 1650 SUPER] 4GB 100 | UINT16_C(0x2188), // TU116 [GeForce GTX 1650] 4GB 101 | UINT16_C(0x2192), // TU116M [GeForce GTX 1650 Ti Mobile] 4GB 102 | }, 103 | Turing_Device_List_8GB[] = 104 | { 105 | UINT16_C(0x1E81), // TU104 [GeForce RTX 2080 SUPER] 8GB 106 | UINT16_C(0x1E82), // TU104 [GeForce RTX 2080] 8GB 107 | UINT16_C(0x1E84), // TU104 [GeForce RTX 2070 SUPER] 8GB 108 | UINT16_C(0x1E87), // TU104 [GeForce RTX 2080 Rev. A] 8GB 109 | UINT16_C(0x1E89), // TU104 [GeForce RTX 2060] 6GB 110 | UINT16_C(0x1E90), // TU104M [GeForce RTX 2080 Mobile] 8GB 111 | UINT16_C(0x1E91), // TU104M [GeForce RTX 2070 SUPER Mobile / Max-Q] 8GB 112 | UINT16_C(0x1E93), // TU104M [GeForce RTX 2080 SUPER Mobile / Max-Q] 8GB 113 | UINT16_C(0x1EAB), // TU104M [GeForce RTX 2080 Mobile] 8GB 114 | UINT16_C(0x1EAE), // TU104M [GeForce GTX 2080 Engineering Sample] 8GB ??? 115 | UINT16_C(0x1EB1), // TU104GL [Quadro RTX 4000] 8GB 116 | UINT16_C(0x1EB6), // TU104GLM [Quadro RTX 4000 Mobile / Max-Q] 8GB 117 | 118 | UINT16_C(0x1EC2), // TU104 [GeForce RTX 2070 SUPER] 8GB 119 | UINT16_C(0x1EC7), // TU104 [GeForce RTX 2070 SUPER] 8GB 120 | UINT16_C(0x1ED0), // TU104BM [GeForce RTX 2080 Mobile] 8GB 121 | UINT16_C(0x1ED1), // TU104BM [GeForce RTX 2070 SUPER Mobile / Max-Q] 8GB 122 | UINT16_C(0x1ED3), // TU104BM [GeForce RTX 2080 SUPER Mobile / Max-Q] 8GB 123 | 124 | UINT16_C(0x1F02), // TU106 [GeForce RTX 2070] 8GB 125 | //UINT16_C(0x1F04), // TU106 126 | 127 | UINT16_C(0x1F06), // TU106 [GeForce RTX 2060 SUPER] 8GB 128 | UINT16_C(0x1F07), // TU106 [GeForce RTX 2070 Rev. A] 8GB 129 | UINT16_C(0x1F08), // TU106 [GeForce RTX 2060 Rev. A] 6GB 130 | UINT16_C(0x1F09), // TU106 [GeForce GTX 1660 SUPER] 6GB 131 | UINT16_C(0x1F0B), // TU106 [CMP 40HX] 8GB 132 | UINT16_C(0x1F10), // TU106M [GeForce RTX 2070 Mobile] 8GB 133 | UINT16_C(0x1F11), // TU106M [GeForce RTX 2060 Mobile] 6GB 134 | UINT16_C(0x1F12), // TU106M [GeForce RTX 2060 Max-Q] 6GB 135 | UINT16_C(0x1F14), // TU106M [GeForce RTX 2070 Mobile / Max-Q Refresh] 8GB 136 | UINT16_C(0x1F15), // TU106M [GeForce RTX 2060 Mobile] 6GB 137 | //UINT16_C(0x1F2E), // TU106M ?? 138 | 139 | UINT16_C(0x1F36), // TU106GLM [Quadro RTX 3000 Mobile / Max-Q] 6GB 140 | 141 | UINT16_C(0x1F42), // TU106 [GeForce RTX 2060 SUPER] 8GB 142 | UINT16_C(0x1F47), // TU106 [GeForce RTX 2060 SUPER] 8gb 143 | UINT16_C(0x1F50), // TU106BM [GeForce RTX 2070 Mobile / Max-Q] 8GB 144 | UINT16_C(0x1F51), // TU106BM [GeForce RTX 2060 Mobile] 6GB 145 | UINT16_C(0x1F54), // TU106BM [GeForce RTX 2070 Mobile] 8GB 146 | UINT16_C(0x1F55), // TU106BM [GeForce RTX 2060 Mobile] 6GB 147 | 148 | UINT16_C(0x1F76), // TU106GLM [Quadro RTX 3000 Mobile Refresh] 6GB 149 | UINT16_C(0x1FF0), // TU117GL [T1000 8GB] 150 | UINT16_C(0x21C4), // TU116 [GeForce GTX 1660 SUPER] 6GB 151 | UINT16_C(0x2189), // TU116 [CMP 30HX] 6GB 152 | UINT16_C(0x2191), // TU116M [GeForce GTX 1660 Ti Mobile] 6GB 153 | 154 | UINT16_C(0x2182), // TU116 [GeForce GTX 1660 Ti] 6GB 155 | UINT16_C(0x2183), // TU116 [GeForce GTX 1660 Ti 8GB] 8GB 156 | UINT16_C(0x2184), // TU116 [GeForce GTX 1660] 6GB 157 | // UINT16_C(0x21AE), // TU116GL 158 | // UINT16_C(0x21BF), // TU116GL 159 | // UINT16_C(0x21C2), // TU116 160 | }, 161 | Turing_Device_List_16GB[] = 162 | { 163 | UINT16_C(0x1E03), // TU102 [GeForce RTX 2080 Ti 12GB] 164 | UINT16_C(0X1E04), // TU102 [GeForce RTX 2080 Ti] 11GB 165 | UINT16_C(0x1E07), // TU102 [GeForce RTX 2080 Ti Rev. A] 11GB 166 | UINT16_C(0x1E09), // TU102 [CMP 50HX] 10GB 167 | UINT16_C(0x1E2D), // TU102 [GeForce RTX 2080 Ti Engineering Sample] 11GB ??? 168 | UINT16_C(0x1E2E), // TU102 [GeForce RTX 2080 Ti 12GB Engineering Sample] 169 | 170 | UINT16_C(0x1EB0), // TU104GL [Quadro RTX 5000] 16GB 171 | UINT16_C(0x1EB4), // TU104GL [Tesla T4G] 16GB 172 | UINT16_C(0x1EB5), // TU104GLM [Quadro RTX 5000 Mobile / Max-Q] 16GB 173 | UINT16_C(0x1EB8), // TU104GL [Tesla T4] 16GB 174 | UINT16_C(0x1EF5), // TU104GLM [Quadro RTX 5000 Mobile Refresh] 16GB 175 | 176 | UINT16_C(0x1F03) // TU106 [GeForce RTX 2060 12GB] 12GB 177 | }, 178 | 179 | Turing_Device_List_32GB[] = 180 | { 181 | UINT16_C(0x1E02), // TU102 [Titan RTX] 24GB 182 | }; 183 | 184 | static inline bool inRange(UINT16 value, IDRange const *range) 185 | { 186 | return range->first <= value && value <= range->last; 187 | } 188 | 189 | static inline bool isTU102(UINT16 deviceID) 190 | { 191 | return inRange(deviceID, &PCI_ID_RANGE_TU102); 192 | } 193 | 194 | static inline bool isTU104(UINT16 deviceID) 195 | { 196 | return inRange(deviceID, &PCI_ID_RANGE_TU104); 197 | } 198 | 199 | static inline bool isTU106(UINT16 deviceID) 200 | { 201 | return inRange(deviceID, &PCI_ID_RANGE_TU106); 202 | } 203 | 204 | static inline bool isTU116(UINT16 deviceID) 205 | { 206 | return inRange(deviceID, &PCI_ID_RANGE_TU116); 207 | } 208 | 209 | static inline bool isTU117(UINT16 deviceID) 210 | { 211 | return inRange(deviceID, &PCI_ID_RANGE_TU117); 212 | } 213 | 214 | bool isTuringGPU(UINT16 deviceID) 215 | { 216 | return isTU102(deviceID) || isTU104(deviceID) || isTU106(deviceID) || isTU116(deviceID) || isTU117(deviceID); 217 | } 218 | 219 | typedef struct RegistryRange 220 | { 221 | UINT16 const *first, *last; 222 | } 223 | RegistryRange; 224 | static struct RegistryGroup 225 | { 226 | BarSizeSelector barSize; 227 | RegistryRange values; 228 | } 229 | const DeviceRegistry[] = 230 | { 231 | { .barSize = BarSizeSelector_Excluded, .values = { .first = Turing_Device_List_Skip, .last = Turing_Device_List_Skip + ARRAY_SIZE(Turing_Device_List_Skip) } }, 232 | { .barSize = BarSizeSelector_2G, .values = { .first = Turing_Device_List_2GB, .last = Turing_Device_List_2GB + ARRAY_SIZE(Turing_Device_List_2GB) } }, 233 | { .barSize = BarSizeSelector_4G, .values = { .first = Turing_Device_List_4GB, .last = Turing_Device_List_4GB + ARRAY_SIZE(Turing_Device_List_4GB) } }, 234 | { .barSize = BarSizeSelector_8G, .values = { .first = Turing_Device_List_8GB, .last = Turing_Device_List_8GB + ARRAY_SIZE(Turing_Device_List_8GB) } }, 235 | { .barSize = BarSizeSelector_16G, .values = { .first = Turing_Device_List_16GB, .last = Turing_Device_List_16GB + ARRAY_SIZE(Turing_Device_List_16GB) } }, 236 | { .barSize = BarSizeSelector_32G, .values = { .first = Turing_Device_List_32GB, .last = Turing_Device_List_32GB + ARRAY_SIZE(Turing_Device_List_32GB) } } 237 | }; 238 | 239 | BarSizeSelector lookupBarSizeInRegistry(UINT16 deviceID) 240 | { 241 | for (struct RegistryGroup const *group = DeviceRegistry; group < DeviceRegistry + ARRAY_SIZE(DeviceRegistry); group++) 242 | for (UINT16 const *devID = group->values.first; devID < group->values.last; devID++) 243 | if (*devID == deviceID) 244 | return group->barSize; 245 | 246 | return BarSizeSelector_None; 247 | } 248 | -------------------------------------------------------------------------------- /ReBarDxe/EfiVariable.c: -------------------------------------------------------------------------------- 1 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 2 | # include 3 | # include 4 | #else 5 | # if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64) 6 | # if defined(_M_AMD64) && !defined(_AMD64_) 7 | # define _AMD64_ 8 | # endif 9 | # include 10 | # include 11 | # include 12 | # include 13 | # else 14 | # include 15 | # endif 16 | #endif 17 | 18 | #include 19 | 20 | #include "LocalAppConfig.h" 21 | #include "EfiVariable.h" 22 | 23 | // e3ee4a27-e2a2-4435-bba3-184ccad935a8 // the PLATFROM_GUID from .dsc file 24 | 25 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 26 | static GUID const variableGUID = { 0xe3ee4a27u, 0xe2a2u, 0x4435u, { 0xbbu, 0xa3u, 0x18u, 0x4cu, 0xcau, 0xd9u, 0x35u, 0xa8u } }; 27 | #else 28 | # if defined(WINDOWS_SOURCE) 29 | static char const variableGUID[] = "{e3ee4a27-e2a2-4435-bba3-184ccad935a8}"; 30 | # else 31 | static char const variableGUID[] = "e3ee4a27-e2a2-4435-bba3-184ccad935a8"; 32 | static char const variablePath[] = "/sys/firmware/efi/efivars/"; 33 | 34 | void fillFilePath(char *filePath, char const *name) 35 | { 36 | unsigned i; 37 | 38 | for (i = 0u; i < ARRAY_SIZE(variablePath; i++)) 39 | filePath[i] = variablePath[i]; 40 | 41 | for (unsigned j = 0u; j < MAX_VARIABLE_NAME_LENGTH && name[j]; j++) 42 | filePath[i++] = name[j]; 43 | 44 | filePath[i++] = '-'; 45 | 46 | for (unsigned j = 0u; j < ARRAY_SIZE(variableGUID); j++) 47 | filePath[i++] = variableGUID[j]; 48 | 49 | filePath[i] = '\0'; 50 | } 51 | 52 | struct __attribute__((__packed__)) rebarVar 53 | { 54 | uint32_t attr; 55 | uint8_t value; 56 | }; 57 | 58 | # endif 59 | #endif 60 | 61 | ERROR_CODE ReadEfiVariable(char const *name, BYTE *buffer, uint_least32_t *size) 62 | { 63 | #if defined(UEIF_SOURCE) || defined(EFIAPI) 64 | CHAR16 varName[MAX_VARIABLE_NAME_LENGTH + 1u]; 65 | unsigned i; 66 | 67 | for (i = 0u; i < ARRAY_SIZE(varName) - 1u && name[i]; i++) 68 | varName[i] = name[i]; 69 | 70 | varName[i] = u'\0'; 71 | EFI_GUID guid = variableGUID; 72 | UINT32 attributes = 0u; 73 | UINTN dataSize = *size; 74 | 75 | ERROR_CODE status = gRT->GetVariable(varName, &guid, &attributes, &dataSize, buffer); 76 | 77 | if (EFI_ERROR(status)) 78 | { 79 | *size = 0u; 80 | 81 | if (status == EFI_NOT_FOUND) 82 | status = EFI_SUCCESS; 83 | } 84 | else 85 | *size = (uint_least32_t)dataSize; 86 | 87 | return status; 88 | #elif defined(WINDOWS_SOURCE) 89 | *size = GetFirmwareEnvironmentVariableA(name, variableGUID, buffer, *size); 90 | 91 | if (*size) 92 | return ERROR_SUCCESS; 93 | 94 | ERROR_CODE status = GetLastError(); 95 | 96 | return status == ERROR_ENVVAR_NOT_FOUND ? ERROR_SUCCESS : status; 97 | #else 98 | char filePath[ARRAY_SIZE(variablePath) + MAX_VARIABLE_NAME_LENGTH + 1u + ARRAY_SIZE(variableGUID)]; 99 | fillFilePath(filePath, name); 100 | 101 | FILE *file = fopen(filePath, "rb"); 102 | ERROR_CODE result = 0 103 | 104 | if (file) 105 | { 106 | do 107 | { 108 | if (fseek(file, DWORD_SIZE, SEEK_CUR)) 109 | { 110 | result = errno; 111 | break; 112 | } 113 | 114 | errno = 0; 115 | *size = fread(buffer, 1u, *size, file); 116 | 117 | if (ferror(file)) 118 | { 119 | result = errno ? errno : EIO; 120 | break; 121 | } 122 | 123 | off_t pos = ftello(file); 124 | 125 | if (pos < 0) 126 | { 127 | result = errno; 128 | break; 129 | } 130 | 131 | if (fseek(file, 0, SEEK_END)) 132 | { 133 | result = errno; 134 | break; 135 | } 136 | 137 | off_t new_pos = ftello(file); 138 | 139 | if (new_pos < 0) 140 | { 141 | result = errno; 142 | break; 143 | } 144 | 145 | if (pos != new_pos) 146 | result = EOVERFLOW; // content truncated 147 | } 148 | while (false); 149 | 150 | fclose(file); 151 | } 152 | else 153 | *size = 0, result = errno == ENOENT ? 0 : errno; 154 | 155 | return errno; 156 | #endif 157 | } 158 | 159 | ERROR_CODE WriteEfiVariable(char const name[MAX_VARIABLE_NAME_LENGTH], BYTE /* const */ *buffer, uint_least32_t size, uint_least32_t attributes) 160 | { 161 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 162 | CHAR16 varName[MAX_VARIABLE_NAME_LENGTH + 1u]; 163 | unsigned i; 164 | 165 | for (i = 0u; i < ARRAY_SIZE(varName) - 1u && name[i]; i++) 166 | varName[i] = name[i]; 167 | 168 | varName[i] = u'\0'; 169 | EFI_GUID guid = variableGUID; 170 | 171 | return gRT->SetVariable(varName, &guid, attributes, size, buffer); 172 | #elif defined(WINDOWS_SOURCE) 173 | BOOL bSucceeded = SetFirmwareEnvironmentVariableExA(name, variableGUID, buffer, size, attributes); 174 | ERROR_CODE status = bSucceeded ? ERROR_SUCCESS : GetLastError(); 175 | return status == ERROR_ENVVAR_NOT_FOUND ? ERROR_SUCCESS : status; // Ok to deleting non-existent variable 176 | #else 177 | char filePath[ARRAY_SIZE(variablePath) + MAX_VARIABLE_NAME_LENGTH + 1u + ARRAY_SIZE(variableGUID)]; 178 | fillFilePath(filePath, name); 179 | 180 | FILE *file = fopen(filePath, "rb"); 181 | ERROR_CODE result = 0 182 | 183 | if (file) 184 | { 185 | // remove immutable flag that linux sets on all unknown efi variables 186 | int attr; 187 | ioctl(fileno(file), FS_IOC_GETFLAGS, &attr); 188 | attr &= ~FS_IMMUTABLE_FL; 189 | ioctl(fileno(file), FS_IOC_SETFLAGS, &attr); 190 | 191 | fclose(file), file = NULL; 192 | 193 | if (remove(filePath)) 194 | return errno; 195 | } 196 | else 197 | return errno; 198 | 199 | file = fopen(filePath, "wb"); 200 | 201 | if (!file) 202 | return errno; 203 | 204 | errno_t result = 0; 205 | 206 | do 207 | { 208 | errno = 0; 209 | 210 | // write variable attributes 211 | if (fwrite(&attributes, DWORD_SIZE, 1, file) != 1) 212 | { 213 | result = errno; 214 | break; 215 | } 216 | 217 | // write variable content (data) 218 | if (fwrite(buffer, size, 1, file) != 1) 219 | result = errno; 220 | } 221 | while (false); 222 | 223 | if (fclose(file) && !result) 224 | result = errno; 225 | 226 | return result; 227 | #endif 228 | } 229 | -------------------------------------------------------------------------------- /ReBarDxe/PciConfig.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "pciRegs.h" 12 | #include "S3ResumeScript.h" 13 | #include "LocalAppConfig.h" 14 | #include "StatusVar.h" 15 | #include "SetupNvStraps.h" 16 | #include "ReBar.h" 17 | #include "PciConfig.h" 18 | 19 | inline bool PCI_POSSIBLE_ERROR(UINT32 val) 20 | { 21 | return val == MAX_UINT32; 22 | }; 23 | 24 | static EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pciRootBridgeIo; 25 | 26 | UINT64 pciAddrOffset(UINTN pciAddress, INTN offset) 27 | { 28 | UINTN reg = (pciAddress & 0xffffffff00000000) >> 32; 29 | UINTN bus = (pciAddress & 0xff000000) >> 24; 30 | UINTN dev = (pciAddress & 0xff0000) >> 16; 31 | UINTN func = (pciAddress & 0xff00) >> 8; 32 | 33 | return EFI_PCI_ADDRESS(bus, dev, func, ((INT64)reg + offset)); 34 | } 35 | 36 | // created these functions to make it easy to read as we are adapting alot of code from Linux 37 | static inline EFI_STATUS pciReadConfigDword(UINTN pciAddress, INTN pos, UINT32 *buf) 38 | { 39 | return pciRootBridgeIo->Pci.Read(pciRootBridgeIo, EfiPciWidthUint32, pciAddrOffset(pciAddress, pos), 1u, buf); 40 | } 41 | 42 | // Using the PollMem function silently breaks UEFI boot (the board needs flash recovery...) 43 | static inline EFI_STATUS pciPollConfigDword(UINTN pciAddress, INTN pos, UINT64 mask, UINT64 value, UINT64 delay, UINT64 *result) 44 | { 45 | return pciRootBridgeIo->PollMem(pciRootBridgeIo, EfiPciWidthUint32, pciAddrOffset(pciAddress, pos), mask, value, delay, result); 46 | } 47 | 48 | static inline EFI_STATUS pciWriteConfigDword(UINTN pciAddress, INTN pos, UINT32 *buf) 49 | { 50 | return pciRootBridgeIo->Pci.Write(pciRootBridgeIo, EfiPciWidthUint32, pciAddrOffset(pciAddress, pos), 1u, buf); 51 | } 52 | 53 | static inline EFI_STATUS pciReadConfigWord(UINTN pciAddress, INTN pos, UINT16 *buf) 54 | { 55 | return pciRootBridgeIo->Pci.Read(pciRootBridgeIo, EfiPciWidthUint16, pciAddrOffset(pciAddress, pos), 1u, buf); 56 | } 57 | 58 | static inline EFI_STATUS pciWriteConfigWord(UINTN pciAddress, INTN pos, UINT16 *buf) 59 | { 60 | return pciRootBridgeIo->Pci.Write(pciRootBridgeIo, EfiPciWidthUint16, pciAddrOffset(pciAddress, pos), 1u, buf); 61 | } 62 | 63 | static inline EFI_STATUS pciReadConfigByte(UINTN pciAddress, INTN pos, UINT8 *buf) 64 | { 65 | return pciRootBridgeIo->Pci.Read(pciRootBridgeIo, EfiPciWidthUint8, pciAddrOffset(pciAddress, pos), 1u, buf); 66 | } 67 | 68 | static inline EFI_STATUS pciWriteConfigByte(UINTN pciAddress, INTN pos, UINT8 *buf) 69 | { 70 | return pciRootBridgeIo->Pci.Write(pciRootBridgeIo, EfiPciWidthUint8, pciAddrOffset(pciAddress, pos), 1u, buf); 71 | } 72 | 73 | EFI_STATUS pciReadDeviceSubsystem(UINTN pciAddress, uint_least16_t *subsysVenID, uint_least16_t *subsysDevID) 74 | { 75 | UINT32 subsys = MAX_UINT32; 76 | EFI_STATUS status = pciReadConfigDword(pciAddress, PCI_SUBSYSTEM_VENDOR_ID_OFFSET, &subsys); 77 | 78 | if (EFI_ERROR(status)) 79 | *subsysVenID = WORD_BITMASK, *subsysDevID = WORD_BITMASK; 80 | else 81 | *subsysVenID = subsys & WORD_BITMASK, *subsysDevID = subsys >> WORD_BITSIZE & WORD_BITMASK; 82 | 83 | return status; 84 | } 85 | 86 | uint_least32_t pciDeviceClass(UINTN pciAddress) 87 | { 88 | UINT32 configReg; 89 | 90 | if (EFI_ERROR(pciReadConfigDword(pciAddress, PCI_REVISION_ID_OFFSET, &configReg))) 91 | return UINT32_C(0xFFFF'FFFF); 92 | 93 | return configReg & UINT32_C(0xFFFF'FF00); 94 | } 95 | 96 | uint_least32_t pciDeviceBAR0(UINTN pciAddress, EFI_STATUS *status) 97 | { 98 | UINT32 baseAddress; 99 | 100 | *status = pciReadConfigDword(pciAddress, PCI_BASE_ADDRESS_0, &baseAddress); 101 | 102 | if (EFI_ERROR(*status)) 103 | return UINT32_C(0xFFFF'FFFF); 104 | 105 | return baseAddress; 106 | } 107 | 108 | EFI_STATUS pciBridgeSecondaryBus(UINTN pciAddress, uint_least8_t *secondaryBus) 109 | { 110 | UINT32 configReg; 111 | 112 | EFI_STATUS status = pciReadConfigDword(pciAddress, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, &configReg); 113 | 114 | if (EFI_ERROR(status)) 115 | *secondaryBus = BYTE_BITMASK; 116 | else 117 | *secondaryBus = configReg >> BYTE_BITSIZE & BYTE_BITMASK; 118 | 119 | return status; 120 | } 121 | 122 | bool pciIsPciBridge(uint_least8_t headerType) 123 | { 124 | return (headerType & ~HEADER_TYPE_MULTI_FUNCTION) == (uint_least8_t) HEADER_TYPE_PCI_TO_PCI_BRIDGE; 125 | } 126 | 127 | bool pciIsVgaController(uint_least32_t pciClassReg) 128 | { 129 | return pciClassReg == 130 | ((uint_least32_t)PCI_CLASS_DISPLAY << 3u * BYTE_BITSIZE 131 | | (uint_least32_t)PCI_CLASS_DISPLAY_VGA << 2u * BYTE_BITSIZE 132 | | (uint_least32_t)PCI_IF_VGA_VGA << 1u * BYTE_BITSIZE); 133 | } 134 | 135 | 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) 136 | { 137 | gBS->HandleProtocol(RootBridgeHandle, &gEfiPciRootBridgeIoProtocolGuid, (void **)&pciRootBridgeIo); 138 | 139 | UINTN pciAddress = EFI_PCI_ADDRESS(addressInfo.Bus, addressInfo.Device, addressInfo.Function, 0x00u); 140 | UINT32 pciID; 141 | 142 | pciReadConfigDword(pciAddress, PCI_VENDOR_ID_OFFSET, &pciID); 143 | 144 | if (pciID != ((uint_least32_t) WORD_BITMASK << WORD_BITSIZE | WORD_BITMASK)) 145 | { 146 | UINT32 configReg; 147 | 148 | if (EFI_ERROR(pciReadConfigDword(pciAddress, PCI_CACHELINE_SIZE_OFFSET, &configReg))) 149 | *headerType = BYTE_BITMASK; 150 | else 151 | *headerType = (configReg >> WORD_BITSIZE) & BYTE_BITMASK; 152 | } 153 | else 154 | *headerType = BYTE_BITMASK; 155 | 156 | *venID = pciID & WORD_BITMASK; 157 | *devID = pciID >> WORD_BITSIZE & WORD_BITMASK; 158 | 159 | return pciAddress; 160 | } 161 | 162 | // adapted from Linux pci_find_ext_capability 163 | uint_least16_t pciFindExtCapability(UINTN pciAddress, uint_least32_t cap) 164 | { 165 | uint_least16_t capabilityOffset = EFI_PCIE_CAPABILITY_BASE_OFFSET; 166 | UINT32 capabilityHeader; 167 | EFI_STATUS status; 168 | 169 | if (EFI_ERROR((status = pciReadConfigDword(pciAddress, capabilityOffset, &capabilityHeader)))) 170 | return SetEFIError(EFIError_PCI_StartFindCap, status), 0u; 171 | 172 | /* 173 | * If we have no capabilities, this is indicated by cap ID, 174 | * cap version and next pointer all being 0. Or it could also be all FF 175 | */ 176 | if (capabilityHeader == 0u || PCI_POSSIBLE_ERROR(capabilityHeader)) 177 | return 0u; 178 | 179 | /* minimum 8 bytes per capability */ 180 | int_fast16_t ttl = (PCI_CFG_SPACE_EXP_SIZE - EFI_PCIE_CAPABILITY_BASE_OFFSET) / 8u; 181 | 182 | while (ttl-- > 0) 183 | { 184 | if (PCI_EXT_CAP_ID(capabilityHeader) == cap && capabilityOffset) 185 | return capabilityOffset; 186 | 187 | capabilityOffset = PCI_EXT_CAP_NEXT(capabilityHeader); 188 | 189 | if (capabilityOffset < EFI_PCIE_CAPABILITY_BASE_OFFSET) 190 | break; 191 | 192 | if (EFI_ERROR((status = pciReadConfigDword(pciAddress, capabilityOffset, &capabilityHeader)))) 193 | { 194 | SetEFIError(EFIError_PCI_FindCap, status); 195 | break; 196 | } 197 | } 198 | 199 | return 0u; 200 | } 201 | 202 | static uint_least16_t pciBARConfigOffset(UINTN pciAddress, uint_least16_t capOffset, uint_least8_t barIndex) 203 | { 204 | UINT32 configValue; 205 | pciReadConfigDword(pciAddress, capOffset + PCI_REBAR_CTRL, &configValue); 206 | 207 | unsigned nBars = (configValue & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT; 208 | 209 | for (unsigned i = 0u; i < nBars; i++, capOffset += 8u) 210 | { 211 | pciReadConfigDword(pciAddress, capOffset + PCI_REBAR_CTRL, &configValue); 212 | 213 | if ((configValue & PCI_REBAR_CTRL_BAR_IDX) == barIndex) 214 | return capOffset; 215 | } 216 | 217 | return 0u; 218 | } 219 | 220 | uint_least32_t pciRebarGetPossibleSizes(UINTN pciAddress, uint_least16_t capabilityOffset, UINT16 vid, UINT16 did, uint_least8_t barIndex) 221 | { 222 | uint_least16_t barConfigOffset = pciBARConfigOffset(pciAddress, capabilityOffset, barIndex); 223 | 224 | if (barConfigOffset) 225 | { 226 | UINT32 barSizeMask; 227 | pciReadConfigDword(pciAddress, barConfigOffset + PCI_REBAR_CAP, &barSizeMask); 228 | barSizeMask &= PCI_REBAR_CAP_SIZES; 229 | 230 | return barSizeMask >> 4u; 231 | } 232 | 233 | return 0u; 234 | } 235 | 236 | /* 237 | * This broke UEFI boot (the board won't POST) 238 | uint_least32_t pciRebarPollPossibleSizes(UINTN pciAddress, uint_least16_t capabilityOffset, uint_least8_t barIndex, uint_least32_t barSizeMask) 239 | { 240 | uint_least16_t barConfigOffset = pciBARConfigOffset(pciAddress, capabilityOffset, barIndex); 241 | 242 | if (barConfigOffset) 243 | { 244 | UINT64 resultSizeMask; 245 | pciPollConfigDword(pciAddress, barConfigOffset + PCI_REBAR_CAP, barSizeMask, barSizeMask, UINT64_C(1'000'000), &resultSizeMask); 246 | barSizeMask &= PCI_REBAR_CAP_SIZES; 247 | 248 | return (uint_least32_t)(barSizeMask) >> 4u; 249 | } 250 | 251 | return SetStatusVar(StatusVar_EFIError), 0u; 252 | } 253 | */ 254 | 255 | bool pciRebarSetSize(UINTN pciAddress, uint_least16_t capabilityOffset, uint_least8_t barIndex, uint_least8_t barSizeBitIndex) 256 | { 257 | uint_least16_t barConfigOffset = pciBARConfigOffset(pciAddress, capabilityOffset, barIndex); 258 | 259 | if (barConfigOffset) 260 | { 261 | UINT32 barSizeControl; 262 | pciReadConfigDword(pciAddress, barConfigOffset + PCI_REBAR_CTRL, &barSizeControl); 263 | 264 | barSizeControl &= ~ (uint_least32_t)PCI_REBAR_CTRL_BAR_SIZE; 265 | barSizeControl |= (uint_least32_t)barSizeBitIndex << PCI_REBAR_CTRL_BAR_SHIFT; 266 | 267 | pciWriteConfigDword(pciAddress, barConfigOffset + PCI_REBAR_CTRL, &barSizeControl); 268 | 269 | return true; 270 | } 271 | 272 | return false; 273 | } 274 | 275 | void pciSaveAndRemapBridgeConfig(UINTN bridgePciAddress, UINT32 bridgeSaveArea[3u], EFI_PHYSICAL_ADDRESS baseAddress0, EFI_PHYSICAL_ADDRESS topAddress0, EFI_PHYSICAL_ADDRESS ioBaseLimit) 276 | { 277 | bool efiError = false, s3SaveStateError = false; 278 | EFI_STATUS status; 279 | 280 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(bridgePciAddress, PCI_COMMAND_OFFSET, bridgeSaveArea + 0u))); 281 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(bridgePciAddress, PCI_IO_BASE, bridgeSaveArea + 1u))); 282 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(bridgePciAddress, PCI_MEMORY_BASE, bridgeSaveArea + 2u))); 283 | 284 | UINT32 configReg; 285 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(bridgePciAddress, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, &configReg))); 286 | 287 | if (!efiError) 288 | { 289 | topAddress0++; 290 | 291 | if (topAddress0 & UINT32_C(0x000F'FFFF)) 292 | { 293 | topAddress0 += UINT32_C(0x0010'0000); // round up to next 1 MiByte alignment 294 | topAddress0 &= UINT32_C(0xFFF0'0000); 295 | } 296 | 297 | if (topAddress0 <= baseAddress0) 298 | { 299 | SetStatusVar(StatusVar_BadBridgeConfig); 300 | return; 301 | } 302 | 303 | UINT32 bridgeIoRange = ioBaseLimit & 0xFF00u | ioBaseLimit >> BYTE_BITSIZE & 0x00FFu; 304 | UINT32 305 | bridgeCommand = bridgeSaveArea[0u] | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER, 306 | bridgeIoBaseLimit = bridgeSaveArea[1u] & UINT32_C(0xFFFF'0000) | bridgeIoRange & UINT32_C(0x0000'FFFF), 307 | bridgeMemoryBaseLimit = (baseAddress0 >> 16u & UINT32_C(0x0000'FFF0) | topAddress0 & UINT32_C(0xFFF0'0000)); 308 | 309 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_MEMORY_BASE, &bridgeMemoryBaseLimit))); 310 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_IO_BASE, &bridgeIoBaseLimit))); 311 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_COMMAND_OFFSET, &bridgeCommand))); 312 | 313 | if (!efiError) 314 | { 315 | status = S3ResumeScript_PciConfigReadWrite_DWORD 316 | ( 317 | bridgePciAddress, 318 | PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 319 | configReg & UINT32_C(0x00FF'FFFF), // primary bus, secondary bus, subsidiary bus 320 | UINT32_C(0xFF00'0000) 321 | ); 322 | 323 | efiError = efiError || EFI_ERROR(status); 324 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 325 | } 326 | 327 | if (!efiError) 328 | { 329 | status = S3ResumeScript_PciConfigWrite_DWORD 330 | ( 331 | bridgePciAddress, 332 | PCI_MEMORY_BASE, 333 | bridgeMemoryBaseLimit 334 | ); 335 | 336 | efiError = efiError || EFI_ERROR(status); 337 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 338 | } 339 | 340 | if (!efiError) 341 | { 342 | status = S3ResumeScript_PciConfigReadWrite_DWORD 343 | ( 344 | bridgePciAddress, 345 | PCI_IO_BASE, 346 | bridgeIoBaseLimit & UINT32_C(0x0000'FFFF), 347 | UINT32_C(0xFFFF'0000) 348 | ); 349 | 350 | efiError = efiError || EFI_ERROR(status); 351 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 352 | } 353 | 354 | if (!efiError) 355 | { 356 | status = S3ResumeScript_PciConfigReadWrite_DWORD 357 | ( 358 | bridgePciAddress, 359 | PCI_COMMAND_OFFSET, 360 | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER, 361 | (UINT32) ~(UINT32)(EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) 362 | ); 363 | 364 | efiError = efiError || EFI_ERROR(status); 365 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 366 | } 367 | } 368 | 369 | if (efiError) 370 | SetEFIError(s3SaveStateError ? EFIError_WriteS3SaveStateProtocol : EFIError_PCI_BridgeConfig, status); 371 | } 372 | 373 | void pciRestoreBridgeConfig(UINTN bridgePciAddress, UINT32 bridgeSaveArea[3u]) 374 | { 375 | bool efiError = false; 376 | EFI_STATUS status; 377 | 378 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_COMMAND_OFFSET, bridgeSaveArea + 0u))); 379 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_IO_BASE, bridgeSaveArea + 1u))); 380 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(bridgePciAddress, PCI_MEMORY_BASE, bridgeSaveArea + 2u))); 381 | 382 | if (efiError) 383 | SetEFIError(EFIError_PCI_BridgeRestore, status); 384 | } 385 | 386 | void pciSaveAndRemapDeviceBAR0(UINTN pciAddress, UINT32 gpuSaveArea[2u], EFI_PHYSICAL_ADDRESS baseAddress0) 387 | { 388 | bool efiError = false, s3SaveStateError = false; 389 | EFI_STATUS status; 390 | 391 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(pciAddress, PCI_COMMAND_OFFSET, gpuSaveArea + 0u))); 392 | efiError = efiError || EFI_ERROR((status = pciReadConfigDword(pciAddress, PCI_BASE_ADDRESS_0, gpuSaveArea + 1u))); 393 | 394 | if (!efiError) 395 | { 396 | if (baseAddress0 & UINT32_C(0x0000'000F)) 397 | { 398 | SetDeviceStatusVar(pciAddress, StatusVar_BadGpuConfig); 399 | return; 400 | } 401 | 402 | UINT32 403 | gpuBaseAddress = baseAddress0 & UINT32_C(0xFFFFFFF0), 404 | gpuCommand = gpuSaveArea[0u] | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; 405 | 406 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_BASE_ADDRESS_0, &gpuBaseAddress))); 407 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_COMMAND_OFFSET, &gpuCommand))); 408 | 409 | if (!efiError) 410 | { 411 | status = S3ResumeScript_PciConfigWrite_DWORD 412 | ( 413 | pciAddress, 414 | PCI_BASE_ADDRESS_0, 415 | gpuBaseAddress 416 | ); 417 | 418 | efiError = efiError || EFI_ERROR(status); 419 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 420 | } 421 | 422 | if (!efiError) 423 | { 424 | status = S3ResumeScript_PciConfigReadWrite_DWORD 425 | ( 426 | pciAddress, 427 | PCI_COMMAND_OFFSET, 428 | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER, 429 | (uint_least32_t) ~(uint_least32_t)(EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) 430 | ); 431 | 432 | efiError = efiError || EFI_ERROR(status); 433 | s3SaveStateError = s3SaveStateError || EFI_ERROR(status); 434 | } 435 | } 436 | 437 | if (efiError) 438 | SetEFIError(s3SaveStateError ? EFIError_WriteS3SaveStateProtocol : EFIError_PCI_DeviceBARConfig, status); 439 | } 440 | 441 | void pciRestoreDeviceConfig(UINTN pciAddress, UINT32 saveArea[2u]) 442 | { 443 | bool efiError = false; 444 | EFI_STATUS status; 445 | 446 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_COMMAND_OFFSET, saveArea + 0u))); 447 | efiError = efiError || EFI_ERROR((status = pciWriteConfigDword(pciAddress, PCI_BASE_ADDRESS_0, saveArea + 1u))); 448 | 449 | if (efiError) 450 | SetEFIError(EFIError_PCI_DeviceBARRestore, status); 451 | } 452 | 453 | // vim: ft=cpp 454 | -------------------------------------------------------------------------------- /ReBarDxe/ReBar.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2022-2023 xCuri0 3 | SPDX-License-Identifier: MIT 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #if defined(_ASSERT) 18 | # undef _ASSERT 19 | #endif 20 | 21 | #include 22 | 23 | #include "LocalAppConfig.h" 24 | #include "StatusVar.h" 25 | #include "PciConfig.h" 26 | #include "S3ResumeScript.h" 27 | #include "NvStrapsConfig.h" 28 | #include "SetupNvStraps.h" 29 | #include "CheckSetupVar.h" 30 | 31 | #include "ReBar.h" 32 | 33 | // if system time is before this year then CMOS reset will be detected and rebar will be disabled. 34 | static unsigned const BUILD_YEAR = 2024u; 35 | 36 | // for quirk 37 | static uint_least16_t const 38 | PCI_VENDOR_ID_AMD = 0x1002u, 39 | PCI_DEVICE_Sapphire_RX_5600_XT_Pulse = 0x731Fu; 40 | 41 | // 0: disabled 42 | // >0: maximum BAR size (2^x) set to value. 32 for unlimited, 64 for selected GPU only 43 | static uint_least8_t nPciBarSizeSelector = TARGET_PCI_BAR_SIZE_DISABLED; 44 | 45 | static EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *pciResAlloc; 46 | 47 | static EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER o_PreprocessController; 48 | 49 | EFI_HANDLE reBarImageHandle = NULL; 50 | NvStrapsConfig *config = NULL; 51 | 52 | // find highest-order bit set and return the bit index 53 | static inline uint_least8_t highestBitIndex(uint_least32_t val) 54 | { 55 | uint_least8_t bitIndex = (uint_least8_t)(sizeof val * BYTE_BITSIZE - 1u); 56 | uint_least32_t checkBit = (uint_least32_t)1u << bitIndex; 57 | 58 | while (bitIndex && (val & checkBit) == 0u) 59 | bitIndex--, checkBit >>= 1u; 60 | 61 | return bitIndex; 62 | } 63 | 64 | static inline uint_least8_t min(uint_least8_t val1, uint_least8_t val2) 65 | { 66 | return val1 < val2 ? val1 : val2; 67 | } 68 | 69 | uint_least32_t getReBarSizeMask(UINTN pciAddress, uint_least16_t capabilityOffset, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_least8_t barIndex) 70 | { 71 | uint_least32_t barSizeMask = pciRebarGetPossibleSizes(pciAddress, capabilityOffset, vid, did, barIndex); 72 | 73 | /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ 74 | if (vid == PCI_VENDOR_ID_AMD && did == PCI_DEVICE_Sapphire_RX_5600_XT_Pulse && barIndex == PCI_BAR_IDX0 && barSizeMask == 0x7000u) 75 | barSizeMask = 0x3'F000u; 76 | else 77 | if (NvStraps_CheckBARSizeListAdjust(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex)) 78 | barSizeMask = NvStraps_AdjustBARSizeList(pciAddress, vid, did, subsysVenID, subsysDevID, barIndex, barSizeMask); 79 | 80 | return barSizeMask; 81 | } 82 | 83 | static void reBarSetupDevice(EFI_HANDLE handle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS addrInfo) 84 | { 85 | uint_least16_t vid, did; 86 | uint_least8_t headerType; 87 | UINTN pciAddress = pciLocateDevice(handle, addrInfo, &vid, &did, &headerType); 88 | 89 | if (vid == WORD_BITMASK) 90 | return; 91 | 92 | DEBUG((DEBUG_INFO, "ReBarDXE: Device vid:%x did:%x\n", vid, did)); 93 | 94 | NvStraps_EnumDevice(pciAddress, vid, did, headerType); 95 | 96 | uint_least16_t subsysVenID = WORD_BITMASK, subsysDevID = WORD_BITMASK; 97 | bool isSelectedGpu = NvStraps_CheckDevice(pciAddress, vid, did, &subsysVenID, &subsysDevID); 98 | 99 | if (isSelectedGpu) 100 | NvStraps_Setup(pciAddress, vid, did, subsysVenID, subsysDevID, nPciBarSizeSelector); 101 | 102 | if (TARGET_PCI_BAR_SIZE_MIN <= nPciBarSizeSelector && nPciBarSizeSelector <= TARGET_PCI_BAR_SIZE_MAX) 103 | { 104 | uint_least16_t const capOffset = pciFindExtCapability(pciAddress, PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID); 105 | 106 | if (capOffset) 107 | for (uint_least8_t barIndex = 0u; barIndex < PCI_MAX_BAR; barIndex++) 108 | { 109 | uint_least32_t nBarSizeMask = getReBarSizeMask(pciAddress, capOffset, vid, did, subsysVenID, subsysDevID, barIndex); 110 | 111 | if (nBarSizeMask) 112 | for (uint_least8_t barSizeBitIndex = min(highestBitIndex(nBarSizeMask), nPciBarSizeSelector); barSizeBitIndex > 0u; barSizeBitIndex--) 113 | if (nBarSizeMask & 1u << barSizeBitIndex) 114 | { 115 | bool resized = pciRebarSetSize(pciAddress, capOffset, barIndex, barSizeBitIndex); 116 | 117 | if (isSelectedGpu && resized) 118 | SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarConfigured); 119 | 120 | break; 121 | } 122 | } 123 | } 124 | } 125 | 126 | static EFI_STATUS EFIAPI PreprocessControllerOverride 127 | ( 128 | IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, 129 | IN EFI_HANDLE RootBridgeHandle, 130 | IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, 131 | IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase 132 | ) 133 | { 134 | // call the original method 135 | EFI_STATUS status = o_PreprocessController(This, RootBridgeHandle, PciAddress, Phase); 136 | 137 | DEBUG((DEBUG_INFO, "ReBarDXE: Hooked PreprocessController called %d\n", Phase)); 138 | 139 | // EDK2 PciBusDxe setups Resizable BAR twice so we will do same 140 | if (Phase <= EfiPciBeforeResourceCollection) 141 | reBarSetupDevice(RootBridgeHandle, PciAddress); 142 | 143 | return status; 144 | } 145 | 146 | static void pciHostBridgeResourceAllocationProtocolHook() 147 | { 148 | EFI_STATUS status; 149 | UINTN handleCount; 150 | EFI_HANDLE *handleBuffer = NULL; 151 | 152 | status = gBS->LocateHandleBuffer( 153 | ByProtocol, 154 | &gEfiPciHostBridgeResourceAllocationProtocolGuid, 155 | NULL, 156 | &handleCount, 157 | &handleBuffer); 158 | 159 | if (EFI_ERROR(status)) 160 | { 161 | SetEFIError(EFIError_LocateBridgeProtocol, status); 162 | goto free; 163 | } 164 | 165 | status = gBS->OpenProtocol 166 | ( 167 | handleBuffer[0], 168 | &gEfiPciHostBridgeResourceAllocationProtocolGuid, 169 | (VOID **)&pciResAlloc, 170 | gImageHandle, 171 | NULL, 172 | EFI_OPEN_PROTOCOL_GET_PROTOCOL 173 | ); 174 | 175 | if (EFI_ERROR(status)) 176 | { 177 | SetEFIError(EFIError_LoadBridgeProtocol, status); 178 | goto free; 179 | } 180 | 181 | DEBUG((DEBUG_INFO, "ReBarDXE: Hooking EfiPciHostBridgeResourceAllocationProtocol->PreprocessController\n")); 182 | 183 | // Hook PreprocessController 184 | o_PreprocessController = pciResAlloc->PreprocessController; 185 | pciResAlloc->PreprocessController = &PreprocessControllerOverride; 186 | 187 | free: 188 | if (handleBuffer) 189 | FreePool(handleBuffer), handleBuffer = NULL; 190 | } 191 | 192 | static bool IsCMOSClear() 193 | { 194 | // Detect CMOS reset by checking if year before BUILD_YEAR 195 | EFI_STATUS status; 196 | EFI_TIME time = { .Year = 0u }; 197 | 198 | if (EFI_ERROR((status = gRT->GetTime(&time, NULL)))) 199 | SetEFIError(EFIError_CMOSTime, status); 200 | 201 | return time.Year < BUILD_YEAR; 202 | } 203 | 204 | EFI_STATUS EFIAPI rebarInit(IN EFI_HANDLE imageHandle, IN EFI_SYSTEM_TABLE *systemTable) 205 | { 206 | DEBUG((DEBUG_INFO, "ReBarDXE: Loaded\n")); 207 | 208 | reBarImageHandle = imageHandle; 209 | config = GetNvStrapsConfig(false, NULL); // attempts to overflow EFI variable data should result in EFI_BUFFER_TOO_SMALL 210 | nPciBarSizeSelector = NvStrapsConfig_TargetPciBarSizeSelector(config); 211 | 212 | if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_DISABLED && NvStrapsConfig_IsGpuConfigured(config)) 213 | nPciBarSizeSelector = TARGET_PCI_BAR_SIZE_GPU_STRAPS_ONLY; 214 | else 215 | if (NvStrapsConfig_IsDriverConfigured(config) && !NvStrapsConfig_IsGpuConfigured(config)) 216 | SetStatusVar(StatusVar_GPU_Unconfigured); 217 | 218 | if (nPciBarSizeSelector != TARGET_PCI_BAR_SIZE_DISABLED) 219 | { 220 | DEBUG((DEBUG_INFO, "ReBarDXE: Enabled, maximum BAR size 2^%u MiB\n", nPciBarSizeSelector)); 221 | 222 | bool isSetupVarChanged = NvStrapsConfig_EnableSetupVarCRC(config) && IsSetupVariableChanged(); 223 | 224 | if (isSetupVarChanged || IsCMOSClear()) 225 | { 226 | NvStrapsConfig_Clear(config); 227 | NvStrapsConfig_SetIsDirty(config, true); 228 | 229 | if (!isSetupVarChanged) 230 | SaveNvStrapsConfig(NULL); 231 | 232 | SetStatusVar(StatusVar_Cleared); 233 | 234 | return EFI_SUCCESS; 235 | } 236 | 237 | SetStatusVar(StatusVar_Configured); 238 | 239 | S3ResumeScript_Init(NvStrapsConfig_IsGpuConfigured(config)); 240 | pciHostBridgeResourceAllocationProtocolHook(); // For overriding PciHostBridgeResourceAllocationProtocol 241 | } 242 | else 243 | SetStatusVar(StatusVar_Unconfigured); 244 | 245 | return EFI_SUCCESS; 246 | } 247 | 248 | // vim:ft=cpp 249 | -------------------------------------------------------------------------------- /ReBarDxe/ReBar.dsc: -------------------------------------------------------------------------------- 1 | [DEFINES] 2 | DSC_SPECIFICATION = 1.28 3 | PLATFORM_NAME = NvStrapsReBar 4 | PLATFORM_GUID = e3ee4a27-e2a2-4435-bba3-184ccad935a8 5 | PLATFORM_VERSION = 1.00 6 | OUTPUT_DIRECTORY = Build/NvStrapsReBar 7 | SUPPORTED_ARCHITECTURES = X64 8 | BUILD_TARGETS = DEBUG|RELEASE|NOOPT 9 | SKUID_IDENTIFIER = DEFAULT 10 | 11 | [Components] 12 | NvStrapsReBar/ReBarDxe/ReBarDxe.inf 13 | 14 | !include MdePkg/MdeLibs.dsc.inc 15 | [LibraryClasses] 16 | UefiLib|MdePkg/Library/UefiLib/UefiLib.inf 17 | UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf 18 | UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf 19 | UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf 20 | UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf 21 | PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf 22 | DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf 23 | BaseLib|MdePkg/Library/BaseLib/BaseLib.inf 24 | PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf 25 | BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf 26 | ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf 27 | MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf 28 | DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf 29 | FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf 30 | HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf 31 | SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf 32 | UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf 33 | DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf 34 | -------------------------------------------------------------------------------- /ReBarDxe/ReBarDxe.inf: -------------------------------------------------------------------------------- 1 | [Defines] 2 | INF_VERSION = 1.25 3 | BASE_NAME = NvStrapsReBar 4 | FILE_GUID = 06a0b4db-3f73-4cbb-81fc-dabf6ea720c1 5 | MODULE_TYPE = DXE_DRIVER 6 | VERSION_STRING = 1.0 7 | ENTRY_POINT = rebarInit 8 | 9 | [Sources] 10 | include/pciRegs.h 11 | include/LocalAppConfig.h 12 | include/CheckSetupVar.h 13 | include/PciConfig.h 14 | include/S3ResumeScript.h 15 | include/DeviceRegistry.h 16 | include/SetupNvStraps.h 17 | include/EfiVariable.h 18 | include/NvStrapsConfig.h 19 | include/StatusVar.h 20 | include/ReBar.h 21 | PciConfig.c 22 | S3ResumeScript.c 23 | DeviceRegistry.c 24 | SetupNvStraps.c 25 | EfiVariable.c 26 | CheckSetupVar.c 27 | NvStrapsConfig.c 28 | StatusVar.c 29 | ReBar.c 30 | 31 | [Packages] 32 | MdePkg/MdePkg.dec 33 | MdeModulePkg/MdeModulePkg.dec 34 | 35 | [LibraryClasses] 36 | DxeServicesTableLib 37 | UefiDriverEntryPoint 38 | UefiBootServicesTableLib 39 | UefiRuntimeServicesTableLib 40 | UefiLib 41 | 42 | [Protocols] 43 | gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES 44 | gEfiPciHostBridgeResourceAllocationProtocolGuid ## SOMETIMES_CONSUMES 45 | gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES 46 | 47 | [Depex] 48 | gEfiPciRootBridgeIoProtocolGuid 49 | 50 | [Guids] 51 | gEfiEventReadyToBootGuid 52 | 53 | [BuildOptions] 54 | GCC:*_*_*_CC_FLAGS = -flto -DUSING_LTO -Wextra -Wno-unused-parameter -D UEFI_SOURCE 55 | GCC:*_*_*_DLINK_FLAGS = -flto 56 | GCC:*_CLANGPDB_*_CC_FLAGS = -Weverything -Wno-documentation -Wno-missing-variable-declarations -Wno-missing-prototypes -Wno-reserved-macro-identifier -Wno-gnu-zero-variadic-macro-arguments -Wno-padded -Wno-reserved-identifier -Wno-strict-prototypes -Wno-documentation-pedantic -Wno-unused-macros 57 | INTEL:*_*_*_CC_FLAGS = /D UEFI_SOURCE 58 | MSFT:*_*_*_CC_FLAGS = /GL /DUSING_LTO /analyze /W4 /D UEFI_SOURCE /std:c++latest 59 | MSFT:*_*_*_CXX_FLAGS = /std:c++latest 60 | MSFT:*_*_*_DLINK_FLAGS = /LTCG /NOCOFFGRPINFO /BASE:0x180000000 61 | GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG 62 | INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG 63 | MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG 64 | -------------------------------------------------------------------------------- /ReBarDxe/S3ResumeScript.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ReBar.h" 11 | #include "PciConfig.h" 12 | #include "StatusVar.h" 13 | #include "S3ResumeScript.h" 14 | 15 | EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState = NULL; 16 | 17 | static void LoadS3SaveStateProtocol() 18 | { 19 | EFI_STATUS status = gBS->LocateProtocol(&gEfiS3SaveStateProtocolGuid, NULL, (void **)&S3SaveState); 20 | 21 | if (EFI_ERROR(status)) 22 | SetEFIError(EFIError_LocateS3SaveStateProtocol, status); 23 | } 24 | 25 | void S3ResumeScript_Init(bool enabled) 26 | { 27 | if (enabled && !NvStrapsConfig_SkipS3Resume(config)) 28 | LoadS3SaveStateProtocol(); 29 | } 30 | 31 | // EFI_STATUS S3ResumeScript_MemWrite_DWORD(uintptr_t address, uint_least32_t data); 32 | 33 | EFI_STATUS S3ResumeScript_MemReadWrite_DWORD(uintptr_t address, uint_least32_t data, uint_least32_t dataMask) 34 | { 35 | if (S3SaveState) 36 | return S3SaveState->Write 37 | ( 38 | S3SaveState, 39 | (UINT16)EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, 40 | (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, 41 | (UINT64)address, 42 | (void *)&data, 43 | (void *)&dataMask 44 | ); 45 | 46 | return EFI_SUCCESS; 47 | } 48 | 49 | EFI_STATUS S3ResumeScript_PciConfigWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data) 50 | { 51 | if (S3SaveState) 52 | return S3SaveState->Write 53 | ( 54 | S3SaveState, 55 | (UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE, 56 | (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, 57 | (UINT64)pciAddrOffset(pciAddress, offset), 58 | (UINTN)1u, 59 | (void *)&data 60 | ); 61 | 62 | return EFI_SUCCESS; 63 | } 64 | 65 | EFI_STATUS S3ResumeScript_PciConfigReadWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data, uint_least32_t dataMask) 66 | { 67 | if (S3SaveState) 68 | return S3SaveState->Write 69 | ( 70 | S3SaveState, 71 | (UINT16)EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, 72 | (EFI_BOOT_SCRIPT_WIDTH)EfiBootScriptWidthUint32, 73 | (UINT64)pciAddrOffset(pciAddress, offset), 74 | (void *)&data, 75 | (void *)&dataMask 76 | ); 77 | 78 | return EFI_SUCCESS; 79 | } 80 | -------------------------------------------------------------------------------- /ReBarDxe/SetupNvStraps.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "StatusVar.h" 14 | #include "PciConfig.h" 15 | #include "S3ResumeScript.h" 16 | #include "DeviceRegistry.h" 17 | #include "NvStrapsConfig.h" 18 | #include "ReBar.h" 19 | 20 | #include "SetupNvStraps.h" 21 | 22 | // From envytools documentation at: 23 | // https://envytools.readthedocs.io/en/latest/hw/io/pstraps.html 24 | 25 | static uint_least32_t const 26 | TARGET_GPU_STRAPS_BASE_OFFSET = 0x0010'1000u, 27 | TARGET_GPU_STRAPS_SET0_OFFSET = 0x0000'0000u, 28 | TARGET_GPU_STRAPS_SET1_OFFSET = 0x0000'000Cu, 29 | 30 | BAR1_SIZE_PART1_SHIFT = 14u, 31 | BAR1_SIZE_PART1_BITSIZE = 2u, 32 | 33 | BAR1_SIZE_PART2_SHIFT = 20u, 34 | BAR1_SIZE_PART2_BITSIZE = 3u; 35 | 36 | static uint_least16_t enumeratedBridges[ARRAY_SIZE(config->bridge)] = { 0, }; 37 | static uint_least8_t enumeratedBridgeCount = 0u; 38 | 39 | static bool isBridgeEnumerated(uint_least16_t pciLocation) 40 | { 41 | for (unsigned index = 0u; index < enumeratedBridgeCount; index++) 42 | if (enumeratedBridges[index] == pciLocation) 43 | return true; 44 | 45 | return false; 46 | } 47 | 48 | void NvStraps_EnumDevice(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least8_t headerType) 49 | { 50 | if (pciIsPciBridge(headerType) && (enumeratedBridgeCount < ARRAY_SIZE(enumeratedBridges))) 51 | { 52 | uint_least8_t bus, dev, fun; 53 | pciUnpackAddress(pciAddress, &bus, &dev, &fun); 54 | 55 | if (NvStrapsConfig_HasBridgeDevice(config, bus, dev, fun) != ((uint_least32_t)WORD_BITMASK << WORD_BITSIZE | WORD_BITMASK)) 56 | { 57 | enumeratedBridges[enumeratedBridgeCount++] = pciPackLocation(bus, dev, fun); 58 | SetStatusVar(StatusVar_BridgeFound); 59 | } 60 | } 61 | } 62 | 63 | bool NvStraps_CheckDevice(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least16_t *subsysVenID, uint_least16_t *subsysDevID) 64 | { 65 | if (vendorId == TARGET_GPU_VENDOR_ID && NvStrapsConfig_IsGpuConfigured(config) && pciIsVgaController(pciDeviceClass(pciAddress))) 66 | { 67 | EFI_STATUS status = pciReadDeviceSubsystem(pciAddress, subsysVenID, subsysDevID); 68 | 69 | if (EFI_ERROR(status)) 70 | return SetEFIError(EFIError_PCI_DeviceSubsystem, status), false; 71 | 72 | uint_least8_t bus, device, fun; 73 | 74 | pciUnpackAddress(pciAddress, &bus, &device, &fun); 75 | 76 | NvStraps_BarSize barSizeSelector = 77 | NvStrapsConfig_LookupBarSize(config, deviceId, *subsysVenID, *subsysDevID, bus, device, fun); 78 | 79 | if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) 80 | { 81 | SetDeviceStatusVar(pciAddress, barSizeSelector.barSizeSelector == BarSizeSelector_Excluded ? StatusVar_GpuExcluded : StatusVar_GPU_Unconfigured); 82 | return false; 83 | } 84 | 85 | SetDeviceStatusVar(pciAddress, StatusVar_GpuFound); 86 | 87 | return true; 88 | } 89 | 90 | return false; 91 | } 92 | 93 | static bool ConfigureNvStrapsBAR1Size(EFI_PHYSICAL_ADDRESS baseAddress0, UINT8 barSize) 94 | { 95 | UINT32 96 | *pSTRAPS0 = (UINT32 *)(baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET0_OFFSET), 97 | *pSTRAPS1 = (UINT32 *)(baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET1_OFFSET), 98 | STRAPS0, STRAPS1; 99 | 100 | CopyMem(&STRAPS0, pSTRAPS0, sizeof STRAPS0); 101 | CopyMem(&STRAPS1, pSTRAPS1, sizeof STRAPS1); 102 | 103 | UINT8 104 | barSize_Part1 = STRAPS0 >> BAR1_SIZE_PART1_SHIFT & (UINT32_C(1) << BAR1_SIZE_PART1_BITSIZE) - 1u, 105 | barSize_Part2 = STRAPS1 >> BAR1_SIZE_PART2_SHIFT & (UINT32_C(1) << BAR1_SIZE_PART2_BITSIZE) - 1u; 106 | 107 | UINT8 108 | targetBarSize_Part1 = barSize < 3u ? barSize : barSize < 10u ? 2u : 3u, 109 | targetBarSize_Part2 = barSize < 3u ? 0u : barSize < 10u ? barSize - 2u : 7u; 110 | 111 | if (barSize_Part1 != targetBarSize_Part1) 112 | { 113 | STRAPS0 &= ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART1_BITSIZE) - 1u) << BAR1_SIZE_PART1_SHIFT); 114 | STRAPS0 |= (UINT32)targetBarSize_Part1 << BAR1_SIZE_PART1_SHIFT; 115 | STRAPS0 |= UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u); 116 | 117 | CopyMem(pSTRAPS0, &STRAPS0, sizeof STRAPS0); 118 | 119 | EFI_STATUS status = S3ResumeScript_MemReadWrite_DWORD 120 | ( 121 | (UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET0_OFFSET, 122 | (UINT32)targetBarSize_Part1 << BAR1_SIZE_PART1_SHIFT | UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u), 123 | (UINT32) ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART1_BITSIZE) - 1u) << BAR1_SIZE_PART1_SHIFT) 124 | ); 125 | 126 | if (EFI_ERROR(status)) 127 | SetEFIError(EFIError_WriteS3SaveStateProtocol, status); 128 | } 129 | 130 | if (barSize_Part2 != targetBarSize_Part2) 131 | { 132 | STRAPS1 &= ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART2_BITSIZE) - 1u) << BAR1_SIZE_PART2_SHIFT); 133 | STRAPS1 |= (UINT32)targetBarSize_Part2 << BAR1_SIZE_PART2_SHIFT; 134 | STRAPS1 |= UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u); 135 | 136 | CopyMem(pSTRAPS1, &STRAPS1, sizeof STRAPS1); 137 | 138 | EFI_STATUS status = S3ResumeScript_MemReadWrite_DWORD 139 | ( 140 | (UINT64)baseAddress0 + TARGET_GPU_STRAPS_BASE_OFFSET + TARGET_GPU_STRAPS_SET1_OFFSET, 141 | (UINT32)targetBarSize_Part2 << BAR1_SIZE_PART2_SHIFT | UINT32_C(1) << (DWORD_SIZE * BYTE_BITSIZE - 1u), 142 | (UINT32) ~(UINT32)(((UINT32_C(1) << BAR1_SIZE_PART2_BITSIZE) - 1u) << BAR1_SIZE_PART2_SHIFT) 143 | ); 144 | 145 | if (EFI_ERROR(status)) 146 | SetEFIError(EFIError_WriteS3SaveStateProtocol, status); 147 | } 148 | 149 | return barSize_Part1 + barSize_Part2 != targetBarSize_Part1 + targetBarSize_Part2; 150 | } 151 | 152 | void NvStraps_Setup(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_fast8_t nPciBarSizeSelector) 153 | { 154 | uint_least8_t bus, device, func; 155 | 156 | pciUnpackAddress(pciAddress, &bus, &device, &func); 157 | 158 | NvStraps_BarSize barSizeSelector = 159 | NvStrapsConfig_LookupBarSize(config, deviceId, subsysVenID, subsysDevID, bus, device, func); 160 | 161 | if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) 162 | return; 163 | 164 | NvStraps_BarSizeMaskOverride sizeMaskOverride = NvStrapsConfig_LookupBarSizeMaskOverride(config, deviceId, subsysVenID, subsysDevID, bus, device, func); 165 | 166 | NvStraps_GPUConfig const *gpuConfig = NvStrapsConfig_LookupGPUConfig(config, bus, device, func); 167 | 168 | if (!gpuConfig) 169 | { 170 | SetDeviceStatusVar(pciAddress, StatusVar_NoGpuConfig); 171 | return; 172 | } 173 | 174 | if (gpuConfig->bar0.base >= UINT32_MAX || gpuConfig->bar0.top >= UINT32_MAX || gpuConfig->bar0.base & UINT32_C(0x0000'000F) 175 | || gpuConfig->bar0.base % (gpuConfig->bar0.top - gpuConfig->bar0.base + 1u)) 176 | { 177 | SetDeviceStatusVar(pciAddress, StatusVar_BadGpuConfig); 178 | return; 179 | } 180 | 181 | NvStraps_BridgeConfig const *bridgeConfig = NvStrapsConfig_LookupBridgeConfig(config, bus); 182 | 183 | if (!bridgeConfig) 184 | { 185 | SetDeviceStatusVar(pciAddress, StatusVar_NoBridgeConfig); 186 | return; 187 | } 188 | else 189 | if (!isBridgeEnumerated(pciPackLocation(bridgeConfig->bridgeBus, bridgeConfig->bridgeDevice, bridgeConfig->bridgeFunction))) 190 | { 191 | SetDeviceStatusVar(pciAddress, StatusVar_BridgeNotEnumerated); 192 | return; 193 | } 194 | 195 | UINTN bridgePciAddress = EFI_PCI_ADDRESS(bridgeConfig->bridgeBus, bridgeConfig->bridgeDevice, bridgeConfig->bridgeFunction, 0u); 196 | uint_least8_t bridgeSecondaryBus; 197 | EFI_STATUS status = pciBridgeSecondaryBus(bridgePciAddress, &bridgeSecondaryBus); 198 | 199 | if (EFI_ERROR(status)) 200 | { 201 | SetDeviceEFIError(pciAddress, EFIError_PCI_BridgeSecondaryBus, status); 202 | return; 203 | } 204 | 205 | if (bridgeSecondaryBus != bus) 206 | { 207 | SetDeviceStatusVar(pciAddress, StatusVar_BadBridgeConfig); 208 | return; 209 | } 210 | 211 | UINT32 bridgeSaveArea[3u], gpuSaveArea[2u]; 212 | 213 | // EFI_PHYSICAL_ADDRESS baseAddress0 = BASE_4GB - 1u, bridgeIoPortRangeBegin = BASE_64KB - 1u; 214 | 215 | // if (EFI_SUCCESS == gDS->AllocateMemorySpace(EfiGcdAllocateMaxAddressSearchTopDown, EfiGcdMemoryTypeMemoryMappedIo, 25u, SIZE_32MB, &baseAddress0, reBarImageHandle, NULL)) 216 | // { 217 | // if (EFI_SUCCESS == gDS->AllocateIoSpace(EfiGcdAllocateMaxAddressSearchTopDown, EfiGcdIoTypeIo, 12u, SIZE_1KB / 2, &bridgeIoPortRangeBegin, reBarImageHandle, NULL)) 218 | // { 219 | // EFI_GCD_MEMORY_SPACE_DESCRIPTOR memoryDescriptor; 220 | // 221 | // if (EFI_ERROR(gDS->GetMemorySpaceDescriptor(baseAddress0, &memoryDescriptor))) 222 | // SetStatusVar(StatusVar_EFIError); 223 | // else 224 | // if (EFI_ERROR(gDS->SetMemorySpaceAttributes(baseAddress0, SIZE_16MB, memoryDescriptor.Attributes | EFI_MEMORY_UC))) 225 | // SetStatusVar(StatusVar_EFIError); 226 | 227 | pciSaveAndRemapBridgeConfig(bridgePciAddress, bridgeSaveArea, gpuConfig->bar0.base, gpuConfig->bar0.top, TARGET_BRIDGE_IO_BASE_LIMIT); 228 | pciSaveAndRemapDeviceBAR0(pciAddress, gpuSaveArea, gpuConfig->bar0.base); 229 | 230 | bool configUpdated = ConfigureNvStrapsBAR1Size(gpuConfig->bar0.base & UINT32_C(0xFFFF'FFF0), barSizeSelector.barSizeSelector); // mask the flag bits from the address 231 | 232 | // RecordUpdateGPU(bus, device, func, barSizeSelector.barSizeSelector); 233 | 234 | pciRestoreDeviceConfig(pciAddress, gpuSaveArea); 235 | pciRestoreBridgeConfig(bridgePciAddress, bridgeSaveArea); 236 | 237 | SetDeviceStatusVar(pciAddress, configUpdated ? StatusVar_GpuStrapsConfigured : StatusVar_GpuStrapsPreConfigured); 238 | 239 | uint_least16_t capabilityOffset = pciFindExtCapability(pciAddress, PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID); 240 | uint_least32_t barSizeMask = capabilityOffset ? pciRebarGetPossibleSizes(pciAddress, capabilityOffset, vendorId, deviceId, PCI_BAR_IDX1) : 0u; 241 | 242 | if (barSizeMask) 243 | { 244 | if (barSizeMask & UINT32_C(1) << (barSizeSelector.barSizeSelector + 6u)) 245 | SetDeviceStatusVar(pciAddress, StatusVar_GpuStrapsConfirm); 246 | else 247 | SetDeviceStatusVar(pciAddress, StatusVar_GpuStrapsNoConfirm); 248 | } 249 | else 250 | if (isTuringGPU(deviceId)) 251 | SetDeviceStatusVar(pciAddress, StatusVar_GpuNoReBarCapability); 252 | 253 | if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_GPU_ONLY) 254 | { 255 | if (capabilityOffset && (barSizeMask & UINT32_C(0x0000'0001) << (barSizeSelector.barSizeSelector + 6u) || sizeMaskOverride.sizeMaskOverride)) 256 | { 257 | if ((barSizeMask & UINT32_C(0x0000'0001) << (barSizeSelector.barSizeSelector + 6u)) == 0) 258 | SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarSizeOverride); 259 | 260 | if (pciRebarSetSize(pciAddress, capabilityOffset, PCI_BAR_IDX1, (uint_least8_t)(barSizeSelector.barSizeSelector + 6u))) 261 | SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarConfigured); 262 | } 263 | } 264 | else 265 | if (nPciBarSizeSelector == TARGET_PCI_BAR_SIZE_GPU_STRAPS_ONLY) 266 | { 267 | EFI_EVENT eventTimer = NULL; 268 | 269 | if (EFI_ERROR((status = gBS->CreateEvent(EVT_TIMER, TPL_APPLICATION, NULL, NULL, &eventTimer)))) 270 | SetDeviceEFIError(pciAddress, EFIError_CreateTimer, status); 271 | else 272 | { 273 | if (EFI_ERROR((status = gBS->SetTimer(eventTimer, TimerRelative, 1'000'000u)))) 274 | SetDeviceEFIError(pciAddress, EFIError_SetupTimer, status); 275 | else 276 | { 277 | UINTN eventIndex = 0u; 278 | 279 | if (EFI_ERROR((status = gBS->WaitForEvent(1, &eventTimer, &eventIndex)))) 280 | SetDeviceEFIError(pciAddress, EFIError_WaitTimer, status); 281 | } 282 | 283 | if (EFI_ERROR((status = gBS->CloseEvent(eventTimer)))) 284 | SetDeviceEFIError(pciAddress, EFIError_CloseTimer, status); 285 | } 286 | } 287 | 288 | // gDS->FreeIoSpace(bridgeIoPortRangeBegin, SIZE_1KB / 2u); 289 | // } 290 | // else 291 | // SetStatusVar(StatusVar_EFIAllocationError); 292 | // 293 | // gDS->FreeMemorySpace(baseAddress0, SIZE_32MB); 294 | // } 295 | // else 296 | // SetStatusVar(StatusVar_EFIAllocationError); 297 | } 298 | 299 | 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) 300 | { 301 | if (vid == TARGET_GPU_VENDOR_ID && subsysVenID != WORD_BITMASK && subsysDevID != WORD_BITMASK && barIndex == PCI_BAR_IDX1) 302 | { 303 | uint_least8_t bus, device, func; 304 | pciUnpackAddress(pciAddress, &bus, &device, &func); 305 | 306 | NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); 307 | 308 | if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) 309 | return false; 310 | 311 | NvStraps_BarSizeMaskOverride sizeMaskOverride = NvStrapsConfig_LookupBarSizeMaskOverride(config, did, subsysVenID, subsysDevID, bus, device, func); 312 | 313 | if (sizeMaskOverride.sizeMaskOverride) 314 | { 315 | NvStraps_BridgeConfig const *bridgeConfig = NvStrapsConfig_LookupBridgeConfig(config, bus); 316 | 317 | return isBridgeEnumerated(pciPackLocation(bridgeConfig->bridgeBus, bridgeConfig->bridgeDevice, bridgeConfig->bridgeFunction)); 318 | } 319 | 320 | return false; 321 | } 322 | 323 | return false; 324 | } 325 | 326 | 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) 327 | { 328 | uint_least8_t bus, device, func; 329 | 330 | pciUnpackAddress(pciAddress, &bus, &device, &func); 331 | 332 | NvStraps_BarSize barSizeSelector = NvStrapsConfig_LookupBarSize(config, did, subsysVenID, subsysDevID, bus, device, func); 333 | 334 | if (barSizeSelector.priority == UNCONFIGURED || barSizeSelector.barSizeSelector == BarSizeSelector_None || barSizeSelector.barSizeSelector == BarSizeSelector_Excluded) 335 | return barSizeMask; 336 | 337 | if ((barSizeMask & UINT32_C(0x00000001) << (6u + (unsigned)barSizeSelector.barSizeSelector)) == 0u) 338 | SetDeviceStatusVar(pciAddress, StatusVar_GpuReBarSizeOverride); 339 | 340 | return barSizeMask | UINT32_C(0x00000001) << (6u + (unsigned)barSizeSelector.barSizeSelector); 341 | } 342 | 343 | // vim: ft=cpp 344 | -------------------------------------------------------------------------------- /ReBarDxe/StatusVar.c: -------------------------------------------------------------------------------- 1 | 2 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 3 | # include 4 | # include 5 | #else 6 | # if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64) 7 | # if defined(_M_AMD64) && !defined(_AMD64_) 8 | # define _AMD64_ 9 | # endif 10 | # include 11 | # endif 12 | #endif 13 | 14 | #include 15 | 16 | #include "LocalAppConfig.h" 17 | #include "PciConfig.h" 18 | #include "NvStrapsConfig.h" 19 | #include "EfiVariable.h" 20 | #include "StatusVar.h" 21 | 22 | char const StatusVar_Name[] = "NvStrapsReBarStatus"; 23 | 24 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 25 | static uint_least8_t nVarCount = 2u; 26 | static uint_least64_t statusVar[NvStraps_GPU_MAX_COUNT + 1u] = { StatusVar_NotLoaded, StatusVar_NotLoaded }; 27 | 28 | static inline uint_least16_t MakeBusLocation(uint_least8_t bus, uint_least8_t device, uint_least8_t function) 29 | { 30 | return (uint_least16_t)bus << 8u | ((uint_least16_t)device & 0b0001'1111u) << 3u | function & 0b0111u; 31 | } 32 | 33 | static inline UINT16 PciAddressToBusLocation(UINTN pciAddress) 34 | { 35 | return MakeBusLocation(pciAddress >> 24u & 0xFFu, pciAddress >> 16u & 0xFFu, pciAddress >> 8u & 0xFFu); 36 | } 37 | 38 | static EFI_STATUS WriteStatusVar(uint_least16_t pciLocation) 39 | { 40 | uint_least64_t var = 41 | (uint_least64_t)pciLocation << (WORD_BITSIZE + DWORD_BITSIZE) 42 | | (uint_least64_t)statusVar[0u] & UINT64_C(0x0000FFFF'FFFFFFFF); 43 | 44 | BYTE buffer[QWORD_SIZE]; 45 | 46 | return WriteEfiVariable(StatusVar_Name, buffer, (uint_least32_t)(pack_QWORD(buffer, var) - buffer), EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); 47 | }; 48 | 49 | static void SetStatusVarInternal(StatusVar val, uint_least16_t pciLocation) 50 | { 51 | if (val > statusVar[0u]) 52 | { 53 | statusVar[0u] = val; 54 | WriteStatusVar(pciLocation); 55 | } 56 | } 57 | 58 | void SetStatusVar(StatusVar val) 59 | { 60 | SetStatusVarInternal(val, 0u); 61 | } 62 | 63 | void SetEFIErrorInternal(EFIErrorLocation errLocation, EFI_STATUS status, uint_least16_t pciLocation) 64 | { 65 | if (statusVar[0u] < UINT64_C(1) << DWORD_BITSIZE) 66 | { 67 | uint_least64_t value = 68 | (uint_least64_t)(+errLocation & +BYTE_BITMASK) << (DWORD_BITSIZE + BYTE_BITSIZE) 69 | | (uint_least64_t)(status & BYTE_BITMASK) << DWORD_BITSIZE 70 | | StatusVar_Internal_EFIError; 71 | 72 | statusVar[0u] = value; 73 | WriteStatusVar(pciLocation); 74 | } 75 | } 76 | 77 | void SetEFIError(EFIErrorLocation errLocation, EFI_STATUS status) 78 | { 79 | SetEFIErrorInternal(errLocation, status, 0u); 80 | } 81 | 82 | void SetDeviceEFIError(UINTN pciAddress, EFIErrorLocation errLocation, EFI_STATUS status) 83 | { 84 | uint_least8_t bus, dev, fun; 85 | 86 | pciUnpackAddress(pciAddress, &bus, &dev, &fun); 87 | SetEFIErrorInternal(errLocation, status, pciPackLocation(bus, dev, fun)); 88 | } 89 | 90 | void SetDeviceStatusVar(UINTN pciAddress, StatusVar val) 91 | { 92 | uint_least8_t bus, dev, fun; 93 | 94 | pciUnpackAddress(pciAddress, &bus, &dev, &fun); 95 | SetStatusVarInternal(val, pciPackLocation(bus, dev, fun)); 96 | } 97 | #else 98 | uint_least64_t ReadStatusVar(ERROR_CODE *errorCode) 99 | { 100 | BYTE buffer[QWORD_SIZE]; 101 | uint_least32_t size = sizeof buffer; 102 | *errorCode = ReadEfiVariable(StatusVar_Name, buffer, &size); 103 | 104 | if (*errorCode) 105 | return StatusVar_NVAR_API_Error; 106 | 107 | if (size == 0u) 108 | return StatusVar_NotLoaded; 109 | 110 | if (size != sizeof buffer) 111 | return StatusVar_ParseError; 112 | 113 | return unpack_QWORD(buffer); 114 | } 115 | #endif 116 | -------------------------------------------------------------------------------- /ReBarDxe/buildffs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) 2022 xCuri0 4 | # SPDX-License-Identifier: MIT 5 | # 6 | import os 7 | import sys 8 | import glob 9 | import subprocess 10 | import glob 11 | from pefile import PE 12 | 13 | name = "NvStrapsReBar" 14 | version = "1.0" 15 | GUID = "90d10790-bbfa-404b-873b-5bdb3ada3c56" 16 | shell = sys.platform == "win32" 17 | buildtype = "RELEASE" 18 | 19 | 20 | def filesub(filep, f, r): 21 | # Read in the file 22 | with open(filep, 'r') as file : 23 | filedata = file.read() 24 | 25 | # Replace the target string 26 | filedata = filedata.replace(f, r) 27 | 28 | # Write the file out again 29 | with open(filep, 'w') as file: 30 | file.write(filedata) 31 | 32 | def set_bit(data, bit): 33 | """Sets a specific bit.""" 34 | return data | (1 << bit) 35 | 36 | def set_nx_compat_flag(pe): 37 | """Sets the nx_compat flag to 1 in the PE/COFF file.""" 38 | dllchar = pe.OPTIONAL_HEADER.DllCharacteristics 39 | dllchar = set_bit(dllchar, 8) # 8th bit is the nx_compat_flag 40 | pe.OPTIONAL_HEADER.DllCharacteristics = dllchar 41 | pe.merge_modified_section_data() 42 | return pe 43 | 44 | if len(sys.argv) > 1: 45 | buildtype = sys.argv[1].upper() 46 | 47 | # 3 arguments = Github Actions 48 | if len(sys.argv) == 3: 49 | print("TARGET: ", os.environ['TARGET']) 50 | print("TARGET_ARCH: ", os.environ['TARGET_ARCH']) 51 | print("TOOL_CHAIN_TAG: ", os.environ['TOOL_CHAIN_TAG']) 52 | 53 | # setup Conf/target.txt 54 | filesub("./Conf/target.txt", "DEBUG", os.environ['TARGET']) 55 | filesub("./Conf/target.txt", "IA32", os.environ['TARGET_ARCH']) 56 | filesub("./Conf/target.txt", "VS2015x86", os.environ['TOOL_CHAIN_TAG']) 57 | else: 58 | os.chdir("../..") 59 | 60 | subprocess.run(["build", "--platform=NvStrapsReBar/ReBarDxe/ReBar.dsc"], shell=shell, env=os.environ, stderr=sys.stderr, stdout=sys.stdout) 61 | 62 | ReBarDXE = glob.glob(f"./Build/NvStrapsReBar/{buildtype}_*/X64/NvStrapsReBar.efi") 63 | 64 | if len(ReBarDXE) != 1: 65 | print("Build failed") 66 | sys.exit(1) 67 | 68 | # set NX_COMPAT 69 | pe = PE(ReBarDXE[0]) 70 | set_nx_compat_flag(pe) 71 | 72 | os.remove(ReBarDXE[0]) 73 | pe.write(ReBarDXE[0]) 74 | 75 | print(ReBarDXE[0]) 76 | print("Building FFS") 77 | os.chdir(os.path.dirname(ReBarDXE[0])) 78 | 79 | try: 80 | os.remove("pe32.sec") 81 | os.remove("name.sec") 82 | os.remove("NvStrapsReBar.ffs") 83 | except FileNotFoundError: 84 | pass 85 | 86 | subprocess.run(["GenSec", "-o", "pe32.sec", "NvStrapsReBar.efi", "-S", "EFI_SECTION_PE32"], shell=shell, env=os.environ, stderr=sys.stderr, stdout=sys.stdout) 87 | subprocess.run(["GenSec", "-o", "name.sec", "-S", "EFI_SECTION_USER_INTERFACE", "-n", name], shell=shell, env=os.environ, stderr=sys.stderr, stdout=sys.stdout) 88 | subprocess.run(["GenFfs", "-g", GUID, "-o", "NvStrapsReBar.ffs", "-i", "pe32.sec", "-i" ,"name.sec", "-t", "EFI_FV_FILETYPE_DRIVER", "--checksum"], shell=shell, env=os.environ, stderr=sys.stderr, stdout=sys.stdout) 89 | 90 | try: 91 | os.remove("pe32.sec") 92 | os.remove("name.sec") 93 | except FileNotFoundError: 94 | pass 95 | 96 | print("Finished") -------------------------------------------------------------------------------- /ReBarDxe/include/CheckSetupVar.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_CHECK_SETUP_VAR_H) 2 | #define NV_STRAPS_REBAR_CHECK_SETUP_VAR_H 3 | 4 | #include 5 | 6 | bool IsSetupVariableChanged(); 7 | 8 | #endif // !defined(NV_STRAPS_REBAR_CHECK_SETUP_VAR_H) 9 | -------------------------------------------------------------------------------- /ReBarDxe/include/DeviceRegistry.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_DEVICE_REGISTRY_H) 2 | #define NV_STRAPS_REBAR_DEVICE_REGISTRY_H 3 | 4 | // Some test to check if compiling UEFI code 5 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 6 | # include 7 | #else 8 | # if defined(__cplusplus) && !defined(NVSTRAPS_DXE_DRIVER) 9 | import NvStraps.WinAPI; 10 | # else 11 | # include 12 | # endif 13 | #endif 14 | 15 | #if !defined(__cplusplus) 16 | # include 17 | #endif 18 | 19 | // From PSTRAPS documentation in envytools: 20 | // https://envytools.readthedocs.io/en/latest/hw/io/pstraps.html 21 | #if defined(__cplusplus) && !defined(NVSTRAPS_DXE_DRIVER) 22 | extern constexpr 23 | #else 24 | static 25 | #endif 26 | unsigned short const MAX_BAR_SIZE_SELECTOR = 10u; 27 | 28 | typedef enum BarSizeSelector 29 | { 30 | BarSizeSelector_64M = 0u, 31 | BarSizeSelector_128M = 1u, 32 | BarSizeSelector_256M = 2u, 33 | BarSizeSelector_512M = 3u, 34 | BarSizeSelector_1G = 4u, 35 | BarSizeSelector_2G = 5u, 36 | BarSizeSelector_4G = 6u, 37 | BarSizeSelector_8G = 7u, 38 | BarSizeSelector_16G = 8u, 39 | BarSizeSelector_32G = 9u, 40 | BarSizeSelector_64G = 10u, 41 | 42 | BarSizeSelector_Excluded = 0xFEu, 43 | BarSizeSelector_None = 0xFFu 44 | } 45 | BarSizeSelector; 46 | 47 | #if defined(__cplusplus) 48 | extern "C" 49 | { 50 | #endif 51 | 52 | bool isTuringGPU(UINT16 deviceID); 53 | BarSizeSelector lookupBarSizeInRegistry(UINT16 deviceID); 54 | 55 | #if defined(__cplusplus) 56 | } // extern "C" 57 | #endif 58 | 59 | #endif // !defined(NV_STRAPS_REBAR_DEVICE_REGISTRY_H) 60 | -------------------------------------------------------------------------------- /ReBarDxe/include/EfiVariable.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_EFI_VARIABLE_H) 2 | #define NV_STRAPS_REBAR_EFI_VARIABLE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "LocalAppConfig.h" 8 | 9 | #if defined(__cplusplus) 10 | extern "C" 11 | { 12 | #endif 13 | 14 | enum 15 | { 16 | MAX_VARIABLE_NAME_LENGTH = 64u 17 | }; 18 | 19 | #if defined(WINDOWS_SOURCE) 20 | # if !defined(EFI_VARIABLE_NON_VOLATILE) && !defined(EFI_VARIABLE_BOOTSERVICE_ACCESS) && !defined(EFI_VARIABLE_RUNTIME_ACCESS) 21 | enum 22 | { 23 | EFI_VARIABLE_NON_VOLATILE = UINT32_C(0x0000'0001), 24 | EFI_VARIABLE_BOOTSERVICE_ACCESS = UINT32_C(0x0000'0002), 25 | EFI_VARIABLE_RUNTIME_ACCESS = UINT32_C(0x0000'0004), 26 | EFI_VARIABLE_HARDWARE_ERROR_RECORD = UINT32_C(0x0000'0008) 27 | }; 28 | # endif 29 | #endif 30 | 31 | inline uint_least8_t unpack_BYTE(BYTE const *buffer); 32 | inline uint_least16_t unpack_WORD(BYTE const *buffer); 33 | inline uint_least32_t unpack_DWORD(BYTE const *buffer); 34 | inline uint_least64_t unpack_QWORD(BYTE const *buffer); 35 | inline BYTE *pack_BYTE(BYTE *buffer, uint_least8_t value); 36 | inline BYTE *pack_WORD(BYTE *buffer, uint_least16_t value); 37 | inline BYTE *pack_DWORD(BYTE *buffer, uint_least32_t value); 38 | inline BYTE *pack_QWORD(BYTE *buffer, uint_least64_t value); 39 | 40 | ERROR_CODE ReadEfiVariable(char const name[MAX_VARIABLE_NAME_LENGTH], BYTE *buffer, uint_least32_t *size); 41 | ERROR_CODE WriteEfiVariable(char const name[MAX_VARIABLE_NAME_LENGTH], BYTE /* const */ *buffer, uint_least32_t size, uint_least32_t attributes); 42 | 43 | inline uint_least8_t unpack_BYTE(BYTE const *buffer) 44 | { 45 | return *buffer; 46 | } 47 | 48 | inline uint_least16_t unpack_WORD(BYTE const *buffer) 49 | { 50 | return *buffer | (uint_least16_t)buffer[1u] << BYTE_BITSIZE; 51 | } 52 | 53 | inline uint_least32_t unpack_DWORD(BYTE const *buffer) 54 | { 55 | return *buffer 56 | | (uint_least16_t)buffer[1u] << BYTE_BITSIZE 57 | | (uint_least32_t)buffer[2u] << 2u * BYTE_BITSIZE 58 | | (uint_least32_t)buffer[3u] << 3u * BYTE_BITSIZE; 59 | } 60 | 61 | inline uint_least64_t unpack_QWORD(BYTE const *buffer) 62 | { 63 | return *buffer 64 | | (uint_least16_t)buffer[1u] << BYTE_BITSIZE 65 | | (uint_least32_t)buffer[2u] << 2u * BYTE_BITSIZE 66 | | (uint_least32_t)buffer[3u] << 3u * BYTE_BITSIZE 67 | | (uint_least64_t)buffer[4u] << 4u * BYTE_BITSIZE 68 | | (uint_least64_t)buffer[5u] << 5u * BYTE_BITSIZE 69 | | (uint_least64_t)buffer[6u] << 6u * BYTE_BITSIZE 70 | | (uint_least64_t)buffer[7u] << 7u * BYTE_BITSIZE; 71 | } 72 | 73 | inline BYTE *pack_BYTE(BYTE *buffer, uint_least8_t value) 74 | { 75 | return *buffer++ = value, buffer; 76 | } 77 | 78 | inline BYTE *pack_WORD(BYTE *buffer, uint_least16_t value) 79 | { 80 | *buffer++ = value & BYTE_BITMASK, value >>= BYTE_BITSIZE; 81 | *buffer++ = value & BYTE_BITMASK; 82 | 83 | return buffer; 84 | } 85 | 86 | inline BYTE *pack_DWORD(BYTE *buffer, uint_least32_t value) 87 | { 88 | for (unsigned i = 0u; i < DWORD_SIZE; i++) 89 | *buffer++ = value & BYTE_BITMASK, value >>= BYTE_BITSIZE; 90 | 91 | return buffer; 92 | } 93 | 94 | inline BYTE *pack_QWORD(BYTE *buffer, uint_least64_t value) 95 | { 96 | for (unsigned i = 0u; i < QWORD_SIZE; i++) 97 | *buffer++ = value & BYTE_BITMASK, value >>= BYTE_BITSIZE; 98 | 99 | return buffer; 100 | } 101 | 102 | #if defined(__cplusplus) 103 | } // extern "C" 104 | #endif 105 | 106 | #endif // !defined(NV_STRAPS_REBAR_EFI_VARIABLE_H) 107 | -------------------------------------------------------------------------------- /ReBarDxe/include/LocalAppConfig.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_LOCAL_APP_CONFIG_H) 2 | #define NV_STRAPS_REBAR_LOCAL_APP_CONFIG_H 3 | 4 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 5 | # include 6 | typedef UINT8 BYTE; 7 | typedef EFI_STATUS ERROR_CODE; 8 | enum 9 | { 10 | ERROR_CODE_SUCCESS = (ERROR_CODE)EFI_SUCCESS 11 | }; 12 | #else 13 | # if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 14 | # if defined(__cplusplus) && !defined(NVSTRAPS_DXE_DRIVER) 15 | import NvStraps.WinAPI; 16 | # else 17 | # include 18 | # include 19 | # endif 20 | # define WINDOWS_SOURCE 21 | typedef DWORD ERROR_CODE; 22 | enum 23 | { 24 | ERROR_CODE_SUCCESS = (ERROR_CODE)ERROR_SUCCESS 25 | }; 26 | # else 27 | # include 28 | typedef errno_t ERROR_CODE; 29 | enum 30 | { 31 | ERROR_CODE_SUCCESS = (ERROR_CODE)0 32 | }; 33 | # endif 34 | # define ARRAY_SIZE(Container) (sizeof(Container) / sizeof((Container)[0u])) 35 | #endif 36 | 37 | #if defined(__cplusplus) 38 | import std; 39 | using UINTN = std::uintptr_t; 40 | using std::uint_least64_t; 41 | static_assert(std::numeric_limits::radix == 2u, "Binary digits expected for char representation"); 42 | #else 43 | # include 44 | # include 45 | # include 46 | typedef uintptr_t UINTN; 47 | #endif 48 | 49 | enum 50 | { 51 | #if defined(__cplusplus) 52 | BYTE_BITSIZE = unsigned { std::numeric_limits::digits }, 53 | #else 54 | BYTE_BITSIZE = (unsigned)CHAR_BIT, 55 | #endif 56 | BYTE_BITMASK = (1u << BYTE_BITSIZE) - 1u, 57 | BYTE_SIZE = 1u, 58 | 59 | WORD_SIZE = 2u, 60 | WORD_BITSIZE = WORD_SIZE * BYTE_BITSIZE, 61 | WORD_BITMASK = (1u << WORD_BITSIZE) - 1u, 62 | 63 | DWORD_SIZE = 4u, 64 | DWORD_BITSIZE = DWORD_SIZE * BYTE_BITSIZE, 65 | // DWORD_BITMASK = ((uint_least64_t)1u << DWORD_BITSIZE) - 1u, // end up with the wrong type (int) 66 | 67 | QWORD_SIZE = 8u, 68 | QWORD_BITSIZE = QWORD_SIZE * BYTE_BITSIZE 69 | }; 70 | 71 | #endif // !defined(NV_STRAPS_REBAR_LOCAL_APP_CONFIG_H) 72 | -------------------------------------------------------------------------------- /ReBarDxe/include/PciConfig.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_PCI_CONFIG_H) 2 | #define NV_STRAPS_REBAR_PCI_CONFIG_H 3 | 4 | #include 5 | #include 6 | 7 | #if defined(UEFI_SOURCE) 8 | # include 9 | # include 10 | #endif 11 | 12 | #include "LocalAppConfig.h" 13 | 14 | #if defined(UEFI_SOURCE) 15 | UINT64 pciAddrOffset(UINTN pciAddress, INTN offset); 16 | 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); 17 | uint_least16_t pciFindExtCapability(UINTN pciAddress, uint_least32_t cap); 18 | uint_least32_t pciRebarGetPossibleSizes(UINTN pciAddress, uint_least16_t capabilityOffset, UINT16 vid, UINT16 did, uint_least8_t barIndex); 19 | uint_least32_t pciRebarPollPossibleSizes(UINTN pciAddress, uint_least16_t capabilityOffset, uint_least8_t barIndex, uint_least32_t barSizeMask); 20 | 21 | EFI_STATUS pciReadDeviceSubsystem(UINTN pciAddress, uint_least16_t *subsysVenID, uint_least16_t *subsysDevID); 22 | EFI_STATUS pciBridgeSecondaryBus(UINTN pciAddress, uint_least8_t *secondaryBus); 23 | uint_least32_t pciDeviceClass(UINTN pciAddress); 24 | uint_least32_t pciDeviceBAR0(UINTN pciAddress, EFI_STATUS *status); 25 | bool pciRebarSetSize(UINTN pciAddress, uint_least16_t capabilityOffset, uint_least8_t barIndex, uint_least8_t barSizeBitIndex); 26 | 27 | void pciSaveAndRemapBridgeConfig(UINTN bridgePciAddress, UINT32 bridgeSaveArea[3u], EFI_PHYSICAL_ADDRESS baseAddress0, EFI_PHYSICAL_ADDRESS topAddress0, EFI_PHYSICAL_ADDRESS bridgeIoBaseLimit); 28 | void pciRestoreBridgeConfig(UINTN bridgePciAddress, UINT32 bridgeSaveArea[3u]); 29 | 30 | void pciSaveAndRemapDeviceBAR0(UINTN pciAddress, UINT32 deviceSaveArea[2u], EFI_PHYSICAL_ADDRESS baseAddress0); 31 | void pciRestoreDeviceConfig(UINTN pciAddress, UINT32 deviceSaveArea[2u]); 32 | 33 | bool pciIsPciBridge(uint_least8_t headerType); 34 | bool pciIsVgaController(uint_least32_t pciClassReg); 35 | 36 | #endif // defined(UEFI_SOURCE) 37 | 38 | inline void pciUnpackAddress(UINTN pciAddress, uint_least8_t *bus, uint_least8_t *dev, uint_least8_t *fun) 39 | { 40 | *bus = pciAddress >> 24u & BYTE_BITMASK; 41 | *dev = pciAddress >> 16u & BYTE_BITMASK; 42 | *fun = pciAddress >> 8u & BYTE_BITMASK; 43 | } 44 | 45 | inline uint_least16_t pciPackLocation(uint_least8_t bus, uint_least8_t dev, uint_least8_t fun) 46 | { 47 | return (uint_least16_t) bus << BYTE_BITSIZE | dev << 3u & 0b1111'1000u | fun & 0b0111u; 48 | } 49 | 50 | 51 | #endif // !defined(NV_STRAPS_REBAR_PCI_CONFIG_H) 52 | -------------------------------------------------------------------------------- /ReBarDxe/include/ReBar.h: -------------------------------------------------------------------------------- 1 | #if !defined(REBAR_UEFI_REBAR_H) 2 | #define REBAR_UEFI_REBAR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "NvStrapsConfig.h" 8 | 9 | extern EFI_HANDLE reBarImageHandle; 10 | extern NvStrapsConfig *config; 11 | 12 | #endif // !defined(REBAR_UEFI_REBAR_H) 13 | -------------------------------------------------------------------------------- /ReBarDxe/include/S3ResumeScript.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H) 2 | #define NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | void S3ResumeScript_Init(bool enabled); 10 | // EFI_STATUS S3ResumeScript_MemWrite_DWORD(uintptr_t address, uint_least32_t data); 11 | EFI_STATUS S3ResumeScript_MemReadWrite_DWORD(uintptr_t address, uint_least32_t data, uint_least32_t dataMask); 12 | EFI_STATUS S3ResumeScript_PciConfigWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data); 13 | EFI_STATUS S3ResumeScript_PciConfigReadWrite_DWORD(UINTN pciAddress, uint_least16_t offset, uint_least32_t data, uint_least32_t dataMask); 14 | 15 | #endif // !defined(NV_STRAPS_REBAR_S3_RESUME_SCRIPT_H) 16 | -------------------------------------------------------------------------------- /ReBarDxe/include/SetupNvStraps.h: -------------------------------------------------------------------------------- 1 | #if !defined(REBAR_UEFI_SETUP_NV_STRAPS_H) 2 | #define REBAR_UEFI_SETUP_NV_STRAPS_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | void NvStraps_EnumDevice(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least8_t headerType); 10 | bool NvStraps_CheckDevice(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least16_t *subsysVenID, uint_least16_t *subsysDevID); 11 | void NvStraps_Setup(UINTN pciAddress, uint_least16_t vendorId, uint_least16_t deviceId, uint_least16_t subsysVenID, uint_least16_t subsysDevID, uint_fast8_t reBarState); 12 | 13 | bool NvStraps_CheckBARSizeListAdjust(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, UINT8 barIndex); 14 | uint_least32_t NvStraps_AdjustBARSizeList(UINTN pciAddress, uint_least16_t vid, uint_least16_t did, uint_least16_t subsysVenID, uint_least16_t subsysDevID, UINT8 barIndex, uint_least32_t barSizeMask); 15 | 16 | #endif // !defined(REBAR_UEFI_SETUP_NV_STRAPS_H) 17 | -------------------------------------------------------------------------------- /ReBarDxe/include/StatusVar.h: -------------------------------------------------------------------------------- 1 | #if !defined(NV_STRAPS_REBAR_STATUS_VAR_H) 2 | #define NV_STRAPS_REBAR_STATUS_VAR_H 3 | 4 | #if defined(UEFI_SOURCE) 5 | # include 6 | #else 7 | #if defined(__cplusplus) && !defined(NVSTRAPS_DXE_DRIVER) 8 | import std; 9 | using std::uint_least64_t; 10 | # else 11 | # include 12 | # endif 13 | #endif 14 | 15 | #if defined(__cplusplus) && !defined(NVSTRAPS_DXE_DRIVER) 16 | import LocalAppConfig; 17 | #else 18 | # include "LocalAppConfig.h" 19 | #endif 20 | 21 | typedef enum StatusVar 22 | { 23 | StatusVar_NotLoaded = 10u, 24 | StatusVar_Configured = 20u, 25 | StatusVar_GPU_Unconfigured = 30u, 26 | StatusVar_Unconfigured = 40u, 27 | StatusVar_Cleared = 50u, 28 | 29 | StatusVar_BridgeFound = 60u, 30 | StatusVar_GpuFound = 70u, 31 | StatusVar_GpuStrapsConfigured = 80u, 32 | StatusVar_GpuStrapsPreConfigured = 90u, 33 | StatusVar_GpuStrapsConfirm = 100u, 34 | StatusVar_GpuDelayElapsed = 110u, 35 | StatusVar_GpuReBarConfigured = 120u, 36 | StatusVar_GpuStrapsNoConfirm = 130u, 37 | StatusVar_GpuReBarSizeOverride = 135u, 38 | StatusVar_GpuNoReBarCapability = 140u, 39 | StatusVar_GpuExcluded = 150u, 40 | 41 | StatusVar_NoBridgeConfig = 159u, 42 | StatusVar_BadBridgeConfig = 160u, 43 | StatusVar_BridgeNotEnumerated = 161u, 44 | StatusVar_NoGpuConfig = 162u, 45 | StatusVar_BadGpuConfig = 163u, 46 | StatusVar_BadSetupVarAttributes = 164u, 47 | StatusVar_AmbiguousSetupVariable = 165u, 48 | StatusVar_MissingSetupVariable = 166u, 49 | StatusVar_EFIAllocationError = 170u, 50 | StatusVar_Internal_EFIError = 180u, 51 | StatusVar_NVAR_API_Error = 190u, 52 | StatusVar_ParseError = 200u 53 | } 54 | StatusVar; 55 | 56 | typedef enum EFIErrorLocation 57 | { 58 | EFIError_None, 59 | EFIError_ReadConfigVar, 60 | EFIError_EnumVar, 61 | EFIError_EnumSetupVarSize, 62 | EFIError_ReadSetupVar, 63 | EFIError_ReadSetupVarSize, 64 | EFIError_AllocateSetupVarName, 65 | EFIError_AllocateSetupVarData, 66 | EFIError_WriteConfigVar, 67 | EFIError_PCI_StartFindCap, 68 | EFIError_PCI_FindCap, 69 | EFIError_PCI_BridgeSecondaryBus, 70 | EFIError_PCI_BridgeConfig, 71 | EFIError_PCI_BridgeRestore, 72 | EFIError_PCI_DeviceBARConfig, 73 | EFIError_PCI_DeviceBARRestore, 74 | EFIError_PCI_DeviceSubsystem, 75 | EFIError_LocateBridgeProtocol, 76 | EFIError_LoadBridgeProtocol, 77 | EFIError_LocateS3SaveStateProtocol, 78 | EFIError_LoadS3SaveStateProtocol, 79 | EFIError_WriteS3SaveStateProtocol, 80 | EFIError_ReadBaseAddress0, 81 | EFIError_CMOSTime, 82 | EFIError_CreateTimer, 83 | EFIError_CloseTimer, 84 | EFIError_SetupTimer, 85 | EFIError_WaitTimer, 86 | EFIError_CreateEvent, 87 | EFIError_CloseEvent 88 | } 89 | EFIErrorLocation; 90 | 91 | extern char const StatusVar_Name[]; 92 | 93 | void SetStatusVar(StatusVar val); 94 | 95 | #if defined(UEFI_SOURCE) || defined(EFIAPI) 96 | void SetEFIError(EFIErrorLocation errLocation, EFI_STATUS status); 97 | void SetDeviceStatusVar(UINTN pciAddress, StatusVar val); 98 | void SetDeviceEFIError(UINTN pciAddress, EFIErrorLocation errLocation, EFI_STATUS status); 99 | #else 100 | #if defined(__cplusplus) 101 | extern "C" 102 | { 103 | #endif 104 | 105 | uint_least64_t ReadStatusVar(ERROR_CODE *errorCode); 106 | 107 | #if defined(__cplusplus) 108 | } 109 | #endif 110 | #endif 111 | 112 | #endif // !defined(NV_STRAPS_REBAR_STATUS_VAR_H) 113 | -------------------------------------------------------------------------------- /ReBarState/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.28) 2 | 3 | project("NvStrapsReBar" LANGUAGES C CXX) 4 | 5 | include(cmake/LocalModulePath.cmake) 6 | include(CxxStdModule) 7 | 8 | set(CMAKE_CXX_STANDARD 23) 9 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 10 | set(CMAKE_CXX_SCAN_FOR_MODULES ON) 11 | 12 | if(NOT REBAR_DXE_DIRECTORY) 13 | cmake_path(SET REBAR_DXE_DIRECTORY NORMALIZE "${CMAKE_CURRENT_SOURCE_DIR}/../ReBarDxe") 14 | endif() 15 | 16 | add_executable(NvStrapsReBar 17 | "${REBAR_DXE_DIRECTORY}/include/LocalAppConfig.h" 18 | "${REBAR_DXE_DIRECTORY}/include/DeviceRegistry.h" 19 | "${REBAR_DXE_DIRECTORY}/DeviceRegistry.c" 20 | "${REBAR_DXE_DIRECTORY}/include/EfiVariable.h" 21 | "${REBAR_DXE_DIRECTORY}/EfiVariable.c" 22 | "${REBAR_DXE_DIRECTORY}/include/NvStrapsConfig.h" 23 | "${REBAR_DXE_DIRECTORY}/NvStrapsConfig.c" 24 | "${REBAR_DXE_DIRECTORY}/include/StatusVar.h" 25 | "${REBAR_DXE_DIRECTORY}/StatusVar.c" 26 | "ReBarState.cc") 27 | 28 | set_property(SOURCE 29 | "${REBAR_DXE_DIRECTORY}/DeviceRegistry.c" 30 | "${REBAR_DXE_DIRECTORY}/EfiVariable.c" 31 | "${REBAR_DXE_DIRECTORY}/NvStrapsConfig.c" 32 | "${REBAR_DXE_DIRECTORY}/StatusVar.c" 33 | 34 | # for clang to compile as C++, but not include C++ headers and libraries 35 | APPEND PROPERTY COMPILE_DEFINITIONS "NVSTRAPS_DXE_DRIVER") 36 | 37 | target_sources(NvStrapsReBar 38 | PRIVATE "cxx_std_lib.hh" 39 | PRIVATE FILE_SET CXX_MODULES BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" FILES 40 | "LocalAppConfig.ixx" 41 | "StatusVar.ixx" 42 | "DeviceRegistry.ixx" 43 | "NvStrapsWinAPI.ixx" 44 | "NvStrapsDXGI.ixx" 45 | "WinApiError.ixx" 46 | "ConfigManagerError.ixx" 47 | "DeviceList.ixx" 48 | "TextWizardPage.ixx" 49 | "NvStrapsConfig.ixx" 50 | "TextWizardMenu.ixx" 51 | "ConfigurationWizard.ixx" 52 | ) 53 | 54 | target_compile_features(NvStrapsReBar PRIVATE c_std_17 cxx_std_23) 55 | target_include_directories(NvStrapsReBar PRIVATE "${REBAR_DXE_DIRECTORY}/include" "${NvStrapsReBar_SOURCE_DIR}") 56 | 57 | if(WIN32) 58 | target_link_libraries(NvStrapsReBar PRIVATE CxxModule::Std) 59 | target_link_libraries(NvStrapsReBar PRIVATE "DXGI" "SetupAPI" "CfgMgr32") 60 | 61 | if(MSVC) 62 | set_target_properties(NvStrapsReBar PROPERTIES LINK_FLAGS " /MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\" ") 63 | endif() 64 | endif() 65 | 66 | if(ENABLE_TESTING) 67 | enable_testing() 68 | add_subdirectory(test) 69 | endif() 70 | -------------------------------------------------------------------------------- /ReBarState/ConfigManagerError.ixx: -------------------------------------------------------------------------------- 1 | export module ConfigManagerError; 2 | 3 | import std; 4 | import NvStraps.WinAPI; 5 | 6 | using std::string; 7 | using std::string_view; 8 | using std::to_string; 9 | using std::error_category; 10 | using std::system_error; 11 | using std::uncaught_exceptions; 12 | 13 | using namespace std::literals::string_literals; 14 | 15 | export class ConfigManagerErrorCategory: public error_category 16 | { 17 | public: 18 | char const *name() const noexcept override; 19 | string message(int error) const override; 20 | 21 | protected: 22 | ConfigManagerErrorCategory() = default; 23 | 24 | friend error_category const &config_manager_error_category(); 25 | }; 26 | 27 | export error_category const &config_manager_error_category(); 28 | export system_error make_config_ret(int error); 29 | export system_error make_config_ret(int error, char const *message); 30 | export system_error make_config_ret(int error, string const &message); 31 | export int validate_config_ret(int error); 32 | export int validate_config_ret(int error, char const *message); 33 | 34 | export template 35 | int validate_config_ret(int error); 36 | 37 | export template 38 | int validate_config_ret(int error, char const *message); 39 | 40 | export template 41 | int validate_config_ret(int error, std::string const &message); 42 | 43 | inline char const *ConfigManagerErrorCategory::name() const noexcept 44 | { 45 | return "PnP Configuration Manager"; 46 | } 47 | 48 | inline error_category const &config_manager_error_category() 49 | { 50 | static ConfigManagerErrorCategory errorCategory; 51 | 52 | return errorCategory; 53 | } 54 | 55 | inline system_error make_config_ret(int error) 56 | { 57 | return { error, config_manager_error_category() }; 58 | } 59 | 60 | inline system_error make_config_ret(int error, char const *message) 61 | { 62 | return { error, config_manager_error_category(), message }; 63 | } 64 | 65 | inline system_error make_config_ret(int error, string const &message) 66 | { 67 | return { error, config_manager_error_category(), message }; 68 | } 69 | 70 | inline int validate_config_ret(int error) 71 | { 72 | if (error && !uncaught_exceptions()) 73 | throw make_config_ret(error); 74 | 75 | return error; 76 | } 77 | 78 | inline int validate_config_ret(int error, char const *message) 79 | { 80 | if (error && !uncaught_exceptions()) 81 | throw make_config_ret(error, message); 82 | 83 | return error; 84 | } 85 | 86 | template 87 | inline int validate_config_ret(int error) 88 | { 89 | if (error && !(false || ... || (error == SUCCESS_VALUE)) && !uncaught_exceptions()) 90 | throw make_config_ret(error); 91 | 92 | return error; 93 | } 94 | 95 | template 96 | inline int validate_config_ret(int error, char const *message) 97 | { 98 | if (error && !(false || ... || (error == SUCCESS_VALUES)) && !uncaught_exceptions()) 99 | throw make_config_ret(error, message); 100 | 101 | return error; 102 | } 103 | 104 | template 105 | inline int validate_config_ret(int error, std::string const &message) 106 | { 107 | if (error && !(false || ... || (error == SUCCESS_VALUES)) && !uncaught_exceptions()) 108 | throw make_config_ret(error, message); 109 | 110 | return error; 111 | } 112 | 113 | module: private; 114 | 115 | static char const *configurationManagerErrorMessage(int error) 116 | { 117 | switch (error) 118 | { 119 | case CR_SUCCESS: 120 | return "Success"; 121 | 122 | case CR_DEFAULT: 123 | return "Default"; 124 | 125 | case CR_OUT_OF_MEMORY: 126 | return "Out of memory"; 127 | 128 | case CR_INVALID_POINTER: 129 | return "Invalid pointer"; 130 | 131 | case CR_INVALID_FLAG: 132 | return "Invalid flag"; 133 | 134 | case CR_INVALID_DEVNODE: 135 | //case CR_INVALID_DEVINST: 136 | return "Invalid device"; 137 | 138 | case CR_INVALID_RES_DES: 139 | return "Invalid resource descriptor"; 140 | 141 | case CR_INVALID_LOG_CONF: 142 | return "Invalid logical configuration"; 143 | 144 | case CR_INVALID_ARBITRATOR: 145 | return "Invalid arbitrator"; 146 | 147 | case CR_INVALID_NODELIST: 148 | return "Invalid node list"; 149 | 150 | case CR_DEVNODE_HAS_REQS: 151 | return "Device has reqs"; 152 | 153 | case CR_INVALID_RESOURCEID: 154 | return "Invalid resource ID"; 155 | 156 | case CR_DLVXD_NOT_FOUND: 157 | return "DLVXD not found"; 158 | 159 | case CR_NO_SUCH_DEVNODE: 160 | //case CR_NO_SUCH_DEVINST: 161 | return "No such device"; 162 | 163 | case CR_NO_MORE_LOG_CONF: 164 | return "No more logical configurations"; 165 | 166 | case CR_NO_MORE_RES_DES: 167 | return "No more resource descriptors"; 168 | 169 | case CR_ALREADY_SUCH_DEVNODE: 170 | //case CR_ALREADY_SUCH_DEVINST: 171 | return "Device already exists"; 172 | 173 | case CR_INVALID_RANGE_LIST: 174 | return "Invalid range list"; 175 | 176 | case CR_INVALID_RANGE: 177 | return "Invalid range"; 178 | 179 | case CR_FAILURE: 180 | return "Failure"; 181 | 182 | case CR_NO_SUCH_LOGICAL_DEV: 183 | return "No such logical device"; 184 | 185 | case CR_CREATE_BLOCKED: 186 | return "Create blocked"; 187 | 188 | case CR_NOT_SYSTEM_VM: 189 | return "Not system VM"; 190 | 191 | case CR_REMOVE_VETOED: 192 | return "Remove vetoed"; 193 | 194 | case CR_APM_VETOED: 195 | return "APM vetoed"; 196 | 197 | case CR_INVALID_LOAD_TYPE: 198 | return "Invalid load type"; 199 | 200 | case CR_BUFFER_SMALL: 201 | return "Buffer too small"; 202 | 203 | case CR_NO_ARBITRATOR: 204 | return "No arbitrator"; 205 | 206 | case CR_NO_REGISTRY_HANDLE: 207 | return "No registry handle"; 208 | 209 | case CR_REGISTRY_ERROR: 210 | return "Registry error"; 211 | 212 | case CR_INVALID_DEVICE_ID: 213 | return "Invalid device ID"; 214 | 215 | case CR_INVALID_DATA: 216 | return "Invalid data"; 217 | 218 | case CR_INVALID_API: 219 | return "Invalid API"; 220 | 221 | case CR_DEVLOADER_NOT_READY: 222 | return "Device loader not ready"; 223 | 224 | case CR_NEED_RESTART: 225 | return "Need restart"; 226 | 227 | case CR_NO_MORE_HW_PROFILES: 228 | return "No more hardware profiles"; 229 | 230 | case CR_DEVICE_NOT_THERE: 231 | return "Device not there"; 232 | 233 | case CR_NO_SUCH_VALUE: 234 | return "No such value"; 235 | 236 | case CR_WRONG_TYPE: 237 | return "Wrong type"; 238 | 239 | case CR_INVALID_PRIORITY: 240 | return "Invalid priority"; 241 | 242 | case CR_NOT_DISABLEABLE: 243 | return "Not disableble"; 244 | 245 | case CR_FREE_RESOURCES: 246 | return "Free resources"; 247 | 248 | case CR_QUERY_VETOED: 249 | return "Query vetoed"; 250 | 251 | case CR_CANT_SHARE_IRQ: 252 | return "Cannot share IRQ"; 253 | 254 | case CR_NO_DEPENDENT: 255 | return "No dependent"; 256 | 257 | case CR_SAME_RESOURCES: 258 | return "Same resources"; 259 | 260 | case CR_NO_SUCH_REGISTRY_KEY: 261 | return "No such registry key"; 262 | 263 | case CR_INVALID_MACHINENAME: 264 | return "Invalid machine name"; 265 | 266 | case CR_REMOTE_COMM_FAILURE: 267 | return "Remote communication failure"; 268 | 269 | case CR_MACHINE_UNAVAILABLE: 270 | return "Machine unavailable"; 271 | 272 | case CR_NO_CM_SERVICES: 273 | return "No ConfigManager services"; 274 | 275 | case CR_ACCESS_DENIED: 276 | return "Access denied"; 277 | 278 | case CR_CALL_NOT_IMPLEMENTED: 279 | return "Call not implemented"; 280 | 281 | case CR_INVALID_PROPERTY: 282 | return "Invalid property"; 283 | 284 | case CR_DEVICE_INTERFACE_ACTIVE: 285 | return "Device interface active"; 286 | 287 | case CR_NO_SUCH_DEVICE_INTERFACE: 288 | return "No such device interface"; 289 | 290 | case CR_INVALID_REFERENCE_STRING: 291 | return "Invalid reference string"; 292 | 293 | case CR_INVALID_CONFLICT_LIST: 294 | return "Invalid conflict list"; 295 | 296 | case CR_INVALID_INDEX: 297 | return "Invalid index"; 298 | 299 | case CR_INVALID_STRUCTURE_SIZE: 300 | return "Invalid structure size"; 301 | 302 | default: 303 | return "Configuration Manager error"; 304 | } 305 | 306 | return "Configuration Manager error"; 307 | } 308 | 309 | inline string ConfigManagerErrorCategory::message(int error) const 310 | { 311 | return "PnP Configuration Manager error code " + to_string(error) + ": " + configurationManagerErrorMessage(error); 312 | } 313 | 314 | // vim: ft=cpp 315 | -------------------------------------------------------------------------------- /ReBarState/DeviceRegistry.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | #include "DeviceRegistry.h" 4 | 5 | export module DeviceRegistry; 6 | 7 | export using ::MAX_BAR_SIZE_SELECTOR; 8 | export using ::BarSizeSelector; 9 | export using enum ::BarSizeSelector; 10 | export using ::isTuringGPU; 11 | export using ::lookupBarSizeInRegistry; 12 | -------------------------------------------------------------------------------- /ReBarState/LocalAppConfig.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | #include "LocalAppConfig.h" 4 | 5 | export module LocalAppConfig; 6 | 7 | import std; 8 | 9 | using std::uint_least32_t; 10 | using std::uint_least64_t; 11 | 12 | static constexpr bool const local_UEFI_SOURCE = 13 | #if defined(UEFI_SOURCE) 14 | true; 15 | #else 16 | false; 17 | #endif 18 | 19 | static constexpr bool const local_WINDOWS_SOURCE = 20 | #if defined(WINDOWS_SOURCE) 21 | true; 22 | #else 23 | false; 24 | #endif 25 | 26 | #undef UEFI_SOURCE 27 | #undef WINDOWS_SOURCE 28 | 29 | // can be used with if constexpr (WINDOWS_SOURCE) 30 | export constexpr bool const WINDOWS_SOURCE = local_WINDOWS_SOURCE; 31 | export constexpr bool const UEFI_SOURCE = local_UEFI_SOURCE; 32 | 33 | export using ::BYTE_SIZE; 34 | export using ::BYTE_BITSIZE; 35 | export using ::BYTE_BITMASK; 36 | 37 | export using ::WORD_SIZE; 38 | export using ::WORD_BITSIZE; 39 | export using ::WORD_BITMASK; 40 | 41 | export using ::DWORD_SIZE; 42 | export using ::DWORD_BITSIZE; 43 | export auto DWORD_BITMASK = uint_least32_t { (uint_least64_t { 1u } << DWORD_BITSIZE) - 1u }; 44 | 45 | export using ::ERROR_CODE; 46 | export using ::ERROR_CODE_SUCCESS; 47 | -------------------------------------------------------------------------------- /ReBarState/NvStrapsConfig.hh: -------------------------------------------------------------------------------- 1 | 2 | #include "NvStrapsConfig.h" 3 | 4 | import std; 5 | import NvStraps.WinAPI; 6 | import WinApiError; 7 | 8 | using std::begin; 9 | using std::end; 10 | using std::size; 11 | using std::find_if; 12 | using std::copy; 13 | using std::system_error; 14 | 15 | namespace views = std::ranges::views; 16 | namespace execution = std::execution; 17 | using namespace std::literals::string_literals; 18 | 19 | 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) 20 | { 21 | NvStraps_GPUSelector gpuSelector 22 | { 23 | .deviceID = deviceID, 24 | .subsysVendorID = subsysVenID, 25 | .subsysDeviceID = subsysDevID, 26 | .bus = bus, 27 | .device = dev, 28 | .function = fn, 29 | .barSizeSelector = barSizeSelector, 30 | .overrideBarSizeMask = 0u 31 | }; 32 | 33 | auto end_it = begin(GPUs) + nGPUSelector; 34 | auto it = find_if(execution::par_unseq, begin(GPUs), end_it, [&gpuSelector](auto const &selector) 35 | { 36 | return selector.deviceMatch(gpuSelector.deviceID) 37 | && selector.subsystemMatch(gpuSelector.subsysVendorID, gpuSelector.subsysDeviceID) 38 | && selector.busLocationMatch(gpuSelector.bus, gpuSelector.device, gpuSelector.function); 39 | }); 40 | 41 | if (it == end_it) 42 | if (nGPUSelector >= size(GPUs)) 43 | return false; 44 | else 45 | { 46 | dirty = true; 47 | GPUs[nGPUSelector++] = gpuSelector; 48 | } 49 | else 50 | if (it->barSizeSelector != barSizeSelector) 51 | { 52 | dirty = true; 53 | it->barSizeSelector = barSizeSelector; 54 | } 55 | 56 | return true; 57 | } 58 | 59 | 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) 60 | { 61 | NvStraps_GPUSelector gpuSelector 62 | { 63 | .deviceID = deviceID, 64 | .subsysVendorID = subsysVenID, 65 | .subsysDeviceID = subsysDevID, 66 | .bus = bus, 67 | .device = dev, 68 | .function = fn, 69 | .barSizeSelector = BarSizeSelector_None, 70 | .overrideBarSizeMask = sizeMaskOverride ? (uint_least8_t)0x01u : (uint_least8_t)0xFFu 71 | }; 72 | 73 | auto end_it = begin(GPUs) + nGPUSelector; 74 | auto it = find_if(execution::par_unseq, begin(GPUs), end_it, [&gpuSelector](auto const &selector) 75 | { 76 | return selector.deviceMatch(gpuSelector.deviceID) 77 | && selector.subsystemMatch(gpuSelector.subsysVendorID, gpuSelector.subsysDeviceID) 78 | && selector.busLocationMatch(gpuSelector.bus, gpuSelector.device, gpuSelector.function); 79 | }); 80 | 81 | if (it == end_it) 82 | if (nGPUSelector >= size(GPUs)) 83 | return false; 84 | else 85 | { 86 | dirty = true; 87 | GPUs[nGPUSelector++] = gpuSelector; 88 | } 89 | else 90 | if (it->overrideBarSizeMask != gpuSelector.overrideBarSizeMask) 91 | { 92 | dirty = true; 93 | it->overrideBarSizeMask = gpuSelector.overrideBarSizeMask; 94 | } 95 | 96 | return true; 97 | } 98 | 99 | bool NvStrapsConfig::clearGPUSelector(UINT16 deviceID, UINT16 subsysVenID, UINT16 subsysDevID, UINT8 bus, UINT8 dev, UINT8 fn) 100 | { 101 | NvStraps_GPUSelector gpuSelector 102 | { 103 | .deviceID = deviceID, 104 | .subsysVendorID = subsysVenID, 105 | .subsysDeviceID = subsysDevID, 106 | .bus = bus, 107 | .device = dev, 108 | .function = fn 109 | }; 110 | 111 | auto end_it = begin(GPUs) + nGPUSelector; 112 | auto it = find_if(execution::par_unseq, begin(GPUs), end_it, [&gpuSelector](auto const &selector) 113 | { 114 | return selector.deviceMatch(gpuSelector.deviceID) 115 | && selector.subsystemMatch(gpuSelector.subsysVendorID, gpuSelector.subsysDeviceID) 116 | && selector.busLocationMatch(gpuSelector.bus, gpuSelector.device, gpuSelector.function); 117 | }); 118 | 119 | if (it == end_it) 120 | return false; 121 | 122 | dirty = true; 123 | copy(it + 1u, end_it, it); 124 | nGPUSelector--; 125 | 126 | return true; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /ReBarState/NvStrapsConfig.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | #include "NvStrapsConfig.h" 4 | #include "NvStrapsConfig.hh" 5 | 6 | export module NvStrapsConfig; 7 | 8 | import std; 9 | import LocalAppConfig; 10 | 11 | using std::wstring; 12 | using std::function; 13 | 14 | export using ::TARGET_GPU_VENDOR_ID; 15 | export using ::TARGET_PCI_BAR_SIZE; 16 | export using enum ::TARGET_PCI_BAR_SIZE; 17 | export using ::ConfigPriority; 18 | export using ::NvStraps_BarSize; 19 | export using ::NvStraps_GPUSelector; 20 | export using ::NvStraps_GPUConfig; 21 | export using ::NvStraps_BridgeConfig; 22 | export using ::NvStrapsConfig; 23 | 24 | export NvStrapsConfig &GetNvStrapsConfig(bool reload = false); 25 | export void SaveNvStrapsConfig(); 26 | export void ShowNvStrapsConfig(function show); 27 | 28 | module: private; 29 | 30 | using std::to_wstring; 31 | namespace views = std::views; 32 | 33 | NvStrapsConfig &GetNvStrapsConfig(bool reload) 34 | { 35 | auto errorCode = ERROR_CODE { ERROR_CODE_SUCCESS }; 36 | auto strapsConfig = GetNvStrapsConfig(reload, &errorCode); 37 | 38 | return errorCode == ERROR_CODE_SUCCESS 39 | ? *strapsConfig 40 | : throw system_error(static_cast(errorCode), winapi_error_category(), "Error loading configuration from "s + NvStrapsConfig_VarName + " EFI variable"s); 41 | } 42 | 43 | void SaveNvStrapsConfig() 44 | { 45 | auto errorCode = ERROR_CODE { ERROR_CODE_SUCCESS }; 46 | 47 | SaveNvStrapsConfig(&errorCode); 48 | 49 | if (errorCode != ERROR_CODE_SUCCESS) 50 | throw system_error { static_cast(errorCode), winapi_error_category(), "Error saving configuration to "s + NvStrapsConfig_VarName + " EFI variable"s }; 51 | } 52 | 53 | static wchar_t const hexDigits[16 + 1] = L"0123456789ABCDEF"; 54 | 55 | static wstring formatPCI_ID(uint_least16_t pciID) 56 | { 57 | wstring hexStr(WORD_SIZE * 2u, L' '); 58 | 59 | for (auto &ch: hexStr) 60 | ch = hexDigits[pciID & 0x0Fu], pciID >>= 4u; 61 | 62 | return wstring { hexStr.rbegin(), hexStr.rend() }; 63 | } 64 | 65 | static wstring formatAddress64(uint_least64_t addr, bool fCheckWidth = true) 66 | { 67 | wstring hexStr(!fCheckWidth || addr > DWORD_BITMASK ? QWORD_SIZE * 2u + 3u : DWORD_SIZE * 2u + 1u, L' '); 68 | 69 | for (auto [i, ch]: hexStr | views::enumerate) 70 | if ((i + 1) % (WORD_SIZE * 2u + 1u) == 0) 71 | ch = L'\''; 72 | else 73 | ch = hexDigits[addr & 0x0000'000Fu], addr >>= 4u; 74 | 75 | return wstring { hexStr.rbegin(), hexStr.rend() }; 76 | } 77 | 78 | static wstring formatHexByte(uint_least8_t val) 79 | { 80 | return wstring { hexDigits[ val >> 4u & 0x0Fu], hexDigits[val & 0x0Fu] }; 81 | } 82 | 83 | static wstring formatHexWord(uint_least16_t val) 84 | { 85 | return wstring { hexDigits[val >> 4u + BYTE_BITSIZE & 0x0Fu], hexDigits[val >> BYTE_BITSIZE & 0x0Fu], hexDigits[val >> 4u & 0x0Fu], hexDigits[val & 0x0Fu] }; 86 | } 87 | 88 | static wstring formatHexNibble(uint_least8_t val) 89 | { 90 | wstring hexStr { hexDigits[val & 0x0Fu] }; 91 | 92 | if (val > 0x0Fu) 93 | hexStr = hexDigits[val >> 4u & 0x0Fu] + hexStr; 94 | 95 | return hexStr; 96 | } 97 | 98 | void ShowNvStrapsConfig(function show) 99 | { 100 | auto &&config = GetNvStrapsConfig(); 101 | 102 | show(L"DXE Driver configuration:\n"s); 103 | show(L"\tisDirty: "s + to_wstring(config.dirty) + L'\n'); 104 | show(L"\tOptionFlags: "s + L"0x"s + formatHexWord(config.nOptionFlags) + L'\n'); 105 | show(L"\t - nGlobalEnable: "s + to_wstring(config.isGlobalEnable()) + L'\n'); 106 | show(L"\t - skipS3Resume: "s + to_wstring(config.skipS3Resume()) + L'\n'); 107 | show(L"\t - overrideBarSize: "s + to_wstring(config.overrideBarSizeMask()) + L'\n'); 108 | show(L"\t - hasSetupVarCRC: "s + to_wstring(config.hasSetupVarCRC()) + L'\n'); 109 | show(L"\t - disableSetupVarCRC: "s + to_wstring(!config.enableSetupVarCRC()) + L'\n'); 110 | show(L"\tSetupVarCRC: "s + L"0x"s + formatAddress64(config.nSetupVarCRC, false) + L'\n'); 111 | show(L"\tnPciBarSize: "s + to_wstring(config.nPciBarSize) + L'\n'); 112 | show(L"\tnGPUSelectorCount: "s + to_wstring(config.nGPUSelector) + L'\n'); 113 | 114 | for (auto const &&[i, gpuSelector]: config.GPUs | views::enumerate | views::take(config.nGPUSelector)) 115 | { 116 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": deviceID: "s + formatPCI_ID(gpuSelector.deviceID) + L'\n'); 117 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysVendorID: "s + formatPCI_ID(gpuSelector.subsysVendorID) + L'\n'); 118 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": subsysDeviceID: "s + formatPCI_ID(gpuSelector.subsysDeviceID) + L'\n'); 119 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": bus: "s + formatHexByte(gpuSelector.bus) + L'\n'); 120 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": device: "s + formatHexByte(gpuSelector.device) + L'\n'); 121 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": function: "s + formatHexNibble(gpuSelector.function) + L'\n'); 122 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": barSizeSelector: "s + to_wstring(gpuSelector.barSizeSelector) + L'\n'); 123 | show(L"\t\tGPUSelector"s + to_wstring(i + 1) + L": overridebarSizeMask: "s + to_wstring(gpuSelector.overrideBarSizeMask) + L'\n'); 124 | show(L"\n"s); 125 | } 126 | 127 | show(L"\tnGPUConfigCount: "s + to_wstring(config.nGPUConfig) + L'\n'); 128 | 129 | for (auto const &&[i, gpuConfig]: config.gpuConfig | views::enumerate | views::take(config.nGPUConfig)) 130 | { 131 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": deviceID: "s + formatPCI_ID(gpuConfig.deviceID) + L'\n'); 132 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": subsysVendorID: "s + formatPCI_ID(gpuConfig.subsysVendorID) + L'\n'); 133 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": subsysDeviceID: "s + formatPCI_ID(gpuConfig.subsysDeviceID) + L'\n'); 134 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": bus: "s + formatHexByte(gpuConfig.bus) + L'\n'); 135 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": device: "s + formatHexByte(gpuConfig.device) + L'\n'); 136 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": function: "s + formatHexNibble(gpuConfig.function) + L'\n'); 137 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": BAR0 base: 0x"s + formatAddress64(gpuConfig.bar0.base) + L'\n'); 138 | show(L"\t\tGPUConfig"s + to_wstring(i + 1) + L": BAR0 top: 0x"s + formatAddress64(gpuConfig.bar0.top) + L'\n'); 139 | show(L"\n"s); 140 | } 141 | 142 | show(L"\tnBridgeCount: "s + to_wstring(config.nBridgeConfig) + L'\n'); 143 | 144 | for (auto const &&[i, bridgeConfig]: config.bridge | views::enumerate | views::take(config.nBridgeConfig)) 145 | { 146 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": vendorID: "s + formatPCI_ID(bridgeConfig.vendorID) + L'\n'); 147 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": deviceID: "s + formatPCI_ID(bridgeConfig.deviceID) + L'\n'); 148 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": bus: "s + formatHexByte(bridgeConfig.bridgeBus) + L'\n'); 149 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": device: "s + formatHexByte(bridgeConfig.bridgeDevice) + L'\n'); 150 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": function: "s + formatHexNibble(bridgeConfig.bridgeFunction) + L'\n'); 151 | show(L"\t\tBridgeConfig"s + to_wstring(i + 1) + L": secondary bus: "s + formatHexByte(bridgeConfig.bridgeSecondaryBus) + L'\n'); 152 | show(L"\n"s); 153 | } 154 | } 155 | 156 | // vim:ft=cpp 157 | -------------------------------------------------------------------------------- /ReBarState/NvStrapsDXGI.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | #if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 4 | # if defined(_M_AMD64) && !defined(_AMD64_) 5 | # define _AMD64_ 6 | # endif 7 | # include 8 | # include 9 | # include 10 | #endif 11 | 12 | export module NvStraps.DXGI; 13 | 14 | #undef ERROR_NOT_FOUND 15 | 16 | export namespace dxgi 17 | { 18 | using IID = IID; 19 | using GUID = GUID; 20 | 21 | using IFactory = IDXGIFactory; 22 | using IAdapter = IDXGIAdapter; 23 | using ADAPTER_DESC = DXGI_ADAPTER_DESC; 24 | 25 | auto const &IID_IFactory = ::IID_IDXGIFactory; 26 | auto const &CreateFactory = ::CreateDXGIFactory; 27 | 28 | constexpr auto const ERROR_NOT_FOUND = DXGI_ERROR_NOT_FOUND; 29 | } 30 | -------------------------------------------------------------------------------- /ReBarState/ReBarState.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024-2025 Timothy Madden 3 | * Copyright (c) 2022-2023 xCuri0 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 8 | import NvStraps.WinAPI; 9 | #else 10 | #include 11 | #include 12 | #include 13 | #endif 14 | 15 | import std; 16 | 17 | import NvStrapsConfig; 18 | import TextWizardPage; 19 | import ConfigurationWizard; 20 | 21 | using std::exception; 22 | using std::system_error; 23 | using std::make_error_code; 24 | using std::errc; 25 | using std::cin; 26 | using std::cout; 27 | using std::cerr; 28 | using std::endl; 29 | 30 | using namespace std::literals::string_literals; 31 | using namespace std::literals::string_view_literals; 32 | 33 | bool CheckPriviledge() 34 | { 35 | #if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 36 | if (auto hToken = HANDLE { }; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 37 | { 38 | auto tokp = TOKEN_PRIVILEGES { }; 39 | LookupPrivilegeValue(NULL, SE_SYSTEM_ENVIRONMENT_NAME, &tokp.Privileges[0].Luid); 40 | 41 | tokp.PrivilegeCount = 1; 42 | tokp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 43 | 44 | auto len = DWORD { }; 45 | AdjustTokenPrivileges(hToken, FALSE, &tokp, 0, NULL, &len); 46 | 47 | if (GetLastError() != ERROR_SUCCESS) 48 | return cout << "Failed to obtain SE_SYSTEM_ENVIRONMENT_NAME\n"sv, false; 49 | 50 | return true; 51 | } 52 | 53 | return false; 54 | #else // Linux 55 | return getuid() == 0; 56 | #endif 57 | } 58 | 59 | void pause() 60 | { 61 | // Linux will probably be run from terminal not requiring this 62 | #if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 63 | cout << "You can close the app now\n"sv; 64 | cin.get(); 65 | #endif 66 | } 67 | 68 | int main(int argc, char const *argv[]) 69 | try 70 | { 71 | showStartupLogo(); 72 | 73 | if (!CheckPriviledge()) 74 | throw system_error(make_error_code(errc::permission_denied), "No access permissions to EFI variable (try running as admin/root)"s); 75 | 76 | runConfigurationWizard(); 77 | 78 | return pause(), 0; 79 | } 80 | catch (system_error const &ex) 81 | { 82 | cerr << ex.what() << endl; 83 | return pause(), 252u; 84 | } 85 | catch (exception const &ex) 86 | { 87 | cerr << "Application error: "sv << ex.what() << endl; 88 | return pause(), 253u; 89 | } 90 | catch (...) 91 | { 92 | cerr << "Application error!"sv << endl; 93 | return pause(), 254u; 94 | } 95 | -------------------------------------------------------------------------------- /ReBarState/StatusVar.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | #include "StatusVar.h" 4 | 5 | export module StatusVar; 6 | 7 | export using ::StatusVar; 8 | export using enum ::StatusVar; 9 | export using ::EFIErrorLocation; 10 | export using enum ::EFIErrorLocation; 11 | export using ::StatusVar_Name; 12 | export using ::SetStatusVar; 13 | export using ::ReadStatusVar; 14 | -------------------------------------------------------------------------------- /ReBarState/TextWizardPage.ixx: -------------------------------------------------------------------------------- 1 | export module TextWizardPage; 2 | 3 | import std; 4 | import LocalAppConfig; 5 | import NvStrapsConfig; 6 | import StatusVar; 7 | import DeviceRegistry; 8 | import DeviceList; 9 | 10 | using std::uint_least64_t; 11 | using std::string; 12 | using std::wstring; 13 | using std::vector; 14 | using std::wcout; 15 | using std::wcerr; 16 | using std::cerr; 17 | using namespace std::literals::string_view_literals; 18 | 19 | export void showInfo(wstring const &message); 20 | export void showError(wstring const &message); 21 | export void showError(string const &message); 22 | export void showStartupLogo(); 23 | 24 | export void showConfiguration(vector const &devices, NvStrapsConfig const &nvStrapsConfig, uint_least64_t driverStatus); 25 | 26 | inline void showInfo(wstring const &message) 27 | { 28 | wcout << message; 29 | } 30 | 31 | inline void showError(wstring const &message) 32 | { 33 | wcerr << L'\n' << message; 34 | } 35 | 36 | inline void showError(string const &message) 37 | { 38 | cerr << '\n' << message; 39 | } 40 | 41 | inline void showStartupLogo() 42 | { 43 | wcout << L"NvStrapsReBar, based on:\nReBarState (c) 2023 xCuri0\n\n"sv; 44 | } 45 | 46 | module: private; 47 | 48 | using std::uint_least8_t; 49 | using std::uint_least64_t; 50 | using std::string; 51 | using std::wstring_view; 52 | using std::to_wstring; 53 | using std::vector; 54 | using std::wcout; 55 | using std::wostringstream; 56 | using std::hex; 57 | using std::dec; 58 | using std::left; 59 | using std::right; 60 | using std::uppercase; 61 | using std::setw; 62 | using std::setfill; 63 | using std::max; 64 | 65 | namespace views = std::ranges::views; 66 | using namespace std::literals::string_literals; 67 | using namespace std::literals::string_view_literals; 68 | 69 | static wstring formatDirectMemorySize(uint_least64_t memorySize) 70 | { 71 | if (!memorySize) 72 | return L" "s; 73 | 74 | return formatMemorySize(memorySize); 75 | } 76 | 77 | static wstring formatLocation(DeviceInfo const &devInfo) 78 | { 79 | wostringstream str; 80 | 81 | str << hex << uppercase << setfill(L'0') << right; 82 | str << setw(2u) << devInfo.bridge.bus << L':' << setw(2u) << devInfo.bridge.dev << L'.' << devInfo.bridge.func; 83 | str << L' '; 84 | str << setw(2u) << devInfo.bus << L':' << setw(2u) << devInfo.device << L'.' << devInfo.function; 85 | 86 | 87 | return str.str(); 88 | } 89 | 90 | static wstring formatDirectBARSize(uint_least64_t size) 91 | { 92 | if (size < uint_least64_t { 64u } * 1024u * 1024u) 93 | return { }; 94 | 95 | return formatMemorySize(size); 96 | } 97 | 98 | static wstring_view formatBarSizeSelector(uint_least8_t barSizeSelector) 99 | { 100 | switch (barSizeSelector) 101 | { 102 | case 0: 103 | return L"64 MiB"sv; 104 | case 1: 105 | return L"128 MiB"sv; 106 | case 2: 107 | return L"256 MiB"sv; 108 | case 3: 109 | return L"512 MiB"sv; 110 | case 4: 111 | return L"1 GiB"sv; 112 | case 5: 113 | return L"2 GiB"sv; 114 | case 6: 115 | return L"4 GiB"sv; 116 | case 7: 117 | return L"8 GiB"sv; 118 | case 8: 119 | return L"16 GiB"sv; 120 | case 9: 121 | return L"32 GiB"sv; 122 | case 10: 123 | return L"64 GiB"sv; 124 | default: 125 | return L" "sv; 126 | } 127 | 128 | return L" "sv; 129 | } 130 | 131 | static wchar_t locationMarker(ConfigPriority location, ConfigPriority barSizePriority, ConfigPriority sizeMaskOverridePriority, bool bridgeMismatch) 132 | { 133 | if (bridgeMismatch && location == ConfigPriority::EXPLICIT_PCI_LOCATION) 134 | return L'!'; 135 | 136 | if (barSizePriority >= location) 137 | if (sizeMaskOverridePriority >= location) 138 | return L'+'; 139 | else 140 | return L'*'; 141 | else 142 | if (sizeMaskOverridePriority >= location) 143 | return L'\''; 144 | else 145 | return L' '; 146 | } 147 | 148 | static void showLocalGPUs(vector const &deviceSet, NvStrapsConfig const &nvStrapsConfig) 149 | { 150 | #if defined(NDEBUG) 151 | if (deviceSet.empty()) 152 | { 153 | cerr << "No NVIDIA GPUs present!\n"; 154 | return; 155 | } 156 | #endif 157 | 158 | auto 159 | nMaxLocationSize = max("Bridge + GPU"sv.size(), "bus:dev.fn"sv.size()), 160 | nMaxTargetBarSize = max("Target"sv.size(), "BAR size"sv.size()), 161 | nMaxCurrentBarSize = max("current"sv.size(), "BAR size"sv.size()), 162 | nMaxVRAMSize = "VRAM"sv.size(), 163 | nMaxNameSize = "Product Name"sv.size(); 164 | 165 | for (auto const &deviceInfo: deviceSet) 166 | { 167 | nMaxLocationSize = max(nMaxLocationSize, formatLocation(deviceInfo).size()); 168 | nMaxCurrentBarSize = max(nMaxCurrentBarSize, formatMemorySize(deviceInfo.currentBARSize).size()); 169 | nMaxTargetBarSize = max(nMaxTargetBarSize, formatBarSizeSelector(MAX_BAR_SIZE_SELECTOR).size()); 170 | nMaxVRAMSize = max(nMaxVRAMSize, formatDirectMemorySize(deviceInfo.dedicatedVideoMemory).size()); 171 | nMaxNameSize = max(nMaxNameSize, deviceInfo.productName.size()); 172 | } 173 | 174 | 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; 175 | 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; 176 | 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; 177 | 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; 178 | 179 | for (auto const &&[deviceIndex, deviceInfo]: deviceSet | views::enumerate) 180 | { 181 | auto bridgeInfo = nvStrapsConfig.lookupBridgeConfig(deviceInfo.bus); 182 | 183 | auto [configPriority, barSizeSelector] = nvStrapsConfig.lookupBarSize 184 | ( 185 | deviceInfo.deviceID, 186 | deviceInfo.subsystemVendorID, 187 | deviceInfo.subsystemDeviceID, 188 | deviceInfo.bus, 189 | deviceInfo.device, 190 | deviceInfo.function 191 | ); 192 | 193 | auto [sizeMaskOverridePriority, sizeMaskOverride] = nvStrapsConfig.lookupBarSizeMaskOverride 194 | ( 195 | deviceInfo.deviceID, 196 | deviceInfo.subsystemVendorID, 197 | deviceInfo.subsystemDeviceID, 198 | deviceInfo.bus, 199 | deviceInfo.device, 200 | deviceInfo.function 201 | ); 202 | 203 | auto bridgeMismatch = bool 204 | { 205 | !!configPriority && barSizeSelector < BarSizeSelector_Excluded 206 | && 207 | ( 208 | !bridgeInfo 209 | || !bridgeInfo->deviceMatch(deviceInfo.bridge.vendorID, deviceInfo.bridge.deviceID) 210 | || !bridgeInfo->busLocationMatch(deviceInfo.bridge.bus, deviceInfo.bridge.dev, deviceInfo.bridge.func) 211 | ) 212 | }; 213 | 214 | wchar_t marker; 215 | 216 | // GPU number 217 | wcout << L"| "sv << dec << right << setw(2u) << setfill(L' ') << deviceIndex + 1u; 218 | 219 | // PCI ID 220 | 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; 221 | 222 | // PCI subsystem ID 223 | 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; 224 | 225 | // PCI bus location 226 | wcout << L" | "sv << locationMarker(ConfigPriority::EXPLICIT_PCI_LOCATION, configPriority, sizeMaskOverridePriority, bridgeMismatch) << right << setw(nMaxLocationSize) << setfill(L' ') << left << formatLocation(deviceInfo); 227 | 228 | // Target BAR1 size 229 | wcout << L" | "sv << (sizeMaskOverride ? isTuringGPU(deviceInfo.deviceID) ? L'\'' : L' ' : L' ') << dec << setw(nMaxTargetBarSize) << right << setfill(L' ') << formatBarSizeSelector(barSizeSelector); 230 | 231 | // Current BAR size 232 | wcout << L" | "sv << dec << setw(nMaxCurrentBarSize) << right << setfill(L' ') << formatDirectBARSize(deviceInfo.currentBARSize); 233 | 234 | // VRAM capacity 235 | wcout << L" | "sv << dec << setw(nMaxVRAMSize) << right << setfill(L' ') << formatDirectMemorySize(deviceInfo.dedicatedVideoMemory); 236 | 237 | // GPU model name 238 | wcout << L" | "sv << left << setw(nMaxNameSize) << deviceInfo.productName; 239 | 240 | wcout << L" |\n"sv; 241 | } 242 | 243 | 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; 244 | } 245 | 246 | static wstring_view driverStatusString(uint_least64_t driverStatus) 247 | { 248 | switch (driverStatus) 249 | { 250 | case StatusVar_NotLoaded: 251 | return L"Not loaded"sv; 252 | 253 | case StatusVar_Configured: 254 | return L"Configured"sv; 255 | 256 | case StatusVar_GPU_Unconfigured: 257 | return L"GPU Unconfigured"sv; 258 | 259 | case StatusVar_Unconfigured: 260 | return L"Unconfigured"sv; 261 | 262 | case StatusVar_Cleared: 263 | return L"Cleared"sv; 264 | 265 | case StatusVar_BridgeFound: 266 | return L"Bridge Found"sv; 267 | 268 | case StatusVar_GpuFound: 269 | return L"GPU Found"sv; 270 | 271 | case StatusVar_GpuStrapsConfigured: 272 | return L"GPU-side ReBAR Configured"sv; 273 | 274 | case StatusVar_GpuStrapsPreConfigured: 275 | return L"GPU side Already Configured"sv; 276 | 277 | case StatusVar_GpuStrapsConfirm: 278 | return L"GPU-side ReBAR Configured with PCI confirm"sv; 279 | 280 | case StatusVar_GpuDelayElapsed: 281 | return L"GPU PCI delay posted"sv; 282 | 283 | case StatusVar_GpuReBarConfigured: 284 | return L"GPU PCI ReBAR Configured"sv; 285 | 286 | case StatusVar_GpuStrapsNoConfirm: 287 | return L"GPU-side ReBAR Configured without PCI confirm"sv; 288 | 289 | case StatusVar_GpuReBarSizeOverride: 290 | return L"GPU-side ReABR Configured with PCI ReBAR size override"sv; 291 | 292 | case StatusVar_GpuNoReBarCapability: 293 | return L"ReBAR capability not advertised"sv; 294 | 295 | case StatusVar_GpuExcluded: 296 | return L"GPU excluded"sv; 297 | 298 | case StatusVar_NoBridgeConfig: 299 | return L"Missing bridge configuration"sv; 300 | 301 | case StatusVar_BadBridgeConfig: 302 | return L"Bad PCI Bridge Configuration"sv; 303 | 304 | case StatusVar_BridgeNotEnumerated: 305 | return L"GPU enumerated before bridge"sv; 306 | 307 | case StatusVar_BadGpuConfig: 308 | return L"Improper GPU BAR configuration"sv; 309 | 310 | case StatusVar_BadSetupVarAttributes: 311 | return L"Bad attributes for Setup variable"sv; 312 | 313 | case StatusVar_AmbiguousSetupVariable: 314 | return L"Ambiguous Setup variable"sv; 315 | 316 | case StatusVar_MissingSetupVariable: 317 | return L"Setup variable missing"sv; 318 | 319 | case StatusVar_NoGpuConfig: 320 | return L"Missing GPU BAR0 Configuration"sv; 321 | 322 | case StatusVar_EFIAllocationError: 323 | return L"EFI Allocation error"sv; 324 | 325 | case StatusVar_Internal_EFIError: 326 | return L"EFI Error"sv; 327 | 328 | case StatusVar_NVAR_API_Error: 329 | return L"NVAR access API error"sv; 330 | 331 | case StatusVar_ParseError: 332 | default: 333 | return L"Parse error"sv; 334 | } 335 | 336 | return L"Parse error"sv; 337 | } 338 | 339 | wstring_view driverErrorString(EFIErrorLocation errLocation) 340 | { 341 | switch (errLocation) 342 | { 343 | case EFIError_None: 344 | return L""sv; 345 | 346 | case EFIError_ReadConfigVar: 347 | return L" (at Read config var)"sv; 348 | 349 | case EFIError_EnumVar: 350 | return L" (at Enumerate EFI variables)"sv; 351 | 352 | case EFIError_ReadSetupVar: 353 | return L" (at Read Setup variable)"sv; 354 | 355 | case EFIError_ReadSetupVarSize: 356 | return L" (at Read Setup variable size)"sv; 357 | 358 | case EFIError_AllocateSetupVarName: 359 | return L" (at Allocate Setup variable name)"sv; 360 | 361 | case EFIError_AllocateSetupVarData: 362 | return L" (at Allocate Setup variable data)"sv; 363 | 364 | case EFIError_WriteConfigVar: 365 | return L" (at Write config var)"sv; 366 | 367 | case EFIError_PCI_StartFindCap: 368 | return L" (at start PCI find capability)"sv; 369 | 370 | case EFIError_PCI_FindCap: 371 | return L" (at PCI find capability)"sv; 372 | 373 | case EFIError_PCI_BridgeSecondaryBus: 374 | return L" (at Secondary Bus read)"sv; 375 | 376 | case EFIError_PCI_BridgeConfig: 377 | return L" (at PCI bridge configuration)"sv; 378 | 379 | case EFIError_PCI_BridgeRestore: 380 | return L" (at PCI bridge restore)"sv; 381 | 382 | case EFIError_PCI_DeviceBARConfig: 383 | return L" (at PCI device BAR config)"sv; 384 | 385 | case EFIError_PCI_DeviceBARRestore: 386 | return L" (at PCI device BAR restore)"sv; 387 | 388 | case EFIError_PCI_DeviceSubsystem: 389 | return L" (at PCI read device subsystem"sv; 390 | 391 | case EFIError_LocateBridgeProtocol: 392 | return L" (at Locate bridge protocol)"sv; 393 | 394 | case EFIError_LoadBridgeProtocol: 395 | return L" (at Load bridge protocol)"sv; 396 | 397 | case EFIError_LocateS3SaveStateProtocol: 398 | return L" (at Locate S3 Save State Protocol)"sv; 399 | 400 | case EFIError_LoadS3SaveStateProtocol: 401 | return L" (at Load S3 Save State Protocol)"sv; 402 | 403 | case EFIError_ReadBaseAddress0: 404 | return L" (at read base address 0)"sv; 405 | 406 | case EFIError_CMOSTime: 407 | return L" (at CMOS Time)"sv; 408 | 409 | case EFIError_CreateTimer: 410 | return L" (at Create Timer)"sv; 411 | 412 | case EFIError_CloseTimer: 413 | return L" (at Close Timer)"sv; 414 | 415 | case EFIError_SetupTimer: 416 | return L" (at Setup Timer)"sv; 417 | 418 | case EFIError_WaitTimer: 419 | return L" (at Wait Timer)"sv; 420 | 421 | case EFIError_CreateEvent: 422 | return L" (at Create Event BeforeExitBootServices)"sv; 423 | 424 | case EFIError_CloseEvent: 425 | return L" (at Close Event BeforeExitBootServices)"sv; 426 | 427 | default: 428 | return L""sv; 429 | } 430 | 431 | return L""sv; 432 | } 433 | 434 | static void showDriverStatus(uint_least64_t driverStatus) 435 | { 436 | uint_least32_t status = driverStatus & DWORD_BITMASK; 437 | 438 | wcout << L"UEFI DXE driver status: "sv << driverStatusString(status) 439 | << (status == StatusVar_Internal_EFIError ? driverErrorString(static_cast(driverStatus >> (DWORD_BITSIZE + BYTE_BITSIZE) & BYTE_BITMASK)) : L""sv) 440 | << L" (0x"sv << hex << right << setfill(L'0') << setw(QWORD_SIZE * 2u) << driverStatus << dec << setfill(L' ') << L")\n"sv; 441 | 442 | if (status == StatusVar_GpuStrapsNoConfirm) 443 | wcout << L"(use Overide BAR Size Mask option)\n"sv; 444 | } 445 | 446 | static wstring formatPciBarSize(unsigned sizeSelector) 447 | { 448 | auto suffix = sizeSelector < 10u ? L" MiB"s : sizeSelector < 20u ? L" GiB"s : sizeSelector < 30u ? L" TiB"s : L" PiB"s; 449 | 450 | return to_wstring(1u << sizeSelector % 10) + suffix; 451 | } 452 | 453 | static void showPciReBarState(uint_least8_t reBarState) 454 | { 455 | switch (reBarState) 456 | { 457 | case TARGET_PCI_BAR_SIZE_DISABLED: 458 | wcout << L"Target PCI BAR size: "sv << +reBarState << L" / System default\n"sv; 459 | break; 460 | 461 | case TARGET_PCI_BAR_SIZE_MAX: 462 | wcout << L"Target PCI BAR size: "sv << +reBarState << L" / Any BAR size supported by PCI devices.\n"sv; 463 | break; 464 | 465 | case TARGET_PCI_BAR_SIZE_GPU_ONLY: 466 | wcout << L"Target PCI BAR size: "sv << +reBarState << L" / Selected GPUs only\n"sv; 467 | break; 468 | 469 | case TARGET_PCI_BAR_SIZE_GPU_STRAPS_ONLY: 470 | wcout << L"Target PCI BAR size: "sv << +reBarState << L" / GPU-side only for selected GPUs, without PCI BAR configuration\n"sv; 471 | break; 472 | 473 | default: 474 | if (TARGET_PCI_BAR_SIZE_MIN <= reBarState && reBarState < TARGET_PCI_BAR_SIZE_MAX) 475 | wcout << L"Target PCI BAR size: "sv << +reBarState << L" / Maximum "sv << formatPciBarSize(reBarState) << L" BAR size for PCI devices\n"sv; 476 | else 477 | wcout << L"Target PCI BAR size value not unsupported\n"sv; 478 | break; 479 | } 480 | } 481 | 482 | void showConfiguration(vector const &devices, NvStrapsConfig const &nvStrapsConfig, uint_least64_t driverStatus) 483 | { 484 | showLocalGPUs(devices, nvStrapsConfig); 485 | showDriverStatus(driverStatus); 486 | showPciReBarState(nvStrapsConfig.targetPciBarSizeSelector()); 487 | } 488 | 489 | // vi: ft=cpp 490 | -------------------------------------------------------------------------------- /ReBarState/WinApiError.ixx: -------------------------------------------------------------------------------- 1 | export module WinApiError; 2 | 3 | import std; 4 | import NvStraps.WinAPI; 5 | 6 | #if defined(WINDOWS) || defined(_WINDOWS) || defined(_WIN64) || defined(_WIN32) 7 | 8 | using std::string; 9 | using std::error_category; 10 | using std::system_error; 11 | 12 | export class WinAPIErrorCategory: public error_category 13 | { 14 | public: 15 | char const* name() const noexcept override; 16 | string message(int error) const override; 17 | 18 | protected: 19 | WinAPIErrorCategory() = default; 20 | 21 | friend error_category const &winapi_error_category(); 22 | }; 23 | 24 | export error_category const &winapi_error_category(); 25 | 26 | export void check_last_error(DWORD dwLastError = ::GetLastError()); 27 | export void check_last_error(DWORD dwLastError, char const* msg); 28 | export void check_last_error(DWORD dwLastError, string const& msg); 29 | export void check_last_error(char const *msg, DWORD dwLastError = ::GetLastError()); 30 | export void check_last_error(string const &msg, DWORD dwLastError = ::GetLastError()); 31 | 32 | inline error_category const &winapi_error_category() 33 | { 34 | static WinAPIErrorCategory errorCategory; 35 | 36 | return errorCategory; 37 | } 38 | 39 | inline void check_last_error(DWORD dwLastError) 40 | { 41 | if (dwLastError && !std::uncaught_exceptions()) 42 | throw system_error(static_cast(dwLastError), winapi_error_category()); 43 | } 44 | 45 | inline void check_last_error(DWORD dwLastError, char const* msg) 46 | { 47 | if (dwLastError && !std::uncaught_exceptions()) 48 | throw system_error(static_cast(dwLastError), winapi_error_category(), msg); 49 | } 50 | 51 | inline void check_last_error(DWORD dwLastError, string const& msg) 52 | { 53 | if (dwLastError && !std::uncaught_exceptions()) 54 | throw system_error(static_cast(dwLastError), winapi_error_category(), msg); 55 | } 56 | 57 | inline void check_last_error(char const *msg, DWORD dwLastError) 58 | { 59 | if (dwLastError && !std::uncaught_exceptions()) 60 | throw system_error(static_cast(dwLastError), winapi_error_category(), msg); 61 | } 62 | 63 | inline void check_last_error(string const &msg, DWORD dwLastError) 64 | { 65 | if (dwLastError && !std::uncaught_exceptions()) 66 | throw system_error(static_cast(dwLastError), winapi_error_category(), msg); 67 | } 68 | 69 | module: private; 70 | 71 | using std::string; 72 | using std::exchange; 73 | using std::stringstream; 74 | using std::hex; 75 | using std::setfill; 76 | using std::setw; 77 | using std::endl; 78 | using namespace std::literals::string_literals; 79 | 80 | 81 | inline char const *WinAPIErrorCategory::name() const noexcept 82 | { 83 | return "winapi"; 84 | } 85 | 86 | string WinAPIErrorCategory::message(int error) const 87 | { 88 | struct LocalMem 89 | { 90 | HLOCAL hLocal = nullptr; 91 | 92 | ~LocalMem() 93 | { 94 | ::LocalFree(exchange(hLocal, nullptr)); 95 | } 96 | } 97 | localMessageBuffer; 98 | 99 | if (auto nLength = ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, static_cast(error), 100 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), static_cast(static_cast(&localMessageBuffer.hLocal)), 0, nullptr)) 101 | { 102 | return { static_cast(static_cast(localMessageBuffer.hLocal)), nLength }; 103 | } 104 | else 105 | { 106 | auto dwFormatMessageError = ::GetLastError(); 107 | 108 | return static_cast(stringstream { "Windows API error 0x"s } << hex << setfill('0') << setw(sizeof(DWORD) * 2u) << static_cast(error) << endl 109 | << "(FormatError() returned 0x" << hex << setfill('0') << setw(sizeof(dwFormatMessageError) * 2) << dwFormatMessageError << ')').str(); 110 | } 111 | } 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /ReBarState/cmake/CxxStdModule.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 4 | add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_lib.pcm" 5 | COMMAND 6 | "${CMAKE_CXX_COMPILER}" "${CMAKE_CXX_FLAGS}" "-v" 7 | "-std=gnu++23" 8 | "-fexperimental-library" 9 | "-fretain-comments-from-system-headers" 10 | "-x" "c++" "-Xclang" "-emit-module" "-fmodule-name=std" 11 | "-o" "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_lib.pcm" "-c" 12 | "${CMAKE_CURRENT_SOURCE_DIR}/cxx_std_lib.modulemap" 13 | MAIN_DEPENDENCY "cxx_std_lib.modulemap" DEPENDS "cxx_std_lib.hh") 14 | 15 | add_library(CxxModuleStd INTERFACE) 16 | target_compile_options(CxxModuleStd INTERFACE 17 | "-Wno-deprecated-anon-enum-enum-conversion" 18 | "-std=gnu++23" 19 | "-fexperimental-library" 20 | "-x" "c++" 21 | "-Wno-dangling-else" 22 | "-Wno-unqualified-std-cast-call" 23 | "-Wno-switch" 24 | "-fretain-comments-from-system-headers" 25 | "-fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/cxx_std_lib.pcm") 26 | target_sources(CxxModuleStd INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_lib.pcm") 27 | target_compile_features(CxxModuleStd INTERFACE cxx_std_23) 28 | add_library(CxxModule::Std ALIAS CxxModuleStd) 29 | elseif(MSVC) 30 | if(NOT MSVC_CXX_STD_MODULE_SOURCE_FILE) 31 | if(DEFINED ENV{VCToolsInstallDir}) 32 | set(MSVC_CXX_STD_MODULE_SOURCE_FILE "$ENV{VCToolsInstallDir}/modules/std.ixx") 33 | else() 34 | find_program(VSWHERE_EXECUTABLE NAMES vswhere HINTS "$ENV{ProgramFiles\(x86\)}/Microsoft Visual Studio/Installer" REQUIRED) 35 | 36 | if(MSVC) 37 | execute_process( 38 | COMMAND "${VSWHERE_EXECUTABLE}" "-path" "${CMAKE_CXX_COMPILER}" "-find" "VC/Tools/MSVC/*/modules/std.ixx" 39 | COMMAND_ECHO STDOUT 40 | OUTPUT_VARIABLE MSVC_CXX_STD_MODULE_SOURCE_FILE 41 | ECHO_OUTPUT_VARIABLE 42 | OUTPUT_STRIP_TRAILING_WHITESPACE 43 | RESULT_VARIABLE VSWHERE_EXIT_CODE 44 | COMMAND_ERROR_IS_FATAL ANY) 45 | if (MSVC_CXX_STD_MODULE_SOURCE_FILE STREQUAL "" OR NOT VSWHERE_EXIT_CODE STREQUAL "0") 46 | execute_process( 47 | COMMAND "${VSWHERE_EXECUTABLE}" "-latest" 48 | "-requires" "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" 49 | "-requires" "Microsoft.VisualStudio.Component.Windows11SDK.*" 50 | "-products" "Microsoft.VisualStudio.Product.Community" 51 | "-find" "VC/Tools/MSVC/*/modules/std.ixx" 52 | COMMAND_ECHO STDOUT 53 | OUTPUT_VARIABLE MSVC_CXX_STD_MODULE_SOURCE_FILE 54 | ECHO_OUTPUT_VARIABLE 55 | OUTPUT_STRIP_TRAILING_WHITESPACE 56 | COMMAND_ERROR_IS_FATAL ANY) 57 | endif() 58 | endif() 59 | endif() 60 | endif() 61 | 62 | cmake_path(CONVERT "${MSVC_CXX_STD_MODULE_SOURCE_FILE}" TO_CMAKE_PATH_LIST MSVC_CXX_STD_MODULE_SOURCE_FILE NORMALIZE) 63 | 64 | if (NOT MSVC_CXX_STD_MODULE_SOURCE_FILE OR NOT EXISTS "${MSVC_CXX_STD_MODULE_SOURCE_FILE}") 65 | message(FATAL_ERROR "Unable to find C++ module source file std.ixx for Visual C++ standard libary") 66 | endif() 67 | 68 | # add_library(CxxModuleStd OBJECT) 69 | # cmake_path(GET MSVC_CXX_STD_MODULE_SOURCE_FILE PARENT_PATH MSVC_CXX_STD_MODULE_DIR) 70 | # target_sources(CxxModuleStd PUBLIC FILE_SET std_cxx_module TYPE CXX_MODULES BASE_DIRS "${MSVC_CXX_STD_MODULE_DIR}" FILES "${MSVC_CXX_STD_MODULE_SOURCE_FILE}") 71 | # target_compile_features(CxxModuleStd PUBLIC cxx_std_23) 72 | 73 | add_library(CxxModuleStd INTERFACE) 74 | cmake_path(GET MSVC_CXX_STD_MODULE_SOURCE_FILE PARENT_PATH MSVC_CXX_STD_MODULE_DIR) 75 | target_sources(CxxModuleStd INTERFACE "${MSVC_CXX_STD_MODULE_SOURCE_FILE}") 76 | target_compile_features(CxxModuleStd INTERFACE cxx_std_23) 77 | target_compile_options(CxxModuleStd INTERFACE 78 | "/permissive-" 79 | "/Zc:enumTypes" 80 | "/Zc:__cplusplus" 81 | "/Zc:__STDC__" 82 | "/Zc:templateScope" 83 | "/volatile:iso") 84 | 85 | add_library(CxxModule::Std ALIAS CxxModuleStd) 86 | endif() 87 | -------------------------------------------------------------------------------- /ReBarState/cmake/LocalModulePath.cmake: -------------------------------------------------------------------------------- 1 | include_guard(DIRECTORY) 2 | 3 | # Make the local cmake/ subdirectory available in 4 | # CMAKE_MODULE_PATH 5 | 6 | if(NOT "${CMAKE_CURRENT_SOURCE_DIR}/cmake" IN_LIST CMAKE_MODULE_PATH) 7 | list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 8 | endif() 9 | -------------------------------------------------------------------------------- /ReBarState/compile_commands.template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 4 | "command": "C:\\msys64\\clang64\\bin\\cc.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -o CMakeFiles\\NvStrapsReBar.dir\\F_\\UserStorage\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c -x c++", 5 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c", 6 | "output": "CMakeFiles\\NvStrapsReBar.dir\\C_\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c.obj" 7 | }, 8 | { 9 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 10 | "command": "C:\\msys64\\clang64\\bin\\cc.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -o CMakeFiles\\NvStrapsReBar.dir\\F_\\UserStorage\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c -x c++", 11 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c", 12 | "output": "CMakeFiles\\NvStrapsReBar.dir\\C_\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c.obj" 13 | }, 14 | { 15 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 16 | "command": "C:\\msys64\\clang64\\bin\\cc.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -Wno-bitwise-op-parentheses -Wno-deprecated-anon-enum-enum-conversion -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -o CMakeFiles\\NvStrapsReBar.dir\\F_\\UserStorage\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c -x c++", 17 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c", 18 | "output": "CMakeFiles\\NvStrapsReBar.dir\\C_\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c.obj" 19 | }, 20 | { 21 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 22 | "command": "C:\\msys64\\clang64\\bin\\cc.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -o CMakeFiles\\NvStrapsReBar.dir\\F_\\UserStorage\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c -x c++", 23 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c", 24 | "output": "CMakeFiles\\NvStrapsReBar.dir\\C_\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c.obj" 25 | }, 26 | { 27 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 28 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\ReBarState.cc.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\ReBarState.cc.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ReBarState.cc", 29 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ReBarState.cc", 30 | "output": "CMakeFiles\\NvStrapsReBar.dir\\ReBarState.cc.obj" 31 | }, 32 | { 33 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 34 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\StatusVar.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\StatusVar.ixx -x c++", 35 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\StatusVar.ixx", 36 | "output": "CMakeFiles\\NvStrapsReBar.dir\\StatusVar.ixx.obj" 37 | }, 38 | { 39 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 40 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\DeviceRegistry.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\DeviceRegistry.ixx -x c++", 41 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\DeviceRegistry.ixx", 42 | "output": "CMakeFiles\\NvStrapsReBar.dir\\DeviceRegistry.ixx.obj" 43 | }, 44 | { 45 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 46 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\LocalAppConfig.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\LocalAppConfig.ixx -x c++", 47 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\LocalAppConfig.ixx", 48 | "output": "CMakeFiles\\NvStrapsReBar.dir\\LocalAppConfig.ixx.obj" 49 | }, 50 | { 51 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 52 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsWinAPI.ixx -x c++", 53 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsWinAPI.ixx", 54 | "output": "CMakeFiles\\NvStrapsReBar.dir\\NvStrapsWinAPI.ixx.obj" 55 | }, 56 | { 57 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 58 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -fms-compatibility -fms-extensions -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsDXGI.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\NvStrapsDXGI.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsDXGI.ixx -x c++", 59 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsDXGI.ixx", 60 | "output": "CMakeFiles\\NvStrapsReBar.dir\\NvStrapsDXGI.ixx.obj" 61 | }, 62 | { 63 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 64 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\WinApiError.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\WinApiError.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\WinApiError.ixx -x c++", 65 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\WinApiError.ixx", 66 | "output": "CMakeFiles\\NvStrapsReBar.dir\\WinApiError.ixx.obj" 67 | }, 68 | { 69 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 70 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\ConfigManagerError.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\ConfigManagerError.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ConfigManagerError.ixx -x c++", 71 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ConfigManagerError.ixx", 72 | "output": "CMakeFiles\\NvStrapsReBar.dir\\ConfigManagerError.ixx.obj" 73 | }, 74 | { 75 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 76 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\DeviceList.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\DeviceList.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\DeviceList.ixx -x c++", 77 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\DeviceList.ixx", 78 | "output": "CMakeFiles\\NvStrapsReBar.dir\\DeviceList.ixx.obj" 79 | }, 80 | { 81 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 82 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\TextWizardPage.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\TextWizardPage.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\TextWizardPage.ixx -x c++", 83 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\TextWizardPage.ixx", 84 | "output": "CMakeFiles\\NvStrapsReBar.dir\\TextWizardPage.ixx.obj" 85 | }, 86 | { 87 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 88 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\NvStrapsConfig.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\NvStrapsConfig.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsConfig.ixx -x c++", 89 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\NvStrapsConfig.ixx", 90 | "output": "CMakeFiles\\NvStrapsReBar.dir\\NvStrapsConfig.ixx.obj" 91 | }, 92 | { 93 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 94 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\TextWizardMenu.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\TextWizardMenu.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\TextWizardMenu.ixx -x c++", 95 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\TextWizardMenu.ixx", 96 | "output": "CMakeFiles\\NvStrapsReBar.dir\\TextWizardMenu.ixx.obj" 97 | }, 98 | { 99 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 100 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe/include -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -std=gnu++23 -fexperimental-library -Wno-switch -Wno-unqualified-std-cast-call -fretain-comments-from-system-headers -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm @CMakeFiles\\NvStrapsReBar.dir\\ConfigurationWizard.ixx.obj.modmap -o CMakeFiles\\NvStrapsReBar.dir\\ConfigurationWizard.ixx.obj -c C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ConfigurationWizard.ixx -x c++", 101 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\ConfigurationWizard.ixx", 102 | "output": "CMakeFiles\\NvStrapsReBar.dir\\ConfigurationWizard.ixx.obj" 103 | }, 104 | { 105 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw", 106 | "command": "C:\\msys64\\clang64\\bin\\c++.exe -std=gnu++23 -fexperimental-library -x c++ -Xclang -emit-module -fmodule-name=std -fretain-comments-from-system-headers -o C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState -c C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/cxx_std_lib.modulemap", 107 | "file": "C:\\Users\\Adrian\\Packages\\edk2\\NvStrapsReBar\\ReBarState\\cxx_std_lib.modulemap", 108 | "output": "cxx_std_lib.pcm" 109 | } 110 | ] 111 | -------------------------------------------------------------------------------- /ReBarState/cxx_std_lib.hh: -------------------------------------------------------------------------------- 1 | #if !defined(CLANG_STD_MODULE_HH) 2 | #define CLANG_STD_MODULE_HH 3 | 4 | #include 5 | #if _HAS_STATIC_RTTI 6 | #include 7 | #endif // _HAS_STATIC_RTTI 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #if _HAS_CXX23 25 | #include 26 | #endif // _HAS_CXX23 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #if _HAS_CXX23 54 | #include 55 | #endif // _HAS_CXX23 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #if _HAS_CXX23 68 | #include 69 | #endif // _HAS_CXX23 70 | #include 71 | #include 72 | #if _HAS_CXX23 73 | #include 74 | #endif // _HAS_CXX23 75 | #include 76 | #if _HAS_CXX23 77 | #include 78 | #endif // _HAS_CXX23 79 | #include 80 | #include 81 | #include 82 | #include 83 | // #include 84 | #if !defined(__clang__) 85 | # include 86 | #endif 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | 101 | // "C++ headers for C library facilities" [tab:headers.cpp.c] 102 | #include 103 | #include 104 | #include 105 | #include 106 | #include 107 | #include 108 | #include 109 | #include 110 | #include 111 | #include 112 | #include 113 | #include 114 | #include 115 | #include 116 | #include 117 | #include 118 | #include 119 | #include 120 | #include 121 | #include 122 | #include 123 | 124 | #endif // !defined(CLANG_STD_MODULE_HH) 125 | -------------------------------------------------------------------------------- /ReBarState/cxx_std_lib.modulemap: -------------------------------------------------------------------------------- 1 | module std { 2 | requires cplusplus23 3 | header "cxx_std_lib.hh" 4 | export * 5 | } 6 | -------------------------------------------------------------------------------- /ReBarState/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(CTest) 2 | include(CxxStdModule) 3 | 4 | cmake_minimum_required(VERSION 3.27) 5 | 6 | create_test_sourcelist(NVSTRAPS_REBAR_TEST_SOURCES TestNvStrapsReBar.cc TestNvStrapsConfig.cc) 7 | 8 | set(TEST_NVSTRAPS_REBAR_SOURCES 9 | "${REBAR_DXE_DIRECTORY}/include/EfiVariable.h" 10 | "${REBAR_DXE_DIRECTORY}/include/StatusVar.h" 11 | "${REBAR_DXE_DIRECTORY}/include/DeviceRegistry.h" 12 | "${REBAR_DXE_DIRECTORY}/include/NvStrapsConfig.h" 13 | "${REBAR_DXE_DIRECTORY}/EfiVariable.c" 14 | "${REBAR_DXE_DIRECTORY}/StatusVar.c" 15 | "${REBAR_DXE_DIRECTORY}/DeviceRegistry.c" 16 | "${REBAR_DXE_DIRECTORY}/NvStrapsConfig.c" 17 | "${NvStrapsReBar_SOURCE_DIR}/LocalAppConfig.ixx" 18 | "${NvStrapsReBar_SOURCE_DIR}/WinApiError.ixx" 19 | "${NvStrapsReBar_SOURCE_DIR}/NvStrapsWinAPI.ixx" 20 | "${NvStrapsReBar_SOURCE_DIR}/DeviceRegistry.ixx" 21 | "${NvStrapsReBar_SOURCE_DIR}/NvStrapsConfig.ixx" 22 | 23 | TestNvStrapsReBar.cc 24 | TestNvStrapsConfig.cc 25 | ) 26 | 27 | add_executable(TestNvStrapsReBar ${TEST_NVSTRAPS_REBAR_SOURCES}) 28 | target_link_libraries(TestNvStrapsReBar PRIVATE SetupAPI $) 29 | 30 | target_include_directories(TestNvStrapsReBar PRIVATE $) 31 | 32 | list(POP_FRONT NVSTRAPS_REBAR_TEST_SOURCES) 33 | 34 | foreach(TEST_FILE IN LISTS NVSTRAPS_REBAR_TEST_SOURCES) 35 | cmake_path(GET TEST_FILE STEM TEST_NAME) 36 | add_test(NAME "${TEST_NAME}" COMMAND TestNvStrapsReBar "${TEST_NAME}") 37 | endforeach() 38 | -------------------------------------------------------------------------------- /ReBarState/test/TestNvStrapsConfig.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int TestNvStrapsConfig(int argc, char *argv[]) 4 | { 5 | return EXIT_SUCCESS; 6 | } 7 | -------------------------------------------------------------------------------- /UEFIPatch/BdwUSB3.txt: -------------------------------------------------------------------------------- 1 | # PciBus | Add Intel 9 Series XHCI Controller to 64-bit blacklist (fix broken USB in UEFI with 4G decoding) 2 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:DE10D301FFFF00000B00000014:8680B18CFFFF00000B00000010 3 | 4 | # It works by replacing NVIDIA 7200 GS (10de:01d3) BAR offset 0x14 force 32-bit BAR with 9 series XHCI (8086:8cb1) BAR offset 0x10 5 | -------------------------------------------------------------------------------- /UEFIPatch/HswUSB3.txt: -------------------------------------------------------------------------------- 1 | # PciBus | Add Intel 8 Series XHCI Controller to 64-bit blacklist (fix broken USB in UEFI with 4G decoding) 2 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:DE10D301FFFF00000B00000014:8680319CFFFF00000B00000010 3 | 4 | # It works by replacing NVIDIA 7200 GS (10de:01d3) BAR offset 0x14 force 32-bit BAR with 8 series XHCI (8086:9c31) BAR offset 0x10 5 | -------------------------------------------------------------------------------- /UEFIPatch/IvyUSB3.txt: -------------------------------------------------------------------------------- 1 | # PciBus | Add Intel 7 Series XHCI Controller to 64-bit blacklist (fix broken USB in UEFI with 4G decoding) 2 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:DE10D301FFFF00000B00000014:8680311EFFFF00000B00000010 3 | 4 | # It works by replacing NVIDIA 7200 GS (10de:01d3) BAR offset 0x14 force 32-bit BAR with 7 series XHCI (8086:1e31) BAR offset 0x10 5 | -------------------------------------------------------------------------------- /UEFIPatch/patches.txt: -------------------------------------------------------------------------------- 1 | # PciHostBridge | Remove <4GB BAR size limit in SubmitResources (Ivy Bridge) 2 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:77B6488B0F493BCF73AE48FFC1E81BFFFFFF488B1748FFC8483BD0759B:669066909066909066906690909090669090488B176690906690906690 3 | 4 | # PciHostBridge | Replace 16GB MMIO region with complete use of physical address space (Ivy Bridge). MAY REQUIRE DSDT MODIFICATION 5 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:48BA000000000100000049B80000000004000000483BDA8BCE480F47D3:49B800000000100000004929D8909090909090906690908BCE4889DA90 6 | 7 | # PciHostBridge | Replace 8-16GB MMIO region with complete use of 64GB address space (Haswell). MAY REQUIRE DSDT MODIFICATION 8 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:080000004823C1483BC3770C48BE0000000004000000EB7A48BB000000000C000000483BC3770C48BE0000000002000000EB5F48BB000000000E000000483BC3770C48BE0000000001000000EB4448BB000000000F000000483BC37707BE00000080EB2E48BB000000800F000000483BC37707BE00000040EB1848BB000000C00F000000483BC30F87A4FEFFFFBE00000020:010000004821C84839D8480F47D848BE00000000100000004829DE9090909090909066909066906690909090909090909066906690909090909090909066909066906690909090909090909066906690909090909090909066909066909090909090669066909090909090909090669090669090909090906690669090909090909090906690909090909090909090909090 9 | 10 | # PciHostBridge | Replace 32/48GB - 63GB MMIO region with 32/48GB - 64GB (Haswell) 11 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:3BC3771548BE000000C00F000000482B:3BC3771548BE0000000010000000482B 12 | 13 | # PciBus | Remove <16GB BAR size limit (Ivy Bridge/Haswell) 14 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:B8FFFFFFFF030000004C3B:B8FFFFFFFFFFFFFF004C3B 15 | 16 | # PciBus | Remove <64GB BAR size limit (Skylake/Kaby Lake/Coffee Lake) 17 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:B800000000100000004C3B:B8FFFFFFFFFFFFFF004C3B 18 | 19 | # PciBus | Don't downgrade 64-bit BARs to 32-bit (Haswell) 20 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:833E067506C70604000000833E077506C70605000000:66906690669066906690669066906690669066906690 21 | 22 | # PciBus | Don't downgrade 64-bit BARs to 32-bit (by @Mak3rde) 23 | 3C1DE39F-D207-408A-AACC-731CFB7F1DD7 10 P:C70605000000833E067506C70604000000BE01000000:909090909090833E067506909090909090BE01000000 24 | 25 | # AMI APTIO V NvramSmiDxe (Socket 2011-v3 MB: C612, X99) NVRAM whitelist unlock 26 | 54B070F3-9EB8-47CC-ADAF-39029C853CBB 10 P:0F84B300000041F6:90E9B300000041F6 27 | 28 | # NvramSmi NVRAM whitelist unlock (by @vit9696) 29 | 842A454A-75E5-408B-8B1C-36420E4E3F21 10 P:9801000072:0000000072 30 | 31 | # PciHostBridge | Fix AddMemorySpace call (Sandy/Ivy Bridge) 32 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:040000004823C1483BC2480F47D04C2BC27411:100000004823C1483BC2480F47D04C2BC26690 33 | 34 | # Runtime | Remove 4GB limit for CpuIo2 35 | CBC59C4A-383A-41EB-A8EE-4498AEA567E4 10 P:B9FFFFFFFF490FAFC14903C0483BC1776C:6690669090490FAFC14903C06690906690 36 | 37 | # PciHostBridge | Remove 4GB limit for PciRootBridgeIo.Mem 38 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:493B4C24C0771B:66906690669090 39 | 8D6756B9-E55E-4D6A-A3A5-5E4D72DDF772 10 P:493B4C24C0771C:66906690669090 40 | 41 | # IvtQpiandMrcInit | Extend MMIOH limit to fix Above 4G Decoding (X79), untested with multi CPU 42 | #5C08C7C8-24C2-4400-9627-CF2869421E06 10 P:0FB796....00006685D2:BA0020000066906685D2 43 | -------------------------------------------------------------------------------- /compile_commands.template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 4 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG\\AutoGen.c", 5 | "file": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG\\AutoGen.c", 6 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\AutoGen.obj" 7 | }, 8 | { 9 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 10 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\ReBar.c", 11 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\ReBar.c", 12 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\ReBar.obj" 13 | }, 14 | { 15 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 16 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c", 17 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\DeviceRegistry.c", 18 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\DeviceRegistry.obj" 19 | }, 20 | { 21 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 22 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c", 23 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\NvStrapsConfig.c", 24 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\NvStrapsConfig.obj" 25 | }, 26 | { 27 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 28 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c", 29 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\EfiVariable.c", 30 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\EfiVariable.obj" 31 | }, 32 | { 33 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 34 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\SetupNvStraps.c", 35 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\SetupNvStraps.c", 36 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\SetupNvStraps.obj" 37 | }, 38 | { 39 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 40 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c", 41 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\StatusVar.c", 42 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\StatusVar.obj" 43 | }, 44 | { 45 | "directory": "C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarDxe", 46 | "command": "clang.exe -x c++ -fms-compatibility -fms-extensions -fretain-comments-from-system-headers -Wno-unused-includes -Wno-bitwise-op-parentheses -Wno-dangling-else -c -DUNICODE -include AutoGen.h -DUSING_LTO -DUEFI_SOURCE -std=gnu++23 -DMDEPKG_NDEBUG -fmodule-file=C:/Users/Adrian/Packages/edk2/NvStrapsReBar/ReBarState/build-mingw/cxx_std_lib.pcm -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\include -IC:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe -IC:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\DEBUG -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Library\\MipiSysTLib\\mipisyst\\library\\include -isystemc:\\users\\adrian\\packages\\edk2\\MdePkg\\Include\\X64 -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg -isystemc:\\users\\adrian\\packages\\edk2\\MdeModulePkg\\Include c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\PciConfig.c", 47 | "file": "c:\\users\\adrian\\packages\\edk2\\NvStrapsReBar\\ReBarDxe\\PciConfig.c", 48 | "output": "c:\\users\\adrian\\packages\\edk2\\Build\\NvStrapsReBar\\RELEASE_VS2019\\X64\\NvStrapsReBar\\ReBarDxe\\ReBarDxe\\OUTPUT\\PciConfig.obj" 49 | } 50 | ] 51 | 52 | -------------------------------------------------------------------------------- /rebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terminatorul/NvStrapsReBar/5ce12bb5585c19cd54eefe670910ebf19793586d/rebar.png -------------------------------------------------------------------------------- /tools/uuidconv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # convert uuid to C structure. couldn't find any way to generate guid structure on linux so made this uwu 3 | # usage 4 | # ./uuidconv.py a3c5b77a-c88f-4a93-bf1c-4a92a32c65ce 5 | 6 | import sys 7 | 8 | uuid = sys.argv[1].replace("-","") 9 | print(f"{{0x{uuid[:8]}, 0x{uuid[8:12]}, 0x{uuid[12:16]}, {{0x{uuid[16:18]}, 0x{uuid[18:20]}, 0x{uuid[20:22]}, 0x{uuid[22:24]}, 0x{uuid[24:26]}, 0x{uuid[26:28]}, 0x{uuid[28:30]}, 0x{uuid[30:32]}}}}};") --------------------------------------------------------------------------------