From 98d7e84da4cf7100ae8bc4e4efae542428a2bf5b Mon Sep 17 00:00:00 2001 From: kuqin12 <42554914+kuqin12@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:16:52 -0800 Subject: [PATCH] Integrate 202311 release branches (#809) ## Description This change updates all submodules to point to 202311 based MU submodules. Code change specifically applicable to QEMU Q35: https://github.com/tianocore/edk2/commit/dea6002d6e612ee3066fc755b5ad47558d84d645 https://github.com/tianocore/edk2/commit/24e6daa2bcfb64bbe871f76d8e9774d67f247717 https://github.com/tianocore/edk2/commit/12d3d60f51550a7166f8f3e758866b53b9a88e73 Specifically, the submodules are updated to: | Submodule | Version | | - | - | | MU_BASECORE | v2023110000.0.1 | | MU_PLUS | v2023110000.0.0 | | MU_OEM_SAMPLE | v2023110000.0.0 | | MU_TIANO_PLUS | v2023110000.0.0 | | MM_SUPV | v9.0.0 | | MU_SILICON_ARM | v2023110000.0.0 | - [x] 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, ... - [x] 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 This branch was tested on QEMU Q35 and verified bootable to UEFI shell and Windows OS. ## Integration Instructions N/A --------- Co-authored-by: Michael Kubacki --- .github/workflows/codeql-platform.yml | 49 ++++- Common/MU | 2 +- Common/MU_OEM_SAMPLE | 2 +- Common/MU_TIANO | 2 +- Features/MM_SUPV | 2 +- MU_BASECORE | 2 +- .../X64/SnpPageStateChangeInternal.c | 1 - .../Plugins/QemuRunner/QemuRunner.py | 167 +----------------- Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc | 8 + .../ResetVector/Ia16/ResetVectorVtf0.asm | 16 +- .../Plugins/QemuRunner/QemuRunner.py | 167 +----------------- Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc | 4 +- Silicon/Arm/MU_TIANO | 2 +- 13 files changed, 79 insertions(+), 345 deletions(-) diff --git a/.github/workflows/codeql-platform.yml b/.github/workflows/codeql-platform.yml index 1904bc60..2a76c3ad 100644 --- a/.github/workflows/codeql-platform.yml +++ b/.github/workflows/codeql-platform.yml @@ -3,11 +3,16 @@ # Any platform that supports the `--codeql` parameter will be built and the # results will be uploaded to GitHub Code Scanning. # +# Note: Important: This file only works with "platform" builds. "CI" builds are +# supported with the codeql.yml file. +# # Note: This workflow only supports Windows as CodeQL CLI has confirmed issues running # against edk2-style codebases on Linux (only tested on Ubuntu). Therefore, this # workflow is written only for Windows but could easily be adapted to run on Linux # in the future if needed (e.g. swap out "windows" with agent OS var value, etc.) # +# For details about the Linux issue see: https://github.com/github/codeql-action/issues/1338 +# # NOTE: This file is automatically synchronized from Mu DevOps. Update the original file there # instead of the file in this repo. # @@ -323,7 +328,14 @@ jobs: import sys from pathlib import Path - # Find the plugin directory that contains the CodeQL plugin + # + # Find the plugin directory that contains the CodeQL plugin. + # + # Prior to Mu Basecore 202311, the CodeQL plugin was located in .pytool. After it + # is located in BaseTools. First check BaseTools, but consider .pytool as a backup + # for backward compatibility. The .pytool backup can be removed when no longer needed + # for supported branches. + # plugin_dir = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('BaseTools/Plugin/CodeQL')) if not plugin_dir: plugin_dir = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('.pytool/Plugin/CodeQL')) @@ -376,19 +388,48 @@ jobs: working-directory: "Z:" run: stuart_update -c ${{ matrix.build_file }} -t DEBUG -a ${{ matrix.archs }} TOOL_CHAIN_TAG=${{ matrix.tool_chain_tag }} --codeql + - name: Find pytool Plugin Directory + id: find_pytool_dir + shell: python + run: | + import os + import sys + from pathlib import Path + + # Find the plugin directory that contains the Compiler plugin + plugin_dir = list(Path(os.environ['GITHUB_WORKSPACE']).rglob('.pytool/Plugin/CompilerPlugin')) + + # This should only be found once + if len(plugin_dir) == 1: + # If the directory is found get the parent Plugin directory + plugin_dir = str(plugin_dir[0].parent) + + with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: + print(f'pytool_plugin_dir={plugin_dir}', file=fh) + else: + print("::error title=Workspace Error!::Failed to find Mu Basecore .pytool/Plugin directory!") + sys.exit(1) + - name: Remove CI Plugins Irrelevant to CodeQL shell: python env: - CODEQL_PLUGIN_DIR: ${{ steps.find_dir.outputs.codeql_plugin_dir }} + PYTOOL_PLUGIN_DIR: ${{ steps.find_pytool_dir.outputs.pytool_plugin_dir }} run: | import os import shutil from pathlib import Path - # Only these two plugins are needed for CodeQL + # Only these two plugins are needed for CodeQL. + # + # CodeQL build time is reduced by removing other plugins that are not needed for the CodeQL + # build in the .pytool directory. The CompilerPlugin is required to compile code for CodeQL + # to extract results from and the CodeQL plugin is necessary to to analyze the results and + # build the CodeQL database from them. The CodeQL plugin should be in BaseTools moving forward + # but still might be in .pytool in older branches so it is kept here as an exception. + # plugins_to_keep = ['CodeQL', 'CompilerPlugin'] - plugin_dir = Path(os.environ['CODEQL_PLUGIN_DIR']).parent.absolute() + plugin_dir = Path(os.environ['PYTOOL_PLUGIN_DIR']).absolute() if plugin_dir.is_dir(): for dir in plugin_dir.iterdir(): if str(dir.stem) not in plugins_to_keep: diff --git a/Common/MU b/Common/MU index 12f028aa..c9d74b38 160000 --- a/Common/MU +++ b/Common/MU @@ -1 +1 @@ -Subproject commit 12f028aaa23f23d229bdb6b266f736f3ff928ac8 +Subproject commit c9d74b38897beb2993235ee14ef7fa86038c5e1d diff --git a/Common/MU_OEM_SAMPLE b/Common/MU_OEM_SAMPLE index f7eeee8b..f29260e7 160000 --- a/Common/MU_OEM_SAMPLE +++ b/Common/MU_OEM_SAMPLE @@ -1 +1 @@ -Subproject commit f7eeee8b42a2bc8311cfae9b51ee28e4b62fc3be +Subproject commit f29260e748abea574c714d25c8fb782b6f9317c7 diff --git a/Common/MU_TIANO b/Common/MU_TIANO index 70722925..d83dfb8b 160000 --- a/Common/MU_TIANO +++ b/Common/MU_TIANO @@ -1 +1 @@ -Subproject commit 70722925361b7207d46f6c28feaef62d9c3b091f +Subproject commit d83dfb8be497b3b1121934f754a8a67744e5de84 diff --git a/Features/MM_SUPV b/Features/MM_SUPV index e0c16a86..cb08bb67 160000 --- a/Features/MM_SUPV +++ b/Features/MM_SUPV @@ -1 +1 @@ -Subproject commit e0c16a86900a7a467067354b966c503e19bb034a +Subproject commit cb08bb671806197fa57b14f34b8c449a82b1d7fa diff --git a/MU_BASECORE b/MU_BASECORE index d77131a0..c6e7c620 160000 --- a/MU_BASECORE +++ b/MU_BASECORE @@ -1 +1 @@ -Subproject commit d77131a0e26de78d9847a7a0bdfeca8d0993de87 +Subproject commit c6e7c62056882238ed28905bf148e271a94e005f diff --git a/Platforms/QemuQ35Pkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c b/Platforms/QemuQ35Pkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c index 4d684964..7a8878b1 100644 --- a/Platforms/QemuQ35Pkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c +++ b/Platforms/QemuQ35Pkg/Library/BaseMemEncryptSevLib/X64/SnpPageStateChangeInternal.c @@ -20,7 +20,6 @@ #include "SnpPageStateChange.h" -#define IS_ALIGNED(x, y) ((((x) & (y - 1)) == 0)) #define PAGES_PER_LARGE_ENTRY 512 STATIC diff --git a/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py b/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py index 50e628ca..8102d5d5 100644 --- a/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py +++ b/Platforms/QemuQ35Pkg/Plugins/QemuRunner/QemuRunner.py @@ -8,19 +8,13 @@ import logging import os -import threading import datetime -import subprocess import re import io import shutil from pathlib import Path -from edk2toolext.environment import plugin_manager from edk2toolext.environment.plugintypes import uefi_helper_plugin from edk2toollib import utility_functions -from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser -from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser -from edk2toolext.environment.multiple_workspace import MultipleWorkspace class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): @@ -94,14 +88,18 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): storage_format = { ".vhd": "raw", - ".qcow2": "qcow2" + ".qcow2": "qcow2", + ".iso": "iso", }.get(file_extension, None) if storage_format is None: raise Exception(f"Unknown OS storage type: {path_to_os}") - args += f" -drive file=\"{path_to_os}\",format={storage_format},if=none,id=os_nvme" - args += " -device nvme,serial=nvme-1,drive=os_nvme" + if storage_format == "iso": + args += f" -cdrom \"{path_to_os}\"" + else: + args += f" -drive file=\"{path_to_os}\",format={storage_format},if=none,id=os_nvme" + args += " -device nvme,serial=nvme-1,drive=os_nvme" else: args += " -m 2048" @@ -220,7 +218,6 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): args += " -monitor tcp:127.0.0.1:" + monitor_port + ",server,nowait" # Run QEMU - #ret = QemuRunner.RunCmd(executable, args, thread_target=QemuRunner.QemuCmdReader) ret = utility_functions.RunCmd(executable, args) if ret != 0 and os.name != 'nt': # Linux version of QEMU will mess with the print if its run failed, this is to restore it @@ -237,153 +234,3 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): ret = 0 return ret - - #### - # Helper functions for running commands from the shell in python environment - # Don't use directly - # - # process output stream and write to log. - # part of the threading pattern. - # - # http://stackoverflow.com/questions/19423008/logged-subprocess-communicate - #### - @staticmethod - def QemuCmdReader(filepath, outstream, stream, logging_level=logging.INFO): - f = None - # open file if caller provided path - error_found = False - if(filepath): - f = open(filepath, "w") - while True: - try: - s = stream.readline().decode() - ss = s.rstrip() # string stripped - except UnicodeDecodeError as e: - logging.error(str(e)) - if not s: - break - if(f is not None): - # write to file if caller provided file - f.write(ss) - f.write("\n") - if(outstream is not None): - # write to stream object if caller provided object - outstream.write(ss) - f.write("\n") - logging.log(logging_level, ss) - if s.startswith("ASSERT "): - message = "ASSERT DETECTED, killing QEMU process: " + ss - logging.error(message) - if (outstream is not None): - outstream.write(message) - if (f is not None): - f.write(message) - error_found = True - break - stream.close() - if(f is not None): - f.close() - return None if not error_found else 1 - - #### - # Run a shell command and print the output to the log file - # This is the public function that should be used to run commands from the shell in python environment - # @param cmd - command being run, either quoted or not quoted - # @param parameters - parameters string taken as is - # @param capture - boolean to determine if caller wants the output captured in any format. - # @param workingdir - path to set to the working directory before running the command. - # @param outfile - capture output to file of given path. - # @param outstream - capture output to a stream. - # @param environ - shell environment variables dictionary that replaces the one inherited from the - # current process. - # @param target - a function to call. It must accept four parameters: filepath, outstream, stream, logging_level - # @param logging_level - log level to log output at. Default is INFO - # @param raise_exception_on_nonzero - Setting to true causes exception to be raised if the cmd - # return code is not zero. - # - # @return returncode of called cmd - #### - @staticmethod - def RunCmd(cmd, parameters, capture=True, workingdir=None, outfile=None, outstream=None, environ=None, thread_target=None, logging_level=logging.INFO, raise_exception_on_nonzero=False): - cmd = cmd.strip('"\'') - if " " in cmd: - cmd = '"' + cmd + '"' - if parameters is not None: - parameters = parameters.strip() - cmd += " " + parameters - if thread_target is None: - thread_target = utility_functions.reader - starttime = datetime.datetime.now() - logging.log(logging_level, "Cmd to run is: " + cmd) - logging.log(logging_level, "------------------------------------------------") - logging.log(logging_level, "--------------Cmd Output Starting---------------") - logging.log(logging_level, "------------------------------------------------") - wait_delay = 0.5 # we check about every second - c = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=workingdir, shell=True, env=environ) - if(capture): - thread = PropagatingThread(target=thread_target, args=(outfile, outstream, c.stdout, logging_level)) - thread.start() - while True: - try: - c.wait(wait_delay) - except subprocess.TimeoutExpired: - # we expect this to throw and this is safe behavior - pass - ret = thread.join(wait_delay) - if c.poll() is not None or not thread.is_alive() or ret is not None: - break - # if the propagating thread exited but the cmd is still going - if c.poll() is None and not thread.is_alive(): - logging.log(logging_level,"WARNING: Terminating the process early due to target") - c.kill() - if thread.ret != None: - c.returncode = thread.ret # force the return code to be non zero - if c.poll() is None and not thread.is_alive(): - logging.log(logging_level,"WARNING: Killing the process early due to target") - c.terminate() - if thread.ret != None: - c.returncode = thread.ret # force the return code to be non zero - else: - c.wait() - endtime = datetime.datetime.now() - delta = endtime - starttime - endtime_str = "{0[0]:02}:{0[1]:02}".format(divmod(delta.seconds, 60)) - returncode_str = "{0:#010x}".format(c.returncode) - logging.log(logging_level, "------------------------------------------------") - logging.log(logging_level, "--------------Cmd Output Finished---------------") - logging.log(logging_level, "--------- Running Time (mm:ss): " + endtime_str + " ----------") - logging.log(logging_level, "----------- Return Code: " + returncode_str + " ------------") - logging.log(logging_level, "------------------------------------------------") - - if raise_exception_on_nonzero and c.returncode != 0: - raise Exception("{0} failed with Return Code: {1}".format(cmd, returncode_str)) - return c.returncode - -#### -# Class to support running commands from the shell in a python environment. -# Don't use directly. -# -# PropagatingThread copied from sample here: -# https://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python -#### -class PropagatingThread(threading.Thread): - def run(self): - self.exc = None - self.ret = None - try: - if hasattr(self, '_Thread__target'): - # Thread uses name mangling prior to Python 3. - self.ret = self._Thread__target(*self._Thread__args, **self._Thread__kwargs) - else: - self.ret = self._target(*self._args, **self._kwargs) - except SystemExit as e: - self.ret = e.code - except BaseException as e: - self.exc = e - - def join(self, timeout=0.5): - ''' timeout is the number of seconds to timeout ''' - super(PropagatingThread, self).join(timeout) - if self.exc: - raise self.exc - return self.ret diff --git a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc index bfe22e63..d664a308 100644 --- a/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc +++ b/Platforms/QemuQ35Pkg/QemuQ35Pkg.dsc @@ -509,6 +509,8 @@ SmmPolicyGateLib|MmSupervisorPkg/Library/SmmPolicyGateLib/SmmPolicyGateLib.inf HwResetSystemLib|QemuQ35Pkg/Library/ResetSystemLib/StandaloneMmResetSystemLib.inf IhvSmmSaveStateSupervisionLib|MmSupervisorPkg/Library/IhvMmSaveStateSupervisionLib/IhvMmSaveStateSupervisionLib.inf + MmServicesTableLib|StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLibCore.inf + MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/AmdMmSaveStateLib.inf [LibraryClasses.common.MM_STANDALONE] TimerLib|QemuQ35Pkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf @@ -589,6 +591,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerLocator|TRUE + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerAutoWrapEnable|TRUE gQemuPkgTokenSpaceGuid.PcdSmmSmramRequire|$(SMM_ENABLED) gUefiQemuQ35PkgTokenSpaceGuid.PcdStandaloneMmEnable|$(SMM_ENABLED) @@ -746,8 +749,13 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0x80 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0x20 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0x510 +!if $(SMM_ENABLED) == FALSE + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x200 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0x200 +!else gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x100 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0x1C0 +!endif [PcdsFixedAtBuild.X64] diff --git a/Platforms/QemuQ35Pkg/ResetVector/Ia16/ResetVectorVtf0.asm b/Platforms/QemuQ35Pkg/ResetVector/Ia16/ResetVectorVtf0.asm index 12f2cedd..8ab883fe 100644 --- a/Platforms/QemuQ35Pkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/Platforms/QemuQ35Pkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -159,23 +159,13 @@ sevEsResetBlockEnd: guidedStructureEnd: ALIGN 16 - -applicationProcessorEntryPoint: ; -; Application Processors entry point +; 0xffffffe0 ; -; GenFv generates code aligned on a 4k boundary which will jump to this -; location. (0xffffffe0) This allows the Local APIC Startup IPI to be -; used to wake up the application processors. -; - jmp EarlyApInitReal16 - -ALIGN 8 - - DD 0 + DD 0, 0, 0 ; -; The VTF signature +; The VTF signature (0xffffffec) ; ; VTF-0 means that the VTF (Volume Top File) code does not require ; any fixups. diff --git a/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py b/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py index 131dbf30..cf2e7295 100644 --- a/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py +++ b/Platforms/QemuSbsaPkg/Plugins/QemuRunner/QemuRunner.py @@ -10,16 +10,10 @@ import logging import io import os 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 -from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser -from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser -from edk2toolext.environment.multiple_workspace import MultipleWorkspace class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): @@ -71,14 +65,18 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): storage_format = { ".vhd": "raw", - ".qcow2": "qcow2" + ".qcow2": "qcow2", + ".iso": "iso", }.get(file_extension, None) if storage_format is None: raise Exception(f"Unknown OS storage type: {path_to_os}") - args += f" -drive file=\"{path_to_os}\",format={storage_format},if=none,id=os_nvme" - args += " -device nvme,serial=nvme-1,drive=os_nvme" + if storage_format == "iso": + args += f" -cdrom \"{path_to_os}\"" + else: + args += f" -drive file=\"{path_to_os}\",format={storage_format},if=none,id=os_nvme" + args += " -device nvme,serial=nvme-1,drive=os_nvme" elif os.path.isfile(VirtualDrive): args += f" -drive file={VirtualDrive},if=virtio" elif os.path.isdir(VirtualDrive): @@ -139,7 +137,6 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): args += " -monitor tcp:127.0.0.1:" + monitor_port + ",server,nowait" # Run QEMU - #ret = QemuRunner.RunCmd(executable, args, thread_target=QemuRunner.QemuCmdReader) ret = utility_functions.RunCmd(executable, args) if ret != 0 and os.name != 'nt': # Linux version of QEMU will mess with the print if its run failed, this is to restore it @@ -156,153 +153,3 @@ class QemuRunner(uefi_helper_plugin.IUefiHelperPlugin): ret = 0 return ret - - #### - # Helper functions for running commands from the shell in python environment - # Don't use directly - # - # process output stream and write to log. - # part of the threading pattern. - # - # http://stackoverflow.com/questions/19423008/logged-subprocess-communicate - #### - @staticmethod - def QemuCmdReader(filepath, outstream, stream, logging_level=logging.INFO): - f = None - # open file if caller provided path - error_found = False - if(filepath): - f = open(filepath, "w") - while True: - try: - s = stream.readline().decode() - ss = s.rstrip() # string stripped - except UnicodeDecodeError as e: - logging.error(str(e)) - if not s: - break - if(f is not None): - # write to file if caller provided file - f.write(ss) - f.write("\n") - if(outstream is not None): - # write to stream object if caller provided object - outstream.write(ss) - f.write("\n") - logging.log(logging_level, ss) - if s.startswith("ASSERT "): - message = "ASSERT DETECTED, killing QEMU process: " + ss - logging.error(message) - if (outstream is not None): - outstream.write(message) - if (f is not None): - f.write(message) - error_found = True - break - stream.close() - if(f is not None): - f.close() - return None if not error_found else 1 - - #### - # Run a shell command and print the output to the log file - # This is the public function that should be used to run commands from the shell in python environment - # @param cmd - command being run, either quoted or not quoted - # @param parameters - parameters string taken as is - # @param capture - boolean to determine if caller wants the output captured in any format. - # @param workingdir - path to set to the working directory before running the command. - # @param outfile - capture output to file of given path. - # @param outstream - capture output to a stream. - # @param environ - shell environment variables dictionary that replaces the one inherited from the - # current process. - # @param target - a function to call. It must accept four parameters: filepath, outstream, stream, logging_level - # @param logging_level - log level to log output at. Default is INFO - # @param raise_exception_on_nonzero - Setting to true causes exception to be raised if the cmd - # return code is not zero. - # - # @return returncode of called cmd - #### - @staticmethod - def RunCmd(cmd, parameters, capture=True, workingdir=None, outfile=None, outstream=None, environ=None, thread_target=None, logging_level=logging.INFO, raise_exception_on_nonzero=False): - cmd = cmd.strip('"\'') - if " " in cmd: - cmd = '"' + cmd + '"' - if parameters is not None: - parameters = parameters.strip() - cmd += " " + parameters - if thread_target is None: - thread_target = utility_functions.reader - starttime = datetime.datetime.now() - logging.log(logging_level, "Cmd to run is: " + cmd) - logging.log(logging_level, "------------------------------------------------") - logging.log(logging_level, "--------------Cmd Output Starting---------------") - logging.log(logging_level, "------------------------------------------------") - wait_delay = 0.5 # we check about every second - c = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=workingdir, shell=True, env=environ) - if(capture): - thread = PropagatingThread(target=thread_target, args=(outfile, outstream, c.stdout, logging_level)) - thread.start() - while True: - try: - c.wait(wait_delay) - except subprocess.TimeoutExpired: - # we expect this to throw and this is safe behavior - pass - ret = thread.join(wait_delay) - if c.poll() is not None or not thread.is_alive() or ret is not None: - break - # if the propagating thread exited but the cmd is still going - if c.poll() is None and not thread.is_alive(): - logging.log(logging_level,"WARNING: Terminating the process early due to target") - c.kill() - if thread.ret != None: - c.returncode = thread.ret # force the return code to be non zero - if c.poll() is None and not thread.is_alive(): - logging.log(logging_level,"WARNING: Killing the process early due to target") - c.terminate() - if thread.ret != None: - c.returncode = thread.ret # force the return code to be non zero - else: - c.wait() - endtime = datetime.datetime.now() - delta = endtime - starttime - endtime_str = "{0[0]:02}:{0[1]:02}".format(divmod(delta.seconds, 60)) - returncode_str = "{0:#010x}".format(c.returncode) - logging.log(logging_level, "------------------------------------------------") - logging.log(logging_level, "--------------Cmd Output Finished---------------") - logging.log(logging_level, "--------- Running Time (mm:ss): " + endtime_str + " ----------") - logging.log(logging_level, "----------- Return Code: " + returncode_str + " ------------") - logging.log(logging_level, "------------------------------------------------") - - if raise_exception_on_nonzero and c.returncode != 0: - raise Exception("{0} failed with Return Code: {1}".format(cmd, returncode_str)) - return c.returncode - -#### -# Class to support running commands from the shell in a python environment. -# Don't use directly. -# -# PropagatingThread copied from sample here: -# https://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python -#### -class PropagatingThread(threading.Thread): - def run(self): - self.exc = None - self.ret = None - try: - if hasattr(self, '_Thread__target'): - # Thread uses name mangling prior to Python 3. - self.ret = self._Thread__target(*self._Thread__args, **self._Thread__kwargs) - else: - self.ret = self._target(*self._args, **self._kwargs) - except SystemExit as e: - self.ret = e.code - except BaseException as e: - self.exc = e - - def join(self, timeout=0.5): - ''' timeout is the number of seconds to timeout ''' - super(PropagatingThread, self).join(timeout) - if self.exc: - raise self.exc - return self.ret diff --git a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc index 01d15a21..70a406a1 100644 --- a/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc +++ b/Platforms/QemuSbsaPkg/QemuSbsaPkg.dsc @@ -464,6 +464,7 @@ ArmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf StandaloneMmCoreEntryPoint|ArmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf + MmServicesTableLib|StandaloneMmPkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLibCore.inf [LibraryClasses.common.MM_STANDALONE] StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf @@ -555,6 +556,7 @@ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE gQemuPkgTokenSpaceGuid.PcdEnableMemoryProtection|$(MEMORY_PROTECTION) gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerLocator|TRUE + gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerAutoWrapEnable|TRUE [PcdsFeatureFlag.AARCH64] # @@ -603,7 +605,7 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0x0 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0x505 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0x258 - gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x190 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x260 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|0x5DC gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|0x2EE0 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|0x14 diff --git a/Silicon/Arm/MU_TIANO b/Silicon/Arm/MU_TIANO index e684179e..4e4f1724 160000 --- a/Silicon/Arm/MU_TIANO +++ b/Silicon/Arm/MU_TIANO @@ -1 +1 @@ -Subproject commit e684179ecef2f6b17f8c1c6d82ad1f9c70fcb668 +Subproject commit 4e4f1724a97002e3ec0603a4fa48117bd12e3d0e