summaryrefslogtreecommitdiff
path: root/BREAKING-CHANGES.md
blob: 9182a198d1d385fffcab74c63a5e3a3fdcd7e701 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
# EDK II Breaking Changes

This file is the in-tree record of breaking changes in EDK II. Each breaking change has a single entry that is added
in the pull request that introduces the change and updated in any later pull request that changes its state. The file
is organized by stable tag milestone with most recent first.

Within a given section, each breaking change is added after existing entries so they are in chronological merge order
within the section.

For the full process, including the breaking change taxonomy, deprecation timeline, required entry content, and GitHub
issue requirements, see the [Breaking Change and Release Process for EDK II](https://raw.githubusercontent.com/tianocore/tianocore-wiki.github.io/refs/heads/main/rfc/text/0003-edk2-breaking-change-and-release-process.md)
RFC.

## edk2-stable202702

- Milestone: [edk2-stable202702](https://github.com/tianocore/edk2/milestone/7)

### edk2-stable202702: Source-Level Breaking Changes

#### edk2-stable202702: Changes with Removal

None

#### edk2-stable202702: Changes without Removal

None

### edk2-stable202702: Behavioral Breaking Changes

None

### edk2-stable202702: Build-System Breaking Changes

None

---

## edk2-stable202611

- Milestone: [edk2-stable202611](https://github.com/tianocore/edk2/milestone/6)

### edk2-stable202611: Source-Level Breaking Changes

#### edk2-stable202611: Changes with Removal

None

#### edk2-stable202611: Changes without Removal

##### Breaking Change: Rename the DMC-620 PMU Dynamic Tables interfaces

- **Status**: Announced
- **Tracking Issue**: [tianocore/edk2#13070](https://github.com/tianocore/edk2/issues/13070)
- **Pull Request**: [tianocore/edk2#12994](https://github.com/tianocore/edk2/pull/12994)
- **Type**: Source-Level (Non-removal) - Public identifier, structure,
  structure member, generator symbol, file, and library path rename

**What changed**: The DMC-620 PMU Dynamic Tables interfaces and SSDT
generator were renamed to use the DMC PMU terminology adopted by the
ACPI for Arm Components 1.3 Platform Design Document. The
table-generator ID, Configuration Manager object IDs and structures,
structure member, generator symbol, source files and library path were
renamed. The generated AML, `ARMHD620` hardware identifier and generator
behaviour are unchanged.

**Why it changed**: ACPI for Arm Components 1.3 updates the relevant
section and interface terminology from “DMC620 Memory Controller” and
“DMC620 PMU” to “DMC Memory Controller” and “DMC PMU”. The edk2
interfaces are renamed to align with the terminology used by the latest
specification.

**What replaces it**:

- `EStdAcpiTableIdSsdtDmc620Pmu` is replaced by
  `EStdAcpiTableIdSsdtDmcPmu`.
- `EArmObjDmc620PmuSocketInfo` is replaced by
  `EArmObjDmcPmuSocketInfo`.
- `EArmObjDmc620PmuRegInfo` is replaced by `EArmObjDmcPmuRegInfo`.
- `CM_ARM_DMC620_PMU_REG_INFO` is replaced by
  `CM_ARM_DMC_PMU_REG_INFO`.
- `CM_ARM_DMC620_INFO` is replaced by `CM_ARM_DMC_INFO`.
- `Dmc620PmuRegInfoToken` is replaced by `DmcPmuRegInfoToken`.
- `SsdtDmc620PmuGenerator` is replaced by `SsdtDmcPmuGenerator`.
- `AcpiSsdtDmc620PmuLibArm` is replaced by `AcpiSsdtDmcPmuLibArm`.

**How to migrate**: Replace the DMC-620-specific identifiers, structure
names, structure member, generator symbol, filenames and library path with
the DMC PMU equivalents listed above. No platform-data or behavioural changes
are required.

**Breaking conditions**: This affects out-of-tree platforms that consume
the DMC-620 PMU Configuration Manager interfaces or reference the old
generator symbol, filenames or library path. No consumer was found in the
current edk2 or edk2-platforms repositories.

**Companion PR**: None required; no edk2-platforms consumer was identified.

##### Breaking Change: Generalize the CMN SSDT generator

- **Status**: Announced
- **Tracking Issue**: [tianocore/edk2#13060](https://github.com/tianocore/edk2/issues/13060)
- **Pull Request**: [tianocore/edk2#13019](https://github.com/tianocore/edk2/pull/13019)
- **Type**: Source-Level (Non-removal) - Public identifier rename,
  structure layout change, and library path rename

**What changed**: The CMN-600-specific Dynamic Tables interfaces and
generator were generalized to support CMN-600, CMN-650, CMN-700 and
CMN-S3. The Configuration Manager object, table-generator ID, structure,
generator symbols and library paths now use generic CMN terminology.
The generic CMN information structure also identifies the CMN
implementation and describes the optional ROOT resource length.

**Why it changed**: The existing generator names and interfaces implied
that only CMN-600 was supported. Generalizing them allows one generator
to describe multiple CMN implementations while retaining the existing
CMN-600 table-generation behaviour.

**What replaces it**:

- `EStdAcpiTableIdSsdtCmn600` is replaced by
  `EStdAcpiTableIdSsdtCmn`.
- `EArmObjCmn600Info` is replaced by `EArmObjCmnInfo`.
- `CM_ARM_CMN_600_INFO` is replaced by `CM_ARM_CMN_INFO`.
- The `AcpiSsdtCmn600LibArm` generator is replaced by
  `AcpiSsdtCmnLibArm`.

**How to migrate**: Replace the CMN-600-specific identifiers, structure
name, generator symbols and library paths with their generic CMN
equivalents. Initialize `CmnType` to the appropriate `ARM_CMN_TYPE`.
For an existing CMN-600 description, set `CmnType` to
`ArmCmnType600` and `RootNodeBaseAddressLength` to the CMN-600 ROOT
region length. For CMN implementations without a separate ROOT
resource, set `RootNodeBaseAddress` and `RootNodeBaseAddressLength`
to zero.

**Breaking conditions**: This affects out-of-tree platforms that consume
the CMN-600 Dynamic Tables Configuration Manager object or reference the
CMN-600 generator library path. No consumer was found in the current
edk2-platforms repository.

**Companion PR**: None required; no edk2-platforms consumer was identified.

### edk2-stable202611: Behavioral Breaking Changes

None

### edk2-stable202611: Build-System Breaking Changes

None

---

## edk2-stable202608

- Milestone: [edk2-stable202608](https://github.com/tianocore/edk2/milestone/5)

> Note: The entries below with "N/A" issues were merged during the edk2-stable202608 development period
> (after the `edk2-stable202605 tag`) and before the breaking change process took effect. They therefore have no
> associated GitHub Tracking, Deprecation, or Removal issues. Each entry links to the pull request that introduced
> the change in place of those issues. This is expected to be a one-time occurrence during the transition to the new
> breaking changes process during the `edk2-stable202608` development period.

### edk2-stable202608: Source-Level Breaking Changes

#### edk2-stable202608: Changes with Removal

##### Breaking Change: AArch64 exception handling relocated from ArmPkg to UefiCpuPkg

- **Status**: Removed
- **Tracking Issue**: N/A (merged before the breaking change process took effect)
- **Deprecation Issue**: N/A
- **Removal Issue**: N/A
- **Pull Request**: [tianocore/edk2#12340](https://github.com/tianocore/edk2/pull/12340)
- **Type**: Source-Level (Removal) - Library class restructure, API removal, and header file removal

**What changed**: AArch64 exception handling was moved from `ArmPkg` to `UefiCpuPkg`. `ArmExceptionLib` and
`DefaultExceptionHandlerLib` were merged into `CpuExceptionHandlerLib`, the `DefaultExceptionHandler()` API was renamed
to `DumpCpuContext()`, and the `ArmPkg/Include/Library/DefaultExceptionHandlerLib.h` public header was removed.

**What is removed**: The `ArmPkg` `ArmExceptionLib` and `DefaultExceptionHandlerLib` library instances, the
`DefaultExceptionHandlerLib.h` public header, and the `DefaultExceptionHandler()` API.

**Why it changed**: To provide consistent exception handling across all CPU architectures (IA32, X64, LoongArch64,
RISCV64, AARCH64) by unifying on the `UefiCpuPkg` `CpuExceptionHandlerLib`.

**What replaces it**: The `UefiCpuPkg` `CpuExceptionHandlerLib` (for example, `DxeCpuExceptionHandlerLib.inf`) and the
`DumpCpuContext()` API declared in the `UefiCpuPkg` `CpuExceptionLib.h` interface.

**How to migrate**: For out-of-tree modules that used `DefaultExceptionHandlerLib`, add `UefiCpuPkg.dec` as a package
dependency and update the platform DSC to map the exception handling library class to `CpuExceptionHandlerLib`. Replace
all `DefaultExceptionHandler()` calls with `DumpCpuContext()`. Remove all references of `ArmExceptionLib` from the DSC
file.

**Breaking conditions**: Affects AArch64 (ARM) platforms and out-of-tree modules that consumed `ArmExceptionLib`,
`DefaultExceptionHandlerLib`, or the `DefaultExceptionHandler()` API.

**Earliest removal**: Already removed in this change. The old code was removed in the same PR with no compatibility window.

##### Breaking Change: PrePiLib FfsFindSectionDataWithHook and FfsProcessFvFile gain new parameters

- **Status**: Removed
- **Tracking Issue**: N/A (merged before the breaking change process took effect)
- **Deprecation Issue**: N/A
- **Removal Issue**: N/A
- **Pull Request**: [tianocore/edk2#12672](https://github.com/tianocore/edk2/pull/12672)
- **Type**: Source-Level (Removal) - API signature change

**What changed**: `EmbeddedPkg` `PrePiLib` API signatures changed to improve FV2/FV3 HOB handling.
`FfsFindSectionDataWithHook()` gained an `AuthenticationStatus` output parameter and `FfsProcessFvFile()` gained a
`ParentVolumeHandle` parameter. In addition, `PrePi.h` dropped duplicate HOB definitions in favor of `HobLib.h`.

**What is removed**: The previous `FfsFindSectionDataWithHook()` and `FfsProcessFvFile()` function signatures.

**Why it changed**: To correctly produce FV3 HOBs (which supersede FV2 HOBs) for extracted FVs and to set the FV2 HOB
`FvName` to the parent FV name so DXE does not re-extract already-extracted FVs (a performance hit of approximately one
second on some platforms). Producing the FV3 HOB requires the authentication status from the GUIDed extraction, and
correct FV2 HOB production requires the parent FV handle.

**What replaces it**: The same functions with the new signatures.

**How to migrate**: Update callers of `FfsFindSectionDataWithHook()` to pass the new `AuthenticationStatus` argument
(pass `NULL` to retain existing behavior, or a `UINT32 *` to receive the status). Update callers of
`FfsProcessFvFile()` to pass the `ParentVolumeHandle`.

**Breaking conditions**: Affects modules that call `PrePiLib`'s `FfsFindSectionDataWithHook()` or `FfsProcessFvFile()`
(for example, `EmbeddedPkg` and `OvmfPkg` peiless startup consumers).

**Earliest removal**: Already removed in this change. The old signatures were replaced in the same PR with no
compatibility window.

##### Breaking Change: BaseRiscV64CpuTimerLib renamed and split into SEC and DXE TimerLib instances

- **Status**: Removed
- **Tracking Issue**: N/A (merged before the breaking change process took effect)
- **Deprecation Issue**: N/A
- **Removal Issue**: N/A
- **Pull Request**: [tianocore/edk2#12210](https://github.com/tianocore/edk2/pull/12210)
- **Type**: Source-Level (Removal) - Library class restructure

**What changed**: The `UefiCpuPkg` `BaseRiscV64CpuTimerLib` was renamed to `RiscV64CpuTimerLib` and split into two
instances: `RiscV64CpuTimerSecLib.inf` (`MODULE_TYPE` `SEC`, for SEC and PEI, no constructor) and
`RiscV64CpuTimerDxeLib.inf` (for `DXE_CORE`, `DXE_DRIVER`, and other DXE-phase modules, which retains the constructor).
The old `UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf` path was removed.

**What is removed**: The `BaseRiscV64CpuTimerLib` library instance and its INF path.

**Why it changed**: The library constructor calls `GetPerformanceCounterProperties()`, which requires the HOB list. In
the SEC and PEI phases the HOB list may not yet be available, causing a crash. Splitting the instances runs the
constructor only in the DXE instance.

**What replaces it**: The phase-specific instances `RiscV64CpuTimerSecLib.inf` (SEC and PEI) and
`RiscV64CpuTimerDxeLib.inf` (DXE).

**How to migrate**: Update platform DSC `TimerLib` mappings that referenced
`UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf`. Map `TimerLib` to `RiscV64CpuTimerSecLib.inf`
for SEC and PEI modules and to `RiscV64CpuTimerDxeLib.inf` for DXE modules.

**Breaking conditions**: Affects RISC-V (RISCV64) platforms that consume the RISC-V CPU timer library.

**Earliest removal**: Already removed in this change. The old INF path was removed in the same PR with no compatibility
window.

##### Breaking Change: TPM2 helper functions moved to new Tpm2HelpLib library class

- **Status**: Deprecation Active
- **Tracking Issue**: [tianocore/edk2#12797](https://github.com/tianocore/edk2/issues/12797)
- **Deprecation Issue**: [tianocore/edk2#12799](https://github.com/tianocore/edk2/issues/12799)
- **Pull Request**: [tianocore/edk2#11634](https://github.com/tianocore/edk2/pull/11634)
- **Type**: Source-Level (Non-removal) - Library class dependency addition (single expected instance)

**What changed**: The TPM2 helper functions in `Tpm2Help.c` were decoupled from `Tpm2CommandLib` into a new standalone
`SecurityPkg` library class, `Tpm2HelpLib`. This allows using the helpers without pulling in `Tpm2CommandLib` and
`Tpm2DeviceLib`, which are tied to TPM communication. In-tree modules (for example, `HashLibBaseCryptoRouter`,
`PeilessSecMeasureLib`, and `TdTcg2Dxe`) were updated to consume `Tpm2HelpLib`.

**Library class dependency case**: Single expected instance. `SecurityPkg` provides the single recommended instance at
`SecurityPkg/Library/Tpm2HelpLib/Tpm2HelpLib.inf`, so migration is a DSC library class mapping.

**Why it changed**: Some callers need the helper functions without TPM communication dependencies. Examples include
generating a HOB for pre-DXE measurements and the SEC phase, where there is no `Tpm2DeviceLib`.

**What replaces it**: The `Tpm2HelpLib` library class. The helper functions remaining in `Tpm2CommandLib`'s
`Tpm2Help.c` are now deprecated wrappers that delegate to `Tpm2HelpLib`.

**How to migrate**: Platforms building modules that now depend on `Tpm2HelpLib` must add a mapping in their DSC
(`Tpm2HelpLib|SecurityPkg/Library/Tpm2HelpLib/Tpm2HelpLib.inf`) or the build fails with an unresolved library class. For
code, add `Tpm2HelpLib` to the module INF and include the header, then update calls to the deprecated `Tpm2Help.c`
wrappers in `Tpm2CommandLib` to use the `Tpm2HelpLib` versions.

**Earliest removal**: The deprecated `Tpm2CommandLib` `Tpm2Help.c` wrappers may be removed in a future stable tag. A
removal stable tag has not been scheduled at this time.

> Note: GitHub issues were created to track edk2-platforms following migration instructions.
>
> - [Platform/ARM: Switch to Tpm2HelpLib](https://github.com/tianocore/edk2-platforms/issues/994)
> - [Platform/MinPlatformPkg: Switch to Tpm2HelpLib](https://github.com/tianocore/edk2-platforms/issues/995)
> - [Silicon/Ampere/AmpereAltraPkg: Switch to Tpm2HelpLib](https://github.com/tianocore/edk2-platforms/issues/996)

#### edk2-stable202608: Changes without Removal

##### Breaking Change: New GptLib library class dependency

- **Status**: Announced
- **Tracking Issue**: [tianocore/edk2#12808](https://github.com/tianocore/edk2/issues/12808)
- **Pull Request**: [tianocore/edk2#12745](https://github.com/tianocore/edk2/pull/12745)

**Type**: Source-Level (Non-removal) - Library class dependency addition
(single expected instance)

**What changed**: PartitionDxe, DxeTpm2MeasureBootLib and
DxeTpmMeasureBootLib gained a required dependency on the new GptLib library
class declared in MdeModulePkg. Platforms that build any of these modules
must resolve GptLib in their DSC or the build fails with an unresolved
library class.

**Why it changed**: As reported in CVE-2024-13745, DxeTpm2MeasureBootLib
could measure a GPT partition table that differs from the one parsed and
used by PartitionDxe, because the two components carried independent GPT
parsing logic. GptLib consolidates GPT parsing and validation so the
partition table measured into PCR[5] is validated by the same logic the
firmware uses.

**What replaces it**: Nothing is removed. A single canonical GptLib
instance is provided in-tree (MdeModulePkg/Library/GptLib/GptLib.inf).

**How to migrate**: Add the following mapping to the platform DSC
[LibraryClasses] section:

  GptLib|MdeModulePkg/Library/GptLib/GptLib.inf

##### Breaking Change: New Tcg2PhysicalPresencePromptLib library class dependency

- **Status**: Announced
- **Tracking Issue**: [tianocore/edk2#TBD](https://github.com/tianocore/edk2/issues/12832)
- **Pull Request**: [tianocore/edk2#12820](https://github.com/tianocore/edk2/pull/12820)
- **Type**: Source-Level (Non-removal) - Library class dependency addition (platform-implemented)

**What changed**: `SecurityPkg` `DxeTcg2PhysicalPresenceLib` gained a required dependency on the new
`Tcg2PhysicalPresencePromptLib` library class declared in `SecurityPkg/SecurityPkg.dec`. Platforms
that build `DxeTcg2PhysicalPresenceLib` must resolve `Tcg2PhysicalPresencePromptLib` in their DSC or
the build fails with an unresolved library class.

**Why it changed**: Previously, `DxeTcg2PhysicalPresenceLib` printed the Physical Presence confirmation prompt
directly to the console, giving platforms no clean way to substitute a platform-specific user-interaction mechanism.
Extracting the prompt behind a library class lets platforms provide their own prompt implementation without patching
`DxeTcg2PhysicalPresenceLib` and keeps the TPM 2.0 Physical Presence flow decoupled from any specific UI.

**What replaces it**: Nothing is removed. `DxeTcg2PhysicalPresenceLib` now calls into the
`Tcg2PhysicalPresencePromptLib` interface, and `SecurityPkg` provides the console-based default instance for platforms
that do not implement their own.

**How to migrate**: Platforms building `DxeTcg2PhysicalPresenceLib` must add a `Tcg2PhysicalPresencePromptLib` mapping
to their platform DSC `[LibraryClasses]` section. To keep the existing behavior, map to the in-tree console instance:

  Tcg2PhysicalPresencePromptLib|SecurityPkg/Library/Tcg2PhysicalPresencePromptLib/Tcg2PhysicalPresencePromptLibConsole.inf

Platforms that want a custom prompt UI can instead provide their own instance implementing the
`Tcg2PhysicalPresencePromptLib` interface declared in
`SecurityPkg/Include/Library/Tcg2PhysicalPresencePromptLib.h` and map the library class to that instance in their DSC.

**Breaking conditions**: Affects platforms and out-of-tree modules that build `SecurityPkg`'s
`DxeTcg2PhysicalPresenceLib` (`Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf`).
Platforms that do not consume `DxeTcg2PhysicalPresenceLib` are unaffected.

### edk2-stable202608: Behavioral Breaking Changes

None

### edk2-stable202608: Build-System Breaking Changes

#### Breaking Change: GenFv ForceRebase now honors a per-module Xip flag

- **Status**: Removed
- **Tracking Issue**: N/A (merged before the breaking change process took effect)
- **Deprecation Issue**: N/A
- **Removal Issue**: N/A
- **Pull Request**: [tianocore/edk2#12551](https://github.com/tianocore/edk2/pull/12551)
- **Type**: Build-System - DSC/INF/DEC syntax change and BaseTools change

**What changed**: Previously the `GenFv` rebase feature (`ForceRebase=1`, that is `FvForceRebase=TRUE`) was
all-or-nothing: it rebased every eligible FFS file in the firmware volume to the FV base address, with no way to
selectively rebase only XIP modules. A new `Xip=TRUE/FALSE` keyword was added to the FDF `[Rule]` section PE32/TE
section syntax so specific module types can be tagged for XIP rebase.

```text
[Rule.Common.PEI_CORE]
  FILE PEI_CORE = $(NAMED_GUID) {
    PE32     PE32   Align=Auto   Xip=TRUE   $(INF_OUTPUT)/$(MODULE_NAME).efi
  }
```

When `ForceRebase=1`, `GenFv` now rebases only modules whose type is tagged `Xip=TRUE`; a module type with no `Xip`
keyword defaults to not being rebased. The eligible file types considered for rebase are `SECURITY_CORE`, `PEI_CORE`,
`PEIM`, `COMBINED_PEIM_DRIVER`, `DRIVER`, and `DXE_CORE`. Per-module (rather than per-type) control is available by
defining named `XIP`/`NOXIP` rules and selecting them with `RuleOverride` in the `[FV]` section:

```text
[Rule.Common.PEIM.XIP]
  FILE PEIM = $(NAMED_GUID) {
    PE32     PE32   Align=Auto   Xip=TRUE   $(INF_OUTPUT)/$(MODULE_NAME).efi
  }

[Rule.Common.PEIM.NOXIP]
  FILE PEIM = $(NAMED_GUID) {
    PE32     PE32   Align=Auto              $(INF_OUTPUT)/$(MODULE_NAME).efi
  }

[FV.PEIFV]
  INF RuleOverride=XIP    MdeModulePkg/Core/Pei/PeiMain.inf
  INF RuleOverride=NOXIP  SomePkg/SomePeim/SomePeim.inf
```

**`FvForceRebase` rebase decision table**

| FvForceRebase | FvBaseAddress | Xip in any Rule | Result |
| :---: | :---: | :---: | :--- |
| `TRUE` | any | No files have `Xip=TRUE` | Rebase ALL eligible files (legacy) |
| `TRUE` | any | At least one file has `Xip=TRUE` | Rebase ONLY files with `Xip=TRUE` |
| `FALSE` | any | any | No rebase |
| not specified | != 0 | any | Rebase ALL eligible files (legacy) |
| not specified | == 0 or not specified | any | No rebase |

**Detailed changes**: The pull request description has a detailed explanation of the change and its motivation that
readers may find useful: [tianocore/edk2#12551](https://github.com/tianocore/edk2/pull/12551).

**Why it changed**: Only XIP (execute-in-place) modules (for example, `PEI_CORE` and `PEIM`) need PE32 address fixups to
their flash location. Rebasing non-XIP modules (for example, `DXE_CORE` and `DRIVER`) is unnecessary and can cause
issues. This provides finer-grained control than the all-or-nothing `ForceRebase`.

**What replaces it**: The `Xip` keyword in FDF `[Rule]` sections used together with `ForceRebase`.

**How to migrate**: The selective rebase only activates for an FV once at least one of its `[Rule]` sections uses
`Xip=TRUE`. Platforms that relied on `ForceRebase=1` rebasing all eligible modules and do not use `Xip=TRUE` anywhere
in the FV are unaffected. Platforms adopting selective rebase must add `Xip=TRUE` to the relevant `[Rule]` sections
(for example, the `PEI_CORE` and `PEIM` rules) so those modules continue to be rebased. Module types without
`Xip=TRUE` will not be rebased once any rule in the FV uses `Xip=TRUE`. For per-module rather than per-type control,
define named `XIP`/`NOXIP` rules and select them with `RuleOverride`.

**Breaking conditions**: The new `Xip` filter only applies when `ForceRebase=1` (`FvForceRebase=TRUE`) **and** at
least one FFS file in the FV is produced by a `[Rule]` section with `Xip=TRUE`. If no rule in the FV uses
`Xip=TRUE`, `ForceRebase=1` continues to rebase all eligible files, matching pre-#12551 behavior. The default
behavior is unchanged: when `ForceRebase` is unspecified with a non-zero FV base address, all eligible files are still
rebased unconditionally and the `Xip` keyword is not consulted. When `ForceRebase=0`, nothing is rebased regardless of
`Xip`.

**Earliest removal**: Already in effect in this change. The previous "rebase all" behavior was replaced in the same PR
with no compatibility window.

> Note: [tianocore/edk2#12807](https://github.com/tianocore/edk2/pull/12807) fixed a backward-compatibility
> regression introduced by this change, in which `FvForceRebase=TRUE` stopped rebasing any files in an FV when no
> `[Rule]` section in that FV specified `Xip=TRUE`. The fix tracks the count of `Xip=TRUE` files per FV and only
> enables the selective rebase logic when that count is greater than zero. Otherwise the legacy "rebase all" behavior
> is preserved. The **Breaking conditions** and **How to migrate** guidance above reflect the behavior after this
> fix.

#### Breaking Change: Visual Studio 2015 and 2017 toolchain support removed

- **Status**: Removed
- **Tracking Issue**: N/A (merged before the breaking change process took effect)
- **Deprecation Issue**: N/A
- **Removal Issue**: N/A
- **Pull Request**: [tianocore/edk2#12683](https://github.com/tianocore/edk2/pull/12683)
- **Type**: Build-System - Tool version requirement

**What changed**: Support for the `VS2015` and `VS2017` toolchains was removed from the repository. This removed the
`VS2015` and `VS2017` toolchain definitions from `BaseTools/Conf/tools_def.template`, the associated environment setup
logic in `toolsetup.bat`, `set_vsprefix_envs.bat`, `get_vsvars.bat`, and `edksetup.bat`, the `VS2017` configuration in
the `WindowsVsToolChain` build plugin, the `VS2015`-specific `CryptoPkg` compiler flags, the `EmulatorPkg` `VS2017`
Visual Studio solution, and the unused `ShowEnvironment.bat` and `SetVisualStudio.bat` helper scripts. The oldest
supported Visual Studio toolchain is now `VS2019`.

**What is removed**: The `VS2015` and `VS2017` toolchain definitions and their supporting scripts and build options.

**Why it changed**: To reduce maintenance burden and align on newer, supported toolchains. Visual Studio 2015
mainstream support ended on October 13, 2020 and extended support ended on October 14, 2025. Visual Studio 2017 is past
its mainstream support end date.

**What replaces it**: The `VS2019`, `VS2022`, and `VS2026` toolchains.

**How to migrate**: Developers building locally with the `VS2015` or `VS2017` toolchain must move to a newer Visual
Studio version (`VS2019` is the next supported version).

**Breaking conditions**: Only affects Windows developers and CI environments that build with the `VS2015` or `VS2017`
toolchain.

**Earliest removal**: Already removed in this change. The toolchains were removed in the same PR with no compatibility
window.