From 5bd5b0a01521e88160fad99c231108f2bbb6b822 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Thu, 27 Jul 2023 17:44:45 -0400 Subject: [PATCH] Add BIOS version and release date to SMBIOS (#646) ## Description - Adds the BIOS version and date to Type 0 (BIOS) structure. - Changes BIOS vendor to "Project Mu" so its easier to trace project info. - Adds the QEMU version to the Type 1 (System) version field. - Q35: Changes System product from "MuQemuQ35" to "QEMU Q35". - SBSA: Changes System product from "MuQemuQ35" to "QEMU SBSA". - SBSA: Fixes asset tag values from "Q35" to "SBSA" Other related minor cleanup. The goal is to clean up firmware and system information and make it more useful. - [ ] Impacts functionality? - **Functionality** - Does the change ultimately impact how firmware functions? - Examples: Add a new library, publish a new PPI, update an algorithm, ... - [ ] Impacts security? - **Security** - Does the change have a direct security impact on an application, flow, or firmware? - Examples: Crypto algorithm change, buffer overflow fix, parameter validation improvement, ... - [ ] Breaking change? - **Breaking change** - Will anyone consuming this change experience a break in build or boot behavior? - Examples: Add a new library class, move a module to a different repo, call a function in a new library class in a pre-existing module, ... - [ ] Includes tests? - **Tests** - Does the change include any explicit test code? - Examples: Unit tests, integration tests, robot tests, ... - [ ] Includes documentation? - **Documentation** - Does the change contain explicit documentation additions outside direct code modifications (and comments)? - Examples: Update readme file, add feature readme file, link to documentation on an a separate Web page, ... ## How This Was Tested 1. Verified values in QEMU run command. 2. Read values from `smbiosview` in the EFI shell. 3. Read relevant values from Windows UI. ## Integration Instructions Review values modified and see if they affect tests or features dependent on SMBIOS information. Signed-off-by: Michael Kubacki --- .../Plugins/QemuRunner/QemuRunner.py | 20 ++++---- .../Plugins/QemuRunner/QemuRunner.py | 46 +++++++++++++++---- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py b/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py index ae2b1f8bd..ba2f49e1d 100644 --- a/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py +++ b/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py @@ -8,8 +8,6 @@ import logging import os -import sys -import time import threading import datetime import subprocess @@ -57,13 +55,13 @@ def Runner(env): ''' Runs QEMU ''' VirtualDrive = env.GetValue("VIRTUAL_DRIVE_PATH") OutputPath_FV = os.path.join(env.GetValue("BUILD_OUTPUT_BASE"), "FV") - version = env.GetValue("VERSION", "Unknown") + repo_version = env.GetValue("VERSION", "Unknown") # Check if QEMU is on the path, if not find it executable = "qemu-system-x86_64" # First query the version - ver = QemuRunner.QueryQemuVersion(executable) + qemu_version = QemuRunner.QueryQemuVersion(executable) # write messages to stdio args = "-debugcon stdio" @@ -113,8 +111,10 @@ def Runner(env): args += " -smp " + env.GetBuildValue ("QEMU_CORE_NUM") if smm_enabled == "on": args += " -global driver=cfi.pflash01,property=secure,value=on" + + code_fd = os.path.join(OutputPath_FV, "QEMUQ35_CODE.fd") args += " -drive if=pflash,format=raw,unit=0,file=" + \ - os.path.join(OutputPath_FV, "QEMUQ35_CODE.fd") + ",readonly=on" + code_fd + ",readonly=on" orig_var_store = os.path.join(OutputPath_FV, "QEMUQ35_VARS.fd") dfci_var_store =env.GetValue("DFCI_VAR_STORE") @@ -175,8 +175,12 @@ def Runner(env): # forward ports for robotframework 8270 and 8271 args += " -netdev user,id=net0,hostfwd=tcp::8270-:8270,hostfwd=tcp::8271-:8271" - args += " -smbios type=0,vendor=Palindrome,uefi=on" - args += " -smbios type=1,manufacturer=Palindrome,product=MuQemuQ35,serial=42-42-42-42,uuid=9de555c0-05d7-4aa1-84ab-bb511e3a8bef" + creation_time = Path(code_fd).stat().st_ctime + creation_datetime = datetime.datetime.fromtimestamp(creation_time) + creation_date = creation_datetime.strftime("%m/%d/%Y") + + args += f" -smbios type=0,vendor=\"Project Mu\",version=\"mu_tiano_platforms-{repo_version}\",date={creation_date},uefi=on" + args += f" -smbios type=1,manufacturer=Palindrome,product=\"QEMU Q35\",family=QEMU,version=\"{'.'.join(qemu_version)}\",serial=42-42-42-42,uuid=9de555c0-05d7-4aa1-84ab-bb511e3a8bef" args += f" -smbios type=3,manufacturer=Palindrome,serial=40-41-42-43{boot_selection}" # TPM in Linux @@ -219,7 +223,7 @@ def Runner(env): ret = 0 ## TODO: remove this once we upgrade to newer QEMU - if ret == 0x8B and ver[0] == '4': + if ret == 0x8B and qemu_version[0] == '4': # QEMU v4 will return segmentation fault when shutting down. # Tested same FDs on QEMU 6 and 7, not observing the same. ret = 0 diff --git a/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py b/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py index 7e8d4f785..92270e020 100644 --- a/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py +++ b/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py @@ -7,12 +7,13 @@ ## import logging +import io import os -import sys -import time +import re import threading import datetime import subprocess +from pathlib import Path from edk2toolext.environment import plugin_manager from edk2toolext.environment.plugintypes import uefi_helper_plugin from edk2toollib import utility_functions @@ -30,16 +31,36 @@ def RegisterHelpers(self, obj): obj.Register("QemuRun", QemuRunner.Runner, fp) return 0 + @staticmethod + # raw helper function to extract version number from QEMU + def QueryQemuVersion(exec): + if exec is None: + return None + + result = io.StringIO() + ret = utility_functions.RunCmd(exec, "--version", outstream=result) + if ret != 0: + return None + + # expected version string will be "QEMU emulator version maj.min.rev" + res = result.getvalue() + ver_str = re.search(r'version\s*([\d.]+)', res).group(1) + + return ver_str.split('.') + + @staticmethod def Runner(env): ''' Runs QEMU ''' VirtualDrive = env.GetValue("VIRTUAL_DRIVE_PATH") OutputPath_FV = os.path.join(env.GetValue("BUILD_OUTPUT_BASE"), "FV") - version = env.GetValue("VERSION", "Unknown") + repo_version = env.GetValue("VERSION", "Unknown") # Check if QEMU is on the path, if not find it executable = "qemu-system-aarch64" + qemu_version = QemuRunner.QueryQemuVersion(executable) + # turn off network args = "-net none" # Mount disk with either startup.nsh or OS image @@ -64,16 +85,23 @@ def Runner(env): args += " -global driver=cfi.pflash01,property=secure,value=on" args += " -drive if=pflash,format=raw,unit=0,file=" + \ os.path.join(OutputPath_FV, "SECURE_FLASH0.fd") + + code_fd = os.path.join(OutputPath_FV, "QEMU_EFI.fd") args += " -drive if=pflash,format=raw,unit=1,file=" + \ - os.path.join(OutputPath_FV, "QEMU_EFI.fd") + ",readonly=on" + code_fd + ",readonly=on" # Add XHCI USB controller and mouse args += " -device qemu-xhci,id=usb" args += " -device usb-tablet,id=input0,bus=usb.0,port=1" # add a usb mouse - args += " -device usb-kbd,id=input1,bus=usb.0,port=2" # add a usb keyboard - args += " -smbios type=0,vendor=Palindrome,uefi=on" - args += " -smbios type=1,manufacturer=Palindrome,product=MuQemuQ35,serial=42-42-42-42" - args += f" -smbios type=3,manufacturer=Palindrome,version={version},serial=42-42-42-42,asset=Q35,sku=Q35" + args += " -device usb-kbd,id=input1,bus=usb.0,port=2" # add a usb keyboard + + creation_time = Path(code_fd).stat().st_ctime + creation_datetime = datetime.datetime.fromtimestamp(creation_time) + creation_date = creation_datetime.strftime("%m/%d/%Y") + + args += f" -smbios type=0,vendor=\"Project Mu\",version=\"mu_tiano_platforms-{repo_version}\",date={creation_date},uefi=on" + args += f" -smbios type=1,manufacturer=Palindrome,product=\"QEMU SBSA\",family=QEMU,version=\"{'.'.join(qemu_version)}\",serial=42-42-42-42" + args += f" -smbios type=3,manufacturer=Palindrome,serial=42-42-42-42,asset=SBSA,sku=SBSA" if (env.GetValue("QEMU_HEADLESS").upper() == "TRUE"): args += " -display none" # no graphics @@ -109,7 +137,7 @@ def Runner(env): ret = 0 ## TODO: remove this once we upgrade to newer QEMU - if ret == 0x8B and ver[0] == '4': + if ret == 0x8B and qemu_version[0] == '4': # QEMU v4 will return segmentation fault when shutting down. # Tested same FDs on QEMU 6 and 7, not observing the same. ret = 0