├── .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 | 
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 | 
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