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:dea6002d6e
24e6daa2bc
12d3d60f51
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 <michael.kubacki@microsoft.com>
This commit is contained in:
Родитель
a90e6be500
Коммит
98d7e84da4
|
@ -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:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 12f028aaa23f23d229bdb6b266f736f3ff928ac8
|
||||
Subproject commit c9d74b38897beb2993235ee14ef7fa86038c5e1d
|
|
@ -1 +1 @@
|
|||
Subproject commit f7eeee8b42a2bc8311cfae9b51ee28e4b62fc3be
|
||||
Subproject commit f29260e748abea574c714d25c8fb782b6f9317c7
|
|
@ -1 +1 @@
|
|||
Subproject commit 70722925361b7207d46f6c28feaef62d9c3b091f
|
||||
Subproject commit d83dfb8be497b3b1121934f754a8a67744e5de84
|
|
@ -1 +1 @@
|
|||
Subproject commit e0c16a86900a7a467067354b966c503e19bb034a
|
||||
Subproject commit cb08bb671806197fa57b14f34b8c449a82b1d7fa
|
|
@ -1 +1 @@
|
|||
Subproject commit d77131a0e26de78d9847a7a0bdfeca8d0993de87
|
||||
Subproject commit c6e7c62056882238ed28905bf148e271a94e005f
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "SnpPageStateChange.h"
|
||||
|
||||
#define IS_ALIGNED(x, y) ((((x) & (y - 1)) == 0))
|
||||
#define PAGES_PER_LARGE_ENTRY 512
|
||||
|
||||
STATIC
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e684179ecef2f6b17f8c1c6d82ad1f9c70fcb668
|
||||
Subproject commit 4e4f1724a97002e3ec0603a4fa48117bd12e3d0e
|
Загрузка…
Ссылка в новой задаче