diff --git a/Application/ModernSetupApp/ModernSetupApp.c b/Application/ModernSetupApp/ModernSetupApp.c index 73ff186..29c8307 100644 --- a/Application/ModernSetupApp/ModernSetupApp.c +++ b/Application/ModernSetupApp/ModernSetupApp.c @@ -236,7 +236,7 @@ UefiMain ( Redraw = TRUE; } else if (Page == PageBoot) { Status = ModernSetupLaunchSelectedBootOption (BootSelection); - UnicodeSPrint (StatusMessage, sizeof (StatusMessage), ModernUiGetString (ModernUiStringBootReturnedFormat), Status); + UnicodeSPrint (StatusMessage, sizeof (StatusMessage), ModernUiGetString (ModernUiStringClassicReturnedFormat), Status); Redraw = TRUE; } else if (Page == PageDevices) { Status = ModernSetupOpenSelectedDeviceEntry (DeviceSelection); diff --git a/Application/ModernSetupApp/ModernSetupAppActions.c b/Application/ModernSetupApp/ModernSetupAppActions.c index 2d188b7..8a1a84c 100644 --- a/Application/ModernSetupApp/ModernSetupAppActions.c +++ b/Application/ModernSetupApp/ModernSetupAppActions.c @@ -10,7 +10,11 @@ #include "ModernSetupAppInternal.h" -STATIC CONST EFI_GUID mUiAppGuid = { 0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23, 0x31 } }; +#if defined (MODERN_SETUP_NATIVE_FALLBACK_BOOT_MANAGER_MENU) && (MODERN_SETUP_NATIVE_FALLBACK_BOOT_MANAGER_MENU != 0) +STATIC CONST EFI_GUID mNativeFallbackAppGuid = { 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D } }; +#else +STATIC CONST EFI_GUID mNativeFallbackAppGuid = { 0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23, 0x31 } }; +#endif STATIC CONST MODERN_SETUP_DASHBOARD_ROUTE mDashboardCategoryRoutes[DASHBOARD_QUICK_CARD_COUNT] = { { PageBoot, SetupFocusContent }, @@ -372,39 +376,26 @@ ModernSetupGetPageSelectableCount ( } /** - Boot one visible Boot page row through UefiBootManagerLib. + Open the native Boot Manager for a visible Boot page row. - @param[in] Selection Zero-based visible Boot page row index. + ModernSetupApp is the setup/front-page UI. It lists Boot#### summaries, but + hands Boot#### launch responsibility to edk2's native BootManagerMenuApp (or + UiApp on platforms where the native setup app remains the fallback). Selection + is accepted for the UI contract and is not dereferenced here. - @retval EFI_SUCCESS Boot option was launched and returned. - @retval EFI_NOT_FOUND The selected Boot#### option could not be found. - @retval others Status from boot option decoding or launch. + @param[in] Selection Zero-based visible Boot page row index. Ignored. + + @retval EFI_SUCCESS Native boot manager returned successfully. + @retval EFI_NOT_FOUND Native fallback app could not be resolved. + @retval others Status returned by the native fallback handoff. **/ EFI_STATUS ModernSetupLaunchSelectedBootOption ( IN UINTN Selection ) { - EFI_STATUS Status; - MODERN_UI_BOOT_OPTION *Options; - UINTN OptionCount; - UINT16 OptionNumber; - - Options = NULL; - Status = ModernUiBootDataGetOptions (mModernSetupImageHandle, &Options, &OptionCount); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((Options == NULL) || (Selection >= OptionCount)) { - ModernUiBootDataFreeOptions (Options, OptionCount); - return EFI_NOT_FOUND; - } - - OptionNumber = Options[Selection].OptionNumber; - ModernUiBootDataFreeOptions (Options, OptionCount); - Status = ModernUiBootDataBootOption (OptionNumber); - return Status; + (VOID)Selection; + return ModernSetupLaunchUiAppFallback (mModernSetupImageHandle); } /** @@ -881,11 +872,15 @@ ModernSetupHandlePreferencesEnter ( } /** - Load and start the classic edk2 UiApp from the same firmware volume. + Load and start the native edk2 fallback app from the same firmware volume. + + By default this targets native UiApp. Test builds that replace the UiApp FFS + file with ModernSetupApp define MODERN_SETUP_NATIVE_FALLBACK_BOOT_MANAGER_MENU + so this action targets BootManagerMenuApp instead and avoids self-recursion. @param[in] ImageHandle Current image handle. Must not be NULL. - @retval EFI_SUCCESS UiApp returned successfully. + @retval EFI_SUCCESS Native fallback app returned successfully. @retval EFI_NOT_FOUND Current image device path could not be resolved. @retval EFI_OUT_OF_RESOURCES Device path allocation failed. @retval others Status returned by HandleProtocol(), LoadImage(), @@ -917,7 +912,7 @@ ModernSetupLaunchUiAppFallback ( return EFI_NOT_FOUND; } - EfiInitializeFwVolDevicepathNode (&FileNode, &mUiAppGuid); + EfiInitializeFwVolDevicepathNode (&FileNode, &mNativeFallbackAppGuid); AppPath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileNode); if (AppPath == NULL) { return EFI_OUT_OF_RESOURCES; diff --git a/Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png b/Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png new file mode 100644 index 0000000..7cde150 Binary files /dev/null and b/Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a11974..c15aec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,13 @@ this file as both a release log and a lightweight development progress record. ### Added +- Phase30 XArch/productization validation docs and smoke gate coverage through + `Docs/ProductizationValidationMatrix.md`, its zh-CN counterpart, doc-index + links, and host-side checks for evidence wording, concrete ARCH values, + ModernSetupApp/native HII boundaries, Hardware Health demo-only/read-only + status, app-owned preferences, PCIe policy ownership, and xarch dry-run target + metadata. This is documentation/test coverage only; runtime behavior is + unchanged. - Phase 29 Dashboard density layout: the app-owned `DashboardDensity` preference now feeds the Dashboard grid helper, so `Compact` reduces the top summary area and quick-card spacing while navigation uses the same density-aware diff --git a/Docs/ProductizationFeatureMatrix.md b/Docs/ProductizationFeatureMatrix.md index 7887116..1c46297 100644 --- a/Docs/ProductizationFeatureMatrix.md +++ b/Docs/ProductizationFeatureMatrix.md @@ -9,6 +9,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent Language: English | [简体中文](ProductizationFeatureMatrix.zh-CN.md) +See also: [ProductizationValidationMatrix.md](ProductizationValidationMatrix.md) for +the Phase30 evidence-backed validation matrix and smoke-gate contract. + ModernSetup has two XArch productization layers: ```text diff --git a/Docs/ProductizationFeatureMatrix.zh-CN.md b/Docs/ProductizationFeatureMatrix.zh-CN.md index 9e41612..e3f701a 100644 --- a/Docs/ProductizationFeatureMatrix.zh-CN.md +++ b/Docs/ProductizationFeatureMatrix.zh-CN.md @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent 语言:[English](ProductizationFeatureMatrix.md) | 简体中文 +另请参阅:[ProductizationValidationMatrix.zh-CN.md](ProductizationValidationMatrix.zh-CN.md),其中记录 Phase30 基于证据的验证矩阵和 smoke gate 契约。 + ModernSetup 有两层 XArch 产品化边界: ```text diff --git a/Docs/ProductizationValidationMatrix.md b/Docs/ProductizationValidationMatrix.md new file mode 100644 index 0000000..13a77eb --- /dev/null +++ b/Docs/ProductizationValidationMatrix.md @@ -0,0 +1,84 @@ + + +# Productization Validation Matrix + +Language: English | [简体中文](ProductizationValidationMatrix.zh-CN.md) + +This matrix is the Phase30 evidence checklist for XArch productization. It records what can be validated today from repository docs, smoke tests, scripts, and existing provider boundaries. It is not a feature promise and it is not an edk2 build-architecture abstraction. + +XArch is cross-architecture validation/productization vocabulary for ModernSetupPkg. XArch does not replace edk2 ARCH values. Product integrations, DSC/FDF overlays, build scripts, and toolchains still use concrete edk2 ARCH values: `ARCH=X64`, `ARCH=AARCH64`, `ARCH=LOONGARCH64`, and `ARCH=RISCV64`. There is no supported `ARCH=XArch` or `TARGET=XArch` build implication. + +Related source-of-truth docs: + +- [XArch.md](XArch.md) for target mapping and validation language. +- [ProductizationFeatureMatrix.md](ProductizationFeatureMatrix.md) for feature ownership and App/provider scope. +- [CompatibilityMatrix.md](CompatibilityMatrix.md) for DisplayEngine/FormBrowser evidence. +- [Tests/Smoke/README.md](../Tests/Smoke/README.md) for the host-side smoke gate. + +## Evidence Language + +The validation terms below describe current evidence only: + +- `Smoke`: host-side `Tests/Smoke/smoke_validate.py` static and overlay dry-run checks. +- `Script`: a repository script exists and is checked for syntax/metadata. +- `Manual`: local maintainer validation path is documented, but not CI-gated. +- `Captured`: screenshot/screendump evidence exists for a path. +- `Build/script validation`: the script/overlay path is validated without claiming graphical runtime evidence. +- `Planned`: documented target or behavior only; do not describe it as validated. + +## XArch Target Validation Matrix + +| XArch target | Concrete edk2 ARCH | Platform path | Primary scripts | Current maturity evidence | Productization validation notes | +| --- | --- | --- | --- | --- | --- | +| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh` | Manual OVMF build/run/capture path; smoke overlay generation; local/manual App validation. | Evidence supports target metadata, native/modern DisplayEngine overlay separation, and local screenshot capture path. | +| AARCH64 / ArmVirtQemu | `AARCH64` | `ArmVirtPkg/ArmVirtQemu` | `Scripts/build-armvirt.sh`, `Scripts/run-armvirt.sh`, `Scripts/capture-armvirt.sh`, `Scripts/build-modern-app.sh` | Captured ArmVirt before/after evidence; active build/run path; smoke overlay generation. | Primary compatibility capture path for native UiApp/FormBrowser plus ModernDisplayEngine. | +| LOONGARCH64 / LoongArchVirtQemu | `LOONGARCH64` | `OvmfPkg/LoongArchVirt/LoongArchVirtQemu` | `Scripts/build-loongarchvirt.sh`, `Scripts/run-loongarchvirt.sh` | Active build/run script path; smoke overlay generation. | Evidence covers generated overlays and documented manual run path; external cross toolchain remains product-team responsibility. | +| RISCV64 / RiscVVirtQemu | `RISCV64` | `OvmfPkg/RiscVVirt/RiscVVirtQemu` | `Scripts/build-riscvvirt.sh` | Build/script validation; smoke overlay generation. | RISCV64 remains Build/script validation in Phase30; graphical QEMU helper and captured UI evidence are not claimed. | + +`Scripts/xarch-validate.sh --all --mode dry-run --format json` is the fast target metadata smoke companion. In Phase30 the smoke gate asserts four target `PASS` results and preserves the RISCV64 `Build/script validation` maturity wording. + +## Product Class Validation Matrix + +| Product class | Evidence-backed App role | Native owner / boundary | Current validation evidence | +| --- | --- | --- | --- | +| Desktop / workstation | Dashboard, Boot, Devices/HII, Security, Firmware, Diagnostics, Power/Thermal, Performance, PCIe capability summary, Preferences, Exit. | Boot order editing, Secure Boot key management, CPU/memory tuning, fan policy, PCIe policy, and chipset controls remain native HII/FormBrowser. | OVMF X64 and ArmVirt paths document desktop/workstation-style checks; smoke validates boundary tokens. | +| Server | Dashboard provider health, Management, Diagnostics, Performance, Hardware Health demo visualization, PCIe inventory/policy-entry hints, Exit/native entries. | BMC/IPMI/Redfish configuration, RAS/NUMA policy, PCIe resource policy, ACS/ARI/IOMMU policy, SEL/log clearing remain native or service-app owned. | Provider snapshot, server inventory, management, performance, PCIe, and diagnostics boundaries are smoke-checked. | +| Embedded / industrial | Device/HII entry list, boot/recovery posture, firmware update status, diagnostics evidence, security posture. | GPIO, serial, watchdog, provisioning, boot-pin behavior, board muxes, and power-restore policy remain platform HII/native. | ArmVirt, LoongArchVirt, and RiscVVirt script paths provide cross-arch metadata evidence; product specifics require platform validation. | +| Tablet / appliance | Minimal dashboard, Boot/recovery entry, Security, Firmware, Power/Thermal, Preferences, Exit. | Battery/adapter policy, display panel/backlight, thermal trip points, recovery writes, and appliance provisioning remain native/platform owned. | App/provider docs define read-only status and entry behavior; no product-specific runtime evidence is claimed. | + +## App / Provider Validation Matrix + +| Area | Evidence-backed App/provider behavior | Boundary tokens that must remain true | Phase30 validation evidence | +| --- | --- | --- | --- | +| Dashboard | Shows provider-backed platform, boot, device, firmware, power/thermal, performance, and provider-health summaries. | Dashboard consumes `ModernSetupAppProvider.c` snapshots; it does not call provider LibraryClasses directly. | Smoke checks Dashboard draw ownership, quick-card count, provider snapshot use, and density layout. | +| Boot | Lists boot inventory and launches selected boot options when available. | Boot policy editing and Boot Maintenance remain native; no App-owned platform policy writes. | Smoke covers App source boundaries; feature matrix documents display/entry behavior. | +| Devices / HII | Lists HII/device entries and opens real setup pages through `EFI_FORM_BROWSER2_PROTOCOL.SendForm()`. | Native `FormBrowser2`, native HII, VFR/IFR parsing, `ConfigAccess`, callbacks, validation, defaults, and varstore writes own semantics. ModernSetupApp must not parse IFR, implement ConfigAccess, write HII varstores, or write platform policy. | Smoke checks HII bridge read-only preview boundaries and prohibited App source tokens. | +| Security | Shows read-only Secure Boot, Setup Mode, key presence, and TPM/TCG/TCM posture when discoverable. | Key enrollment, password, physical-presence, measured-boot policy, and chassis security policy remain native. | Smoke validates provider snapshot boundaries and App mutation-token exclusion. | +| Firmware | Shows capsule/update/recovery availability and native entry hints. | Capsule construction, flash programming, rollback policy, and recovery writes remain native/platform utility owned. | Feature and validation docs use evidence language only. | +| Diagnostics | Shows table/log/provider-health summaries and service/debug evidence. | POST log management, error clearing, vendor diagnostics, and repair flows remain native or service-app owned. | Smoke checks provider health derivation and diagnostics inclusion. | +| Management | Shows BMC/IPMI/Redfish presence and management host hints. | BMC networking, users, KVM/media, SEL policy, and remote update configuration remain BMC/native owned. | Smoke checks provider snapshot boundary and server inventory summary. | +| Power / Thermal | Shows ACPI/chassis/power-supply status and can display demo Hardware Health curves. | Fan curves, pump headers, thermal trip points, acoustic profiles, battery, and adapter policy remain native HII/FormBrowser-owned. | Smoke checks Power provider wiring through App boundaries. | +| Hardware Health | Demo-only/read-only provider for deterministic temperature trend UX. | The Hardware Health demo provider does not claim real sensors and does not program SMBus, I2C, IPMI, SuperIO, MMIO, PCI, fan, or trip-point policy. | Smoke checks demo provider files, demo text, read-only docs, and prohibited hardware/mutation tokens. | +| Performance | Shows CPU/memory inventory and tuning/RAS entry availability. | CPU frequency/voltage, memory timing/profile, NUMA/RAS, and workload profile policy remain native. | Smoke checks provider snapshot use and server inventory summary. | +| PCIe | Shows PCIe inventory and read-only capability/native policy-entry hints for ReBAR, Above 4G, SR-IOV, ASPM, bifurcation, hot-plug, ACS, ARI, and IOMMU. | ReBAR, Above 4G, SR-IOV, ASPM, bifurcation, hot-plug, ACS, ARI, IOMMU, BAR/resource allocation, and fabric policy changes stay native HII/FormBrowser-owned. | Smoke checks PCIe provider wiring, mutation-token exclusion, and docs language. | +| Preferences | App-owned UX preferences use `ModernUiPreferencesLib`. | App-owned preferences are not platform policy; platform variables such as BootOrder, SecureBoot, CPU, fan, chipset, and PCIe policy stay out of the preferences library. | Smoke checks `ModernUiPreferencesLib`, app usage, schema/version fields, and no runtime variable access. | +| Exit | Provides session actions, app/version info, language/theme preference access, native UiApp/native setup entries where available. | Save/discard/defaults workflows for real setup variables remain native FormBrowser/platform HII. | Smoke checks App source boundaries and preference routing. | + +## Phase30 Smoke Gate Requirements + +The smoke gate must remain fast and deterministic. For Productization Validation it checks: + +- English and zh-CN validation matrix files exist and link each other. +- X64, AARCH64, LOONGARCH64, and RISCV64 appear with platform paths and scripts. +- XArch does not replace edk2 ARCH values, and no `ARCH=XArch` or `TARGET=XArch` build implication appears. +- ModernSetupApp boundaries: no IFR parsing, no ConfigAccess implementation, no HII varstore writes, no platform policy writes. +- `EFI_FORM_BROWSER2_PROTOCOL.SendForm()`, FormBrowser2/native HII/ConfigAccess ownership, and native semantics are documented. +- Hardware Health remains demo-only/read-only. +- App-owned preferences route through `ModernUiPreferencesLib`. +- PCIe policy tokens remain native-owned: ReBAR, Above 4G, SR-IOV, ASPM, bifurcation, hot-plug, ACS, ARI, and IOMMU. +- `Scripts/xarch-validate.sh --all --mode dry-run --format json` reports four target `PASS` results and preserves RISCV64 as `Build/script validation`. diff --git a/Docs/ProductizationValidationMatrix.zh-CN.md b/Docs/ProductizationValidationMatrix.zh-CN.md new file mode 100644 index 0000000..a95e651 --- /dev/null +++ b/Docs/ProductizationValidationMatrix.zh-CN.md @@ -0,0 +1,84 @@ + + +# 产品化验证矩阵 + +语言:[English](ProductizationValidationMatrix.md) | 简体中文 + +本矩阵是 Phase30 的 XArch 产品化证据清单。它记录当前可以通过仓库文档、smoke 测试、脚本和既有 provider 边界验证的内容。它不是功能承诺,也不是 edk2 构建架构抽象。 + +XArch 是 ModernSetupPkg 的跨架构验证/产品化术语。XArch 不会替代 edk2 ARCH 值。产品集成、DSC/FDF overlay、构建脚本和工具链仍然使用具体 edk2 ARCH 值:`ARCH=X64`、`ARCH=AARCH64`、`ARCH=LOONGARCH64` 和 `ARCH=RISCV64`。当前不存在受支持的 `ARCH=XArch` 或 `TARGET=XArch` 构建含义。 + +相关事实来源文档: + +- [XArch.zh-CN.md](XArch.zh-CN.md):目标映射和验证语言。 +- [ProductizationFeatureMatrix.zh-CN.md](ProductizationFeatureMatrix.zh-CN.md):功能归属与 App/provider 范围。 +- [CompatibilityMatrix.md](CompatibilityMatrix.md):DisplayEngine/FormBrowser 证据。 +- [Tests/Smoke/README.md](../Tests/Smoke/README.md):主机端 smoke gate。 + +## 证据语言 + +以下验证术语只描述当前证据: + +- `Smoke`:主机端 `Tests/Smoke/smoke_validate.py` 静态检查和 overlay dry-run 检查。 +- `Script`:仓库脚本存在,并被语法/元数据检查覆盖。 +- `Manual`:本地维护者验证路径已有文档,但不是 CI gate。 +- `Captured`:相关路径有截图或 screendump 证据。 +- `Build/script validation`:脚本或 overlay 路径已验证,但不声明图形运行证据。 +- `Planned`:仅为规划或已记录目标,不应描述成已验证。 + +## XArch 目标验证矩阵 + +| XArch 目标 | 具体 edk2 ARCH | 平台路径 | 主要脚本 | 当前成熟度证据 | 产品化验证说明 | +| --- | --- | --- | --- | --- | --- | +| X64 / OVMF X64 | `X64` | `OvmfPkg/OvmfPkgX64` | `Scripts/build-ovmf-x64.sh`, `Scripts/run-ovmf-x64.sh`, `Scripts/capture-ovmf-x64.sh` | Manual OVMF 构建/运行/捕获路径;smoke overlay generation;本地/手动 App 验证。 | 证据覆盖目标元数据、native/modern DisplayEngine overlay 分离和本地截图捕获路径。 | +| AARCH64 / ArmVirtQemu | `AARCH64` | `ArmVirtPkg/ArmVirtQemu` | `Scripts/build-armvirt.sh`, `Scripts/run-armvirt.sh`, `Scripts/capture-armvirt.sh`, `Scripts/build-modern-app.sh` | Captured ArmVirt before/after 证据;active 构建/运行路径;smoke overlay generation。 | native UiApp/FormBrowser 加 ModernDisplayEngine 的主要兼容性捕获路径。 | +| LOONGARCH64 / LoongArchVirtQemu | `LOONGARCH64` | `OvmfPkg/LoongArchVirt/LoongArchVirtQemu` | `Scripts/build-loongarchvirt.sh`, `Scripts/run-loongarchvirt.sh` | Active 构建/运行脚本路径;smoke overlay generation。 | 证据覆盖生成 overlay 和已记录的手动运行路径;外部交叉工具链仍由产品团队负责。 | +| RISCV64 / RiscVVirtQemu | `RISCV64` | `OvmfPkg/RiscVVirt/RiscVVirtQemu` | `Scripts/build-riscvvirt.sh` | Build/script validation;smoke overlay generation。 | Phase30 中 RISCV64 仍保持 Build/script validation;不声明图形 QEMU helper 或捕获 UI 证据。 | + +`Scripts/xarch-validate.sh --all --mode dry-run --format json` 是快速目标元数据 smoke 辅助检查。Phase30 smoke gate 会断言四个目标均为 `PASS`,并保持 RISCV64 的 `Build/script validation` 成熟度用语。 + +## 产品类别验证矩阵 + +| 产品类别 | 有证据支持的 App 角色 | 原生 owner / 边界 | 当前验证证据 | +| --- | --- | --- | --- | +| Desktop / workstation | Dashboard、Boot、Devices/HII、Security、Firmware、Diagnostics、Power/Thermal、Performance、PCIe capability summary、Preferences、Exit。 | Boot order 编辑、Secure Boot 密钥管理、CPU/内存调优、风扇策略、PCIe 策略和芯片组控制保持 native HII/FormBrowser 所有。 | OVMF X64 和 ArmVirt 路径记录桌面/工作站风格检查;smoke 验证边界 token。 | +| Server | Dashboard provider health、Management、Diagnostics、Performance、Hardware Health demo 可视化、PCIe inventory/policy-entry hints、Exit/native entries。 | BMC/IPMI/Redfish 配置、RAS/NUMA 策略、PCIe resource policy、ACS/ARI/IOMMU 策略、SEL/log clearing 保持 native 或 service app 所有。 | Provider snapshot、server inventory、management、performance、PCIe 和 diagnostics 边界由 smoke 检查。 | +| Embedded / industrial | Device/HII 入口列表、boot/recovery 姿态、firmware update 状态、diagnostics 证据、安全姿态。 | GPIO、serial、watchdog、provisioning、boot-pin behavior、board muxes 和 power-restore policy 保持平台 HII/native。 | ArmVirt、LoongArchVirt 和 RiscVVirt 脚本路径提供跨架构元数据证据;产品细节需要平台验证。 | +| Tablet / appliance | 最小 Dashboard、Boot/recovery 入口、Security、Firmware、Power/Thermal、Preferences、Exit。 | Battery/adapter policy、display panel/backlight、thermal trip points、recovery writes 和 appliance provisioning 保持 native/platform 所有。 | App/provider 文档定义只读状态和入口行为;不声明产品特定运行证据。 | + +## App / Provider 验证矩阵 + +| 区域 | 有证据支持的 App/provider 行为 | 必须保持的边界 token | Phase30 验证证据 | +| --- | --- | --- | --- | +| Dashboard | 显示 provider-backed platform、boot、device、firmware、power/thermal、performance 和 provider-health summary。 | Dashboard 消费 `ModernSetupAppProvider.c` snapshot;不直接从展示模块调用 provider LibraryClasses。 | Smoke 检查 Dashboard 绘制归属、quick-card count、provider snapshot 使用和 density layout。 | +| Boot | 列出 boot inventory,并在可用时启动选中的 boot option。 | Boot policy editing 和 Boot Maintenance 保持 native;无 App-owned platform policy writes。 | Smoke 覆盖 App source boundary;feature matrix 记录 display/entry 行为。 | +| Devices / HII | 列出 HII/device entries,并通过 `EFI_FORM_BROWSER2_PROTOCOL.SendForm()` 打开真实 setup 页面。 | Native `FormBrowser2`、native HII、VFR/IFR 解析、`ConfigAccess`、callbacks、validation、defaults 和 varstore writes 拥有语义。ModernSetupApp 不得解析 IFR、不得实现 ConfigAccess、不得写 HII varstores、不得写 platform policy。 | Smoke 检查 HII bridge read-only preview 边界和 App source 禁止 token。 | +| Security | 显示只读 Secure Boot、Setup Mode、key presence 和可发现的 TPM/TCG/TCM 姿态。 | Key enrollment、password、physical-presence、measured-boot policy 和 chassis security policy 保持 native。 | Smoke 验证 provider snapshot boundary 和 App mutation-token 排除。 | +| Firmware | 显示 capsule/update/recovery availability 和 native entry hints。 | Capsule construction、flash programming、rollback policy 和 recovery writes 保持 native/platform utility 所有。 | Feature 和 validation 文档仅使用证据语言。 | +| Diagnostics | 显示 table/log/provider-health summaries 和 service/debug evidence。 | POST log management、error clearing、vendor diagnostics 和 repair flows 保持 native 或 service app 所有。 | Smoke 检查 provider health derivation 和 diagnostics inclusion。 | +| Management | 显示 BMC/IPMI/Redfish presence 和 management host hints。 | BMC networking、users、KVM/media、SEL policy 和 remote update configuration 保持 BMC/native 所有。 | Smoke 检查 provider snapshot boundary 和 server inventory summary。 | +| Power / Thermal | 显示 ACPI/chassis/power-supply status,并可展示 demo Hardware Health curves。 | Fan curves、pump headers、thermal trip points、acoustic profiles、battery 和 adapter policy 保持 native HII/FormBrowser-owned。 | Smoke 检查 Power provider 经 App boundary 的 wiring。 | +| Hardware Health | demo-only/read-only provider,用于确定性的 temperature trend UX。 | Hardware Health demo provider 不声明真实传感器,不编程 SMBus、I2C、IPMI、SuperIO、MMIO、PCI、fan 或 trip-point policy。 | Smoke 检查 demo provider 文件、demo 文案、只读文档和禁止硬件/mutation token。 | +| Performance | 显示 CPU/memory inventory 和 tuning/RAS entry availability。 | CPU frequency/voltage、memory timing/profile、NUMA/RAS 和 workload profile policy 保持 native。 | Smoke 检查 provider snapshot 使用和 server inventory summary。 | +| PCIe | 显示 PCIe inventory,以及 ReBAR、Above 4G、SR-IOV、ASPM、bifurcation、hot-plug、ACS、ARI、IOMMU 的只读 capability/native policy-entry hints。 | ReBAR、Above 4G、SR-IOV、ASPM、bifurcation、hot-plug、ACS、ARI、IOMMU、BAR/resource allocation 和 fabric policy changes 保持 native HII/FormBrowser-owned。 | Smoke 检查 PCIe provider wiring、mutation-token 排除和文档语言。 | +| Preferences | App-owned UX preferences 通过 `ModernUiPreferencesLib`。 | App-owned preferences 不是 platform policy;BootOrder、SecureBoot、CPU、fan、chipset 和 PCIe policy 等平台变量不得进入 preferences library。 | Smoke 检查 `ModernUiPreferencesLib`、App 使用、schema/version fields 和无 runtime variable access。 | +| Exit | 提供 session actions、app/version info、language/theme preference access,以及可用时的 native UiApp/native setup entries。 | 真实 setup variables 的 save/discard/defaults 工作流保持 native FormBrowser/platform HII。 | Smoke 检查 App source boundary 和 preference routing。 | + +## Phase30 Smoke Gate 要求 + +Smoke gate 必须保持快速且确定性。Productization Validation 会检查: + +- 英文和 zh-CN 验证矩阵文件存在且互相链接。 +- X64、AARCH64、LOONGARCH64 和 RISCV64 均带有平台路径和脚本。 +- XArch 不会替代 edk2 ARCH 值,并且不存在 `ARCH=XArch` 或 `TARGET=XArch` 构建含义。 +- ModernSetupApp 边界:不解析 IFR、不实现 ConfigAccess、不写 HII varstore、不写 platform policy。 +- 已记录 `EFI_FORM_BROWSER2_PROTOCOL.SendForm()`、FormBrowser2/native HII/ConfigAccess ownership 和 native semantics。 +- Hardware Health 保持 demo-only/read-only。 +- App-owned preferences 通过 `ModernUiPreferencesLib`。 +- PCIe policy tokens 保持 native-owned:ReBAR、Above 4G、SR-IOV、ASPM、bifurcation、hot-plug、ACS、ARI 和 IOMMU。 +- `Scripts/xarch-validate.sh --all --mode dry-run --format json` 报告四个 target `PASS`,并保持 RISCV64 为 `Build/script validation`。 diff --git a/Docs/README.md b/Docs/README.md index fa069ad..ac7e89c 100644 --- a/Docs/README.md +++ b/Docs/README.md @@ -18,6 +18,7 @@ Simplified Chinese counterparts for the core project docs. | --- | --- | --- | | XArch architecture model | [XArch.md](XArch.md) | [XArch.zh-CN.md](XArch.zh-CN.md) | | Productization feature matrix | [ProductizationFeatureMatrix.md](ProductizationFeatureMatrix.md) | [ProductizationFeatureMatrix.zh-CN.md](ProductizationFeatureMatrix.zh-CN.md) | +| Productization validation matrix | [ProductizationValidationMatrix.md](ProductizationValidationMatrix.md) | [ProductizationValidationMatrix.zh-CN.md](ProductizationValidationMatrix.zh-CN.md) | | Module boundaries | [MODULE_BOUNDARIES.md](MODULE_BOUNDARIES.md) | [MODULE_BOUNDARIES.zh-CN.md](MODULE_BOUNDARIES.zh-CN.md) | | Development guide | [DEVELOPMENT.md](DEVELOPMENT.md) | [DEVELOPMENT.zh-CN.md](DEVELOPMENT.zh-CN.md) | | IBV and platform setup survey | [IbvAndPlatformSetupSurvey.md](IbvAndPlatformSetupSurvey.md) | [IbvAndPlatformSetupSurvey.zh-CN.md](IbvAndPlatformSetupSurvey.zh-CN.md) | diff --git a/Docs/README.zh-CN.md b/Docs/README.zh-CN.md index ee40850..8c70c84 100644 --- a/Docs/README.zh-CN.md +++ b/Docs/README.zh-CN.md @@ -17,6 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent | --- | --- | --- | | XArch 架构模型 | [XArch.zh-CN.md](XArch.zh-CN.md) | [XArch.md](XArch.md) | | 产品化功能矩阵 | [ProductizationFeatureMatrix.zh-CN.md](ProductizationFeatureMatrix.zh-CN.md) | [ProductizationFeatureMatrix.md](ProductizationFeatureMatrix.md) | +| 产品化验证矩阵 | [ProductizationValidationMatrix.zh-CN.md](ProductizationValidationMatrix.zh-CN.md) | [ProductizationValidationMatrix.md](ProductizationValidationMatrix.md) | | 模块边界 | [MODULE_BOUNDARIES.zh-CN.md](MODULE_BOUNDARIES.zh-CN.md) | [MODULE_BOUNDARIES.md](MODULE_BOUNDARIES.md) | | 开发指南 | [DEVELOPMENT.zh-CN.md](DEVELOPMENT.zh-CN.md) | [DEVELOPMENT.md](DEVELOPMENT.md) | | IBV 与平台 Setup 调研 | [IbvAndPlatformSetupSurvey.zh-CN.md](IbvAndPlatformSetupSurvey.zh-CN.md) | [IbvAndPlatformSetupSurvey.md](IbvAndPlatformSetupSurvey.md) | diff --git a/Docs/XArch.md b/Docs/XArch.md index 84f49d2..def122c 100644 --- a/Docs/XArch.md +++ b/Docs/XArch.md @@ -9,6 +9,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent Language: English | [简体中文](XArch.zh-CN.md) +See also: [ProductizationValidationMatrix.md](ProductizationValidationMatrix.md) for +the Phase30 XArch target/product validation evidence matrix. + XArch is ModernSetupPkg's cross-architecture architecture model for keeping one Setup UX, one HII/FormBrowser ownership boundary, and one validation vocabulary across X64, AARCH64, LOONGARCH64, and RISCV64 targets. diff --git a/Docs/XArch.zh-CN.md b/Docs/XArch.zh-CN.md index f95a827..fc5d25d 100644 --- a/Docs/XArch.zh-CN.md +++ b/Docs/XArch.zh-CN.md @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent 语言:[English](XArch.md) | 简体中文 +另请参阅:[ProductizationValidationMatrix.zh-CN.md](ProductizationValidationMatrix.zh-CN.md),其中记录 Phase30 XArch 目标/产品化验证证据矩阵。 + XArch 是 ModernSetupPkg 的跨架构项目模型:在 X64、AARCH64、LOONGARCH64 和 RISCV64 目标之间保持同一套 Setup UX、同一条 HII/FormBrowser 所有权边界,以及同一套验证词汇。 XArch 是项目、产品和验证词汇,不替代 edk2 的 `ARCH` 值。构建脚本、DSC/FDF overlay、工具链选择和 edk2 构建变量仍使用具体值:`ARCH=X64`、`ARCH=AARCH64`、`ARCH=LOONGARCH64`、`ARCH=RISCV64`。 diff --git a/Library/ModernUiStringLib/ModernUiStringLib.c b/Library/ModernUiStringLib/ModernUiStringLib.c index 54acda9..0c23874 100644 --- a/Library/ModernUiStringLib/ModernUiStringLib.c +++ b/Library/ModernUiStringLib/ModernUiStringLib.c @@ -109,7 +109,7 @@ STATIC CONST CHAR16 *mEnglishStrings[ModernUiStringMax] = { L"Key management is intentionally read-only in v1.", L"Use Up/Down to select an action, Enter to run it.", L"Continue boot", - L"Launch classic UiApp fallback", + L"Open Native Boot Manager", L"Reset system", L"Language: %s", L"Language", @@ -125,7 +125,7 @@ STATIC CONST CHAR16 *mEnglishStrings[ModernUiStringMax] = { L"Enter opens the selected form or advances a supported value.", L"RouteConfig returned: %r", L"Boot option returned: %r", - L"Classic UiApp returned: %r", + L"Native Boot Manager returned: %r", L"ModernSetupApp: graphics initialization failed: %r\n", L"Boot & Devices", L"Platform Health", diff --git a/README.md b/README.md index 4244908..2d097ee 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,10 @@ OVMF X64 now has a pinned edk2 baseline, scripted QEMU screendump capture, and a local/manual `ModernSetupApp` dashboard validation path. The current OVMF capture shows the shared XArch `ModernUiEngineLib` front-page shell with Simplified Chinese text, read-only platform summaries, provider health, and the -black/orange advanced-mode theme after the CJK glyph and Dashboard spacing +Graphite Gold app runtime theme after the CJK glyph and Dashboard spacing polish. -![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-phase18.png) +![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png) The same graphics stack also renders native FormBrowser pages; edk2 still owns HII/VFR/IFR parsing, GUID formset discovery, callbacks, and variable writes. @@ -52,6 +52,8 @@ demos. `Docs/XArch.md` defines the target model and validation vocabulary, and `Docs/ProductizationFeatureMatrix.md` records the common desktop, workstation, server, embedded, and appliance front-page capabilities that should be filled in through provider libraries while keeping real setup pages on native FormBrowser. +`Docs/ProductizationValidationMatrix.md` records the Phase30 evidence matrix and +smoke-gate checks for the same XArch/productization boundaries. For a lightweight target metadata check, run: ```sh @@ -104,15 +106,17 @@ route for Device Manager, DriverSample, Boot Maintenance, or third-party HII driver pages. The current DisplayEngine visual direction uses a commercial-IBV-style -advanced-mode structure without reusing commercial artwork. The default theme is -black/orange with yellow focus accents; an experimental black/deep-red/yellow -theme can be selected at build time with `MODERN_SETUP_THEME=red`. These -surfaces are drawn from theme tokens and GOP primitives so OEM-specific styling -can later be provided through theme/layout configuration instead of by changing -HII parsing behavior. +advanced-mode structure without reusing commercial artwork. The default +build-time theme is dark/orange with yellow focus accents; an experimental +black/deep-red/yellow theme can be selected at build time with +`MODERN_SETUP_THEME=red`. The app front-page shell also supports runtime theme +preferences such as Graphite Gold, which uses graphite surfaces with warm gold +accents. These surfaces are drawn from theme tokens and GOP primitives so +OEM-specific styling can later be provided through theme/layout configuration +instead of by changing HII parsing behavior. ```sh -# Default black/orange theme +# Default dark/orange build-time theme ModernSetupPkg/Scripts/build-armvirt.sh # Experimental black/deep-red/yellow theme @@ -574,7 +578,7 @@ assets. Current OVMF X64 capture: -![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-phase18.png) +![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png) Current LoongArch captures: diff --git a/README.zh-CN.md b/README.zh-CN.md index 055c8e2..7064447 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -17,9 +17,9 @@ UI 只使用开源 edk2 接口和原创视觉资产。商业 IBV 固件界面只 ## 最新状态 -OVMF X64 已有固定 edk2 baseline、脚本化 QEMU screendump 捕获,以及本地/手工 `ModernSetupApp` dashboard 验证路径。当前 OVMF 捕获展示了共享 XArch `ModernUiEngineLib` 首页壳层、简体中文文本、只读平台摘要、provider health,以及 CJK 字形和 Dashboard 间距打磨后的黑/橙 advanced-mode theme。 +OVMF X64 已有固定 edk2 baseline、脚本化 QEMU screendump 捕获,以及本地/手工 `ModernSetupApp` dashboard 验证路径。当前 OVMF 捕获展示了共享 XArch `ModernUiEngineLib` 首页壳层、简体中文文本、只读平台摘要、provider health,以及 CJK 字形和 Dashboard 间距打磨后的 Graphite Gold 应用运行时主题。 -![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-phase18.png) +![ModernSetup OVMF X64 dashboard](Assets/Screenshots/modern-ovmf-x64-dashboard-graphite-gold.png) 同一 graphics stack 也用于渲染原生 FormBrowser 页面;edk2 仍拥有 HII/VFR/IFR 解析、GUID formset discovery、callbacks 和 variable writes。 @@ -80,6 +80,7 @@ ModernSetupApp - [`Docs/DEVELOPMENT.zh-CN.md`](Docs/DEVELOPMENT.zh-CN.md) / [`Docs/DEVELOPMENT.md`](Docs/DEVELOPMENT.md):编码规则、函数注释、架构边界和扩展点。 - [`Docs/XArch.zh-CN.md`](Docs/XArch.zh-CN.md) / [`Docs/XArch.md`](Docs/XArch.md):XArch 模型、具体目标映射、验证词汇、成熟度和所有权边界。 - [`Docs/ProductizationFeatureMatrix.zh-CN.md`](Docs/ProductizationFeatureMatrix.zh-CN.md) / [`Docs/ProductizationFeatureMatrix.md`](Docs/ProductizationFeatureMatrix.md):XArch App 功能路线图和 provider 边界。 +- [`Docs/ProductizationValidationMatrix.zh-CN.md`](Docs/ProductizationValidationMatrix.zh-CN.md) / [`Docs/ProductizationValidationMatrix.md`](Docs/ProductizationValidationMatrix.md):Phase30 XArch 产品化证据矩阵和 smoke gate 检查。 - [`Docs/MODULE_BOUNDARIES.zh-CN.md`](Docs/MODULE_BOUNDARIES.zh-CN.md) / [`Docs/MODULE_BOUNDARIES.md`](Docs/MODULE_BOUNDARIES.md):稳定契约和层级规则。 - [`Docs/IbvAndPlatformSetupSurvey.zh-CN.md`](Docs/IbvAndPlatformSetupSurvey.zh-CN.md) / [`Docs/IbvAndPlatformSetupSurvey.md`](Docs/IbvAndPlatformSetupSurvey.md):IBV/OEM/platform form setup surface 调研。 - `CHANGELOG.md`:开发进度、用户可见变化和计划版本工作。 diff --git a/Scripts/build-loongarchvirt.sh b/Scripts/build-loongarchvirt.sh index 4de0c88..e319c1c 100755 --- a/Scripts/build-loongarchvirt.sh +++ b/Scripts/build-loongarchvirt.sh @@ -16,10 +16,22 @@ JOBS="${JOBS:-$(sysctl -n hw.ncpu 2>/dev/null || echo 4)}" MODERN_SETUP_DEMO_DRIVER_SAMPLE="${MODERN_SETUP_DEMO_DRIVER_SAMPLE:-1}" MODERN_SETUP_THEME="${MODERN_SETUP_THEME:-orange}" MODERN_SETUP_DISPLAY_ENGINE="${MODERN_SETUP_DISPLAY_ENGINE:-modern}" -GCC_LOONGARCH64_PREFIX="${GCC_LOONGARCH64_PREFIX:-loongarch64-unknown-linux-gnu-}" +MODERN_SETUP_INCLUDE_APP="${MODERN_SETUP_INCLUDE_APP:-0}" +MODERN_SETUP_REPLACE_UIAPP="${MODERN_SETUP_REPLACE_UIAPP:-0}" +GCC_LOONGARCH64_PREFIX="${GCC_LOONGARCH64_PREFIX:-}" GENERATE_ONLY="${GENERATE_ONLY:-0}" OVERLAY_DIR="${WORKSPACE}/Build/ModernSetupPkgOverlay" +if [[ -z "${GCC_LOONGARCH64_PREFIX}" ]]; then + if command -v loongarch64-unknown-linux-gnu-gcc >/dev/null 2>&1; then + GCC_LOONGARCH64_PREFIX="loongarch64-unknown-linux-gnu-" + elif command -v loongarch64-linux-gnu-gcc >/dev/null 2>&1; then + GCC_LOONGARCH64_PREFIX="loongarch64-linux-gnu-" + else + GCC_LOONGARCH64_PREFIX="loongarch64-unknown-linux-gnu-" + fi +fi + export PATH="/opt/homebrew/bin:${PATH}" export WORKSPACE export GCC_LOONGARCH64_PREFIX @@ -32,8 +44,9 @@ fi mkdir -p "${OVERLAY_DIR}" -python3 - <<'PY' "${WORKSPACE}" "${OVERLAY_DIR}" "${MODERN_SETUP_DEMO_DRIVER_SAMPLE}" "${MODERN_SETUP_THEME}" "${MODERN_SETUP_DISPLAY_ENGINE}" +python3 - <<'PY' "${WORKSPACE}" "${OVERLAY_DIR}" "${MODERN_SETUP_DEMO_DRIVER_SAMPLE}" "${MODERN_SETUP_THEME}" "${MODERN_SETUP_DISPLAY_ENGINE}" "${MODERN_SETUP_INCLUDE_APP}" "${MODERN_SETUP_REPLACE_UIAPP}" from pathlib import Path +import re import sys workspace = Path(sys.argv[1]) @@ -41,6 +54,8 @@ overlay = Path(sys.argv[2]) enable_driver_sample = sys.argv[3] != "0" theme_name = sys.argv[4].strip().lower() display_engine = sys.argv[5].strip().lower() +include_app_flag = sys.argv[6].strip().lower() +replace_uiapp_flag = sys.argv[7].strip().lower() theme_pcd = { "orange": "0x00", "amber": "0x00", @@ -58,15 +73,50 @@ if display_engine not in {"modern", "native"}: raise SystemExit( f"Unsupported MODERN_SETUP_DISPLAY_ENGINE={display_engine!r}; use modern or native" ) +if include_app_flag not in {"0", "1", "false", "true", "no", "yes"}: + raise SystemExit( + f"Unsupported MODERN_SETUP_INCLUDE_APP={include_app_flag!r}; use 0 or 1" + ) +if replace_uiapp_flag not in {"0", "1", "false", "true", "no", "yes"}: + raise SystemExit( + f"Unsupported MODERN_SETUP_REPLACE_UIAPP={replace_uiapp_flag!r}; use 0 or 1" + ) +replace_uiapp = replace_uiapp_flag in {"1", "true", "yes"} +include_modern_setup_app = (include_app_flag in {"1", "true", "yes"}) or replace_uiapp +modern_setup_app_component = " ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf" +modern_setup_app_component_boot_manager_fallback = """ ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf { + + GCC:*_*_*_CC_FLAGS = -DMODERN_SETUP_NATIVE_FALLBACK_BOOT_MANAGER_MENU=1 + }""" +modern_setup_app_fdf_inf = "INF ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf" +modern_setup_app_uiapp_fdf_inf = "INF RuleOverride = MODERN_SETUP_UIAPP ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf" modern_display_component = " ModernSetupPkg/Universal/ModernDisplayEngineDxe/ModernDisplayEngineDxe.inf" modern_display_fdf_inf = "INF ModernSetupPkg/Universal/ModernDisplayEngineDxe/ModernDisplayEngineDxe.inf" +boot_manager_menu_component = " MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf" +boot_manager_menu_fdf_inf = "INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf" driver_sample_component = " MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf" driver_sample_fdf_inf = "INF MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf" library_block = """ ModernUiEngineLib|ModernSetupPkg/Library/ModernUiEngineLib/ModernUiEngineLib.inf ModernUiRendererLib|ModernSetupPkg/Library/ModernUiRendererLib/ModernUiRendererLib.inf ModernUiThemeLib|ModernSetupPkg/Library/ModernUiThemeLib/ModernUiThemeLib.inf """ +app_library_block = """ ModernUiPlatformDataLib|ModernSetupPkg/Library/ModernUiPlatformDataLib/ModernUiPlatformDataLib.inf + ModernUiBootDataLib|ModernSetupPkg/Library/ModernUiBootDataLib/ModernUiBootDataLib.inf + ModernUiDeviceDataLib|ModernSetupPkg/Library/ModernUiDeviceDataLib/ModernUiDeviceDataLib.inf + ModernUiSecurityDataLib|ModernSetupPkg/Library/ModernUiSecurityDataLib/ModernUiSecurityDataLib.inf + ModernUiFirmwareDataLib|ModernSetupPkg/Library/ModernUiFirmwareDataLib/ModernUiFirmwareDataLib.inf + ModernUiHardwareHealthDataLib|ModernSetupPkg/Library/ModernUiHardwareHealthDataLib/ModernUiHardwareHealthDataLib.inf + ModernUiHiiBridgeLib|ModernSetupPkg/Library/ModernUiHiiBridgeLib/ModernUiHiiBridgeLib.inf + ModernUiDiagnosticsDataLib|ModernSetupPkg/Library/ModernUiDiagnosticsDataLib/ModernUiDiagnosticsDataLib.inf + ModernUiManagementDataLib|ModernSetupPkg/Library/ModernUiManagementDataLib/ModernUiManagementDataLib.inf + ModernUiPowerDataLib|ModernSetupPkg/Library/ModernUiPowerDataLib/ModernUiPowerDataLib.inf + ModernUiPerformanceDataLib|ModernSetupPkg/Library/ModernUiPerformanceDataLib/ModernUiPerformanceDataLib.inf + ModernUiPcieDataLib|ModernSetupPkg/Library/ModernUiPcieDataLib/ModernUiPcieDataLib.inf + ModernUiInputLib|ModernSetupPkg/Library/ModernUiInputLib/ModernUiInputLib.inf + ModernUiPreferencesLib|ModernSetupPkg/Library/ModernUiPreferencesLib/ModernUiPreferencesLib.inf + ModernUiStringLib|ModernSetupPkg/Library/ModernUiStringLib/ModernUiStringLib.inf +""" dsc_path = workspace / "OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc" dsc = dsc_path.read_text() @@ -81,8 +131,39 @@ dsc = dsc.replace( 1, ) if "ModernUiEngineLib|ModernSetupPkg" not in dsc: - if display_engine == "modern": + if display_engine == "modern" or include_modern_setup_app: dsc = dsc.replace("[LibraryClasses.common]\n", "[LibraryClasses.common]\n" + library_block, 1) +if include_modern_setup_app and "ModernUiPlatformDataLib|ModernSetupPkg" not in dsc: + dsc = dsc.replace("[LibraryClasses.common]\n", "[LibraryClasses.common]\n" + app_library_block, 1) +if include_modern_setup_app and modern_setup_app_component not in dsc: + dsc = dsc.replace( + " MdeModulePkg/Application/UiApp/UiApp.inf {", + (modern_setup_app_component_boot_manager_fallback if replace_uiapp else modern_setup_app_component) + "\n MdeModulePkg/Application/UiApp/UiApp.inf {", + 1, + ) +if replace_uiapp and boot_manager_menu_component not in dsc: + dsc = dsc.replace( + " MdeModulePkg/Application/UiApp/UiApp.inf {", + boot_manager_menu_component + "\n MdeModulePkg/Application/UiApp/UiApp.inf {", + 1, + ) +if replace_uiapp: + dsc, uiapp_component_count = re.subn( + r"(?m)^ MdeModulePkg/Application/UiApp/UiApp\.inf \{\r?\n" + r"(?: [^\r\n]*\r?\n)*?" + r" \}\r?\n", + "", + dsc, + count=1, + ) + if uiapp_component_count != 1: + raise SystemExit("MODERN_SETUP_REPLACE_UIAPP could not remove native UiApp DSC component") + if enable_driver_sample and driver_sample_component not in dsc: + dsc = dsc.replace( + " OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf {", + driver_sample_component + "\n OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf {", + 1, + ) if display_engine == "modern": dsc = dsc.replace( " CustomizedDisplayLib | MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf", @@ -125,18 +206,58 @@ if display_engine == "modern": modern_display_fdf_inf, 1, ) -if enable_driver_sample and driver_sample_fdf_inf not in fdf: +if replace_uiapp: + if modern_setup_app_uiapp_fdf_inf not in fdf: + fdf = fdf.replace( + "INF MdeModulePkg/Application/UiApp/UiApp.inf", + modern_setup_app_uiapp_fdf_inf, + 1, + ) + if boot_manager_menu_fdf_inf not in fdf: + fdf = fdf.replace( + modern_setup_app_uiapp_fdf_inf, + boot_manager_menu_fdf_inf + "\n" + modern_setup_app_uiapp_fdf_inf, + 1, + ) +elif include_modern_setup_app and modern_setup_app_fdf_inf not in fdf: fdf = fdf.replace( "INF MdeModulePkg/Application/UiApp/UiApp.inf", - driver_sample_fdf_inf + "\nINF MdeModulePkg/Application/UiApp/UiApp.inf", + modern_setup_app_fdf_inf + "\nINF MdeModulePkg/Application/UiApp/UiApp.inf", 1, ) +if enable_driver_sample and driver_sample_fdf_inf not in fdf: + if replace_uiapp: + fdf = fdf.replace( + modern_setup_app_uiapp_fdf_inf, + driver_sample_fdf_inf + "\n" + modern_setup_app_uiapp_fdf_inf, + 1, + ) + else: + fdf = fdf.replace( + "INF MdeModulePkg/Application/UiApp/UiApp.inf", + driver_sample_fdf_inf + "\nINF MdeModulePkg/Application/UiApp/UiApp.inf", + 1, + ) +if replace_uiapp and "[Rule.Common.UEFI_APPLICATION.MODERN_SETUP_UIAPP]" not in fdf: + fdf += ( + "\n[Rule.Common.UEFI_APPLICATION.MODERN_SETUP_UIAPP]\n" + " FILE APPLICATION = 462CAA21-7614-4503-836E-8AB6F4662331 {\n" + " PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi\n" + " UI STRING=\"ModernSetupApp\" Optional\n" + " }\n" + ) (overlay / "LoongArchVirtQemuModernSetup.fdf").write_text(fdf) PY echo "Generated: ${OVERLAY_DIR}/LoongArchVirtQemuModernSetup.dsc" echo "Generated: ${OVERLAY_DIR}/LoongArchVirtQemuModernSetup.fdf" echo "DisplayEngine: ${MODERN_SETUP_DISPLAY_ENGINE}" +if [[ "${MODERN_SETUP_REPLACE_UIAPP}" =~ ^(1|true|yes)$ ]]; then + echo "ModernSetupApp in FV: 1 (via MODERN_SETUP_REPLACE_UIAPP)" +else + echo "ModernSetupApp in FV: ${MODERN_SETUP_INCLUDE_APP}" +fi +echo "Replace UiApp with ModernSetupApp: ${MODERN_SETUP_REPLACE_UIAPP}" if [[ "${GENERATE_ONLY}" == "1" ]]; then exit 0 diff --git a/Tests/Manual/LoongArchVirtQemu.md b/Tests/Manual/LoongArchVirtQemu.md index ea3d5d6..0f464f0 100644 --- a/Tests/Manual/LoongArchVirtQemu.md +++ b/Tests/Manual/LoongArchVirtQemu.md @@ -36,6 +36,11 @@ Expected result: - With `MODERN_SETUP_DISPLAY_ENGINE=native`, the overlay keeps upstream `DisplayEngineDxe` for before/after comparison. - The overlay keeps native `UiApp` as the setup entry. +- For the opt-in architecture-validation image, + `MODERN_SETUP_REPLACE_UIAPP=1` keeps LoongArchVirt's original + `PcdBootManagerMenuFile` pointing at the UiApp file GUID, replaces that FV + file with `ModernSetupApp`, and adds native `BootManagerMenuApp` to the FV so + ModernSetupApp's native fallback does not recurse into itself. - `DriverSampleDxe` is included by default unless `MODERN_SETUP_DEMO_DRIVER_SAMPLE=0` is set. - `Build/LoongArchVirtQemu/DEBUG_GCC/FV/QEMU_EFI.fd` exists. @@ -69,6 +74,9 @@ Expected result: - QEMU opens a LoongArch64 graphical window. - Pressing `Esc` or `F2` during BDS enters native `UiApp`. - UiApp rendering is handled by `ModernDisplayEngineDxe`. +- With `MODERN_SETUP_REPLACE_UIAPP=1`, the same firmware setup entry enters + `ModernSetupApp`; use the app's native fallback action to launch + `BootManagerMenuApp` for the native Boot#### launch path. - Device Manager can enumerate platform HII formsets. - DriverSample appears automatically when the demo driver is enabled. - No ASSERT, exception, or GOP initialization failure is printed to serial. diff --git a/Tests/README.md b/Tests/README.md index 74729ce..76c68cd 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -89,6 +89,8 @@ Tests pages. - `Docs/ProductizationFeatureMatrix.md` tracks standard App feature coverage across x86, ARM, RISC-V, and LoongArch product classes. +- `Docs/ProductizationValidationMatrix.md` tracks the Phase30 XArch target, + product-class, and App/provider validation matrix enforced by smoke checks. - `Docs/IbvAndPlatformSetupSurvey.md` records the public IBV/OEM/form-factor survey used to decide common App surfaces. diff --git a/Tests/Smoke/README.md b/Tests/Smoke/README.md index ab01643..8e7e27b 100644 --- a/Tests/Smoke/README.md +++ b/Tests/Smoke/README.md @@ -54,6 +54,10 @@ The smoke harness currently checks: - PCIe docs must describe read-only capability summaries and native HII entry hints; real ReBAR, Above 4G, SR-IOV, ASPM, and bifurcation policy changes remain platform HII/FormBrowser-owned. +- `Docs/ProductizationValidationMatrix.md` and its zh-CN counterpart exist, + keep XArch separate from concrete edk2 ARCH values, preserve + ModernSetupApp/HII/native ownership boundaries, and match the dry-run XArch + target metadata report. Use this as the first validation for docs, ownership, script, and static overlay changes. It complements, but does not replace, manual QEMU checks for firmware UI diff --git a/Tests/Smoke/smoke_validate.py b/Tests/Smoke/smoke_validate.py index df75668..0e638b2 100755 --- a/Tests/Smoke/smoke_validate.py +++ b/Tests/Smoke/smoke_validate.py @@ -277,6 +277,7 @@ (Path("README.md"), Path("README.zh-CN.md")), (Path("Docs") / "XArch.md", Path("Docs") / "XArch.zh-CN.md"), (Path("Docs") / "ProductizationFeatureMatrix.md", Path("Docs") / "ProductizationFeatureMatrix.zh-CN.md"), + (Path("Docs") / "ProductizationValidationMatrix.md", Path("Docs") / "ProductizationValidationMatrix.zh-CN.md"), (Path("Docs") / "MODULE_BOUNDARIES.md", Path("Docs") / "MODULE_BOUNDARIES.zh-CN.md"), (Path("Docs") / "DEVELOPMENT.md", Path("Docs") / "DEVELOPMENT.zh-CN.md"), (Path("Docs") / "IbvAndPlatformSetupSurvey.md", Path("Docs") / "IbvAndPlatformSetupSurvey.zh-CN.md"), @@ -292,6 +293,147 @@ "RAS/NUMA/PCIe policy", "ARCH=LOONGARCH64", ) +PRODUCTIZATION_VALIDATION_DOCS = ( + Path("Docs") / "ProductizationValidationMatrix.md", + Path("Docs") / "ProductizationValidationMatrix.zh-CN.md", +) +PRODUCTIZATION_VALIDATION_LINK_SOURCES = ( + Path("README.md"), + Path("README.zh-CN.md"), + Path("Docs") / "README.md", + Path("Docs") / "README.zh-CN.md", + Path("Docs") / "XArch.md", + Path("Docs") / "XArch.zh-CN.md", + Path("Docs") / "ProductizationFeatureMatrix.md", + Path("Docs") / "ProductizationFeatureMatrix.zh-CN.md", + Path("Tests") / "README.md", + Path("Tests") / "Smoke" / "README.md", + Path("CHANGELOG.md"), +) +PRODUCTIZATION_VALIDATION_TARGET_TOKENS = ( + "X64", + "AARCH64", + "LOONGARCH64", + "RISCV64", + "OvmfPkg/OvmfPkgX64", + "ArmVirtPkg/ArmVirtQemu", + "OvmfPkg/LoongArchVirt/LoongArchVirtQemu", + "OvmfPkg/RiscVVirt/RiscVVirtQemu", + "Scripts/build-ovmf-x64.sh", + "Scripts/build-armvirt.sh", + "Scripts/build-loongarchvirt.sh", + "Scripts/build-riscvvirt.sh", +) +PRODUCTIZATION_VALIDATION_DOC_CONTRACTS = ( + ( + Path("Docs") / "ProductizationValidationMatrix.md", + { + "XArch-not-ARCH boundary": ( + "XArch", + "edk2 ARCH", + "ARCH=X64", + "ARCH=AARCH64", + "ARCH=LOONGARCH64", + "ARCH=RISCV64", + ), + "native HII/SendForm ownership": ( + "EFI_FORM_BROWSER2_PROTOCOL.SendForm()", + "FormBrowser2", + "native HII", + "ConfigAccess", + "IFR", + "HII varstores", + "platform policy", + ), + "Hardware Health demo-only/read-only boundary": ( + "Hardware Health", + "demo-only/read-only", + "does not claim real sensors", + "does not program", + ), + "ModernUiPreferencesLib ownership": ( + "Preferences", + "ModernUiPreferencesLib", + "not platform policy", + ), + "PCIe native policy ownership": ( + "PCIe", + "ReBAR", + "Above 4G", + "SR-IOV", + "ASPM", + "bifurcation", + "hot-plug", + "ACS", + "ARI", + "IOMMU", + "native HII", + ), + }, + ), + ( + Path("Docs") / "ProductizationValidationMatrix.zh-CN.md", + { + "XArch-not-ARCH boundary": ( + "XArch", + "不会替代", + "edk2 ARCH", + "ARCH=X64", + "ARCH=AARCH64", + "ARCH=LOONGARCH64", + "ARCH=RISCV64", + ), + "native HII/SendForm ownership": ( + "EFI_FORM_BROWSER2_PROTOCOL.SendForm()", + "FormBrowser2", + "native HII", + "ConfigAccess", + "不得解析 IFR", + "不得写 HII varstores", + "不得写 platform policy", + ), + "Hardware Health demo-only/read-only boundary": ( + "Hardware Health", + "demo-only/read-only", + "不声明真实传感器", + "不编程", + "只读", + ), + "ModernUiPreferencesLib ownership": ( + "Preferences", + "ModernUiPreferencesLib", + "不是 platform policy", + ), + "PCIe native policy ownership": ( + "PCIe", + "ReBAR", + "Above 4G", + "SR-IOV", + "ASPM", + "bifurcation", + "hot-plug", + "ACS", + "ARI", + "IOMMU", + "native HII", + ), + }, + ), +) +PRODUCTIZATION_XARCH_NEGATION_CUES = ( + "no supported", + "not supported", + "does not", + "do not", + "not an edk2 build-architecture abstraction", + "no `ARCH=XArch`", + "no `TARGET=XArch`", + "不存在", + "不会", + "不是 edk2 构建架构抽象", + "不支持", + "不应", +) class SmokeFailure(Exception): @@ -360,6 +502,13 @@ def check_static_overlay_script_contracts(root: Path) -> list[str]: for token in PROHIBITED_DEFAULT_OVERLAY_TOKENS: if token in text: + is_loongarch_replace_uiapp_opt_in = ( + name == "build-loongarchvirt.sh" + and "MODERN_SETUP_REPLACE_UIAPP" in text + and token in {"ModernSetupApp", "ModernUiHiiBridgeLib"} + ) + if is_loongarch_replace_uiapp_opt_in: + continue raise SmokeFailure(f"{path} default overlay generator references prohibited token: {token}") lowered = text.lower() @@ -419,6 +568,7 @@ def loongarch_fixture(workspace: Path) -> None: workspace / "OvmfPkg" / "LoongArchVirt" / "LoongArchVirtQemu.dsc", """[Defines] FLASH_DEFINITION = OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | { 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } !include LoongArchVirt.fdf.inc [LibraryClasses.common] @@ -1479,6 +1629,113 @@ def check_bilingual_documentation_contract(root: Path) -> list[str]: return [f"PASS bilingual documentation pairs and IBV taxonomy split: {len(pairs)} pairs"] +def check_xarch_build_tokens_are_negated(relative: Path, text: str) -> None: + for line_number, line in enumerate(text.splitlines(), start=1): + for token in ("ARCH=XArch", "TARGET=XArch"): + if token not in line: + continue + lowered = line.lower() + if not any(cue.lower() in lowered for cue in PRODUCTIZATION_XARCH_NEGATION_CUES): + raise SmokeFailure( + f"{relative}:{line_number} mentions {token} without an explicit same-line rejection" + ) + + +def check_phase30_productization_validation_matrix(root: Path) -> list[str]: + english = root / PRODUCTIZATION_VALIDATION_DOCS[0] + chinese = root / PRODUCTIZATION_VALIDATION_DOCS[1] + for relative in PRODUCTIZATION_VALIDATION_DOCS: + if not (root / relative).exists(): + raise SmokeFailure(f"missing Phase30 productization validation doc: {relative}") + + english_text = english.read_text(encoding="utf-8") + chinese_text = chinese.read_text(encoding="utf-8") + combined = english_text + "\n" + chinese_text + + if PRODUCTIZATION_VALIDATION_DOCS[1].name not in english_text: + raise SmokeFailure("ProductizationValidationMatrix.md missing zh-CN cross-link") + if PRODUCTIZATION_VALIDATION_DOCS[0].name not in chinese_text: + raise SmokeFailure("ProductizationValidationMatrix.zh-CN.md missing English cross-link") + + for relative in PRODUCTIZATION_VALIDATION_LINK_SOURCES: + if "ProductizationValidationMatrix" not in (root / relative).read_text(encoding="utf-8"): + raise SmokeFailure(f"{relative} missing Phase30 validation matrix link/reference") + + for token in PRODUCTIZATION_VALIDATION_TARGET_TOKENS: + if token not in combined: + raise SmokeFailure(f"Phase30 validation matrix missing target/platform/script token: {token}") + + for relative, contracts in PRODUCTIZATION_VALIDATION_DOC_CONTRACTS: + text = (root / relative).read_text(encoding="utf-8") + for area, tokens in contracts.items(): + for token in tokens: + if token not in text: + raise SmokeFailure(f"{relative} missing Phase30 {area} token: {token}") + check_xarch_build_tokens_are_negated(relative, text) + + for required_heading in ( + "XArch Target Validation Matrix", + "Product Class Validation Matrix", + "App / Provider Validation Matrix", + "XArch 目标验证矩阵", + "产品类别验证矩阵", + "App / Provider 验证矩阵", + ): + if required_heading not in combined: + raise SmokeFailure(f"Phase30 validation matrix missing section: {required_heading}") + + for area in ( + "Dashboard", + "Boot", + "Devices / HII", + "Security", + "Firmware", + "Diagnostics", + "Management", + "Power / Thermal", + "Hardware Health", + "Performance", + "PCIe", + "Preferences", + "Exit", + ): + if area not in combined: + raise SmokeFailure(f"Phase30 validation matrix missing App/provider area: {area}") + + bash = shutil.which("bash") + if bash is None: + return ["PASS Phase30 productization validation matrix docs; SKIP xarch JSON smoke: bash not found"] + + with tempfile.TemporaryDirectory(prefix="phase30-xarch-smoke-") as tmp: + json_path = Path(tmp) / "xarch-validation.json" + run( + [ + bash, + str(root / XARCH_RUNNER), + "--all", + "--mode", + "dry-run", + "--format", + "json", + "--output", + str(json_path), + ], + cwd=root, + ) + payload = json.loads(json_path.read_text(encoding="utf-8")) + targets = payload.get("targets") + if not isinstance(targets, list) or len(targets) != 4: + raise SmokeFailure("Phase30 xarch JSON smoke expected four targets") + for target in targets: + if target.get("result") != "PASS": + raise SmokeFailure(f"Phase30 xarch JSON target did not pass: {target}") + riscv = [target for target in targets if target.get("edk2_arch") == "RISCV64"] + if len(riscv) != 1 or riscv[0].get("validation_level") != "Build/script validation": + raise SmokeFailure("Phase30 xarch JSON smoke must keep RISCV64 at Build/script validation") + + return ["PASS Phase30 XArch/productization validation matrix docs and xarch JSON smoke"] + + def check_hii_bridge_view_model_boundary(root: Path) -> list[str]: header = root / "Include" / "ModernUi" / "ModernUiHiiBridge.h" source = root / "Library" / "ModernUiHiiBridgeLib" / "ModernUiHiiBridgeLib.c" @@ -1717,6 +1974,36 @@ def check_overlay_generation(root: Path) -> list[str]: messages.append(f"PASS {platform} {engine} overlay generation dry run") + overlay_dir = workspace / "Build" / "ModernSetupPkgOverlay" + if overlay_dir.exists(): + shutil.rmtree(overlay_dir) + + env = os.environ.copy() + env.update( + { + "WORKSPACE": str(workspace), + "GENERATE_ONLY": "1", + "MODERN_SETUP_DISPLAY_ENGINE": "modern", + "MODERN_SETUP_DEMO_DRIVER_SAMPLE": "0", + "MODERN_SETUP_REPLACE_UIAPP": "1", + } + ) + script = workspace / "ModernSetupPkg" / "Scripts" / "build-loongarchvirt.sh" + run([bash, str(script)], cwd=workspace / "ModernSetupPkg", env=env) + + dsc = workspace / "Build" / "ModernSetupPkgOverlay" / "LoongArchVirtQemuModernSetup.dsc" + fdf = workspace / "Build" / "ModernSetupPkgOverlay" / "LoongArchVirtQemuModernSetup.fdf" + assert_contains(dsc, "ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf") + assert_contains(dsc, "MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf") + assert_contains( + dsc, + "gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | { 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }", + ) + assert_contains(fdf, "INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf") + assert_contains(fdf, "INF RuleOverride = MODERN_SETUP_UIAPP ModernSetupPkg/Application/ModernSetupApp/ModernSetupApp.inf") + assert_contains(fdf, "FILE APPLICATION = 462CAA21-7614-4503-836E-8AB6F4662331") + messages.append("PASS loongarch replace-uiapp opt-in overlay generation dry run") + return messages @@ -1741,6 +2028,7 @@ def main() -> int: messages.extend(check_hardware_health_demo_provider(root)) messages.extend(check_pcie_docs_language(root)) messages.extend(check_bilingual_documentation_contract(root)) + messages.extend(check_phase30_productization_validation_matrix(root)) messages.extend(check_hii_bridge_view_model_boundary(root)) messages.extend(check_modern_ui_builtin_glyph_subset(root)) messages.extend(check_ip_hygiene_notices(root))