summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c8
-rw-r--r--ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf2
-rw-r--r--ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.c2
-rwxr-xr-xBaseTools/Conf/tools_def.template48
-rw-r--r--DynamicTablesPkg/DynamicTables.dsc.inc1
-rw-r--r--DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h117
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c533
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf32
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c460
-rw-r--r--EmbeddedPkg/Include/Protocol/HardwareInterrupt2.h4
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi50.h34
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi66.h184
-rw-r--r--OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S3
-rw-r--r--OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc6
-rw-r--r--OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c33
-rw-r--r--SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c33
-rw-r--r--ShellPkg/Application/Shell/Shell.c8
-rw-r--r--UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf42
-rw-r--r--UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.uni13
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf13
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.c175
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.h57
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelper.c71
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelperSec.c42
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandler.h (renamed from UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.h)8
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandlerAsm.S (renamed from UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/SupervisorTrapHandler.S)2
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionLib.c (renamed from UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.c)18
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf9
-rw-r--r--UefiCpuPkg/Library/MpInitLib/AmdSev.c4
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c12
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h2
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm7
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c12
-rw-r--r--UefiCpuPkg/UefiCpuPkg.ci.yaml1
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dsc1
35 files changed, 1847 insertions, 150 deletions
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
index bf437af..afa3fc4 100644
--- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
+++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
@@ -37,11 +37,11 @@ SerialPortInitialize (
EFI_STATUS Status;
UINT8 Scratch;
- BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
+ BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
ReceiveFifoDepth = 0; // Use default FIFO depth
- Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
- DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
- StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
+ Parity = (EFI_PARITY_TYPE)PcdGet8 (PcdUartDefaultParity);
+ DataBits = PcdGet8 (PcdUartDefaultDataBits);
+ StopBits = (EFI_STOP_BITS_TYPE)PcdGet8 (PcdUartDefaultStopBits);
Status = PL011UartInitializePort (
(UINTN)PcdGet64 (PcdSerialRegisterBase),
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
index b6b87f3..07424cc 100644
--- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
@@ -33,7 +33,7 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
-[FixedPcd]
+[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
diff --git a/ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.c b/ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.c
index 60f9bc5..e8e2e1d 100644
--- a/ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.c
+++ b/ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.c
@@ -193,7 +193,7 @@ PL011UartInitializePort (
return RETURN_INVALID_PARAMETER;
}
- Divisor = (UartClkInHz * 4) / *BaudRate;
+ Divisor = (UINT32)((UartClkInHz * 4) / *BaudRate);
Integer = Divisor >> FRACTION_PART_SIZE_IN_BITS;
Fractional = Divisor & FRACTION_PART_MASK;
}
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 2108948..0caa1c9 100755
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -929,18 +929,15 @@ DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-
DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only
DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only
DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds
-DEFINE GCC_IA32_X64_DLINK_COMMON = -nostdlib --pie --fatal-warnings -z,noexecstack --gc-sections
-DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -Wl,--fatal-warnings -Wl,-z,noexecstack
+DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
DEFINE GCC_LOONGARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
DEFINE GCC_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) -z common-page-size=0x20 -Wl,--pic-veneer
DEFINE GCC_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) -z common-page-size=0x20
DEFINE GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_COMMON) -z common-page-size=0x20
DEFINE GCC_ARM_AARCH64_ASLDLINK_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(GCC_DLINK2_FLAGS_COMMON) -z common-page-size=0x20
-DEFINE GCC_IA32_X64_ASLDLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry _ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
DEFINE GCC_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS)
DEFINE GCC_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS)
DEFINE GCC_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
-DEFINE GCC_IA32_X64_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry _$(IMAGE_ENTRY_POINT) --file-alignment 0x20 --section-alignment 0x20 -Map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
DEFINE GCC_ASM_FLAGS = -c -x assembler -imacros AutoGen.h
DEFINE GCC_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h
DEFINE GCC_VFRPP_FLAGS = -x c -E -DVFRCOMPILE --include $(MODULE_NAME)StrDefs.h
@@ -1006,13 +1003,13 @@ DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS)
DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)
DEFINE GCC49_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS)
+DEFINE GCC5_DLINK_WARNING_FLAGS = -Wl,--fatal-warnings -Wl,-z,noexecstack -Wl,-z,notext
DEFINE GCC5_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS)
DEFINE GCC5_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS)
-DEFINE GCC5_IA32_X64_DLINK_COMMON = DEF(GCC49_IA32_X64_DLINK_COMMON)
-DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS)
-DEFINE GCC5_IA32_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS)
+DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
+DEFINE GCC5_IA32_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_IA32_DLINK2_FLAGS = DEF(GCC49_IA32_DLINK2_FLAGS) -Wno-error
-DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS)
+DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC49_X64_DLINK2_FLAGS) -Wno-error
DEFINE GCC5_ASM_FLAGS = DEF(GCC49_ASM_FLAGS)
DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC49_ARM_ASM_FLAGS)
@@ -1021,16 +1018,16 @@ DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS)
DEFINE GCC5_ARM_CC_XIPFLAGS = DEF(GCC49_ARM_CC_XIPFLAGS)
DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS)
DEFINE GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC49_AARCH64_CC_XIPFLAGS)
-DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS)
+DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_ARM_DLINK2_FLAGS = DEF(GCC49_ARM_DLINK2_FLAGS) -Wno-error
-DEFINE GCC5_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS)
+DEFINE GCC5_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_AARCH64_DLINK2_FLAGS = DEF(GCC49_AARCH64_DLINK2_FLAGS) -Wno-error
-DEFINE GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS)
-DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS)
+DEFINE GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
+DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -fno-lto
-DEFINE GCC5_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -msmall-data-limit=0
-DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40
+DEFINE GCC5_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-omit-frame-pointer -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -msmall-data-limit=0
+DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_RISCV_ALL_DLINK_FLAGS = DEF(GCC5_RISCV_ALL_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds
DEFINE GCC5_RISCV_ALL_ASM_FLAGS = -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h
@@ -1046,9 +1043,9 @@ DEFINE GCC5_RISCV64_DLINK2_FLAGS = DEF(GCC5_RISCV_ALL_DLINK2_FLAGS)
DEFINE GCC5_RISCV64_ASM_FLAGS = DEF(GCC5_RISCV_ALL_ASM_FLAGS) -march=DEF(GCC5_RISCV64_ARCH) -mcmodel=medany -mabi=lp64
DEFINE GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC_LOONGARCH64_CC_FLAGS) -march=loongarch64 -mno-memcpy -Werror -Wno-maybe-uninitialized -Wno-stringop-overflow -Wno-pointer-to-int-cast -no-pie -fno-stack-protector -mno-explicit-relocs
-DEFINE GCC5_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_FLAGS)
+DEFINE GCC5_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_LOONGARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x228
-DEFINE GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_ASLDLINK_FLAGS) DEF(GCC5_LOONGARCH64_DLINK2_FLAGS)
+DEFINE GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_ASLDLINK_FLAGS) DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) DEF(GCC5_DLINK_WARNING_FLAGS)
DEFINE GCC5_LOONGARCH64_ASM_FLAGS = -x assembler-with-cpp -mabi=lp64d -march=loongarch64 -fno-builtin -c -Wall -mno-explicit-relocs
DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF(GCC_PP_FLAGS)
@@ -2031,10 +2028,11 @@ DEFINE CLANGDWARF_X64_PREFIX = ENV(CLANG_BIN)
# LLVM/CLANG doesn't support -n link option. So, it can't share the same IA32_X64_DLINK_COMMON flag.
# LLVM/CLANG doesn't support common page size. So, it can't share the same GccBase.lds script.
-DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40
+DEFINE CLANGDWARF_DLINK_WARNING_FLAGS = -Wl,-z,notext
+DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40 DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
DEFINE CLANGDWARF_DLINK2_FLAGS_COMMON = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds
DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable
-DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -Wl,-z,notext
+DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive
DEFINE CLANGDWARF_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON)
DEFINE CLANGDWARF_X64_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON)
@@ -2121,7 +2119,7 @@ NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O0 -fu
##################
DEFINE CLANGDWARF_ARM_TARGET = -target arm-linux-gnueabi
DEFINE CLANGDWARF_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) DEF(CLANGDWARF_ARM_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES) -mno-movt -fno-stack-protector
-DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS)
+DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS) DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS)
*_CLANGDWARF_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
@@ -2165,7 +2163,7 @@ RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,
##################
DEFINE CLANGDWARF_AARCH64_TARGET = -target aarch64-linux-gnu
DEFINE CLANGDWARF_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -mcmodel=small DEF(CLANGDWARF_WARNING_OVERRIDES)
-DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000
+DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000 DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS)
*_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
@@ -2187,9 +2185,9 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_
*_CLANGDWARF_AARCH64_RC_PATH = ENV(CLANGDWARF_BIN)llvm-objcopy
*_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto
-*_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS)
+*_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) $(PLATFORM_FLAGS) -Qunused-arguments
-*_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000
+*_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000 DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
*_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x228
*_CLANGDWARF_AARCH64_PLATFORM_FLAGS =
@@ -2214,7 +2212,7 @@ DEFINE CLANGDWARF_RISCV64_CC_COMMON = DEF(GCC5_RISCV_ALL_CC_FLAGS) DEF(GCC5_RISC
DEFINE CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_COMMON) DEF(CLANGDWARF_RISCV64_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES)
# This is similar to GCC flags but without -n
-DEFINE CLANGDWARF_RISCV64_ALL_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40
+DEFINE CLANGDWARF_RISCV64_ALL_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40 DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
DEFINE CLANGDWARF_RISCV64_ALL_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_ALL_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map
DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(CLANGDWARF_RISCV64_ALL_DLINK_FLAGS) -Wl,-melf64lriscv,--oformat=elf64-littleriscv,--no-relax
@@ -2239,9 +2237,9 @@ DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF
*_CLANGDWARF_RISCV64_RC_PATH = ENV(CLANGDWARF_BIN)llvm-objcopy
*_CLANGDWARF_RISCV64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto
-*_CLANGDWARF_RISCV64_ASLDLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV32_RISCV64_ASLDLINK_FLAGS)
+*_CLANGDWARF_RISCV64_ASLDLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV32_RISCV64_ASLDLINK_FLAGS) DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_RISCV64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) -Qunused-arguments -mabi=lp64 -mno-relax
-*_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV64_DLINK_FLAGS)
+*_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV64_DLINK_FLAGS) DEF(CLANGDWARF_DLINK_WARNING_FLAGS)
*_CLANGDWARF_RISCV64_DLINK_XIPFLAGS = -z common-page-size=0x20
*_CLANGDWARF_RISCV64_DLINK2_FLAGS = DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x240
*_CLANGDWARF_RISCV64_PLATFORM_FLAGS =
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 371efe9..95b6407 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -67,6 +67,7 @@
DynamicTablesPkg/Library/Acpi/X64/AcpiMadtLib/AcpiMadtLib.inf
DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
+ DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
#
# Dynamic Table Factory Dxe
diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 9e294ac..a966148 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -2107,4 +2107,121 @@ AmlCreatePssNode (
OUT AML_OBJECT_NODE_HANDLE *NewPssNode OPTIONAL
);
+/** Code generation for the IRQ Descriptor.
+
+ The Resource Data effectively created is an IRQ Resource
+ Data. Cf ACPI 6.5 specification:
+ - s6.4.2.1 "IRQ Descriptor"
+ - s19.6.66 "IRQ (Interrupt Resource Descriptor Macro)"
+
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] IsEdgeTriggered The interrupt is edge triggered or
+ level triggered.
+ @param [in] IsActiveLow The interrupt is active-high or active-low.
+ @param [in] IsShared The interrupt can be shared with other
+ devices or not (Exclusive).
+ @param [in] IrqList List of IRQ numbers. Must be non-NULL.
+ @param [in] IrqCount Number of IRQs in IrqList. Must be > 0 and <= 16.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data node
+ to the list of resource data elements of this node.
+ @param [out] NewRdNode If provided and success, contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval various Other errors as indicated.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdIrq (
+ IN BOOLEAN IsEdgeTriggered,
+ IN BOOLEAN IsActiveLow,
+ IN BOOLEAN IsShared,
+ IN UINT8 *IrqList,
+ IN UINT8 IrqCount,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ );
+
+/** Code generation for the UARTSerialBusV2() ASL macro.
+
+ The Resource Data effectively created is a UART Serial Bus Connection
+ Resource Descriptor Resource Data.
+ Cf ACPI 6.5:
+ - s19.6.143 UARTSerialBusV2
+ (UART Serial Bus Connection Resource Descriptor Version 2 Macro)
+ - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] InitialBaudRate Initial baud rate.
+ @param [in] BitsPerByte Number of bits per byte.
+ Optional, default is 8.
+ @param [in] StopBits Number of stop bits.
+ Optional, default is 1.
+ @param [in] LinesInUse Number of lines in use.
+ @param [in] IsBigEndian Indicates whether the bit transfer is big-endian.
+ Optional, default is FALSE (little-endian).
+ @param [in] Parity Parity format used.
+ Optional, default is no parity.
+ @param [in] FlowControl Flow control protocol used.
+ Optional, default is no flow control.
+ @param [in] ReceiveBufferSize Size of the receive buffer.
+ @param [in] TransmitBufferSize Size of the transmit buffer.
+ @param [in] ResourceSource Name of source resource used.
+ @param [in] ResourceSourceLength Length of the Resource Source.
+ @param [in] ResourceSourceIndex Resource Source index.
+ Optional, default is 0.
+ @param [in] ResourceUsage Resource usage, TRUE for consumer,
+ FALSE for producer.
+ Optional, default is TRUE (consumer).
+ @param [in] IsShared Indicates whether the resource is shared.
+ Optional, default is FALSE (exclusive).
+ @param [in] VendorDefinedData Vendor defined data.
+ Optional, can be NULL.
+ @param [in] VendorDefinedDataLength Length of the vendor defined data.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data
+ node to the list of resource data elements
+ of this node.
+ @param [out] NewRdNode If provided and success,
+ contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval various Various failure values of called functions.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdUartSerialBusV2 (
+ IN UINT32 InitialBaudRate,
+ IN UINT8 *BitsPerByte OPTIONAL,
+ IN UINT8 *StopBits OPTIONAL,
+ IN UINT8 LinesInUse,
+ IN BOOLEAN *IsBigEndian OPTIONAL,
+ IN UINT8 *Parity OPTIONAL,
+ IN UINT8 *FlowControl OPTIONAL,
+ IN UINT16 ReceiveBufferSize,
+ IN UINT16 TransmitBufferSize,
+ IN CHAR8 *ResourceSource,
+ IN UINT16 ResourceSourceLength,
+ IN UINT8 *ResourceSourceIndex OPTIONAL,
+ IN BOOLEAN *ResourceUsage OPTIONAL,
+ IN BOOLEAN *IsShared OPTIONAL,
+ IN UINT8 *VendorDefinedData OPTIONAL,
+ IN UINT16 VendorDefinedDataLength,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ );
+
#endif // AML_LIB_H_
diff --git a/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c b/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
new file mode 100644
index 0000000..b6e7c46
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
@@ -0,0 +1,533 @@
+/** @file
+ SSDT Serial Port Fixup Library for X64.
+
+
+ Copyright (c) 2019 - 2024, Arm Limited. All rights reserved.<BR>
+ Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Arm Server Base Boot Requirements (SBBR), s4.2.1.8 "SPCR".
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+ - ACPI for Arm Components 1.0 - 2020
+ - Arm Generic Interrupt Controller Architecture Specification,
+ Issue H, January 2022.
+ (https://developer.arm.com/documentation/ihi0069/)
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** UART address range length.
+*/
+#define MIN_UART_ADDRESS_LENGTH 0x1000U
+
+/** Validate the Serial Port Information.
+
+ @param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
+ @param [in] SerialPortCount Count of SerialPort in the table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+ValidateSerialPortInfo (
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable,
+ IN UINT32 SerialPortCount
+ )
+{
+ UINT32 Index;
+ CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
+
+ if ((SerialPortInfoTable == NULL) ||
+ (SerialPortCount == 0))
+ {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < SerialPortCount; Index++) {
+ SerialPortInfo = &SerialPortInfoTable[Index];
+ ASSERT (SerialPortInfo != NULL);
+
+ if ((SerialPortInfo == NULL) ||
+ (SerialPortInfo->BaseAddress == 0))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: UART port base address is invalid. BaseAddress = 0x%llx\n",
+ SerialPortInfo->BaseAddress
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: UART port subtype is invalid."
+ " UART Base = 0x%llx, PortSubtype = 0x%x\n",
+ SerialPortInfo->BaseAddress,
+ SerialPortInfo->PortSubtype
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "UART Configuration:\n"));
+ DEBUG ((
+ DEBUG_INFO,
+ " UART Base = 0x%llx\n",
+ SerialPortInfo->BaseAddress
+ ));
+ DEBUG ((
+ DEBUG_INFO,
+ " Length = 0x%llx\n",
+ SerialPortInfo->BaseAddressLength
+ ));
+ DEBUG ((DEBUG_INFO, " Clock = %lu\n", SerialPortInfo->Clock));
+ DEBUG ((DEBUG_INFO, " BaudRate = %llu\n", SerialPortInfo->BaudRate));
+ DEBUG ((DEBUG_INFO, " Interrupt = %lu\n", SerialPortInfo->Interrupt));
+ } // for
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create the _CRS (Current Resource Settings) AML node for a serial port device.
+
+ @param [in] SerialPortInfo Pointer to the serial port information structure.
+ @param [in] Name The Name to give to the Device.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ @param [in] DeviceNode AML device node handle.
+
+ @retval EFI_SUCCESS The CRS node was created successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval Others Failed to create CRS node.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateSerialPortCrs (
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name,
+ IN AML_OBJECT_NODE_HANDLE DeviceNode
+ )
+{
+ AML_OBJECT_NODE_HANDLE CrsNode;
+ EFI_STATUS Status;
+ UINT8 IrqList[1];
+
+ Status = AmlCodeGenNameResourceTemplate ("_CRS", DeviceNode, &CrsNode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML _CRS Node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ IrqList[0] = SerialPortInfo->Interrupt & MAX_UINT8;
+
+ if (SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550) {
+ Status = AmlCodeGenRdIo (
+ TRUE,
+ SerialPortInfo->BaseAddress & MAX_UINT16,
+ SerialPortInfo->BaseAddress & MAX_UINT16,
+ 1,
+ 0x8,
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to generate IO RD node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ //
+ // Generate the IRQ() ASL macro.
+ // This is used for legacy X86/X64/PC-AT compatible systems.
+ //
+ Status = AmlCodeGenRdIrq (
+ TRUE,
+ TRUE,
+ TRUE,
+ IrqList,
+ ARRAY_SIZE (IrqList),
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to generate IRQ RD node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ //
+ // Generate the UARTSerialBusV2() ASL macro.
+ // This describes legacy COM port resources for X86/X64/PC-AT compatible systems.
+ //
+ Status = AmlCodeGenRdUartSerialBusV2 (
+ SerialPortInfo->BaudRate & MAX_UINT32, // BaudRate
+ NULL, // Default 8 Bits Per Byte
+ NULL, // Default 1 Stop Bit
+ 0, // Lines in Use
+ NULL, // Default is little endian
+ NULL, // Default is no parity
+ NULL, // Default is no flow control
+ 0x1, // ReceiveBufferSize
+ 0x1, // TransmitBufferSize
+ (CHAR8 *)Name, // Serial Port Name
+ (AsciiStrLen (Name) + 1) & MAX_UINT16, // Serial Port Name Length
+ NULL, // Default resource index is zero
+ NULL, // Default is consumer
+ NULL, // Default is exclusive
+ NULL, // vendor defined data
+ 0, // VendorDefinedDataLength
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to generate UartSerialBus RD node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ if (SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS) {
+ Status = AmlCodeGenRdMemory32Fixed (
+ TRUE,
+ SerialPortInfo->BaseAddress & MAX_UINT32,
+ ((SerialPortInfo->BaseAddressLength > MIN_UART_ADDRESS_LENGTH)
+ ? SerialPortInfo->BaseAddressLength
+ : MIN_UART_ADDRESS_LENGTH) & MAX_UINT32,
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to generate MMIO RD node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ Status = AmlCodeGenRdIrq (
+ TRUE,
+ TRUE,
+ TRUE,
+ IrqList,
+ 1,
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to generate IRQ RD node."
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Build a SSDT table describing the input serial port.
+
+ The table created by this function must be freed by FreeSsdtSerialTable.
+
+ @param [in] AcpiTableInfo Pointer to the ACPI table information.
+ @param [in] SerialPortInfo Serial port to describe in the SSDT table.
+ @param [in] Name The Name to give to the Device.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ @param [in] Uid UID for the Serial Port.
+ @param [out] Table If success, pointer to the created SSDT table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+BuildSsdtSerialPortTable (
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ )
+{
+ AML_OBJECT_NODE_HANDLE DeviceNode;
+ AML_OBJECT_NODE_HANDLE ScopeNode;
+ AML_ROOT_NODE_HANDLE RootNode;
+ CONST CHAR8 *NonBsaHid;
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINT32 EisaId;
+
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (SerialPortInfo != NULL);
+ ASSERT (Name != NULL);
+ ASSERT (Table != NULL);
+
+ // Validate the Serial Port Info.
+ Status = ValidateSerialPortInfo (SerialPortInfo, 1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = AmlCodeGenDefinitionBlock (
+ "SSDT",
+ "AMDINC",
+ "SERIAL",
+ 0x01,
+ &RootNode
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML Definition Block."
+ " Status = %r\n",
+ Status
+ ));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlCodeGenScope ("\\_SB_", RootNode, &ScopeNode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML Scope Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ // Create the Device Node, COMx, where x is the Uid.
+ Status = AmlCodeGenDevice (Name, ScopeNode, &DeviceNode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML Device Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ NonBsaHid = (CONST CHAR8 *)PcdGetPtr (PcdNonBsaCompliant16550SerialHid);
+ if (SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS) {
+ if ((NonBsaHid != NULL) && (AsciiStrLen (NonBsaHid) != 0)) {
+ if (!(IsValidPnpId (NonBsaHid) || IsValidAcpiId (NonBsaHid))) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Invalid Supplied HID %a.\n",
+ NonBsaHid
+ ));
+ goto exit_handler;
+ }
+
+ Status = AmlCodeGenNameString (
+ "_HID",
+ NonBsaHid,
+ DeviceNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML _HID Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+ }
+ }
+
+ if ((SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_FULL_16550) ||
+ ((SerialPortInfo->PortSubtype == EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS) &&
+ ((NonBsaHid == NULL) || (AsciiStrLen (NonBsaHid) == 0))))
+ {
+ Status = AmlGetEisaIdFromString ("PNP0501", &EisaId);
+ if (EFI_ERROR (Status)) {
+ goto exit_handler;
+ }
+
+ Status = AmlCodeGenNameInteger ("_HID", EisaId, DeviceNode, NULL);
+ if (EFI_ERROR (Status)) {
+ goto exit_handler;
+ }
+
+ Status = AmlGetEisaIdFromString ("PNP0500", &EisaId);
+ if (EFI_ERROR (Status)) {
+ goto exit_handler;
+ }
+
+ Status = AmlCodeGenNameInteger ("_CID", EisaId, DeviceNode, NULL);
+ if (EFI_ERROR (Status)) {
+ goto exit_handler;
+ }
+ }
+
+ // _UID
+ Status = AmlCodeGenNameInteger ("_UID", Uid, DeviceNode, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML _UID Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ // _DDN
+ Status = AmlCodeGenNameString ("_DDN", Name, DeviceNode, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML _DDN Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ // _STA
+ Status = AmlCodeGenMethodRetInteger (
+ "_STA",
+ 0x0F,
+ 0,
+ FALSE,
+ 0,
+ DeviceNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create AML _STA Node."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ Status = CreateSerialPortCrs (SerialPortInfo, Name, DeviceNode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to create _CRS for Serial Port."
+ " Status = %r\n",
+ Status
+ ));
+ goto exit_handler;
+ }
+
+ // Serialize the tree.
+ Status = AmlSerializeDefinitionBlock (
+ RootNode,
+ Table
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to Serialize SSDT Table Data."
+ " Status = %r\n",
+ Status
+ ));
+ }
+
+ return EFI_SUCCESS;
+
+exit_handler:
+ // Cleanup
+ if (RootNode != NULL) {
+ Status1 = AmlDeleteTree (RootNode);
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-SERIAL-PORT-FIXUP: Failed to cleanup AML tree."
+ " Status = %r\n",
+ Status1
+ ));
+ // If Status was success but we failed to delete the AML Tree
+ // return Status1 else return the original error code, i.e. Status.
+ if (!EFI_ERROR (Status)) {
+ return Status1;
+ }
+ }
+ }
+
+ return Status;
+}
+
+/** Free an SSDT table previously created by
+ the BuildSsdtSerialTable function.
+
+ @param [in] Table Pointer to a SSDT table allocated by
+ the BuildSsdtSerialTable function.
+
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+FreeSsdtSerialPortTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Table
+ )
+{
+ ASSERT (Table != NULL);
+ FreePool (Table);
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf b/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
new file mode 100644
index 0000000..73ae99b
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
@@ -0,0 +1,32 @@
+## @file
+# SSDT Serial Port fixup Library
+#
+# Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = DynamicSsdtSerialPortFixupLib
+ FILE_GUID = 83F367CE-9EA3-4A5B-B61F-60E06CA7D9FF
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = SsdtSerialPortFixupLib
+
+[Sources]
+ SsdtSerialPortFixupLib.c
+
+[Packages.common]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ AcpiHelperLib
+ AmlLib
+ BaseLib
+
+[Pcd]
+ gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdNonBsaCompliant16550SerialHid
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index bf0d7b0..8be5eab 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -2,7 +2,7 @@
AML Resource Data Code Generation.
Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
- Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (C) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1670,3 +1670,461 @@ error_handler:
return Status;
}
+
+/** Code generation for the IRQ Descriptor.
+
+ The Resource Data effectively created is an IRQ Resource
+ Data. Cf ACPI 6.5 specification:
+ - s6.4.2.1 "IRQ Descriptor"
+ - s19.6.66 "IRQ (Interrupt Resource Descriptor Macro)"
+
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] IsEdgeTriggered The interrupt is edge triggered or
+ level triggered.
+ @param [in] IsActiveLow The interrupt is active-high or active-low.
+ @param [in] IsShared The interrupt can be shared with other
+ devices or not (Exclusive).
+ @param [in] IrqList List of IRQ numbers. Must be non-NULL.
+ @param [in] IrqCount Number of IRQs in IrqList. Must be > 0 and <= 16.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data node
+ to the list of resource data elements of this node.
+ @param [out] NewRdNode If provided and success, contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval various Other errors as indicated.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdIrq (
+ IN BOOLEAN IsEdgeTriggered,
+ IN BOOLEAN IsActiveLow,
+ IN BOOLEAN IsShared,
+ IN UINT8 *IrqList,
+ IN UINT8 IrqCount,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ )
+{
+ AML_DATA_NODE *RdNode;
+ EFI_ACPI_IRQ_DESCRIPTOR IrqDesc;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT16 Mask;
+
+ if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((IsEdgeTriggered && !IsActiveLow) ||
+ (!IsEdgeTriggered && IsActiveLow))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((IrqList == NULL) || (IrqCount == 0) || (IrqCount > 16)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Mask = 0;
+ for (Index = 0; Index < IrqCount; Index++) {
+ if (IrqList[Index] > 16) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Mask & (1 << IrqList[Index])) != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Mask |= (1 << IrqList[Index]);
+ }
+
+ if (Mask == 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IrqDesc.Header.Bits.Type = ACPI_SMALL_ITEM_FLAG;
+ IrqDesc.Header.Bits.Name = ACPI_SMALL_IRQ_DESCRIPTOR_NAME;
+ IrqDesc.Header.Bits.Length = sizeof (EFI_ACPI_IRQ_DESCRIPTOR) -
+ sizeof (ACPI_SMALL_RESOURCE_HEADER);
+ IrqDesc.Mask = Mask;
+ IrqDesc.Information = (IsEdgeTriggered ? BIT0 : 0) |
+ (IsActiveLow ? BIT3 : 0) |
+ (IsShared ? BIT4 : 0);
+
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeResourceData,
+ (UINT8 *)&IrqDesc,
+ sizeof (EFI_ACPI_IRQ_DESCRIPTOR),
+ &RdNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ return LinkRdNode (RdNode, NameOpNode, NewRdNode);
+}
+
+/** Code generation for the UART Serial Bus Connection Resource Descriptor.
+
+ The Resource Data effectively created is a UART Serial Bus Connection
+ Resource Descriptor Resource Data.
+ Cf ACPI 6.5:
+ - s19.6.143 UARTSerialBusV2
+ (UART Serial Bus Connection Resource Descriptor Version 2 Macro)
+ - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] IsResourceConsumer ResourceUsage parameter.
+ @param [in] IsSlaveMode Indicates whether the uart operates in slave mode.
+ @param [in] IsBigEndian Indicates whether the bit transfer is big-endian.
+ @param [in] BitsPerByte Indicates the number of bits per byte.
+ @param [in] StopBits Specifies the stop bits format used.
+ @param [in] FlowControl Specifies the flow control protocol used.
+ @param [in] BaudRate Specifies the baud rate.
+ @param [in] RxFifo Number of bytes in the receiver FIFO.
+ @param [in] TxFifo Number of bytes in the transmitter FIFO.
+ @param [in] Parity Specifies the parity format used.
+ @param [in] SerialLinesEnabled Specifies which serial lines are enabled.
+ @param [in] VendorDefinedData VendorDefinedData parameter.
+ @param [in] VendorDefinedDataLength VendorDefinedDataLength parameter.
+ @param [in] ResourceSource Name of source resource used.
+ @param [in] ResourceSourceLength Resource Source Length.
+ @param [in] NameOpNode NameOpNode object node defining a named object.
+ If provided, append the new resource data
+ node to the list of resource data elements
+ of this node.
+ @param [out] NewRdNode If provided and success,
+ contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+ @retval various Other errors as indicated.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdUartSerialBus (
+ IN BOOLEAN IsResourceConsumer,
+ IN BOOLEAN IsSlaveMode,
+ IN BOOLEAN IsBigEndian,
+ IN UINT8 BitsPerByte,
+ IN UINT8 StopBits,
+ IN UINT8 FlowControl,
+ IN UINT32 BaudRate,
+ IN UINT16 RxFifo,
+ IN UINT16 TxFifo,
+ IN UINT8 Parity,
+ IN UINT8 SerialLinesEnabled,
+ IN UINT8 *VendorDefinedData OPTIONAL,
+ IN UINT16 VendorDefinedDataLength,
+ IN CHAR8 *ResourceSource,
+ IN UINT16 ResourceSourceLength,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ )
+{
+ AML_DATA_NODE *RdNode;
+ EFI_STATUS Status;
+ UINT16 UartDescBuffLength;
+ UINT8 *UartDescBuff;
+ UINT8 BitsPerByteMask;
+
+ EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR UartDesc;
+
+ if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) ||
+ ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0)))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (StopBits > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_2) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FlowControl > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_XON_XOFF) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Parity > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_SPACE) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (BitsPerByte) {
+ case 5:
+ BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_5_BITS_PER_BYTE;
+ break;
+ case 6:
+ BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_6_BITS_PER_BYTE;
+ break;
+ case 7:
+ BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_7_BITS_PER_BYTE;
+ break;
+ case 8:
+ BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_8_BITS_PER_BYTE;
+ break;
+ case 9:
+ BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_9_BITS_PER_BYTE;
+ break;
+ default:
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /// as per spec last two bits are reserved and must be 0.
+ if ((SerialLinesEnabled &
+ ~(EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RTS |
+ EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_CTS |
+ EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTR |
+ EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DSR |
+ EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RI |
+ EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTD)) != 0)
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UartDesc.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
+ UartDesc.Header.Header.Bits.Name = ACPI_LARGE_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR_NAME;
+ UartDesc.RevisionId = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID;
+ UartDesc.ResourceSourceIndex = 0;
+ UartDesc.SerialBusType = EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_UART;
+ UartDesc.GeneralFlags = (IsResourceConsumer ? BIT1 : 0) |
+ (IsSlaveMode ? BIT0 : 0);
+ UartDesc.TypeSpecificFlags = (IsBigEndian ? BIT7 : 0) |
+ (BitsPerByteMask << 4) |
+ (StopBits << 2) |
+ (FlowControl);
+ UartDesc.TypeSpecificRevisionId = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID;
+ /// TypeDataLength is the length of the data following the TypeDataLength,
+ /// up to the Additional vendor supplied data (not included).
+ UartDesc.TypeDataLength = sizeof (UartDesc.DefaultBaudRate) +
+ sizeof (UartDesc.RxFIFO) +
+ sizeof (UartDesc.TxFIFO) +
+ sizeof (UartDesc.Parity) +
+ sizeof (UartDesc.SerialLinesEnabled) +
+ VendorDefinedDataLength;
+ UartDesc.DefaultBaudRate = BaudRate;
+ UartDesc.RxFIFO = RxFifo;
+ UartDesc.TxFIFO = TxFifo;
+ UartDesc.Parity = Parity;
+ UartDesc.SerialLinesEnabled = SerialLinesEnabled;
+
+ UartDescBuffLength = sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) +
+ VendorDefinedDataLength +
+ ResourceSourceLength;
+
+ UartDesc.Header.Length = UartDescBuffLength - sizeof (ACPI_LARGE_RESOURCE_HEADER);
+
+ UartDescBuff = AllocateZeroPool (UartDescBuffLength);
+ if (UartDescBuff == NULL) {
+ ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (
+ UartDescBuff,
+ &UartDesc,
+ sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR)
+ );
+
+ if (VendorDefinedData != NULL) {
+ CopyMem (
+ UartDescBuff + sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR),
+ VendorDefinedData,
+ VendorDefinedDataLength
+ );
+ }
+
+ CopyMem (
+ UartDescBuff +
+ sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) +
+ VendorDefinedDataLength,
+ ResourceSource,
+ ResourceSourceLength
+ );
+
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeResourceData,
+ UartDescBuff,
+ UartDescBuffLength,
+ &RdNode
+ );
+ FreePool (UartDescBuff);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ return LinkRdNode (RdNode, NameOpNode, NewRdNode);
+}
+
+/** Code generation for the UARTSerialBusV2() ASL macro.
+
+ The Resource Data effectively created is a UART Serial Bus Connection
+ Resource Descriptor Resource Data.
+ Cf ACPI 6.5:
+ - s19.6.143 UARTSerialBusV2
+ (UART Serial Bus Connection Resource Descriptor Version 2 Macro)
+ - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] InitialBaudRate Initial baud rate.
+ @param [in] BitsPerByte Number of bits per byte.
+ Optional, default is 8.
+ @param [in] StopBits Number of stop bits.
+ Optional, default is 1.
+ @param [in] LinesInUse Number of lines in use.
+ @param [in] IsBigEndian Indicates whether the bit transfer is big-endian.
+ Optional, default is FALSE (little-endian).
+ @param [in] Parity Parity format used.
+ Optional, default is no parity.
+ @param [in] FlowControl Flow control protocol used.
+ Optional, default is no flow control.
+ @param [in] ReceiveBufferSize Size of the receive buffer.
+ @param [in] TransmitBufferSize Size of the transmit buffer.
+ @param [in] ResourceSource Name of source resource used.
+ @param [in] ResourceSourceLength Length of the Resource Source.
+ @param [in] ResourceSourceIndex Resource Source index.
+ Optional, default is 0.
+ @param [in] ResourceUsage Resource usage, TRUE for consumer,
+ FALSE for producer.
+ Optional, default is TRUE (consumer).
+ @param [in] IsShared Indicates whether the resource is shared.
+ Optional, default is FALSE (exclusive).
+ @param [in] VendorDefinedData Vendor defined data.
+ Optional, can be NULL.
+ @param [in] VendorDefinedDataLength Length of the vendor defined data.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data
+ node to the list of resource data elements
+ of this node.
+ @param [out] NewRdNode If provided and success,
+ contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval various Various failure values of called functions.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdUartSerialBusV2 (
+ IN UINT32 InitialBaudRate,
+ IN UINT8 *BitsPerByte OPTIONAL,
+ IN UINT8 *StopBits OPTIONAL,
+ IN UINT8 LinesInUse,
+ IN BOOLEAN *IsBigEndian OPTIONAL,
+ IN UINT8 *Parity OPTIONAL,
+ IN UINT8 *FlowControl OPTIONAL,
+ IN UINT16 ReceiveBufferSize,
+ IN UINT16 TransmitBufferSize,
+ IN CHAR8 *ResourceSource,
+ IN UINT16 ResourceSourceLength,
+ IN UINT8 *ResourceSourceIndex OPTIONAL,
+ IN BOOLEAN *ResourceUsage OPTIONAL,
+ IN BOOLEAN *IsShared OPTIONAL,
+ IN UINT8 *VendorDefinedData OPTIONAL,
+ IN UINT16 VendorDefinedDataLength,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode OPTIONAL,
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) ||
+ ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0)))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ResourceSourceIndex != NULL) {
+ if (*ResourceSourceIndex != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ Status = AmlCodeGenRdUartSerialBus (
+ /// default is resource consumer
+ (ResourceUsage != NULL) ? *ResourceUsage : TRUE,
+ /// slave mode
+ TRUE,
+ /// default is little-endian
+ (IsBigEndian != NULL) ? *IsBigEndian : FALSE,
+ /// default is 8 bits per byte
+ (BitsPerByte != NULL) ? *BitsPerByte : 8,
+ /// default is 1 stop bit
+ (StopBits != NULL) ? *StopBits : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_1,
+ /// default is no flow control
+ (FlowControl != NULL) ? *FlowControl : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_NONE,
+ InitialBaudRate,
+ ReceiveBufferSize,
+ TransmitBufferSize,
+ /// default is no parity
+ (Parity != NULL) ? *Parity : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_NONE,
+ LinesInUse,
+ VendorDefinedData,
+ VendorDefinedDataLength,
+ ResourceSource,
+ ResourceSourceLength,
+ NameOpNode,
+ NewRdNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ return Status;
+}
diff --git a/EmbeddedPkg/Include/Protocol/HardwareInterrupt2.h b/EmbeddedPkg/Include/Protocol/HardwareInterrupt2.h
index d017a9e..d5b2f15 100644
--- a/EmbeddedPkg/Include/Protocol/HardwareInterrupt2.h
+++ b/EmbeddedPkg/Include/Protocol/HardwareInterrupt2.h
@@ -11,10 +11,10 @@
#include <Protocol/HardwareInterrupt.h>
-// 22838932-1a2d-4a47-aaba-f3f7cf569470
+// 32898322-2da1-474a-baaa-f3f7cf569470
#define EFI_HARDWARE_INTERRUPT2_PROTOCOL_GUID \
- { 0x32898322, 0x2d1a, 0x474a, \
+ { 0x32898322, 0x2da1, 0x474a, \
{ 0xba, 0xaa, 0xf3, 0xf7, 0xcf, 0x56, 0x94, 0x70 } }
typedef enum {
diff --git a/MdePkg/Include/IndustryStandard/Acpi50.h b/MdePkg/Include/IndustryStandard/Acpi50.h
index c98c35f..dd96ab5 100644
--- a/MdePkg/Include/IndustryStandard/Acpi50.h
+++ b/MdePkg/Include/IndustryStandard/Acpi50.h
@@ -132,6 +132,40 @@ typedef PACKED struct {
UINT16 DeviceSelection;
} EFI_ACPI_SERIAL_BUS_RESOURCE_SPI_DESCRIPTOR;
+/// Revision ID of serial bus uart descriptor
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID 0x1
+
+/// Type specific flags
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_LITTLE_ENDIAN 0x0
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_BIG_ENDIAN 0x1
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_5_BITS_PER_BYTE 0x0
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_6_BITS_PER_BYTE 0x1
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_7_BITS_PER_BYTE 0x2
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_8_BITS_PER_BYTE 0x3
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_9_BITS_PER_BYTE 0x4
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_NONE 0x0
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_1 0x1
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_1_5 0x2
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_2 0x3
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_NONE 0x0
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_HW 0x1
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_XON_XOFF 0x2
+
+/// Parity definitions
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_NONE 0x0
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_EVEN 0x1
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_ODD 0x2
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_MARK 0x3
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_SPACE 0x4
+
+/// Serial lines in use bits
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RTS BIT7
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_CTS BIT6
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTR BIT5
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DSR BIT4
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RI BIT3
+#define EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTD BIT2
+
///
/// Serial Bus Resource Descriptor (UART)
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi66.h b/MdePkg/Include/IndustryStandard/Acpi66.h
index b951668..b7bc8ea 100644
--- a/MdePkg/Include/IndustryStandard/Acpi66.h
+++ b/MdePkg/Include/IndustryStandard/Acpi66.h
@@ -206,7 +206,7 @@ typedef struct {
/// FADT Version (as defined in ACPI 6.6 spec.)
///
#define EFI_ACPI_6_6_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x06
-#define EFI_ACPI_6_6_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x05
+#define EFI_ACPI_6_6_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION 0x06
//
// Fixed ACPI Description Table Preferred Power Management Profile
@@ -324,7 +324,7 @@ typedef struct {
///
/// MADT Revision (as defined in ACPI 6.6 spec.)
///
-#define EFI_ACPI_6_6_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x06
+#define EFI_ACPI_6_6_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x07
///
/// Multiple APIC Flags
@@ -361,6 +361,10 @@ typedef struct {
#define EFI_ACPI_6_6_MSI_PIC 0x15
#define EFI_ACPI_6_6_BIO_PIC 0x16
#define EFI_ACPI_6_6_LPC_PIC 0x17
+#define EFI_ACPI_6_6_RINTC 0x18
+#define EFI_ACPI_6_6_IMSIC 0x19
+#define EFI_ACPI_6_6_APLIC 0x1A
+#define EFI_ACPI_6_6_PLIC 0x1B
//
// APIC Structure Definitions
@@ -746,6 +750,83 @@ typedef struct {
} EFI_ACPI_6_6_LPC_PIC_STRUCTURE;
///
+/// RISC-V INTC (RINTC)
+///
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Version;
+ UINT8 Reserved;
+ UINT32 Flags;
+ UINT64 HartId;
+ UINT32 Uid;
+ UINT32 ExtIntcId;
+ UINT64 ImsicAddr;
+ UINT32 ImsicSize;
+} EFI_ACPI_6_6_RINTC_STRUCTURE;
+
+#define EFI_ACPI_6_6_RINTC_STRUCTURE_VERSION 1
+
+#define EFI_ACPI_6_6_RINTC_FLAG_ENABLE 1
+
+///
+/// RISC-V Incoming MSI Controller (IMSIC)
+///
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Version;
+ UINT8 Reserved;
+ UINT32 Flags;
+ UINT16 NumIds;
+ UINT16 NumGuestIds;
+ UINT8 GuestIndexBits;
+ UINT8 HartIndexBits;
+ UINT8 GroupIndexBits;
+ UINT8 GroupIndexShift;
+} EFI_ACPI_6_6_IMSIC_STRUCTURE;
+
+#define EFI_ACPI_6_6_IMSIC_STRUCTURE_VERSION 1
+
+///
+/// RISC-V APLIC
+///
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Version;
+ UINT8 Id;
+ UINT32 Flags;
+ UINT8 HwId[8];
+ UINT16 NumIdcs;
+ UINT16 NumSources;
+ UINT32 GsiBase;
+ UINT64 BaseAddr;
+ UINT32 Size;
+} EFI_ACPI_6_6_APLIC_STRUCTURE;
+
+#define EFI_ACPI_6_6_APLIC_STRUCTURE_VERSION 1
+
+///
+/// RISC-V PLIC
+///
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Version;
+ UINT8 Id;
+ UINT8 HwId[8];
+ UINT16 NumIrqs;
+ UINT16 MaxPrio;
+ UINT32 Flags;
+ UINT32 Size;
+ UINT64 BaseAddr;
+ UINT32 GsiBase;
+} EFI_ACPI_6_6_PLIC_STRUCTURE;
+
+#define EFI_ACPI_6_6_PLIC_STRUCTURE_VERSION 1
+
+///
/// Smart Battery Description Table (SBST)
///
typedef struct {
@@ -804,6 +885,8 @@ typedef struct {
#define EFI_ACPI_6_6_GICC_AFFINITY 0x03
#define EFI_ACPI_6_6_GIC_ITS_AFFINITY 0x04
#define EFI_ACPI_6_6_GENERIC_INITIATOR_AFFINITY 0x05
+#define EFI_ACPI_6_6_GENERIC_PORT_AFFINITY 0x06
+#define EFI_ACPI_6_6_RINTC_AFFINITY 0x07
///
/// Processor Local APIC/SAPIC Affinity Structure Definition
@@ -890,6 +973,19 @@ typedef struct {
UINT32 ItsId;
} EFI_ACPI_6_6_GIC_ITS_AFFINITY_STRUCTURE;
+///
+/// RINTC Affinity Structure Definition
+///
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Reserved;
+ UINT32 ProximityDomain;
+ UINT32 AcpiProcessorUid;
+ UINT32 Flags;
+ UINT32 ClockDomain;
+} EFI_ACPI_6_6_RINTC_AFFINITY_STRUCTURE;
+
//
// Generic Initiator Affinity Structure Device Handle Types
// All other values between 0x02 an 0xFF are reserved and
@@ -3024,6 +3120,86 @@ typedef struct {
#define EFI_ACPI_6_6_PHAT_RESET_REASON_REASON_POWER_LOSS 0x24
#define EFI_ACPI_6_6_PHAT_RESET_REASON_REASON_POWER_BUTTON 0x25
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 Flags;
+ UINT64 TimeBaseFreq;
+ UINT32 NodeCount;
+ UINT32 NodeOffset;
+} EFI_ACPI_6_6_RISCV_HART_CAPABILITIES_TABLE;
+
+#define EFI_ACPI_6_6_RHCT_TABLE_REVISION 1
+//
+// RHCT Flags
+//
+#define EFI_ACPI_6_6_RHCT_FLAG_TIMER_CANNOT_WAKEUP_CPU 1
+
+//
+// RHCT subtables
+//
+typedef struct {
+ UINT16 Type;
+ UINT16 Length;
+ UINT16 Revision;
+} EFI_ACPI_6_6_RHCT_NODE_HEADER;
+
+/* Values for RHCT subtable Type above */
+#define EFI_ACPI_6_6_RHCT_NODE_TYPE_ISA_STRING 0x0000
+#define EFI_ACPI_6_6_RHCT_NODE_TYPE_CMO 0x0001
+#define EFI_ACPI_6_6_RHCT_NODE_TYPE_MMU 0x0002
+#define EFI_ACPI_6_6_RHCT_NODE_TYPE_HART_INFO 0xFFFF
+
+//
+// ISA string node structure
+//
+typedef struct {
+ EFI_ACPI_6_6_RHCT_NODE_HEADER Node;
+ UINT16 IsaLength;
+ char Isa[];
+} EFI_ACPI_6_6_RHCT_ISA_STRING_NODE;
+
+#define EFI_ACPI_6_6_RHCT_ISA_NODE_STRUCTURE_VERSION 1
+
+//
+// CMO node structure
+//
+typedef struct {
+ EFI_ACPI_6_6_RHCT_NODE_HEADER Node;
+ UINT8 Reserved;
+ UINT8 CbomBlockSize;
+ UINT8 CbopBlockSize;
+ UINT8 CbozBlockSize;
+} EFI_ACPI_6_6_RHCT_CMO_NODE;
+
+#define EFI_ACPI_6_6_RHCT_CMO_NODE_STRUCTURE_VERSION 1
+
+//
+// MMU node structure
+//
+typedef struct {
+ EFI_ACPI_6_6_RHCT_NODE_HEADER Node;
+ UINT8 Reserved;
+ UINT8 MmuType;
+} EFI_ACPI_6_6_RHCT_MMU_NODE;
+
+#define EFI_ACPI_6_6_RHCT_MMU_NODE_STRUCTURE_VERSION 1
+
+#define EFI_ACPI_6_6_RHCT_MMU_TYPE_SV39 0
+#define EFI_ACPI_6_6_RHCT_MMU_TYPE_SV48 1
+#define EFI_ACPI_6_6_RHCT_MMU_TYPE_SV57 2
+
+//
+// Hart Info node structure
+//
+typedef struct {
+ EFI_ACPI_6_6_RHCT_NODE_HEADER Node;
+ UINT16 NumOffsets;
+ UINT32 Uid;
+ UINT32 Offsets[];
+} EFI_ACPI_6_6_RHCT_HART_INFO_NODE;
+
+#define EFI_ACPI_6_6_RHCT_HART_INFO_NODE_STRUCTURE_VERSION 1
+
//
// Known table signatures
//
@@ -3284,6 +3460,10 @@ typedef struct {
#define EFI_ACPI_6_6_PLATFORM_HEALTH_ASSESSMENT_TABLE_SIGNATURE SIGNATURE_32('P', 'H', 'A', 'T')
///
+/// "RHCT" RISC-V Hart Capabilities Table (RHCT)
+///
+#define EFI_ACPI_6_6_RISCV_HART_CAPABILITIES_TABLE_SIGNATURE SIGNATURE_32('R', 'H', 'C', 'T')
+///
/// "SDEI" Software Delegated Exceptions Interface Table
///
#define EFI_ACPI_6_6_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE SIGNATURE_32('S', 'D', 'E', 'I')
diff --git a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S
index de42a90..b52becd 100644
--- a/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S
+++ b/OvmfPkg/RiscVVirt/Library/PlatformSecLib/SecEntry.S
@@ -8,6 +8,9 @@
#include "PlatformSecLib.h"
ASM_FUNC (_ModuleEntryPoint)
+/* Prevent stack unwinding from going further */
+li s0, 0
+
/* Use Temp memory as the stack for calling to C code */
li a2, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)
li a3, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
index 4c3eff7..47248f2 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
@@ -79,7 +79,6 @@
!endif
# RISC-V Architectural Libraries
- CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
RiscVMmuLib|UefiCpuPkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf
PlatformBootManagerLib|OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -153,6 +152,7 @@
PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -163,6 +163,7 @@
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -174,16 +175,19 @@
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
[LibraryClasses.common.DXE_CORE]
PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.DXE_DRIVER]
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
index 5287cda..8547c76 100644
--- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
+++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
@@ -806,6 +806,7 @@ TdGetEventLog (
@retval FALSE This is NOT a Tcg800155PlatformIdEvent.
**/
+STATIC
BOOLEAN
Is800155Event (
IN VOID *NewEventHdr,
@@ -814,18 +815,26 @@ Is800155Event (
IN UINT32 NewEventSize
)
{
- if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&
- (NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
- ((CompareMem (
- NewEventData,
- TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
- sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
- ) == 0) ||
- (CompareMem (
- NewEventData,
- TCG_Sp800_155_PlatformId_Event3_SIGNATURE,
- sizeof (TCG_Sp800_155_PlatformId_Event3_SIGNATURE) - 1
- ) == 0)))
+ if (((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType != EV_NO_ACTION) {
+ return FALSE;
+ }
+
+ if ((NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
+ (CompareMem (
+ NewEventData,
+ TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
+ sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
+ ) == 0))
+ {
+ return TRUE;
+ }
+
+ if ((NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event3)) &&
+ (CompareMem (
+ NewEventData,
+ TCG_Sp800_155_PlatformId_Event3_SIGNATURE,
+ sizeof (TCG_Sp800_155_PlatformId_Event3_SIGNATURE) - 1
+ ) == 0))
{
return TRUE;
}
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index 24a27cd..85a8528 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -798,6 +798,7 @@ Tcg2GetEventLog (
@retval FALSE This is NOT a Tcg800155PlatformIdEvent.
**/
+STATIC
BOOLEAN
Is800155Event (
IN VOID *NewEventHdr,
@@ -806,18 +807,26 @@ Is800155Event (
IN UINT32 NewEventSize
)
{
- if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&
- (NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
- ((CompareMem (
- NewEventData,
- TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
- sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
- ) == 0) ||
- (CompareMem (
- NewEventData,
- TCG_Sp800_155_PlatformId_Event3_SIGNATURE,
- sizeof (TCG_Sp800_155_PlatformId_Event3_SIGNATURE) - 1
- ) == 0)))
+ if (((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType != EV_NO_ACTION) {
+ return FALSE;
+ }
+
+ if ((NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event2)) &&
+ (CompareMem (
+ NewEventData,
+ TCG_Sp800_155_PlatformId_Event2_SIGNATURE,
+ sizeof (TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1
+ ) == 0))
+ {
+ return TRUE;
+ }
+
+ if ((NewEventSize >= sizeof (TCG_Sp800_155_PlatformId_Event3)) &&
+ (CompareMem (
+ NewEventData,
+ TCG_Sp800_155_PlatformId_Event3_SIGNATURE,
+ sizeof (TCG_Sp800_155_PlatformId_Event3_SIGNATURE) - 1
+ ) == 0))
{
return TRUE;
}
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 483fe4d..ae3e943 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -1262,9 +1262,11 @@ LocateStartupScript (
InternalEfiShellSetEnv (L"homefilesystem", StartupScriptPath, TRUE);
- StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);
- PathRemoveLastItem (StartupScriptPath);
- StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);
+ if ((DevicePathType (FileDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType (FileDevicePath) == MEDIA_FILEPATH_DP)) {
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);
+ PathRemoveLastItem (StartupScriptPath);
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);
+ }
}
//
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
deleted file mode 100644
index d804629..0000000
--- a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
+++ /dev/null
@@ -1,42 +0,0 @@
-## @file
-# RISC-V CPU Exception Handler Library
-#
-# Copyright (c) 2022-2023, Ventana Micro Systems Inc. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x0001001B
- BASE_NAME = BaseRiscV64CpuExceptionHandlerLib
- MODULE_UNI_FILE = BaseRiscV64CpuExceptionHandlerLib.uni
- FILE_GUID = 6AB0D5FD-E615-45A3-9374-E284FB061FC9
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = CpuExceptionHandlerLib
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = RISCV64
-#
-
-[Sources]
- SupervisorTrapHandler.S
- CpuExceptionHandlerLib.c
- CpuExceptionHandlerLib.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- UefiCpuPkg/UefiCpuPkg.dec
-
-[LibraryClasses]
- BaseLib
- SerialPortLib
- PrintLib
- SynchronizationLib
- PeCoffGetEntryPointLib
- MemoryAllocationLib
- DebugLib
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.uni b/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.uni
deleted file mode 100644
index 00cca22..0000000
--- a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.uni
+++ /dev/null
@@ -1,13 +0,0 @@
-// /** @file
-//
-// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "RISC-V CPU Exception Handler Librarys."
-
-#string STR_MODULE_DESCRIPTION #language en-US "RISC-V CPU Exception Handler Librarys."
-
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index 9fcba00..9e0b54e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -19,7 +19,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
+# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64 RISCV64
#
[Sources.Ia32]
@@ -46,6 +46,14 @@
LoongArch/LoongArch64/ArchExceptionHandler.c
LoongArch/LoongArch64/ExceptionHandlerAsm.S | GCC
+[Sources.RISCV64]
+ RiscV/Backtrace.h
+ RiscV/Backtrace.c
+ RiscV/BacktraceHelper.c
+ RiscV/ExceptionLib.c
+ RiscV/ExceptionHandler.h
+ RiscV/ExceptionHandlerAsm.S | GCC
+
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard
gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList
@@ -75,5 +83,8 @@
[LibraryClasses.LoongArch64]
CpuLib
+[Guids.RISCV64]
+ gEfiDebugImageInfoTableGuid
+
[BuildOptions]
XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.c
new file mode 100644
index 0000000..9765d72
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.c
@@ -0,0 +1,175 @@
+/** @file
+ RISC-V backtrace implementation.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Backtrace.h"
+
+#define MAX_STACK_FRAME_SIZE SIZE_16KB
+
+STATIC
+INTN
+CheckFpValid (
+ IN UINTN Fp,
+ IN UINTN Sp
+ )
+{
+ UINTN Low, High;
+
+ Low = Sp + 2 * sizeof (UINTN);
+ High = ALIGN_VALUE (Sp, MAX_STACK_FRAME_SIZE);
+
+ return !(Fp < Low || Fp > High || Fp & 0x07);
+}
+
+STATIC
+CONST CHAR8 *
+BaseName (
+ IN CONST CHAR8 *FullName
+ )
+{
+ CONST CHAR8 *Str;
+
+ Str = FullName + AsciiStrLen (FullName);
+
+ while (--Str > FullName) {
+ if ((*Str == '/') || (*Str == '\\')) {
+ return Str + 1;
+ }
+ }
+
+ return Str;
+}
+
+/**
+ Helper for displaying a backtrace.
+
+ @param Regs Pointer to SMODE_TRAP_REGISTERS.
+ @param FirstPdb Pointer to the first symbol file used.
+ @param ListImage If true, only show the full path to symbol file, else
+ show the PC value and its decoded components.
+**/
+STATIC
+VOID
+DumpCpuBacktraceHelper (
+ IN SMODE_TRAP_REGISTERS *Regs,
+ IN CHAR8 *FirstPdb,
+ IN BOOLEAN ListImage
+ )
+{
+ UINTN ImageBase;
+ UINTN PeCoffSizeOfHeader;
+ BOOLEAN IsLeaf;
+ UINTN RootFp;
+ UINTN RootRa;
+ UINTN Sp;
+ UINTN Fp;
+ UINTN Ra;
+ UINTN Idx;
+ CHAR8 *Pdb;
+ CHAR8 *PrevPdb;
+
+ RootRa = Regs->ra;
+ RootFp = Regs->s0;
+
+ Idx = 0;
+ IsLeaf = TRUE;
+ Fp = RootFp;
+ Ra = RootRa;
+ PrevPdb = FirstPdb;
+ while (Fp != 0) {
+ Pdb = GetImageName (Ra, &ImageBase, &PeCoffSizeOfHeader);
+ if (Pdb != NULL) {
+ if (Pdb != PrevPdb) {
+ Idx++;
+ if (ListImage) {
+ DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", Idx, Pdb));
+ }
+
+ PrevPdb = Pdb;
+ }
+
+ if (!ListImage) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "PC 0x%012lx (0x%012lx+0x%08x) [% 2d] %a\n",
+ Ra,
+ ImageBase,
+ Ra - ImageBase,
+ Idx,
+ BaseName (Pdb)
+ ));
+ }
+ } else if (!ListImage) {
+ DEBUG ((DEBUG_ERROR, "PC 0x%012lx\n", Ra));
+ }
+
+ /*
+ * After the prologue, the frame pointer register s0 will point
+ * to the Canonical Frame Address or CFA, which is the stack
+ * pointer value on entry to the current procedure. The previous
+ * frame pointer and return address pair will reside just prior
+ * to the current stack address held in s0. This puts the return
+ * address at s0 - XLEN/8, and the previous frame pointer at
+ * s0 - 2 * XLEN/8.
+ */
+ Sp = Fp;
+ Fp -= sizeof (UINTN) * 2;
+ Ra = *(UINTN *)(Fp + sizeof (UINTN));
+ Fp = *(UINTN *)(Fp);
+ if (IsLeaf && CheckFpValid (Ra, Sp)) {
+ /* We hit function where ra is not saved on the stack */
+ Fp = Ra;
+ Ra = RootRa;
+ }
+
+ IsLeaf = FALSE;
+ }
+}
+
+/**
+ Display a backtrace.
+
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+**/
+VOID
+EFIAPI
+DumpCpuBacktrace (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ SMODE_TRAP_REGISTERS *Regs;
+ CHAR8 *Pdb;
+ UINTN ImageBase;
+ UINTN PeCoffSizeOfHeader;
+
+ Regs = (SMODE_TRAP_REGISTERS *)SystemContext.SystemContextRiscV64;
+ Pdb = GetImageName (Regs->sepc, &ImageBase, &PeCoffSizeOfHeader);
+ if (Pdb != NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "PC 0x%012lx (0x%012lx+0x%08x) [ 0] %a\n",
+ Regs->sepc,
+ ImageBase,
+ Regs->sepc - ImageBase,
+ BaseName (Pdb)
+ ));
+ } else {
+ DEBUG ((DEBUG_ERROR, "PC 0x%012lx\n", Regs->sepc));
+ }
+
+ DumpCpuBacktraceHelper (Regs, Pdb, FALSE);
+
+ if (Pdb != NULL) {
+ DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb));
+ }
+
+ DumpCpuBacktraceHelper (Regs, Pdb, TRUE);
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.h
new file mode 100644
index 0000000..6e29b90
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/Backtrace.h
@@ -0,0 +1,57 @@
+/** @file
+
+ RISC-V backtrace definition file.
+
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BACKTRACE_H_
+#define BACKTRACE_H_
+
+#include <PiPei.h>
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/DebugImageInfoTable.h>
+#include "ExceptionHandler.h"
+
+/**
+ Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image
+ it came from. As long as the PE/COFF image contains a debug directory entry a
+ string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF
+ image. Microsoft tools contain a pointer to the PDB file that contains the debug information.
+
+ @param FaultAddress Address to find PE/COFF image for.
+ @param ImageBase Return load address of found image
+ @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
+
+ @retval NULL FaultAddress not in a loaded PE/COFF image.
+ @retval Path and file name of PE/COFF image.
+
+**/
+CHAR8 *
+EFIAPI
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ );
+
+/**
+ Display a backtrace.
+
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+**/
+VOID
+EFIAPI
+DumpCpuBacktrace (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+#endif // BACKTRACE_H_
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelper.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelper.c
new file mode 100644
index 0000000..fdc5666
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelper.c
@@ -0,0 +1,71 @@
+/** @file
+ RISC-V backtrace helper functions.
+
+ Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Backtrace.h"
+
+/**
+ Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image
+ it came from. As long as the PE/COFF image contains a debug directory entry a
+ string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF
+ image. Microsoft tools contain a pointer to the PDB file that contains the debug information.
+
+ @param FaultAddress Address to find PE/COFF image for.
+ @param ImageBase Return load address of found image
+ @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
+
+ @retval NULL FaultAddress not in a loaded PE/COFF image.
+ @retval Path and file name of PE/COFF image.
+
+**/
+CHAR8 *
+EFIAPI
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugTableHeader;
+ EFI_DEBUG_IMAGE_INFO *DebugTable;
+ UINTN Entry;
+ CHAR8 *Address;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugTableHeader);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ DebugTable = DebugTableHeader->EfiDebugImageInfoTable;
+ if (DebugTable == NULL) {
+ return NULL;
+ }
+
+ Address = (CHAR8 *)(UINTN)FaultAddress;
+ for (Entry = 0; Entry < DebugTableHeader->TableSize; Entry++, DebugTable++) {
+ if (DebugTable->NormalImage != NULL) {
+ if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
+ (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL))
+ {
+ if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) &&
+ (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize)))
+ {
+ *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
+ *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);
+ return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelperSec.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelperSec.c
new file mode 100644
index 0000000..10e3497
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/BacktraceHelperSec.c
@@ -0,0 +1,42 @@
+/** @file
+ RISC-V backtrace helper functions for SEC.
+
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Backtrace.h"
+
+/**
+ Use the EFI Debug Image Table to lookup the FaultAddress and find which PE/COFF image
+ it came from. As long as the PE/COFF image contains a debug directory entry a
+ string can be returned. For ELF and Mach-O images the string points to the Mach-O or ELF
+ image. Microsoft tools contain a pointer to the PDB file that contains the debug information.
+
+ @param FaultAddress Address to find PE/COFF image for.
+ @param ImageBase Return load address of found image
+ @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
+
+ @retval NULL FaultAddress not in a loaded PE/COFF image.
+ @retval Path and file name of PE/COFF image.
+
+**/
+CHAR8 *
+EFIAPI
+GetImageName (
+ IN UINTN FaultAddress,
+ OUT UINTN *ImageBase,
+ OUT UINTN *PeCoffSizeOfHeaders
+ )
+{
+ //
+ // This function is not implemented in SEC phase.
+ // It should be implemented in DXE phase.
+ //
+ *ImageBase = 0;
+ *PeCoffSizeOfHeaders = 0;
+
+ return NULL;
+}
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandler.h
index 9b7e130..0cf8221 100644
--- a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandler.h
@@ -8,16 +8,16 @@
**/
-#ifndef RISCV_CPU_EXECPTION_HANDLER_LIB_H_
-#define RISCV_CPU_EXECPTION_HANDLER_LIB_H_
+#ifndef EXCEPTION_HANDLER_H_
+#define EXCEPTION_HANDLER_H_
#include <Register/RiscV64/RiscVImpl.h>
/**
Trap Handler for S-mode
-
**/
VOID
+EFIAPI
SupervisorModeTrap (
VOID
);
@@ -108,4 +108,4 @@ typedef struct {
} SMODE_TRAP_REGISTERS;
#pragma pack()
-#endif
+#endif /* EXCEPTION_HANDLER_H_ */
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/SupervisorTrapHandler.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandlerAsm.S
index 45070b5..815e28b 100644
--- a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/SupervisorTrapHandler.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionHandlerAsm.S
@@ -8,7 +8,7 @@
**/
#include <Base.h>
-#include "CpuExceptionHandlerLib.h"
+#include "ExceptionHandler.h"
.align 3
.section .entry, "ax", %progbits
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionLib.c
index 73a9dd5..d19c992 100644
--- a/UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/RiscV/ExceptionLib.c
@@ -2,6 +2,9 @@
RISC-V Exception Handler library implementation.
Copyright (c) 2016 - 2022, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2025, Ventana Micro Systems Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,7 +17,8 @@
#include <Library/SerialPortLib.h>
#include <Library/PrintLib.h>
#include <Register/RiscV64/RiscVEncoding.h>
-#include "CpuExceptionHandlerLib.h"
+#include "Backtrace.h"
+#include "ExceptionHandler.h"
//
// Define the maximum message length
@@ -136,11 +140,21 @@ DumpCpuContext (
)
{
UINTN Printed;
+ UINTN RecursiveException;
SMODE_TRAP_REGISTERS *Regs;
Printed = 0;
Regs = (SMODE_TRAP_REGISTERS *)SystemContext.SystemContextRiscV64;
+ RecursiveException = RiscVGetSupervisorScratch ();
+ if (RecursiveException == 0xdeaddead) {
+ InternalPrintMessage ("\nRecursive exception occurred while dumping the CPU state\n");
+
+ CpuDeadLoop ();
+ }
+
+ RiscVSetSupervisorScratch ((UINTN)0xdeaddead);
+
InternalPrintMessage (
"!!!! RISCV64 Exception Type - %016x(%a) !!!!\n",
ExceptionType,
@@ -171,6 +185,8 @@ DumpCpuContext (
#undef REG
#undef REGS
+ DumpCpuBacktrace (SystemContext);
+
DEBUG_CODE_END ();
}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
index 64de252..00a5b49 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -20,7 +20,7 @@
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
-# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64
+# VALID_ARCHITECTURES = IA32 X64 LOONGARCH64 RISCV64
#
[Sources.Ia32]
@@ -46,6 +46,13 @@
LoongArch/LoongArch64/ArchExceptionHandler.c
LoongArch/LoongArch64/ExceptionHandlerAsm.S | GCC
+[Sources.RISCV64]
+ RiscV/Backtrace.h
+ RiscV/Backtrace.c
+ RiscV/BacktraceHelperSec.c
+ RiscV/ExceptionLib.c
+ RiscV/ExceptionHandler.h
+ RiscV/ExceptionHandlerAsm.S | GCC
[Packages]
MdePkg/MdePkg.dec
diff --git a/UefiCpuPkg/Library/MpInitLib/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/AmdSev.c
index 5108873..8ffb1b5 100644
--- a/UefiCpuPkg/Library/MpInitLib/AmdSev.c
+++ b/UefiCpuPkg/Library/MpInitLib/AmdSev.c
@@ -273,7 +273,7 @@ SevEsPlaceApHlt (
@param[in] ExchangeInfo The pointer to CPU Exchange Data structure
**/
VOID
-FillExchangeInfoDataSevEs (
+FillExchangeInfoDataSevSnp (
IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo
)
{
@@ -293,8 +293,6 @@ FillExchangeInfoDataSevEs (
);
ExchangeInfo->ExtTopoAvail = !!ExtTopoEbx.Bits.LogicalProcessors;
}
-
- ExchangeInfo->SevSnpKnownInitApicId = FALSE;
}
/**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 96c0980..63b8464 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -1018,15 +1018,17 @@ FillExchangeInfoData (
ExchangeInfo->Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging));
- ExchangeInfo->SevEsIsEnabled = CpuMpData->SevEsIsEnabled;
- ExchangeInfo->SevSnpIsEnabled = CpuMpData->SevSnpIsEnabled;
- ExchangeInfo->GhcbBase = (UINTN)CpuMpData->GhcbBase;
+ ExchangeInfo->SevEsIsEnabled = CpuMpData->SevEsIsEnabled;
+ ExchangeInfo->SevSnpIsEnabled = CpuMpData->SevSnpIsEnabled;
+ ExchangeInfo->GhcbBase = (UINTN)CpuMpData->GhcbBase;
+ ExchangeInfo->ExtTopoAvail = FALSE;
+ ExchangeInfo->SevSnpKnownInitApicId = FALSE;
//
- // Populate SEV-ES specific exchange data.
+ // Populate SEV-SNP specific exchange data.
//
if (ExchangeInfo->SevSnpIsEnabled) {
- FillExchangeInfoDataSevEs (ExchangeInfo);
+ FillExchangeInfoDataSevSnp (ExchangeInfo);
}
//
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 60cae3b..5d10516 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -901,7 +901,7 @@ ConfidentialComputingGuestHas (
@param[in] ExchangeInfo The pointer to CPU Exchange Data structure
**/
VOID
-FillExchangeInfoDataSevEs (
+FillExchangeInfoDataSevSnp (
IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo
);
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
index 66d63a2..64358e5 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm
@@ -24,13 +24,6 @@
;
SevSnpGetInitCpuNumber:
;
- ; If not an SNP guest, leave EBX (CpuNumber) as is
- ;
- lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]
- cmp byte [edi], 1 ; SevSnpIsEnabled
- jne SevSnpGetCpuNumberDone
-
- ;
; If not starting the AP with a specific ApicId, leave EBX (CpuNumber) as is
;
lea edi, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpKnownInitApicId)]
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index 47ae9fd..1d53b78 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -236,12 +236,14 @@ SmmWaitForApArrival (
UINTN Index;
UINT32 DelayedCount;
UINT32 BlockedCount;
+ UINT32 DisabledCount;
BOOLEAN SyncNeeded;
PERF_FUNCTION_BEGIN ();
- DelayedCount = 0;
- BlockedCount = 0;
+ DelayedCount = 0;
+ BlockedCount = 0;
+ DisabledCount = 0;
ASSERT (SmmCpuSyncGetArrivedCpuCount (mSmmMpSyncData->SyncContext) <= mNumberOfCpus);
@@ -321,10 +323,10 @@ SmmWaitForApArrival (
mSmmMpSyncData->AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled ();
if (!mSmmMpSyncData->AllApArrivedWithException) {
//
- // Check for the Blocked & Delayed Case.
+ // Check for the Disabled & Blocked & Delayed Case.
//
- GetSmmDelayedBlockedDisabledCount (&DelayedCount, &BlockedCount, NULL);
- DEBUG ((DEBUG_INFO, "SmmWaitForApArrival: Delayed AP Count = %d, Blocked AP Count = %d\n", DelayedCount, BlockedCount));
+ GetSmmDelayedBlockedDisabledCount (&DelayedCount, &BlockedCount, &DisabledCount);
+ DEBUG ((DEBUG_ERROR, "SmmWaitForApArrival: Failed to wait all APs enter SMI. Delayed AP Count = %d, Blocked AP Count = %d, Disabled AP Count = %d\n", DelayedCount, BlockedCount, DisabledCount));
}
PERF_FUNCTION_END ();
diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml
index a6fd147..57867dd 100644
--- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
+++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
@@ -30,7 +30,6 @@
],
## Both file path and directory path are accepted.
"IgnoreFiles": [
- "Library/BaseRiscV64CpuExceptionHandlerLib/CpuExceptionHandlerLib.h"
]
},
"CompilerPlugin": {
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index aac4668..e011b18 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -218,7 +218,6 @@
UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
[Components.RISCV64]
- UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/BaseRiscV64CpuTimerLib.inf
UefiCpuPkg/Library/BaseRiscVMmuLib/BaseRiscVMmuLib.inf
UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf