Compare commits
212 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6acd6781ba | ||
|
54d5ab6a73 | ||
|
833f9f2696 | ||
|
9ae0b48624 | ||
|
785e1699ac | ||
|
ddd7bc4ccb | ||
|
e997f66e75 | ||
|
07e17a6278 | ||
|
2cfea54e05 | ||
|
5cb3ae7a54 | ||
|
84f5807928 | ||
|
dc52d24609 | ||
|
34a5f0e3e3 | ||
|
ba09813128 | ||
|
66566e28b5 | ||
|
b633c7357d | ||
|
c924df7ccf | ||
|
935c402311 | ||
|
1d707a02d8 | ||
|
5f0a27fcf9 | ||
|
167e6e48af | ||
|
5c693e581e | ||
|
acaa5d7382 | ||
|
87acb6e298 | ||
|
c4c7fb388e | ||
|
dcfd55d97a | ||
|
818d60f48b | ||
|
1f71fd55b3 | ||
|
c127d3953b | ||
|
993fb9ee22 | ||
|
c3e2883788 | ||
|
688829df30 | ||
|
2b22fe75c4 | ||
|
ac8d86234d | ||
|
f09d6323b1 | ||
|
5b529feaaa | ||
|
3adc5a5fcd | ||
|
0960db18cf | ||
|
f78e28426d | ||
|
bc3aba79b8 | ||
|
2fe3f4d969 | ||
|
fe7868f81c | ||
|
8dcbc07d34 | ||
|
f56e828595 | ||
|
df2b9b73fc | ||
|
80654b7e45 | ||
|
4ebdd4432b | ||
|
de761fb41c | ||
|
7b49d5f26b | ||
|
38ce9cd510 | ||
|
3bc7ae9d7d | ||
|
1a114b3f79 | ||
|
b7fc17ce1f | ||
|
332b4e030e | ||
|
bb45812e3b | ||
|
d006fad08b | ||
|
8d8b9af9d8 | ||
|
b0898ad483 | ||
|
f8c8e99c9e | ||
|
7ebe491ca6 | ||
|
0e7879ad7b | ||
|
3c4cb3ca51 | ||
|
8927f4683b | ||
|
0f6641efed | ||
|
8bb7fa235f | ||
|
1cc04b839b | ||
|
487719e458 | ||
|
3c8012fff3 | ||
|
b6da5e3823 | ||
|
af1b85332b | ||
|
48008d5f59 | ||
|
12afa343ef | ||
|
6b4b6a36ab | ||
|
058a50daf5 | ||
|
d7989c70aa | ||
|
af28682757 | ||
|
b2b89fe3fb | ||
|
21b9d72426 | ||
|
22d1ad2be9 | ||
|
985e2707a0 | ||
|
3d06e18988 | ||
|
1c8bdffe4f | ||
|
864f8a3217 | ||
|
9f293688f8 | ||
|
a91808083b | ||
|
692bb97767 | ||
|
076d0030a0 | ||
|
95a84049eb | ||
|
6e7b7c0c51 | ||
|
b8d87b6177 | ||
|
f0599c8c2d | ||
|
f899049159 | ||
|
8f334a80b3 | ||
|
f9605f5da3 | ||
|
28f9a14a08 | ||
|
62c07ae89f | ||
|
a6845dfa70 | ||
|
678932e524 | ||
|
4b0a612f4b | ||
|
9a1aafdc9f | ||
|
e9c75d4aed | ||
|
16d682ef75 | ||
|
4c12040ba5 | ||
|
9c5247f1fd | ||
|
0618ee43a1 | ||
|
2b91b830b6 | ||
|
52764f7867 | ||
|
94467009ec | ||
|
a63a6dccf7 | ||
|
6a80fbf6ff | ||
|
0444b43b3b | ||
|
44bea14670 | ||
|
c4c2eb888f | ||
|
76240a9bfd | ||
|
1b0ad0628c | ||
|
268c34c0fc | ||
|
97b40e6eb2 | ||
|
b79d8da0ef | ||
|
68b7aeaf22 | ||
|
685dfb6dc3 | ||
|
1b9c0ef81a | ||
|
4e7317f367 | ||
|
3b4d3e06e6 | ||
|
138867bfce | ||
|
7742a8dd23 | ||
|
92cf6c91d0 | ||
|
dfe8c91990 | ||
|
ec6efda3aa | ||
|
1d6b6d1e5a | ||
|
e267ab290b | ||
|
193748cbe4 | ||
|
e854ca76b7 | ||
|
9f93bc870d | ||
|
c6d1b85c40 | ||
|
1ccb42d900 | ||
|
d8f8cb70af | ||
|
6cf2ca6913 | ||
|
e4961ec4a2 | ||
|
b16a16d30c | ||
|
702a585f6d | ||
|
776788926c | ||
|
8c36c0df58 | ||
|
e9d7b97c5b | ||
|
1cf1eebf69 | ||
|
d4fd304f8e | ||
|
87ed293135 | ||
|
42ff47c96d | ||
|
72d1ebc5bc | ||
|
a0fb938ec3 | ||
|
ebded73573 | ||
|
38cbff6597 | ||
|
25ce9e1beb | ||
|
ccf8184ac3 | ||
|
bcda835b36 | ||
|
d64577ac0a | ||
|
e2a6326db6 | ||
|
61699a3247 | ||
|
24dae408e5 | ||
|
cf0277ed78 | ||
|
ce3997f0ba | ||
|
800004bf97 | ||
|
39db198dae | ||
|
c1599f3e4f | ||
|
3b4c8c5f97 | ||
|
3ce826f8df | ||
|
4adfe6c82f | ||
|
23b91293bd | ||
|
e3e92db8c5 | ||
|
0824202952 | ||
|
000b430124 | ||
|
6c6958ce8a | ||
|
28e7f3b4d0 | ||
|
1bbc25874b | ||
|
93cd52af55 | ||
|
242fc42229 | ||
|
5b68bc7db1 | ||
|
e195fcd1c4 | ||
|
08bd0bcbda | ||
|
3ae5a3f64a | ||
|
4a387664ca | ||
|
ec7485fa89 | ||
|
3a357bf404 | ||
|
c1e6864d35 | ||
|
0f63da7c61 | ||
|
07dce6fb78 | ||
|
64f81ce7bd | ||
|
a638395fa4 | ||
|
f0e5329b94 | ||
|
2704b8dd89 | ||
|
698739e887 | ||
|
258f7de25e | ||
|
13370226c9 | ||
|
007386ef63 | ||
|
d207ef6f5a | ||
|
db9d1fa56c | ||
|
e890056bb8 | ||
|
4445bb29b3 | ||
|
1eff644477 | ||
|
3d41e7b48d | ||
|
c3abd1c7a5 | ||
|
f71a70e7a4 | ||
|
8fd313ab9d | ||
|
54cbe51db4 | ||
|
582225d2f3 | ||
|
5d577844f0 | ||
|
eea98eea4c | ||
|
8b2fc8bd87 | ||
|
5a40103e40 | ||
|
a7bf24ea3d | ||
|
9466ebf4ba | ||
|
51bf49ee53 | ||
|
b21ac25c06 |
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
# Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
# Copyright (c) 2015, Hewlett-Packard Development Company, L.P.<BR>
|
||||
@@ -74,6 +74,12 @@ DEFINE VS2015x86_BIN = ENV(VS2015_PREFIX)Vc\bin
|
||||
DEFINE VS2015x86_DLL = ENV(VS2015_PREFIX)Common7\IDE;DEF(VS2015x86_BIN)
|
||||
DEFINE VS2015x86_BINX64 = DEF(VS2015x86_BIN)\x86_amd64
|
||||
|
||||
DEFINE VS2017_BIN = ENV(VS2017_PREFIX)bin
|
||||
DEFINE VS2017_HOST = x86
|
||||
DEFINE VS2017_BIN_HOST = DEF(VS2017_BIN)\HostDEF(VS2017_HOST)\DEF(VS2017_HOST)
|
||||
DEFINE VS2017_BIN_IA32 = DEF(VS2017_BIN)\HostDEF(VS2017_HOST)\x86
|
||||
DEFINE VS2017_BIN_X64 = DEF(VS2017_BIN)\HostDEF(VS2017_HOST)\x64
|
||||
|
||||
DEFINE WINSDK_BIN = ENV(WINSDK_PREFIX)
|
||||
DEFINE WINSDKx86_BIN = ENV(WINSDKx86_PREFIX)
|
||||
|
||||
@@ -93,6 +99,9 @@ DEFINE WINSDK8x86_BIN = ENV(WINSDK8x86_PREFIX)x64
|
||||
DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x86\
|
||||
DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x64
|
||||
|
||||
# Microsoft Visual Studio 2017 Professional Edition
|
||||
DEFINE WINSDK10_BIN = ENV(WINSDK10_PREFIX)DEF(VS2017_HOST)
|
||||
|
||||
# These defines are needed for certain Microsoft Visual Studio tools that
|
||||
# are used by other toolchains. An example is that ICC on Windows normally
|
||||
# uses Microsoft's nmake.exe.
|
||||
@@ -316,6 +325,14 @@ DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G
|
||||
# Required to build platforms or ACPI tables:
|
||||
# Intel(r) ACPI Compiler (iasl.exe) from
|
||||
# https://acpica.org/downloads
|
||||
# VS2017 -win32- Requires:
|
||||
# Microsoft Visual Studio 2017 version 15.2 or later
|
||||
# Optional:
|
||||
# Required to build EBC drivers:
|
||||
# Intel(r) Compiler for Efi Byte Code (Intel(r) EBC Compiler)
|
||||
# Required to build platforms or ACPI tables:
|
||||
# Intel(r) ACPI Compiler (iasl.exe) from
|
||||
# https://acpica.org/downloads
|
||||
# DDK3790 -win32- Requires:
|
||||
# Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830
|
||||
# Optional:
|
||||
@@ -4054,6 +4071,115 @@ NOOPT_VS2015x86xASL_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT
|
||||
*_VS2015x86xASL_EBC_DLINK_FLAGS = "C:\Program Files (x86)\Intel\EBC\Lib\EbcLib.lib" /NOLOGO /NODEFAULTLIB /MACHINE:EBC /OPT:REF /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MAP /ALIGN:32 /DRIVER
|
||||
|
||||
|
||||
####################################################################################
|
||||
# VS2017 - Microsoft Visual Studio 2017 with Intel ASL
|
||||
# ASL - Intel ACPI Source Language Compiler (iasl.exe)
|
||||
####################################################################################
|
||||
# VS2017 - Microsoft Visual Studio 2017 professional Edition with Intel ASL
|
||||
*_VS2017_*_*_FAMILY = MSFT
|
||||
*_VS2017_*_*_DLL = DEF(VS2017_BIN_HOST)
|
||||
|
||||
*_VS2017_*_MAKE_PATH = DEF(VS2017_BIN_HOST)\nmake.exe
|
||||
*_VS2017_*_MAKE_FLAG = /nologo
|
||||
*_VS2017_*_RC_PATH = DEF(WINSDK10_BIN)\rc.exe
|
||||
|
||||
*_VS2017_*_MAKE_FLAGS = /nologo
|
||||
*_VS2017_*_SLINK_FLAGS = /NOLOGO /LTCG
|
||||
*_VS2017_*_APP_FLAGS = /nologo /E /TC
|
||||
*_VS2017_*_PP_FLAGS = /nologo /E /TC /FIAutoGen.h
|
||||
*_VS2017_*_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FI$(MODULE_NAME)StrDefs.h
|
||||
*_VS2017_*_DLINK2_FLAGS = /WHOLEARCHIVE
|
||||
*_VS2017_*_ASM16_PATH = DEF(VS2017_BIN_IA32)\ml.exe
|
||||
|
||||
##################
|
||||
# ASL definitions
|
||||
##################
|
||||
*_VS2017_*_ASL_PATH = DEF(WIN_IASL_BIN)
|
||||
*_VS2017_*_ASL_FLAGS = DEF(DEFAULT_WIN_ASL_FLAGS)
|
||||
*_VS2017_*_ASL_OUTFLAGS = DEF(DEFAULT_WIN_ASL_OUTFLAGS)
|
||||
*_VS2017_*_ASLCC_FLAGS = DEF(MSFT_ASLCC_FLAGS)
|
||||
*_VS2017_*_ASLPP_FLAGS = DEF(MSFT_ASLPP_FLAGS)
|
||||
*_VS2017_*_ASLDLINK_FLAGS = DEF(MSFT_ASLDLINK_FLAGS)
|
||||
|
||||
##################
|
||||
# IA32 definitions
|
||||
##################
|
||||
*_VS2017_IA32_CC_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_VFRPP_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_ASLCC_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_ASLPP_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_SLINK_PATH = DEF(VS2017_BIN_IA32)\lib.exe
|
||||
*_VS2017_IA32_DLINK_PATH = DEF(VS2017_BIN_IA32)\link.exe
|
||||
*_VS2017_IA32_ASLDLINK_PATH= DEF(VS2017_BIN_IA32)\link.exe
|
||||
*_VS2017_IA32_APP_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_PP_PATH = DEF(VS2017_BIN_IA32)\cl.exe
|
||||
*_VS2017_IA32_ASM_PATH = DEF(VS2017_BIN_IA32)\ml.exe
|
||||
|
||||
*_VS2017_IA32_MAKE_FLAGS = /nologo
|
||||
DEBUG_VS2017_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm
|
||||
RELEASE_VS2017_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF
|
||||
NOOPT_VS2017_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gm /Od
|
||||
|
||||
DEBUG_VS2017_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi
|
||||
RELEASE_VS2017_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd
|
||||
NOOPT_VS2017_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi
|
||||
|
||||
DEBUG_VS2017_IA32_NASM_FLAGS = -Ox -f win32 -g
|
||||
RELEASE_VS2017_IA32_NASM_FLAGS = -Ox -f win32
|
||||
NOOPT_VS2017_IA32_NASM_FLAGS = -O0 -f win32 -g
|
||||
|
||||
DEBUG_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
|
||||
RELEASE_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
|
||||
NOOPT_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
|
||||
|
||||
##################
|
||||
# X64 definitions
|
||||
##################
|
||||
*_VS2017_X64_CC_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_PP_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_APP_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_VFRPP_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_ASLCC_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_ASLPP_PATH = DEF(VS2017_BIN_X64)\cl.exe
|
||||
*_VS2017_X64_ASM_PATH = DEF(VS2017_BIN_X64)\ml64.exe
|
||||
*_VS2017_X64_SLINK_PATH = DEF(VS2017_BIN_X64)\lib.exe
|
||||
*_VS2017_X64_DLINK_PATH = DEF(VS2017_BIN_X64)\link.exe
|
||||
*_VS2017_X64_ASLDLINK_PATH = DEF(VS2017_BIN_X64)\link.exe
|
||||
|
||||
DEBUG_VS2017_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm
|
||||
RELEASE_VS2017_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF
|
||||
NOOPT_VS2017_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od
|
||||
|
||||
DEBUG_VS2017_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi
|
||||
RELEASE_VS2017_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd
|
||||
NOOPT_VS2017_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi
|
||||
|
||||
DEBUG_VS2017_X64_NASM_FLAGS = -Ox -f win64 -g
|
||||
RELEASE_VS2017_X64_NASM_FLAGS = -Ox -f win64
|
||||
NOOPT_VS2017_X64_NASM_FLAGS = -O0 -f win64 -g
|
||||
|
||||
DEBUG_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
|
||||
RELEASE_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
|
||||
NOOPT_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
|
||||
|
||||
##################
|
||||
# EBC definitions
|
||||
##################
|
||||
*_VS2017_EBC_*_FAMILY = INTEL
|
||||
|
||||
*_VS2017_EBC_PP_PATH = DEF(EBC_BINx86)\iec.exe
|
||||
*_VS2017_EBC_VFRPP_PATH = DEF(EBC_BINx86)\iec.exe
|
||||
*_VS2017_EBC_CC_PATH = DEF(EBC_BINx86)\iec.exe
|
||||
*_VS2017_EBC_SLINK_PATH = DEF(VS2017_BIN_IA32)\link.exe
|
||||
*_VS2017_EBC_DLINK_PATH = DEF(VS2017_BIN_IA32)\link.exe
|
||||
|
||||
*_VS2017_EBC_MAKE_FLAGS = /nologo
|
||||
*_VS2017_EBC_PP_FLAGS = /nologo /E /TC /FIAutoGen.h
|
||||
*_VS2017_EBC_CC_FLAGS = /nologo /c /WX /W3 /FIAutoGen.h /D$(MODULE_ENTRY_POINT)=$(ARCH_ENTRY_POINT)
|
||||
*_VS2017_EBC_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FI$(MODULE_NAME)StrDefs.h
|
||||
*_VS2017_EBC_SLINK_FLAGS = /lib /NOLOGO /MACHINE:EBC
|
||||
*_VS2017_EBC_DLINK_FLAGS = "C:\Program Files (x86)\Intel\EBC\Lib\EbcLib.lib" /NOLOGO /NODEFAULTLIB /MACHINE:EBC /OPT:REF /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MAP /ALIGN:32 /DRIVER
|
||||
|
||||
####################################################################################
|
||||
#
|
||||
# Microsoft Device Driver Kit 3790.1830 (IA-32, X64, Itanium, with Link Time Code Generation)
|
||||
@@ -7251,189 +7377,12 @@ NOOPT_MYTOOLS_IPF_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /LTCG /DLL /OPT
|
||||
*_MYTOOLS_EBC_DLINK_FLAGS = "C:\Program Files\Intel\EBC\Lib\EbcLib.lib" /NOLOGO /NODEFAULTLIB /MACHINE:EBC /OPT:REF /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /MAP /ALIGN:32 /DRIVER
|
||||
|
||||
|
||||
####################################################################################
|
||||
#
|
||||
# Xcode Support for building on Mac OS X (Snow Leopard)
|
||||
#
|
||||
####################################################################################
|
||||
# XCODE32 - Xcode 3.2 Tools (Snow Leopard)
|
||||
*_XCODE32_*_*_FAMILY = GCC
|
||||
*_XCODE32_*_*_BUILDRULEFAMILY = XCODE
|
||||
*_XCODE32_*_*_BUILDRULEORDER = S s nasm
|
||||
|
||||
|
||||
*_XCODE32_*_ASL_PATH = /usr/bin/iasl
|
||||
|
||||
*_XCODE32_*_MAKE_PATH = make
|
||||
|
||||
*_XCODE32_*_DSYMUTIL_PATH = /usr/bin/dsymutil
|
||||
|
||||
# This tool needs to be installed seperatly from Xcode 3.2
|
||||
*_XCODE32_*_MTOC_PATH = /usr/local/bin/mtoc
|
||||
|
||||
DEBUG_XCODE32_*_MTOC_FLAGS = -align 0x20 -d $(DEBUG_DIR)/$(MODULE_NAME).dll
|
||||
RELEASE_XCODE32_*_MTOC_FLAGS = -align 0x20
|
||||
|
||||
##################
|
||||
# IA32 definitions
|
||||
##################
|
||||
*_XCODE32_IA32_CC_PATH = gcc
|
||||
*_XCODE32_IA32_SLINK_PATH = libtool
|
||||
*_XCODE32_IA32_DLINK_PATH = ld
|
||||
*_XCODE32_IA32_ASM_PATH = as
|
||||
*_XCODE32_IA32_PP_PATH = gcc
|
||||
*_XCODE32_IA32_VFRPP_PATH = gcc
|
||||
*_XCODE32_IA32_ASL_PATH = iasl
|
||||
*_XCODE32_IA32_ASLCC_PATH = gcc
|
||||
*_XCODE32_IA32_ASLPP_PATH = gcc
|
||||
*_XCODE32_IA32_ASLDLINK_PATH = ld
|
||||
|
||||
DEBUG_XCODE32_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
RELEASE_XCODE32_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x220 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCODE32_IA32_SLINK_FLAGS = -static -o
|
||||
DEBUG_XCODE32_IA32_ASM_FLAGS = -arch i386 -g
|
||||
RELEASE_XCODE32_IA32_ASM_FLAGS = -arch i386
|
||||
*_XCODE32_IA32_NASM_FLAGS = -f macho32
|
||||
*_XCODE32_IA32_PP_FLAGS = -arch i386 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
|
||||
*_XCODE32_IA32_VFRPP_FLAGS = -arch i386 -x c -E -P -DVFRCOMPILE --include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h
|
||||
DEBUG_XCODE32_IA32_CC_FLAGS = -arch i386 -save-temps -g -O0 -combine -mms-bitfields -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -c -include AutoGen.h -mdynamic-no-pic -fno-stack-protector
|
||||
RELEASE_XCODE32_IA32_CC_FLAGS = -arch i386 -Oz -combine -mms-bitfields -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -fomit-frame-pointer -c -include AutoGen.h -mdynamic-no-pic -fno-stack-protector
|
||||
|
||||
*_XCODE32_IA32_ASLCC_FLAGS = -arch i386 -x c -save-temps -g -O0 -mms-bitfields -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -c -include AutoGen.h -mdynamic-no-pic
|
||||
*_XCODE32_IA32_ASLDLINK_FLAGS = -arch i386 -e _main -preload -segalign 0x20 -pie -seg1addr 0x220 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCODE32_IA32_ASLPP_FLAGS = -arch i386 -x c -E -include AutoGen.h
|
||||
*_XCODE32_IA32_ASL_FLAGS =
|
||||
|
||||
##################
|
||||
# X64 definitions - still a work in progress. This tool chain does not produce
|
||||
# the correct ABI, it is just used to compile the code....
|
||||
##################
|
||||
*_XCODE32_X64_CC_PATH = gcc
|
||||
*_XCODE32_X64_SLINK_PATH = libtool
|
||||
*_XCODE32_X64_DLINK_PATH = ld
|
||||
*_XCODE32_X64_ASM_PATH = as
|
||||
*_XCODE32_X64_PP_PATH = gcc
|
||||
*_XCODE32_X64_VFRPP_PATH = gcc
|
||||
*_XCODE32_X64_ASL_PATH = iasl
|
||||
*_XCODE32_X64_ASLCC_PATH = gcc
|
||||
*_XCODE32_X64_ASLPP_PATH = gcc
|
||||
*_XCODE32_X64_ASLDLINK_PATH = ld
|
||||
|
||||
*_XCODE32_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCODE32_X64_SLINK_FLAGS = -static -o
|
||||
|
||||
DEBUG_XCODE32_X64_ASM_FLAGS = -arch x86_64 -g
|
||||
RELEASE_XCODE32_X64_ASM_FLAGS = -arch x86_64
|
||||
*_XCODE32_X64_NASM_FLAGS = -f macho64
|
||||
*_XCODE32_X64_PP_FLAGS = -arch x86_64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
|
||||
*_XCODE32_X64_VFRPP_FLAGS = -arch x86_64 -x c -E -P -DVFRCOMPILE --include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h
|
||||
|
||||
DEBUG_XCODE32_X64_CC_FLAGS = -arch x86_64 -save-temps -g -O0 -mms-bitfields -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -Wno-address -fomit-frame-pointer -static -c -include AutoGen.h -fno-stack-protector
|
||||
RELEASE_XCODE32_X64_CC_FLAGS = -arch x86_64 -Oz -mms-bitfields -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -Wno-address -fomit-frame-pointer -static -c -include AutoGen.h -fno-stack-protector
|
||||
|
||||
##################
|
||||
# ARM definitions - (Assumes iPhone SDK installed on Snow Leopard)
|
||||
##################
|
||||
|
||||
*_XCODE32_ARM_ARCHCC_FLAGS = -arch armv7 -march=armv7 -mthumb
|
||||
*_XCODE32_ARM_ARCHASM_FLAGS = -arch armv7
|
||||
*_XCODE32_ARM_ARCHDLINK_FLAGS = -arch armv7
|
||||
*_XCODE32_ARM_PLATFORM_FLAGS =
|
||||
|
||||
*_XCODE32_ARM_CC_PATH = DEF(IPHONE_TOOLS)/usr/bin/gcc
|
||||
*_XCODE32_ARM_SLINK_PATH = DEF(IPHONE_TOOLS)/usr/bin/libtool
|
||||
*_XCODE32_ARM_DLINK_PATH = ld
|
||||
*_XCODE32_ARM_ASM_PATH = DEF(IPHONE_TOOLS)/usr/bin/as
|
||||
*_XCODE32_ARM_PP_PATH = DEF(IPHONE_TOOLS)/usr/bin/gcc
|
||||
*_XCODE32_ARM_VFRPP_PATH = DEF(IPHONE_TOOLS)/usr/bin/gcc
|
||||
|
||||
DEBUG_XCODE32_ARM_DLINK_FLAGS = $(ARCHDLINK_FLAGS) -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x220 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
RELEASE_XCODE32_ARM_DLINK_FLAGS = $(ARCHDLINK_FLAGS) -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x220 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
|
||||
*_XCODE32_ARM_SLINK_FLAGS = -static -o
|
||||
|
||||
DEBUG_XCODE32_ARM_ASM_FLAGS = $(ARCHASM_FLAGS) -g
|
||||
RELEASE_XCODE32_ARM_ASM_FLAGS = $(ARCHASM_FLAGS)
|
||||
*_XCODE32_ARM_PP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
|
||||
*_XCODE32_ARM_VFRPP_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -x c -E -P -DVFRCOMPILE --include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h
|
||||
|
||||
DEBUG_XCODE32_ARM_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -mthumb-interwork -g -Oz -mabi=aapcs -mapcs -fno-short-enums -save-temps -combine -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -fomit-frame-pointer -c -include AutoGen.h
|
||||
RELEASE_XCODE32_ARM_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -mthumb-interwork -Oz -mabi=aapcs -mapcs -fno-short-enums -save-temps -combine -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -fomit-frame-pointer -c -include AutoGen.h
|
||||
|
||||
|
||||
####################################################################################
|
||||
#
|
||||
# Clang Support for building on Mac OS X
|
||||
#
|
||||
####################################################################################
|
||||
# CLANG - clang that produce Mach-O with EFI x86_64 ABI
|
||||
*_XCLANG_*_*_FAMILY = GCC
|
||||
*_XCLANG_*_*_BUILDRULEFAMILY = XCODE
|
||||
*_XCLANG_*_*_BUILDRULEORDER = S s nasm
|
||||
|
||||
*_XCLANG_*_ASL_PATH = /usr/bin/iasl
|
||||
|
||||
*_XCLANG_*_MAKE_PATH = make
|
||||
*_XCLANG_*_DSYMUTIL_PATH = /usr/bin/dsymutil
|
||||
|
||||
*_*_*_MTOC_PATH = /usr/local/bin/mtoc
|
||||
|
||||
DEBUG_XCLANG_*_MTOC_FLAGS = -align 0x20 -d $(DEBUG_DIR)/$(MODULE_NAME).dll
|
||||
RELEASE_XCLANG_*_MTOC_FLAGS = -align 0x20
|
||||
|
||||
|
||||
*_XCLANG_*_CC_PATH = ENV(CLANG_BIN)clang
|
||||
*_XCLANG_*_SLINK_PATH = libtool
|
||||
*_XCLANG_*_DLINK_PATH = ld
|
||||
*_XCLANG_*_ASM_PATH = as
|
||||
*_XCLANG_*_PP_PATH = ENV(CLANG_BIN)clang
|
||||
*_XCLANG_*_VFRPP_PATH = ENV(CLANG_BIN)clang
|
||||
*_XCLANG_*_ASL_PATH = iasl
|
||||
*_XCLANG_*_ASLCC_PATH = ENV(CLANG_BIN)clang
|
||||
*_XCLANG_*_ASLPP_PATH = ENV(CLANG_BIN)clang
|
||||
*_XCLANG_*_ASLDLINK_PATH = ld
|
||||
|
||||
####################
|
||||
# IA-32 definitions
|
||||
####################
|
||||
DEBUG_XCLANG_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
RELEASE_XCLANG_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x220 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCLANG_IA32_SLINK_FLAGS = -static -o
|
||||
DEBUG_XCLANG_IA32_ASM_FLAGS = -arch i386 -g
|
||||
RELEASE_XCLANG_IA32_ASM_FLAGS = -arch i386
|
||||
*_XCLANG_IA32_NASM_FLAGS = -f macho32
|
||||
|
||||
DEBUG_XCLANG_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -fasm-blocks -mms-bitfields -msoft-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
|
||||
RELEASE_XCLANG_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -fasm-blocks -mms-bitfields -msoft-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
|
||||
|
||||
|
||||
##################
|
||||
# X64 definitions
|
||||
##################
|
||||
DEBUG_XCLANG_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
RELEASE_XCLANG_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x220 -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCLANG_X64_SLINK_FLAGS = -static -o
|
||||
DEBUG_XCLANG_X64_ASM_FLAGS = -arch x86_64 -g
|
||||
RELEASE_XCLANG_X64_ASM_FLAGS = -arch x86_64
|
||||
*_XCLANG_X64_NASM_FLAGS = -f macho64
|
||||
*_XCLANG_*_PP_FLAGS = -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
|
||||
*_XCLANG_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h
|
||||
|
||||
|
||||
DEBUG_XCLANG_X64_CC_FLAGS = -ccc-host-triple x86_64-pc-win32-macho -c -g -O0 -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
|
||||
RELEASE_XCLANG_X64_CC_FLAGS = -ccc-host-triple x86_64-pc-win32-macho -c -Os -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
|
||||
*_XCLANG_*_ASLCC_FLAGS = -x c -save-temps -g -O0 -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -c -include AutoGen.h -mdynamic-no-pic
|
||||
*_XCLANG_*_ASLDLINK_FLAGS = -e _main -preload -segalign 0x20 -pie -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
|
||||
*_XCLANG_*_ASLPP_FLAGS = -x c -E -include AutoGen.h
|
||||
*_XCLANG_*_ASL_FLAGS =
|
||||
|
||||
#
|
||||
# XCODE5 support
|
||||
#
|
||||
|
||||
*_XCODE5_*_*_FAMILY = GCC
|
||||
*_XCODE5_*_*_BUILDRULEFAMILY = XCODE
|
||||
*_XCODE5_*_*_BUILDRULEORDER = S s nasm
|
||||
|
||||
#
|
||||
# use xcode-select to change Xcode version of command line tools
|
||||
@@ -7483,9 +7432,9 @@ RELEASE_XCODE5_IA32_ASM_FLAGS = -arch i386
|
||||
*_XCODE5_IA32_NASM_FLAGS = -f macho32
|
||||
|
||||
|
||||
DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS)
|
||||
|
||||
##################
|
||||
# X64 definitions
|
||||
@@ -7502,9 +7451,9 @@ RELEASE_XCODE5_X64_ASM_FLAGS = -arch x86_64
|
||||
*_XCODE5_*_PP_FLAGS = -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h
|
||||
*_XCODE5_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h
|
||||
|
||||
DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS)
|
||||
|
||||
####################################################################################
|
||||
#
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# GNU/Linux makefile for Base Tools project build.
|
||||
#
|
||||
# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -24,12 +24,10 @@ subdirs: $(SUBDIRS)
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
Tests: $(SOURCE_SUBDIRS)
|
||||
|
||||
.PHONY: $(CLEAN_SUBDIRS)
|
||||
$(CLEAN_SUBDIRS):
|
||||
-$(MAKE) -C $(@:-clean=) clean
|
||||
|
||||
clean: $(CLEAN_SUBDIRS)
|
||||
|
||||
test:
|
||||
@$(MAKE) -C Tests
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = BootSectImage
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = Brotli
|
||||
|
@@ -89,11 +89,11 @@ Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
|
||||
Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
|
||||
|
||||
while (NumOfBits > Sd->mBitCount) {
|
||||
|
||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
|
||||
if (Sd->mCompSize > 0) {
|
||||
//
|
||||
@@ -194,12 +194,16 @@ Returns:
|
||||
UINT16 Avail;
|
||||
UINT16 NextCode;
|
||||
UINT16 Mask;
|
||||
UINT16 MaxTableLength;
|
||||
|
||||
for (Index = 1; Index <= 16; Index++) {
|
||||
Count[Index] = 0;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumOfChar; Index++) {
|
||||
if (BitLen[Index] > 16) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Count[BitLen[Index]]++;
|
||||
}
|
||||
|
||||
@@ -237,6 +241,7 @@ Returns:
|
||||
|
||||
Avail = NumOfChar;
|
||||
Mask = (UINT16) (1U << (15 - TableBits));
|
||||
MaxTableLength = (UINT16) (1U << TableBits);
|
||||
|
||||
for (Char = 0; Char < NumOfChar; Char++) {
|
||||
|
||||
@@ -250,6 +255,9 @@ Returns:
|
||||
if (Len <= TableBits) {
|
||||
|
||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||
if (Index >= MaxTableLength) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Table[Index] = Char;
|
||||
}
|
||||
|
||||
@@ -643,13 +651,23 @@ Returns: (VOID)
|
||||
|
||||
BytesRemain--;
|
||||
while ((INT16) (BytesRemain) >= 0) {
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
return ;
|
||||
}
|
||||
if (DataIdx >= Sd->mOrigSize) {
|
||||
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||
return ;
|
||||
}
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
|
||||
BytesRemain--;
|
||||
}
|
||||
//
|
||||
// Once mOutBuf is fully filled, directly return
|
||||
//
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,6 +702,7 @@ Returns:
|
||||
--*/
|
||||
{
|
||||
UINT8 *Src;
|
||||
UINT32 CompSize;
|
||||
|
||||
*ScratchSize = sizeof (SCRATCH_DATA);
|
||||
|
||||
@@ -692,7 +711,13 @@ Returns:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
|
||||
*DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
||||
|
||||
if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -752,7 +777,7 @@ Returns:
|
||||
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
|
||||
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
||||
|
||||
if (SrcSize < CompSize + 8) {
|
||||
if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
# VPATH = ..
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = EfiLdrImage
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = EfiRom
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# GNU/Linux makefile for C tools build.
|
||||
#
|
||||
# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -12,47 +12,49 @@
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
ifndef ARCH
|
||||
ifndef HOST_ARCH
|
||||
#
|
||||
# If ARCH is not defined, then we use 'uname -m' to attempt
|
||||
# try to figure out the appropriate ARCH.
|
||||
# If HOST_ARCH is not defined, then we use 'uname -m' to attempt
|
||||
# try to figure out the appropriate HOST_ARCH.
|
||||
#
|
||||
uname_m = $(shell uname -m)
|
||||
$(info Attempting to detect ARCH from 'uname -m': $(uname_m))
|
||||
$(info Attempting to detect HOST_ARCH from 'uname -m': $(uname_m))
|
||||
ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
|
||||
ARCH=X64
|
||||
HOST_ARCH=X64
|
||||
endif
|
||||
ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
|
||||
ARCH=IA32
|
||||
HOST_ARCH=IA32
|
||||
endif
|
||||
ifneq (,$(findstring aarch64,$(uname_m)))
|
||||
ARCH=AARCH64
|
||||
HOST_ARCH=AARCH64
|
||||
endif
|
||||
ifneq (,$(findstring arm,$(uname_m)))
|
||||
ARCH=ARM
|
||||
HOST_ARCH=ARM
|
||||
endif
|
||||
ifndef ARCH
|
||||
$(info Could not detected ARCH from uname results)
|
||||
$(error ARCH is not defined!)
|
||||
ifndef HOST_ARCH
|
||||
$(info Could not detected HOST_ARCH from uname results)
|
||||
$(error HOST_ARCH is not defined!)
|
||||
endif
|
||||
$(info Detected ARCH of $(ARCH) using uname.)
|
||||
$(info Detected HOST_ARCH of $(HOST_ARCH) using uname.)
|
||||
endif
|
||||
|
||||
export ARCH
|
||||
export HOST_ARCH
|
||||
|
||||
MAKEROOT = .
|
||||
|
||||
include Makefiles/header.makefile
|
||||
|
||||
all: makerootdir subdirs $(MAKEROOT)/libs
|
||||
@echo Finished building BaseTools C Tools with ARCH=$(ARCH)
|
||||
all: makerootdir subdirs
|
||||
@echo Finished building BaseTools C Tools with HOST_ARCH=$(HOST_ARCH)
|
||||
|
||||
LIBRARIES = Common
|
||||
VFRAUTOGEN = VfrCompile/VfrLexer.h
|
||||
# NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage
|
||||
APPLICATIONS = \
|
||||
BrotliCompress \
|
||||
VfrCompile \
|
||||
GnuGenBootSector \
|
||||
BootSectImage \
|
||||
BrotliCompress \
|
||||
EfiLdrImage \
|
||||
EfiRom \
|
||||
GenFfs \
|
||||
@@ -65,11 +67,13 @@ APPLICATIONS = \
|
||||
LzmaCompress \
|
||||
Split \
|
||||
TianoCompress \
|
||||
VolInfo \
|
||||
VfrCompile
|
||||
VolInfo
|
||||
|
||||
SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
|
||||
|
||||
$(LIBRARIES): $(MAKEROOT)/libs
|
||||
$(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
|
||||
|
||||
.PHONY: outputdirs
|
||||
makerootdir:
|
||||
-mkdir -p $(MAKEROOT)
|
||||
@@ -83,6 +87,9 @@ $(SUBDIRS):
|
||||
$(patsubst %,%-clean,$(sort $(SUBDIRS))):
|
||||
-$(MAKE) -C $(@:-clean=) clean
|
||||
|
||||
$(VFRAUTOGEN): VfrCompile/VfrSyntax.g
|
||||
$(MAKE) -C VfrCompile VfrLexer.h
|
||||
|
||||
clean: $(patsubst %,%-clean,$(sort $(SUBDIRS)))
|
||||
|
||||
clean: localClean
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenCrc32
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenFfs
|
||||
|
@@ -48,14 +48,17 @@ STATIC CHAR8 *mFfsFileType[] = {
|
||||
|
||||
STATIC CHAR8 *mAlignName[] = {
|
||||
"1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
|
||||
"1K", "2K", "4K", "8K", "16K", "32K", "64K"
|
||||
"1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
|
||||
"512K", "1M", "2M", "4M", "8M", "16M"
|
||||
};
|
||||
|
||||
STATIC CHAR8 *mFfsValidAlignName[] = {
|
||||
"8", "16", "128", "512", "1K", "4K", "32K", "64K"
|
||||
"8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K","256K",
|
||||
"512K", "1M", "2M", "4M", "8M", "16M"
|
||||
};
|
||||
|
||||
STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536};
|
||||
STATIC UINT32 mFfsValidAlign[] = {0, 8, 16, 128, 512, 1024, 4096, 32768, 65536, 131072, 262144,
|
||||
524288, 1048576, 2097152, 4194304, 8388608, 16777216};
|
||||
|
||||
STATIC EFI_GUID mZeroGuid = {0};
|
||||
|
||||
@@ -140,12 +143,13 @@ Returns:
|
||||
fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");
|
||||
fprintf (stdout, " -a FileAlign, --align FileAlign\n\
|
||||
FileAlign points to file alignment, which only support\n\
|
||||
the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n");
|
||||
the following align: 1,2,4,8,16,128,512,1K,4K,32K,64K\n\
|
||||
128K,256K,512K,1M,2M,4M,8M,16M\n");
|
||||
fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\
|
||||
Section file will be contained in this FFS file.\n");
|
||||
fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\
|
||||
SectionAlign points to section alignment, which support\n\
|
||||
the alignment scope 1~64K. It is specified together\n\
|
||||
the alignment scope 1~16M. It is specified together\n\
|
||||
with sectionfile to point its alignment in FFS file.\n");
|
||||
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
|
||||
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
|
||||
@@ -164,7 +168,7 @@ StringtoAlignment (
|
||||
|
||||
Routine Description:
|
||||
|
||||
Converts Align String to align value (1~64K).
|
||||
Converts Align String to align value (1~16M).
|
||||
|
||||
Arguments:
|
||||
|
||||
@@ -889,7 +893,12 @@ Returns:
|
||||
}
|
||||
VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
|
||||
|
||||
FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
|
||||
//FfsAlign larger than 7, set FFS_ATTRIB_DATA_ALIGNMENT2
|
||||
if (FfsAlign < 8) {
|
||||
FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
|
||||
} else {
|
||||
FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | ((FfsAlign & 0x7) << 3) | FFS_ATTRIB_DATA_ALIGNMENT2);
|
||||
}
|
||||
|
||||
//
|
||||
// Fill in checksums and state, these must be zero for checksumming
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenFv
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
This file contains the internal functions required to generate a Firmware Volume.
|
||||
|
||||
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
|
||||
This program and the accompanying materials
|
||||
@@ -464,57 +464,97 @@ Returns:
|
||||
case 0:
|
||||
//
|
||||
// 1 byte alignment
|
||||
//if bit 1 have set, 128K byte alignmnet
|
||||
//
|
||||
*Alignment = 0;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 17;
|
||||
} else {
|
||||
*Alignment = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
//
|
||||
// 16 byte alignment
|
||||
//if bit 1 have set, 256K byte alignment
|
||||
//
|
||||
*Alignment = 4;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 18;
|
||||
} else {
|
||||
*Alignment = 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
//
|
||||
// 128 byte alignment
|
||||
//if bit 1 have set, 512K byte alignment
|
||||
//
|
||||
*Alignment = 7;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 19;
|
||||
} else {
|
||||
*Alignment = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
//
|
||||
// 512 byte alignment
|
||||
//if bit 1 have set, 1M byte alignment
|
||||
//
|
||||
*Alignment = 9;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 20;
|
||||
} else {
|
||||
*Alignment = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
//
|
||||
// 1K byte alignment
|
||||
//if bit 1 have set, 2M byte alignment
|
||||
//
|
||||
*Alignment = 10;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 21;
|
||||
} else {
|
||||
*Alignment = 10;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
//
|
||||
// 4K byte alignment
|
||||
//if bit 1 have set, 4M byte alignment
|
||||
//
|
||||
*Alignment = 12;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 22;
|
||||
} else {
|
||||
*Alignment = 12;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
//
|
||||
// 32K byte alignment
|
||||
//if bit 1 have set , 8M byte alignment
|
||||
//
|
||||
*Alignment = 15;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 23;
|
||||
} else {
|
||||
*Alignment = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
//
|
||||
// 64K byte alignment
|
||||
//if bit 1 have set, 16M alignment
|
||||
//
|
||||
*Alignment = 16;
|
||||
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||
*Alignment = 24;
|
||||
} else {
|
||||
*Alignment = 16;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1060,7 +1100,7 @@ Returns:
|
||||
// Clear the alignment bits: these have become meaningless now that we have
|
||||
// adjusted the padding section.
|
||||
//
|
||||
FfsFile->Attributes &= ~FFS_ATTRIB_DATA_ALIGNMENT;
|
||||
FfsFile->Attributes &= ~(FFS_ATTRIB_DATA_ALIGNMENT | FFS_ATTRIB_DATA_ALIGNMENT2);
|
||||
|
||||
//
|
||||
// Recalculate the FFS header checksum. Instead of setting Header and State
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenFw
|
||||
|
@@ -2781,6 +2781,7 @@ Returns:
|
||||
EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;
|
||||
EFI_IMAGE_SECTION_HEADER *SectionHeader;
|
||||
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
|
||||
EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry;
|
||||
UINT32 *NewTimeStamp;
|
||||
|
||||
//
|
||||
@@ -2809,6 +2810,7 @@ Returns:
|
||||
// Resource Directory entry need to review.
|
||||
//
|
||||
Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
|
||||
Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
|
||||
if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
|
||||
if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
||||
@@ -2828,7 +2830,6 @@ Returns:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
|
||||
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
|
||||
if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
||||
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
|
||||
@@ -2892,6 +2893,19 @@ Returns:
|
||||
memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
|
||||
memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
|
||||
}
|
||||
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
|
||||
RsdsEntry = (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *) (FileBuffer + DebugEntry->FileOffset);
|
||||
if (RsdsEntry->Signature == CODEVIEW_SIGNATURE_MTOC) {
|
||||
// MTOC sets DebugDirectoryEntrySize to size of the .debug section, so fix it.
|
||||
if (!ZeroDebugFlag) {
|
||||
if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||
Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
|
||||
} else {
|
||||
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenPage
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenSec
|
||||
|
@@ -74,7 +74,8 @@ STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED",
|
||||
|
||||
STATIC CHAR8 *mAlignName[] = {
|
||||
"1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
|
||||
"1K", "2K", "4K", "8K", "16K", "32K", "64K"
|
||||
"1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",
|
||||
"512K", "1M", "2M", "4M", "8M", "16M"
|
||||
};
|
||||
|
||||
//
|
||||
@@ -184,7 +185,7 @@ Returns:
|
||||
used in Ver section.\n");
|
||||
fprintf (stdout, " --sectionalign SectionAlign\n\
|
||||
SectionAlign points to section alignment, which support\n\
|
||||
the alignment scope 1~64K. It is specified in same\n\
|
||||
the alignment scope 1~16M. It is specified in same\n\
|
||||
order that the section file is input.\n");
|
||||
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
|
||||
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
|
||||
@@ -356,7 +357,7 @@ StringtoAlignment (
|
||||
|
||||
Routine Description:
|
||||
|
||||
Converts Align String to align value (1~64K).
|
||||
Converts Align String to align value (1~16M).
|
||||
|
||||
Arguments:
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GenVtf
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = GnuGenBootSector
|
||||
|
@@ -4,7 +4,7 @@
|
||||
@par Revision Reference:
|
||||
Version 1.4.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials are licensed and made available
|
||||
under the terms and conditions of the BSD License which accompanies this
|
||||
@@ -63,6 +63,7 @@ typedef UINT8 EFI_FFS_FILE_STATE;
|
||||
// FFS File Attributes.
|
||||
//
|
||||
#define FFS_ATTRIB_LARGE_FILE 0x01
|
||||
#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02
|
||||
#define FFS_ATTRIB_FIXED 0x04
|
||||
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
|
||||
#define FFS_ATTRIB_CHECKSUM 0x40
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = LzmaCompress
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH = IA32
|
||||
HOST_ARCH = IA32
|
||||
|
||||
!INCLUDE Makefiles\ms.common
|
||||
|
||||
|
@@ -13,12 +13,12 @@
|
||||
|
||||
DEPFILES = $(OBJECTS:%.o=%.d)
|
||||
|
||||
$(MAKEROOT)/libs-$(ARCH):
|
||||
mkdir -p $(MAKEROOT)/libs-$(ARCH)
|
||||
$(MAKEROOT)/libs-$(HOST_ARCH):
|
||||
mkdir -p $(MAKEROOT)/libs-$(HOST_ARCH)
|
||||
|
||||
.PHONY: install
|
||||
install: $(MAKEROOT)/libs-$(ARCH) $(LIBRARY)
|
||||
cp $(LIBRARY) $(MAKEROOT)/libs-$(ARCH)
|
||||
install: $(MAKEROOT)/libs-$(HOST_ARCH) $(LIBRARY)
|
||||
cp $(LIBRARY) $(MAKEROOT)/libs-$(HOST_ARCH)
|
||||
|
||||
$(LIBRARY): $(OBJECTS)
|
||||
$(BUILD_AR) crs $@ $^
|
||||
|
@@ -1,10 +1,10 @@
|
||||
## @file
|
||||
#
|
||||
# The makefile can be invoked with
|
||||
# ARCH = x86_64 or x64 for EM64T build
|
||||
# ARCH = ia32 or IA32 for IA32 build
|
||||
# ARCH = ia64 or IA64 for IA64 build
|
||||
# ARCH = Arm or ARM for ARM build
|
||||
# HOST_ARCH = x86_64 or x64 for EM64T build
|
||||
# HOST_ARCH = ia32 or IA32 for IA32 build
|
||||
# HOST_ARCH = ia64 or IA64 for IA64 build
|
||||
# HOST_ARCH = Arm or ARM for ARM build
|
||||
#
|
||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
@@ -15,7 +15,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
|
||||
CYGWIN:=$(findstring CYGWIN, $(shell uname -s))
|
||||
LINUX:=$(findstring Linux, $(shell uname -s))
|
||||
@@ -27,19 +27,19 @@ BUILD_AS ?= gcc
|
||||
BUILD_AR ?= ar
|
||||
BUILD_LD ?= ld
|
||||
LINKER ?= $(BUILD_CC)
|
||||
ifeq ($(ARCH), IA32)
|
||||
ifeq ($(HOST_ARCH), IA32)
|
||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Ia32/
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), X64)
|
||||
ifeq ($(HOST_ARCH), X64)
|
||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/X64/
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), ARM)
|
||||
ifeq ($(HOST_ARCH), ARM)
|
||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Arm/
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), AARCH64)
|
||||
ifeq ($(HOST_ARCH), AARCH64)
|
||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
|
||||
endif
|
||||
|
||||
@@ -54,7 +54,7 @@ endif
|
||||
BUILD_LFLAGS =
|
||||
BUILD_CXXFLAGS = -Wno-unused-result
|
||||
|
||||
ifeq ($(ARCH), IA32)
|
||||
ifeq ($(HOST_ARCH), IA32)
|
||||
#
|
||||
# Snow Leopard is a 32-bit and 64-bit environment. uname -m returns i386, but gcc defaults
|
||||
# to x86_64. So make sure tools match uname -m. You can manual have a 64-bit kernal on Snow Leopard
|
||||
|
@@ -19,8 +19,8 @@
|
||||
!ERROR "BASE_TOOLS_PATH is not set! Please run build_tools.bat at first!"
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ARCH
|
||||
ARCH = IA32
|
||||
!IFNDEF HOST_ARCH
|
||||
HOST_ARCH = IA32
|
||||
!ENDIF
|
||||
|
||||
MAKE = nmake -nologo
|
||||
@@ -36,7 +36,7 @@ LIB_PATH = $(BASE_TOOLS_PATH)\Lib
|
||||
SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin
|
||||
SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib
|
||||
|
||||
!IF "$(ARCH)"=="IA32"
|
||||
!IF "$(HOST_ARCH)"=="IA32"
|
||||
ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32
|
||||
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32
|
||||
LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win32
|
||||
@@ -44,7 +44,7 @@ SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win32
|
||||
SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32
|
||||
!ENDIF
|
||||
|
||||
!IF "$(ARCH)"=="X64"
|
||||
!IF "$(HOST_ARCH)"=="X64"
|
||||
ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64
|
||||
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64
|
||||
LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win64
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = Split
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = TianoCompress
|
||||
|
@@ -1753,6 +1753,7 @@ Returns:
|
||||
SCRATCH_DATA *Scratch;
|
||||
UINT8 *Src;
|
||||
UINT32 OrigSize;
|
||||
UINT32 CompSize;
|
||||
|
||||
SetUtilityName(UTILITY_NAME);
|
||||
|
||||
@@ -1761,6 +1762,7 @@ Returns:
|
||||
OutBuffer = NULL;
|
||||
Scratch = NULL;
|
||||
OrigSize = 0;
|
||||
CompSize = 0;
|
||||
InputLength = 0;
|
||||
InputFileName = NULL;
|
||||
OutputFileName = NULL;
|
||||
@@ -1979,15 +1981,25 @@ Returns:
|
||||
if (DebugMode) {
|
||||
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
|
||||
}
|
||||
|
||||
if (InputLength < 8){
|
||||
Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);
|
||||
goto ERROR;
|
||||
}
|
||||
//
|
||||
// Get Compressed file original size
|
||||
//
|
||||
Src = (UINT8 *)FileBuffer;
|
||||
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
||||
CompSize = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);
|
||||
|
||||
//
|
||||
// Allocate OutputBuffer
|
||||
//
|
||||
if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {
|
||||
Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);
|
||||
goto ERROR;
|
||||
}
|
||||
OutBuffer = (UINT8 *)malloc(OrigSize);
|
||||
if (OutBuffer == NULL) {
|
||||
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
|
||||
@@ -2066,11 +2078,11 @@ Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
|
||||
Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
|
||||
|
||||
while (NumOfBits > Sd->mBitCount) {
|
||||
|
||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
|
||||
if (Sd->mCompSize > 0) {
|
||||
//
|
||||
@@ -2171,12 +2183,16 @@ Returns:
|
||||
UINT16 Mask;
|
||||
UINT16 WordOfStart;
|
||||
UINT16 WordOfCount;
|
||||
UINT16 MaxTableLength;
|
||||
|
||||
for (Index = 0; Index <= 16; Index++) {
|
||||
Count[Index] = 0;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumOfChar; Index++) {
|
||||
if (BitLen[Index] > 16) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Count[BitLen[Index]]++;
|
||||
}
|
||||
|
||||
@@ -2220,6 +2236,7 @@ Returns:
|
||||
|
||||
Avail = NumOfChar;
|
||||
Mask = (UINT16) (1U << (15 - TableBits));
|
||||
MaxTableLength = (UINT16) (1U << TableBits);
|
||||
|
||||
for (Char = 0; Char < NumOfChar; Char++) {
|
||||
|
||||
@@ -2233,6 +2250,9 @@ Returns:
|
||||
if (Len <= TableBits) {
|
||||
|
||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||
if (Index >= MaxTableLength) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Table[Index] = Char;
|
||||
}
|
||||
|
||||
@@ -2617,14 +2637,25 @@ Returns: (VOID)
|
||||
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
|
||||
|
||||
BytesRemain--;
|
||||
|
||||
while ((INT16) (BytesRemain) >= 0) {
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
goto Done ;
|
||||
}
|
||||
if (DataIdx >= Sd->mOrigSize) {
|
||||
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||
goto Done ;
|
||||
}
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
|
||||
BytesRemain--;
|
||||
}
|
||||
//
|
||||
// Once mOutBuf is fully filled, directly return
|
||||
//
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
goto Done ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = VfrCompile
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
ARCH ?= IA32
|
||||
HOST_ARCH ?= IA32
|
||||
MAKEROOT ?= ..
|
||||
|
||||
APPNAME = VolInfo
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# parse FDF file
|
||||
#
|
||||
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -2340,7 +2340,8 @@ class FdfParser(object):
|
||||
|
||||
AlignValue = None
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
AlignValue = self.__Token
|
||||
|
||||
@@ -2608,7 +2609,8 @@ class FdfParser(object):
|
||||
|
||||
AlignValue = None
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
AlignValue = self.__Token
|
||||
|
||||
@@ -2924,7 +2926,8 @@ class FdfParser(object):
|
||||
|
||||
AlignValue = ""
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||
AlignValue = self.__Token
|
||||
|
||||
@@ -2988,7 +2991,8 @@ class FdfParser(object):
|
||||
CheckSum = True
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
||||
raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
|
||||
@@ -3062,7 +3066,8 @@ class FdfParser(object):
|
||||
FvImageSectionObj.FvFileType = self.__Token
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||
FvImageSectionObj.Alignment = self.__Token
|
||||
|
||||
@@ -3129,7 +3134,8 @@ class FdfParser(object):
|
||||
EfiSectionObj.BuildNum = self.__Token
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
||||
raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
|
||||
|
@@ -67,8 +67,26 @@ def GetVariableOffset(mapfilepath, efifilepath, varnames):
|
||||
if (firstline.startswith("Archive member included ") and
|
||||
firstline.endswith(" file (symbol)")):
|
||||
return _parseForGCC(lines, efifilepath, varnames)
|
||||
if firstline.startswith("# Path:"):
|
||||
return _parseForXcode(lines, efifilepath, varnames)
|
||||
return _parseGeneral(lines, efifilepath, varnames)
|
||||
|
||||
def _parseForXcode(lines, efifilepath, varnames):
|
||||
status = 0
|
||||
ret = []
|
||||
for index, line in enumerate(lines):
|
||||
line = line.strip()
|
||||
if status == 0 and line == "# Symbols:":
|
||||
status = 1
|
||||
continue
|
||||
if status == 1 and len(line) != 0:
|
||||
for varname in varnames:
|
||||
if varname in line:
|
||||
m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname, line)
|
||||
if m != None:
|
||||
ret.append((varname, m.group(1)))
|
||||
return ret
|
||||
|
||||
def _parseForGCC(lines, efifilepath, varnames):
|
||||
""" Parse map file generated by GCC linker """
|
||||
status = 0
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# process data section generation
|
||||
#
|
||||
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -79,8 +79,10 @@ class DataSection (DataSectionClassObject):
|
||||
ImageObj = PeImageClass (Filename)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
self.Alignment = str (ImageObj.SectionAlignment)
|
||||
else:
|
||||
elif ImageObj.SectionAlignment < 0x100000:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||
else:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||
|
||||
NoStrip = True
|
||||
if self.SecType in ('TE', 'PE32'):
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# process rule section generation
|
||||
#
|
||||
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -231,8 +231,10 @@ class EfiSection (EfiSectionClassObject):
|
||||
ImageObj = PeImageClass (File)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
Align = str (ImageObj.SectionAlignment)
|
||||
else:
|
||||
elif ImageObj.SectionAlignment < 0x100000:
|
||||
Align = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||
else:
|
||||
Align = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||
|
||||
if File[(len(File)-4):] == '.efi':
|
||||
MapFile = File.replace('.efi', '.map')
|
||||
|
@@ -2763,7 +2763,8 @@ class FdfParser:
|
||||
while True:
|
||||
AlignValue = None
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
#For FFS, Auto is default option same to ""
|
||||
if not self.__Token == "Auto":
|
||||
@@ -2822,7 +2823,8 @@ class FdfParser:
|
||||
FfsFileObj.CheckSum = True
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
#For FFS, Auto is default option same to ""
|
||||
if not self.__Token == "Auto":
|
||||
@@ -2893,7 +2895,8 @@ class FdfParser:
|
||||
|
||||
AlignValue = None
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
AlignValue = self.__Token
|
||||
|
||||
@@ -3182,7 +3185,8 @@ class FdfParser:
|
||||
|
||||
AlignValue = None
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
AlignValue = self.__Token
|
||||
|
||||
@@ -3773,7 +3777,8 @@ class FdfParser:
|
||||
|
||||
AlignValue = ""
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
#For FFS, Auto is default option same to ""
|
||||
if not self.__Token == "Auto":
|
||||
@@ -3822,7 +3827,8 @@ class FdfParser:
|
||||
|
||||
SectAlignment = ""
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
||||
raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
|
||||
@@ -3901,7 +3907,8 @@ class FdfParser:
|
||||
FvImageSectionObj.FvFileType = self.__Token
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
FvImageSectionObj.Alignment = self.__Token
|
||||
|
||||
@@ -3968,7 +3975,8 @@ class FdfParser:
|
||||
EfiSectionObj.BuildNum = self.__Token
|
||||
|
||||
if self.__GetAlignment():
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
|
||||
if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K",
|
||||
"256K", "512K", "1M", "2M", "4M", "8M", "16M"):
|
||||
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
||||
raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# process FFS generation from INF statement
|
||||
#
|
||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
@@ -728,8 +728,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||
ImageObj = PeImageClass (File)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
self.Alignment = str (ImageObj.SectionAlignment)
|
||||
else:
|
||||
elif ImageObj.SectionAlignment < 0x100000:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||
else:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||
|
||||
if not NoStrip:
|
||||
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
||||
@@ -767,8 +769,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||
ImageObj = PeImageClass (GenSecInputFile)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
self.Alignment = str (ImageObj.SectionAlignment)
|
||||
else:
|
||||
elif ImageObj.SectionAlignment < 0x100000:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||
else:
|
||||
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||
|
||||
if not NoStrip:
|
||||
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
||||
|
@@ -196,9 +196,12 @@ class FV (FvClassObject):
|
||||
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
||||
# FvAlignmentValue is larger than or equal to 1K
|
||||
if FvAlignmentValue >= 0x400:
|
||||
if FvAlignmentValue >= 0x10000:
|
||||
#The max alignment supported by FFS is 64K.
|
||||
self.FvAlignment = "64K"
|
||||
if FvAlignmentValue >= 0x100000:
|
||||
#The max alignment supported by FFS is 16M.
|
||||
if FvAlignmentValue >= 0x1000000:
|
||||
self.FvAlignment = "16M"
|
||||
else:
|
||||
self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
|
||||
else:
|
||||
self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"
|
||||
else:
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# process FV image section generation
|
||||
#
|
||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -80,9 +80,12 @@ class FvImageSection(FvImageSectionClassObject):
|
||||
|
||||
# MaxFvAlignment is larger than or equal to 1K
|
||||
if MaxFvAlignment >= 0x400:
|
||||
if MaxFvAlignment >= 0x10000:
|
||||
#The max alignment supported by FFS is 64K.
|
||||
self.Alignment = "64K"
|
||||
if MaxFvAlignment >= 0x100000:
|
||||
#The max alignment supported by FFS is 16M.
|
||||
if MaxFvAlignment >=1000000:
|
||||
self.Alignment = "16M"
|
||||
else:
|
||||
self.Alignment = str(MaxFvAlignment / 0x100000) + "M"
|
||||
else:
|
||||
self.Alignment = str (MaxFvAlignment / 0x400) + "K"
|
||||
else:
|
||||
@@ -117,9 +120,12 @@ class FvImageSection(FvImageSectionClassObject):
|
||||
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
||||
# FvAlignmentValue is larger than or equal to 1K
|
||||
if FvAlignmentValue >= 0x400:
|
||||
if FvAlignmentValue >= 0x10000:
|
||||
#The max alignment supported by FFS is 64K.
|
||||
self.Alignment = "64K"
|
||||
if FvAlignmentValue >= 0x100000:
|
||||
#The max alignment supported by FFS is 16M.
|
||||
if FvAlignmentValue >= 0x1000000:
|
||||
self.Alignment = "16M"
|
||||
else:
|
||||
self.Alignment = str(FvAlignmentValue / 0x100000) + "M"
|
||||
else:
|
||||
self.Alignment = str (FvAlignmentValue / 0x400) + "K"
|
||||
else:
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# Global variables for GenFds
|
||||
#
|
||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
@@ -420,8 +420,10 @@ class GenFdsGlobalVariable:
|
||||
def GetAlignment (AlignString):
|
||||
if AlignString == None:
|
||||
return 0
|
||||
if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):
|
||||
if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K"):
|
||||
return int (AlignString.rstrip('K')) * 1024
|
||||
elif AlignString in ("1M", "2M", "4M", "8M", "16M"):
|
||||
return int (AlignString.rstrip('M')) * 1024 * 1024
|
||||
else:
|
||||
return int (AlignString)
|
||||
|
||||
@@ -429,7 +431,7 @@ class GenFdsGlobalVariable:
|
||||
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
|
||||
SectionAlign=None):
|
||||
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
|
||||
mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K"]
|
||||
mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
|
||||
if Fixed == True:
|
||||
Cmd += ["-x"]
|
||||
if CheckSum:
|
||||
|
@@ -5,7 +5,7 @@
|
||||
# PCD Name Offset in binary
|
||||
# ======== ================
|
||||
#
|
||||
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -58,8 +58,25 @@ def parsePcdInfoFromMapFile(mapfilepath, efifilepath):
|
||||
if (firstline.startswith("Archive member included ") and
|
||||
firstline.endswith(" file (symbol)")):
|
||||
return _parseForGCC(lines, efifilepath)
|
||||
if firstline.startswith("# Path:"):
|
||||
return _parseForXcode(lines, efifilepath)
|
||||
return _parseGeneral(lines, efifilepath)
|
||||
|
||||
def _parseForXcode(lines, efifilepath):
|
||||
status = 0
|
||||
pcds = []
|
||||
for index, line in enumerate(lines):
|
||||
line = line.strip()
|
||||
if status == 0 and line == "# Symbols:":
|
||||
status = 1
|
||||
continue
|
||||
if status == 1 and len(line) != 0:
|
||||
if '_gPcd_BinaryPatch_' in line:
|
||||
m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*_gPcd_BinaryPatch_([\w]+))', line)
|
||||
if m != None:
|
||||
pcds.append((m.groups(0)[3], int(m.groups(0)[0], 16)))
|
||||
return pcds
|
||||
|
||||
def _parseForGCC(lines, efifilepath):
|
||||
""" Parse map file generated by GCC linker """
|
||||
status = 0
|
||||
|
@@ -4,7 +4,7 @@
|
||||
# {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf}}
|
||||
# This tool has been tested with OpenSSL 1.0.1e 11 Feb 2013
|
||||
#
|
||||
# Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -176,7 +176,7 @@ if __name__ == '__main__':
|
||||
#
|
||||
# Sign the input file using the specified private key and capture signature from STDOUT
|
||||
#
|
||||
Process = subprocess.Popen('%s sha256 -sign "%s"' % (OpenSslCommand, args.PrivateKeyFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||
Process = subprocess.Popen('%s dgst -sha256 -sign "%s"' % (OpenSslCommand, args.PrivateKeyFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||
Signature = Process.communicate(input=FullInputFileBuffer)[0]
|
||||
if Process.returncode <> 0:
|
||||
sys.exit(Process.returncode)
|
||||
@@ -225,7 +225,7 @@ if __name__ == '__main__':
|
||||
#
|
||||
# Verify signature
|
||||
#
|
||||
Process = subprocess.Popen('%s sha256 -prverify "%s" -signature %s' % (OpenSslCommand, args.PrivateKeyFileName, args.OutputFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||
Process = subprocess.Popen('%s dgst -sha256 -prverify "%s" -signature %s' % (OpenSslCommand, args.PrivateKeyFileName, args.OutputFileName), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||
Process.communicate(input=FullInputFileBuffer)
|
||||
if Process.returncode <> 0:
|
||||
print 'ERROR: Verification failed'
|
||||
|
@@ -16,6 +16,12 @@
|
||||
@echo off
|
||||
goto :main
|
||||
|
||||
:set_vsvars
|
||||
for /f "usebackq tokens=1* delims=: " %%i in (`%*`) do (
|
||||
if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
|
||||
)
|
||||
goto :EOF
|
||||
|
||||
:read_vsvars
|
||||
@rem Do nothing if already found, otherwise call vsvars32.bat if there
|
||||
if defined VCINSTALLDIR goto :EOF
|
||||
@@ -33,6 +39,8 @@ REM (Or invoke the relevant vsvars32 file beforehand).
|
||||
|
||||
:main
|
||||
if defined VCINSTALLDIR goto :done
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" call :set_vsvars "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" call :set_vsvars "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
if defined VS140COMNTOOLS call :read_vsvars "%VS140COMNTOOLS%"
|
||||
if defined VS120COMNTOOLS call :read_vsvars "%VS120COMNTOOLS%"
|
||||
if defined VS110COMNTOOLS call :read_vsvars "%VS110COMNTOOLS%"
|
||||
|
@@ -3,7 +3,7 @@
|
||||
@REM however it may be executed directly from the BaseTools project folder
|
||||
@REM if the file is not executed within a WORKSPACE\BaseTools folder.
|
||||
@REM
|
||||
@REM Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
@REM Copyright (c) 2016-2017, Intel Corporation. All rights reserved.<BR>
|
||||
@REM
|
||||
@REM This program and the accompanying materials are licensed and made available
|
||||
@REM under the terms and conditions of the BSD License which accompanies this
|
||||
@@ -90,6 +90,37 @@ if defined VS140COMNTOOLS (
|
||||
)
|
||||
)
|
||||
|
||||
@REM set VS2017
|
||||
if not defined VS150COMNTOOLS (
|
||||
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=1* delims=: " %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"`) do (
|
||||
if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
|
||||
)
|
||||
) else if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" (
|
||||
for /f "usebackq tokens=1* delims=: " %%i in (`"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"`) do (
|
||||
if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
|
||||
)
|
||||
) else (
|
||||
goto SetWinDDK
|
||||
)
|
||||
)
|
||||
|
||||
if defined VCToolsInstallDir (
|
||||
if not defined VS2017_PREFIX (
|
||||
set "VS2017_PREFIX=%VCToolsInstallDir%"
|
||||
)
|
||||
)
|
||||
if not defined WINSDK10_PREFIX (
|
||||
if defined WindowsSdkVerBinPath (
|
||||
set "WINSDK10_PREFIX=%WindowsSdkVerBinPath%"
|
||||
) else if exist "%ProgramFiles(x86)%\Windows Kits\10\bin" (
|
||||
set "WINSDK10_PREFIX=%ProgramFiles(x86)%\Windows Kits\10\bin\"
|
||||
) else if exist "%ProgramFiles%\Windows Kits\10\bin" (
|
||||
set "WINSDK10_PREFIX=%ProgramFiles%\Windows Kits\10\bin\"
|
||||
)
|
||||
)
|
||||
|
||||
:SetWinDDK
|
||||
if not defined WINDDK3790_PREFIX (
|
||||
set WINDDK3790_PREFIX=C:\WINDDK\3790.1830\bin\
|
||||
)
|
||||
|
@@ -93,11 +93,11 @@ Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
|
||||
Sd->mBitBuf = (UINT32) LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);
|
||||
|
||||
while (NumOfBits > Sd->mBitCount) {
|
||||
|
||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
|
||||
Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
|
||||
|
||||
if (Sd->mCompSize > 0) {
|
||||
//
|
||||
|
@@ -137,6 +137,7 @@
|
||||
gEfiLegacyBiosProtocolGuid ## PRODUCES
|
||||
gEfiSerialIoProtocolGuid ## CONSUMES
|
||||
gEfiSioProtocolGuid ## CONSUMES
|
||||
gEdkiiIoMmuProtocolGuid ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion ## CONSUMES
|
||||
|
@@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Protocol/SerialIo.h>
|
||||
#include <Protocol/SuperIo.h>
|
||||
#include <Protocol/IoMmu.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
@@ -41,7 +41,7 @@ BOOLEAN mIgnoreBbsUpdateFlag;
|
||||
BOOLEAN mVgaInstallationInProgress = FALSE;
|
||||
UINT32 mRomCount = 0x00;
|
||||
ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES];
|
||||
|
||||
EDKII_IOMMU_PROTOCOL *mIoMmu;
|
||||
|
||||
/**
|
||||
Query shadowed legacy ROM parameters registered by RomShadow() previously.
|
||||
@@ -2696,6 +2696,61 @@ Done:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Let IOMMU grant DMA access for the PCI device.
|
||||
|
||||
@param PciHandle The EFI handle for the PCI device.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes The number of bytes to map.
|
||||
|
||||
@retval EFI_SUCCESS The DMA access is granted.
|
||||
**/
|
||||
EFI_STATUS
|
||||
IoMmuGrantAccess (
|
||||
IN EFI_HANDLE PciHandle,
|
||||
IN EFI_PHYSICAL_ADDRESS HostAddress,
|
||||
IN UINTN NumberOfBytes
|
||||
)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS DeviceAddress;
|
||||
VOID *Mapping;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (PciHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
if (mIoMmu == NULL) {
|
||||
gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmu);
|
||||
}
|
||||
if (mIoMmu != NULL) {
|
||||
Status = mIoMmu->Map (
|
||||
mIoMmu,
|
||||
EdkiiIoMmuOperationBusMasterCommonBuffer,
|
||||
(VOID *)(UINTN)HostAddress,
|
||||
&NumberOfBytes,
|
||||
&DeviceAddress,
|
||||
&Mapping
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuMap - %r\n", Status));
|
||||
} else {
|
||||
ASSERT (DeviceAddress == HostAddress);
|
||||
Status = mIoMmu->SetAttribute (
|
||||
mIoMmu,
|
||||
PciHandle,
|
||||
Mapping,
|
||||
EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuSetAttribute - %r\n", Status));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Load a legacy PC-AT OPROM on the PciHandle device. Return information
|
||||
about how many disks were added by the OPROM and the shadow address and
|
||||
@@ -2978,6 +3033,21 @@ LegacyBiosInstallPciRom (
|
||||
RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Grant access for below 1M
|
||||
// BDA/EBDA/LowPMM and scratch memory for OPROM.
|
||||
//
|
||||
IoMmuGrantAccess (PciHandle, 0, SIZE_1MB);
|
||||
//
|
||||
// Grant access for HiPmm
|
||||
//
|
||||
IoMmuGrantAccess (
|
||||
PciHandle,
|
||||
Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemory,
|
||||
Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemorySizeInBytes
|
||||
);
|
||||
|
||||
//
|
||||
// Shadow and initialize the OpROM.
|
||||
//
|
||||
|
@@ -30,14 +30,14 @@ FillBuf (
|
||||
//
|
||||
// Left shift NumOfBits of bits in advance
|
||||
//
|
||||
Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
|
||||
Sd->mBitBuf = (UINT32) LShiftU64 (((UINT64)Sd->mBitBuf), NumOfBits);
|
||||
|
||||
//
|
||||
// Copy data needed in bytes into mSbuBitBuf
|
||||
//
|
||||
while (NumOfBits > Sd->mBitCount) {
|
||||
|
||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
||||
NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
|
||||
Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
|
||||
|
||||
if (Sd->mCompSize > 0) {
|
||||
//
|
||||
@@ -143,6 +143,7 @@ MakeTable (
|
||||
UINT16 Mask;
|
||||
UINT16 WordOfStart;
|
||||
UINT16 WordOfCount;
|
||||
UINT16 MaxTableLength;
|
||||
|
||||
//
|
||||
// The maximum mapping table width supported by this internal
|
||||
@@ -155,6 +156,9 @@ MakeTable (
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumOfChar; Index++) {
|
||||
if (BitLen[Index] > 16) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Count[BitLen[Index]]++;
|
||||
}
|
||||
|
||||
@@ -196,6 +200,7 @@ MakeTable (
|
||||
|
||||
Avail = NumOfChar;
|
||||
Mask = (UINT16) (1U << (15 - TableBits));
|
||||
MaxTableLength = (UINT16) (1U << TableBits);
|
||||
|
||||
for (Char = 0; Char < NumOfChar; Char++) {
|
||||
|
||||
@@ -209,6 +214,9 @@ MakeTable (
|
||||
if (Len <= TableBits) {
|
||||
|
||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||
if (Index >= MaxTableLength) {
|
||||
return (UINT16) BAD_TABLE;
|
||||
}
|
||||
Table[Index] = Char;
|
||||
}
|
||||
|
||||
@@ -615,13 +623,23 @@ Decode (
|
||||
//
|
||||
BytesRemain--;
|
||||
while ((INT16) (BytesRemain) >= 0) {
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
goto Done ;
|
||||
}
|
||||
if (DataIdx >= Sd->mOrigSize) {
|
||||
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||
goto Done ;
|
||||
}
|
||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||
|
||||
BytesRemain--;
|
||||
}
|
||||
//
|
||||
// Once mOutBuf is fully filled, directly return
|
||||
//
|
||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||
goto Done ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +706,7 @@ UefiDecompressGetInfo (
|
||||
}
|
||||
|
||||
CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
|
||||
if (SourceSize < (CompressedSize + 8)) {
|
||||
if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@@ -194,6 +194,17 @@ ASM_PFX(AsmGetPeiCoreOffset):
|
||||
mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; Empty function for WHOLEARCHIVE build option
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
|
@@ -53,6 +53,17 @@ ASM_PFX(FspApiCommonContinue):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; Empty function for WHOLEARCHIVE build option
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
|
@@ -1,5 +1,5 @@
|
||||
;
|
||||
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -81,7 +81,7 @@ ASM_PFX(AsmExecute32BitCode):
|
||||
;
|
||||
mov rax, dword 0x10 ; load long mode selector
|
||||
shl rax, 32
|
||||
mov r9, ReloadCS ;Assume the ReloadCS is under 4G
|
||||
lea r9, [ReloadCS] ;Assume the ReloadCS is under 4G
|
||||
or rax, r9
|
||||
push rax
|
||||
;
|
||||
@@ -95,7 +95,7 @@ ASM_PFX(AsmExecute32BitCode):
|
||||
; save the 32-bit function entry and the return address into stack which will be
|
||||
; retrieve in compatibility mode.
|
||||
;
|
||||
mov rax, ReturnBack ;Assume the ReloadCS is under 4G
|
||||
lea rax, [ReturnBack] ;Assume the ReloadCS is under 4G
|
||||
shl rax, 32
|
||||
or rax, rcx
|
||||
push rax
|
||||
@@ -110,7 +110,7 @@ ASM_PFX(AsmExecute32BitCode):
|
||||
;
|
||||
mov rcx, dword 0x8 ; load compatible mode selector
|
||||
shl rcx, 32
|
||||
mov rdx, Compatible ; assume address < 4G
|
||||
lea rdx, [Compatible] ; assume address < 4G
|
||||
or rcx, rdx
|
||||
push rcx
|
||||
retf
|
||||
@@ -208,7 +208,7 @@ ReloadCS:
|
||||
;
|
||||
pop r9 ; get CS
|
||||
shl r9, 32 ; rcx[32..47] <- Cs
|
||||
mov rcx, .0
|
||||
lea rcx, [.0]
|
||||
or rcx, r9
|
||||
push rcx
|
||||
retf
|
||||
|
544
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c
Normal file
544
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c
Normal file
@@ -0,0 +1,544 @@
|
||||
/** @file
|
||||
BmDma related function
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
// TBD: May make it a policy
|
||||
#define DMA_MEMORY_TOP MAX_UINTN
|
||||
//#define DMA_MEMORY_TOP 0x0000000001FFFFFFULL
|
||||
|
||||
#define MAP_HANDLE_INFO_SIGNATURE SIGNATURE_32 ('H', 'M', 'A', 'P')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
LIST_ENTRY Link;
|
||||
EFI_HANDLE DeviceHandle;
|
||||
UINT64 IoMmuAccess;
|
||||
} MAP_HANDLE_INFO;
|
||||
#define MAP_HANDLE_INFO_FROM_LINK(a) CR (a, MAP_HANDLE_INFO, Link, MAP_HANDLE_INFO_SIGNATURE)
|
||||
|
||||
#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
LIST_ENTRY Link;
|
||||
EDKII_IOMMU_OPERATION Operation;
|
||||
UINTN NumberOfBytes;
|
||||
UINTN NumberOfPages;
|
||||
EFI_PHYSICAL_ADDRESS HostAddress;
|
||||
EFI_PHYSICAL_ADDRESS DeviceAddress;
|
||||
LIST_ENTRY HandleList;
|
||||
} MAP_INFO;
|
||||
#define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link, MAP_INFO_SIGNATURE)
|
||||
|
||||
LIST_ENTRY gMaps = INITIALIZE_LIST_HEAD_VARIABLE(gMaps);
|
||||
|
||||
/**
|
||||
This function fills DeviceHandle/IoMmuAccess to the MAP_HANDLE_INFO,
|
||||
based upon the DeviceAddress.
|
||||
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[in] DeviceAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SyncDeviceHandleToMapInfo (
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
IN EFI_PHYSICAL_ADDRESS DeviceAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
)
|
||||
{
|
||||
MAP_INFO *MapInfo;
|
||||
MAP_HANDLE_INFO *MapHandleInfo;
|
||||
LIST_ENTRY *Link;
|
||||
EFI_TPL OriginalTpl;
|
||||
|
||||
//
|
||||
// Find MapInfo according to DeviceAddress
|
||||
//
|
||||
OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
|
||||
MapInfo = NULL;
|
||||
for (Link = GetFirstNode (&gMaps)
|
||||
; !IsNull (&gMaps, Link)
|
||||
; Link = GetNextNode (&gMaps, Link)
|
||||
) {
|
||||
MapInfo = MAP_INFO_FROM_LINK (Link);
|
||||
if (MapInfo->DeviceAddress == DeviceAddress) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((MapInfo == NULL) || (MapInfo->DeviceAddress != DeviceAddress)) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: DeviceAddress(0x%lx) - not found\n", DeviceAddress));
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Find MapHandleInfo according to DeviceHandle
|
||||
//
|
||||
MapHandleInfo = NULL;
|
||||
for (Link = GetFirstNode (&MapInfo->HandleList)
|
||||
; !IsNull (&MapInfo->HandleList, Link)
|
||||
; Link = GetNextNode (&MapInfo->HandleList, Link)
|
||||
) {
|
||||
MapHandleInfo = MAP_HANDLE_INFO_FROM_LINK (Link);
|
||||
if (MapHandleInfo->DeviceHandle == DeviceHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((MapHandleInfo != NULL) && (MapHandleInfo->DeviceHandle == DeviceHandle)) {
|
||||
MapHandleInfo->IoMmuAccess = IoMmuAccess;
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// No DeviceHandle
|
||||
// Initialize and insert the MAP_HANDLE_INFO structure
|
||||
//
|
||||
MapHandleInfo = AllocatePool (sizeof (MAP_HANDLE_INFO));
|
||||
if (MapHandleInfo == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: %r\n", EFI_OUT_OF_RESOURCES));
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
return ;
|
||||
}
|
||||
|
||||
MapHandleInfo->Signature = MAP_HANDLE_INFO_SIGNATURE;
|
||||
MapHandleInfo->DeviceHandle = DeviceHandle;
|
||||
MapHandleInfo->IoMmuAccess = IoMmuAccess;
|
||||
|
||||
InsertTailList (&MapInfo->HandleList, &MapHandleInfo->Link);
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Provides the controller-specific addresses required to access system memory from a
|
||||
DMA bus master.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Operation Indicates if the bus master is going to read or write to system memory.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
|
||||
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuMap (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EDKII_IOMMU_OPERATION Operation,
|
||||
IN VOID *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||
MAP_INFO *MapInfo;
|
||||
EFI_PHYSICAL_ADDRESS DmaMemoryTop;
|
||||
BOOLEAN NeedRemap;
|
||||
EFI_TPL OriginalTpl;
|
||||
|
||||
if (NumberOfBytes == NULL || DeviceAddress == NULL ||
|
||||
Mapping == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuMap: ==> 0x%08x - 0x%08x (%x)\n", HostAddress, *NumberOfBytes, Operation));
|
||||
|
||||
//
|
||||
// Make sure that Operation is valid
|
||||
//
|
||||
if ((UINT32) Operation >= EdkiiIoMmuOperationMaximum) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
NeedRemap = FALSE;
|
||||
PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
|
||||
|
||||
DmaMemoryTop = DMA_MEMORY_TOP;
|
||||
|
||||
//
|
||||
// Alignment check
|
||||
//
|
||||
if ((*NumberOfBytes != ALIGN_VALUE(*NumberOfBytes, SIZE_4KB)) ||
|
||||
(PhysicalAddress != ALIGN_VALUE(PhysicalAddress, SIZE_4KB))) {
|
||||
if ((Operation == EdkiiIoMmuOperationBusMasterCommonBuffer) ||
|
||||
(Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64)) {
|
||||
//
|
||||
// The input buffer might be a subset from IoMmuAllocateBuffer.
|
||||
// Skip the check.
|
||||
//
|
||||
} else {
|
||||
NeedRemap = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((PhysicalAddress + *NumberOfBytes) >= DMA_MEMORY_TOP) {
|
||||
NeedRemap = TRUE;
|
||||
}
|
||||
|
||||
if (((Operation != EdkiiIoMmuOperationBusMasterRead64 &&
|
||||
Operation != EdkiiIoMmuOperationBusMasterWrite64 &&
|
||||
Operation != EdkiiIoMmuOperationBusMasterCommonBuffer64)) &&
|
||||
((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
|
||||
//
|
||||
// If the root bridge or the device cannot handle performing DMA above
|
||||
// 4GB but any part of the DMA transfer being mapped is above 4GB, then
|
||||
// map the DMA transfer to a buffer below 4GB.
|
||||
//
|
||||
NeedRemap = TRUE;
|
||||
DmaMemoryTop = MIN (DmaMemoryTop, SIZE_4GB - 1);
|
||||
}
|
||||
|
||||
if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
|
||||
Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
|
||||
if (NeedRemap) {
|
||||
//
|
||||
// Common Buffer operations can not be remapped. If the common buffer
|
||||
// is above 4GB, then it is not possible to generate a mapping, so return
|
||||
// an error.
|
||||
//
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_UNSUPPORTED));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a MAP_INFO structure to remember the mapping when Unmap() is
|
||||
// called later.
|
||||
//
|
||||
MapInfo = AllocatePool (sizeof (MAP_INFO));
|
||||
if (MapInfo == NULL) {
|
||||
*NumberOfBytes = 0;
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", EFI_OUT_OF_RESOURCES));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the MAP_INFO structure
|
||||
//
|
||||
MapInfo->Signature = MAP_INFO_SIGNATURE;
|
||||
MapInfo->Operation = Operation;
|
||||
MapInfo->NumberOfBytes = *NumberOfBytes;
|
||||
MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
|
||||
MapInfo->HostAddress = PhysicalAddress;
|
||||
MapInfo->DeviceAddress = DmaMemoryTop;
|
||||
InitializeListHead(&MapInfo->HandleList);
|
||||
|
||||
//
|
||||
// Allocate a buffer below 4GB to map the transfer to.
|
||||
//
|
||||
if (NeedRemap) {
|
||||
Status = gBS->AllocatePages (
|
||||
AllocateMaxAddress,
|
||||
EfiBootServicesData,
|
||||
MapInfo->NumberOfPages,
|
||||
&MapInfo->DeviceAddress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (MapInfo);
|
||||
*NumberOfBytes = 0;
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuMap: %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// If this is a read operation from the Bus Master's point of view,
|
||||
// then copy the contents of the real buffer into the mapped buffer
|
||||
// so the Bus Master can read the contents of the real buffer.
|
||||
//
|
||||
if (Operation == EdkiiIoMmuOperationBusMasterRead ||
|
||||
Operation == EdkiiIoMmuOperationBusMasterRead64) {
|
||||
CopyMem (
|
||||
(VOID *) (UINTN) MapInfo->DeviceAddress,
|
||||
(VOID *) (UINTN) MapInfo->HostAddress,
|
||||
MapInfo->NumberOfBytes
|
||||
);
|
||||
}
|
||||
} else {
|
||||
MapInfo->DeviceAddress = MapInfo->HostAddress;
|
||||
}
|
||||
|
||||
OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
|
||||
InsertTailList (&gMaps, &MapInfo->Link);
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
//
|
||||
// The DeviceAddress is the address of the maped buffer below 4GB
|
||||
//
|
||||
*DeviceAddress = MapInfo->DeviceAddress;
|
||||
//
|
||||
// Return a pointer to the MAP_INFO structure in Mapping
|
||||
//
|
||||
*Mapping = MapInfo;
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuMap: 0x%08x - 0x%08x <==\n", *DeviceAddress, *Mapping));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
@retval EFI_SUCCESS The range was unmapped.
|
||||
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
|
||||
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuUnmap (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
{
|
||||
MAP_INFO *MapInfo;
|
||||
MAP_HANDLE_INFO *MapHandleInfo;
|
||||
LIST_ENTRY *Link;
|
||||
EFI_TPL OriginalTpl;
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuUnmap: 0x%08x\n", Mapping));
|
||||
|
||||
if (Mapping == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuUnmap: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
|
||||
MapInfo = NULL;
|
||||
for (Link = GetFirstNode (&gMaps)
|
||||
; !IsNull (&gMaps, Link)
|
||||
; Link = GetNextNode (&gMaps, Link)
|
||||
) {
|
||||
MapInfo = MAP_INFO_FROM_LINK (Link);
|
||||
if (MapInfo == Mapping) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Mapping is not a valid value returned by Map()
|
||||
//
|
||||
if (MapInfo != Mapping) {
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuUnmap: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
RemoveEntryList (&MapInfo->Link);
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
//
|
||||
// remove all nodes in MapInfo->HandleList
|
||||
//
|
||||
while (!IsListEmpty (&MapInfo->HandleList)) {
|
||||
MapHandleInfo = MAP_HANDLE_INFO_FROM_LINK (MapInfo->HandleList.ForwardLink);
|
||||
RemoveEntryList (&MapHandleInfo->Link);
|
||||
FreePool (MapHandleInfo);
|
||||
}
|
||||
|
||||
if (MapInfo->DeviceAddress != MapInfo->HostAddress) {
|
||||
//
|
||||
// If this is a write operation from the Bus Master's point of view,
|
||||
// then copy the contents of the mapped buffer into the real buffer
|
||||
// so the processor can read the contents of the real buffer.
|
||||
//
|
||||
if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite ||
|
||||
MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) {
|
||||
CopyMem (
|
||||
(VOID *) (UINTN) MapInfo->HostAddress,
|
||||
(VOID *) (UINTN) MapInfo->DeviceAddress,
|
||||
MapInfo->NumberOfBytes
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Free the mapped buffer and the MAP_INFO structure.
|
||||
//
|
||||
gBS->FreePages (MapInfo->DeviceAddress, MapInfo->NumberOfPages);
|
||||
}
|
||||
|
||||
FreePool (Mapping);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
|
||||
OperationBusMasterCommonBuffer64 mapping.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Type This parameter is not used and must be ignored.
|
||||
@param MemoryType The type of memory to allocate, EfiBootServicesData or
|
||||
EfiRuntimeServicesData.
|
||||
@param Pages The number of pages to allocate.
|
||||
@param HostAddress A pointer to store the base system memory address of the
|
||||
allocated range.
|
||||
@param Attributes The requested bit mask of attributes for the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were allocated.
|
||||
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
|
||||
MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuAllocateBuffer (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT VOID **HostAddress,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuAllocateBuffer: ==> 0x%08x\n", Pages));
|
||||
|
||||
//
|
||||
// Validate Attributes
|
||||
//
|
||||
if ((Attributes & EDKII_IOMMU_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_UNSUPPORTED));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for invalid inputs
|
||||
//
|
||||
if (HostAddress == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// The only valid memory types are EfiBootServicesData and
|
||||
// EfiRuntimeServicesData
|
||||
//
|
||||
if (MemoryType != EfiBootServicesData &&
|
||||
MemoryType != EfiRuntimeServicesData) {
|
||||
DEBUG ((DEBUG_ERROR, "IoMmuAllocateBuffer: %r\n", EFI_INVALID_PARAMETER));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
PhysicalAddress = DMA_MEMORY_TOP;
|
||||
if ((Attributes & EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
|
||||
//
|
||||
// Limit allocations to memory below 4GB
|
||||
//
|
||||
PhysicalAddress = MIN (PhysicalAddress, SIZE_4GB - 1);
|
||||
}
|
||||
Status = gBS->AllocatePages (
|
||||
AllocateMaxAddress,
|
||||
MemoryType,
|
||||
Pages,
|
||||
&PhysicalAddress
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
*HostAddress = (VOID *) (UINTN) PhysicalAddress;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuAllocateBuffer: 0x%08x <==\n", *HostAddress));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Frees memory that was allocated with AllocateBuffer().
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Pages The number of pages to free.
|
||||
@param HostAddress The base system memory address of the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were freed.
|
||||
@retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
|
||||
was not allocated with AllocateBuffer().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuFreeBuffer (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN UINTN Pages,
|
||||
IN VOID *HostAddress
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuFreeBuffer: 0x%\n", Pages));
|
||||
return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
Get device information from mapping.
|
||||
|
||||
@param[in] Mapping The mapping.
|
||||
@param[out] DeviceAddress The device address of the mapping.
|
||||
@param[out] NumberOfPages The number of pages of the mapping.
|
||||
|
||||
@retval EFI_SUCCESS The device information is returned.
|
||||
@retval EFI_INVALID_PARAMETER The mapping is invalid.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDeviceInfoFromMapping (
|
||||
IN VOID *Mapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT UINTN *NumberOfPages
|
||||
)
|
||||
{
|
||||
MAP_INFO *MapInfo;
|
||||
LIST_ENTRY *Link;
|
||||
|
||||
if (Mapping == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MapInfo = NULL;
|
||||
for (Link = GetFirstNode (&gMaps)
|
||||
; !IsNull (&gMaps, Link)
|
||||
; Link = GetNextNode (&gMaps, Link)
|
||||
) {
|
||||
MapInfo = MAP_INFO_FROM_LINK (Link);
|
||||
if (MapInfo == Mapping) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Mapping is not a valid value returned by Map()
|
||||
//
|
||||
if (MapInfo != Mapping) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*DeviceAddress = MapInfo->DeviceAddress;
|
||||
*NumberOfPages = MapInfo->NumberOfPages;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
672
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
Normal file
672
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
Normal file
@@ -0,0 +1,672 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
UINT64 mBelow4GMemoryLimit;
|
||||
UINT64 mAbove4GMemoryLimit;
|
||||
|
||||
EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;
|
||||
|
||||
VTD_ACCESS_REQUEST *mAccessRequest = NULL;
|
||||
UINTN mAccessRequestCount = 0;
|
||||
UINTN mAccessRequestMaxCount = 0;
|
||||
|
||||
/**
|
||||
Append VTd Access Request to global.
|
||||
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
@param[in] BaseAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RequestAccessAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
)
|
||||
{
|
||||
VTD_ACCESS_REQUEST *NewAccessRequest;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Optimization for memory.
|
||||
//
|
||||
// If the last record is to IoMmuAccess=0,
|
||||
// Check previous records and remove the matched entry.
|
||||
//
|
||||
if (IoMmuAccess == 0) {
|
||||
for (Index = 0; Index < mAccessRequestCount; Index++) {
|
||||
if ((mAccessRequest[Index].Segment == Segment) &&
|
||||
(mAccessRequest[Index].SourceId.Uint16 == SourceId.Uint16) &&
|
||||
(mAccessRequest[Index].BaseAddress == BaseAddress) &&
|
||||
(mAccessRequest[Index].Length == Length) &&
|
||||
(mAccessRequest[Index].IoMmuAccess != 0)) {
|
||||
//
|
||||
// Remove this record [Index].
|
||||
// No need to add the new record.
|
||||
//
|
||||
if (Index != mAccessRequestCount - 1) {
|
||||
CopyMem (
|
||||
&mAccessRequest[Index],
|
||||
&mAccessRequest[Index + 1],
|
||||
sizeof (VTD_ACCESS_REQUEST) * (mAccessRequestCount - 1 - Index)
|
||||
);
|
||||
}
|
||||
ZeroMem (&mAccessRequest[mAccessRequestCount - 1], sizeof(VTD_ACCESS_REQUEST));
|
||||
mAccessRequestCount--;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mAccessRequestCount >= mAccessRequestMaxCount) {
|
||||
NewAccessRequest = AllocateZeroPool (sizeof(*NewAccessRequest) * (mAccessRequestMaxCount + MAX_VTD_ACCESS_REQUEST));
|
||||
if (NewAccessRequest == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
mAccessRequestMaxCount += MAX_VTD_ACCESS_REQUEST;
|
||||
if (mAccessRequest != NULL) {
|
||||
CopyMem (NewAccessRequest, mAccessRequest, sizeof(*NewAccessRequest) * mAccessRequestCount);
|
||||
FreePool (mAccessRequest);
|
||||
}
|
||||
mAccessRequest = NewAccessRequest;
|
||||
}
|
||||
|
||||
ASSERT (mAccessRequestCount < mAccessRequestMaxCount);
|
||||
|
||||
mAccessRequest[mAccessRequestCount].Segment = Segment;
|
||||
mAccessRequest[mAccessRequestCount].SourceId = SourceId;
|
||||
mAccessRequest[mAccessRequestCount].BaseAddress = BaseAddress;
|
||||
mAccessRequest[mAccessRequestCount].Length = Length;
|
||||
mAccessRequest[mAccessRequestCount].IoMmuAccess = IoMmuAccess;
|
||||
|
||||
mAccessRequestCount++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Process Access Requests from before DMAR table is installed.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ProcessRequestedAccessAttribute (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute ...\n"));
|
||||
|
||||
for (Index = 0; Index < mAccessRequestCount; Index++) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"PCI(S%x.B%x.D%x.F%x) ",
|
||||
mAccessRequest[Index].Segment,
|
||||
mAccessRequest[Index].SourceId.Bits.Bus,
|
||||
mAccessRequest[Index].SourceId.Bits.Device,
|
||||
mAccessRequest[Index].SourceId.Bits.Function
|
||||
));
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"(0x%lx~0x%lx) - %lx\n",
|
||||
mAccessRequest[Index].BaseAddress,
|
||||
mAccessRequest[Index].Length,
|
||||
mAccessRequest[Index].IoMmuAccess
|
||||
));
|
||||
Status = SetAccessAttribute (
|
||||
mAccessRequest[Index].Segment,
|
||||
mAccessRequest[Index].SourceId,
|
||||
mAccessRequest[Index].BaseAddress,
|
||||
mAccessRequest[Index].Length,
|
||||
mAccessRequest[Index].IoMmuAccess
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "SetAccessAttribute %r: ", Status));
|
||||
}
|
||||
}
|
||||
|
||||
if (mAccessRequest != NULL) {
|
||||
FreePool (mAccessRequest);
|
||||
}
|
||||
mAccessRequest = NULL;
|
||||
mAccessRequestCount = 0;
|
||||
mAccessRequestMaxCount = 0;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute Done\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
return the UEFI memory information.
|
||||
|
||||
@param[out] Below4GMemoryLimit The below 4GiB memory limit
|
||||
@param[out] Above4GMemoryLimit The above 4GiB memory limit
|
||||
**/
|
||||
VOID
|
||||
ReturnUefiMemoryMap (
|
||||
OUT UINT64 *Below4GMemoryLimit,
|
||||
OUT UINT64 *Above4GMemoryLimit
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_MEMORY_DESCRIPTOR *EfiMemoryMap;
|
||||
EFI_MEMORY_DESCRIPTOR *EfiMemoryMapEnd;
|
||||
EFI_MEMORY_DESCRIPTOR *EfiEntry;
|
||||
EFI_MEMORY_DESCRIPTOR *NextEfiEntry;
|
||||
EFI_MEMORY_DESCRIPTOR TempEfiEntry;
|
||||
UINTN EfiMemoryMapSize;
|
||||
UINTN EfiMapKey;
|
||||
UINTN EfiDescriptorSize;
|
||||
UINT32 EfiDescriptorVersion;
|
||||
UINT64 MemoryBlockLength;
|
||||
|
||||
*Below4GMemoryLimit = 0;
|
||||
*Above4GMemoryLimit = 0;
|
||||
|
||||
//
|
||||
// Get the EFI memory map.
|
||||
//
|
||||
EfiMemoryMapSize = 0;
|
||||
EfiMemoryMap = NULL;
|
||||
Status = gBS->GetMemoryMap (
|
||||
&EfiMemoryMapSize,
|
||||
EfiMemoryMap,
|
||||
&EfiMapKey,
|
||||
&EfiDescriptorSize,
|
||||
&EfiDescriptorVersion
|
||||
);
|
||||
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
do {
|
||||
//
|
||||
// Use size returned back plus 1 descriptor for the AllocatePool.
|
||||
// We don't just multiply by 2 since the "for" loop below terminates on
|
||||
// EfiMemoryMapEnd which is dependent upon EfiMemoryMapSize. Otherwize
|
||||
// we process bogus entries and create bogus E820 entries.
|
||||
//
|
||||
EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (EfiMemoryMapSize);
|
||||
ASSERT (EfiMemoryMap != NULL);
|
||||
Status = gBS->GetMemoryMap (
|
||||
&EfiMemoryMapSize,
|
||||
EfiMemoryMap,
|
||||
&EfiMapKey,
|
||||
&EfiDescriptorSize,
|
||||
&EfiDescriptorVersion
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (EfiMemoryMap);
|
||||
}
|
||||
} while (Status == EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Sort memory map from low to high
|
||||
//
|
||||
EfiEntry = EfiMemoryMap;
|
||||
NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
|
||||
EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);
|
||||
while (EfiEntry < EfiMemoryMapEnd) {
|
||||
while (NextEfiEntry < EfiMemoryMapEnd) {
|
||||
if (EfiEntry->PhysicalStart > NextEfiEntry->PhysicalStart) {
|
||||
CopyMem (&TempEfiEntry, EfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (EfiEntry, NextEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
CopyMem (NextEfiEntry, &TempEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
|
||||
}
|
||||
|
||||
NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (NextEfiEntry, EfiDescriptorSize);
|
||||
}
|
||||
|
||||
EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
|
||||
NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "MemoryMap:\n"));
|
||||
EfiEntry = EfiMemoryMap;
|
||||
EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);
|
||||
while (EfiEntry < EfiMemoryMapEnd) {
|
||||
MemoryBlockLength = (UINT64) (LShiftU64 (EfiEntry->NumberOfPages, 12));
|
||||
DEBUG ((DEBUG_INFO, "Entry(0x%02x) 0x%016lx - 0x%016lx\n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->PhysicalStart + MemoryBlockLength));
|
||||
switch (EfiEntry->Type) {
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
case EfiConventionalMemory:
|
||||
case EfiRuntimeServicesCode:
|
||||
case EfiRuntimeServicesData:
|
||||
case EfiACPIReclaimMemory:
|
||||
case EfiACPIMemoryNVS:
|
||||
case EfiReservedMemoryType:
|
||||
if ((EfiEntry->PhysicalStart + MemoryBlockLength) <= BASE_1MB) {
|
||||
//
|
||||
// Skip the memory block is under 1MB
|
||||
//
|
||||
} else if (EfiEntry->PhysicalStart >= BASE_4GB) {
|
||||
if (*Above4GMemoryLimit < EfiEntry->PhysicalStart + MemoryBlockLength) {
|
||||
*Above4GMemoryLimit = EfiEntry->PhysicalStart + MemoryBlockLength;
|
||||
}
|
||||
} else {
|
||||
if (*Below4GMemoryLimit < EfiEntry->PhysicalStart + MemoryBlockLength) {
|
||||
*Below4GMemoryLimit = EfiEntry->PhysicalStart + MemoryBlockLength;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
|
||||
}
|
||||
|
||||
FreePool (EfiMemoryMap);
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Result:\n"));
|
||||
DEBUG ((DEBUG_INFO, "Below4GMemoryLimit: 0x%016lx\n", *Below4GMemoryLimit));
|
||||
DEBUG ((DEBUG_INFO, "Above4GMemoryLimit: 0x%016lx\n", *Above4GMemoryLimit));
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
The scan bus callback function to always enable page attribute.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ScanBusCallbackAlwaysEnablePageAttribute (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
)
|
||||
{
|
||||
VTD_SOURCE_ID SourceId;
|
||||
EFI_STATUS Status;
|
||||
|
||||
SourceId.Bits.Bus = Bus;
|
||||
SourceId.Bits.Device = Device;
|
||||
SourceId.Bits.Function = Function;
|
||||
Status = AlwaysEnablePageAttribute (Segment, SourceId);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Always enable the VTd page attribute for the device in the DeviceScope.
|
||||
|
||||
@param[in] DeviceScope the input device scope data structure
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device in the device scope.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AlwaysEnablePageAttributeDeviceScope (
|
||||
IN EDKII_PLATFORM_VTD_DEVICE_SCOPE *DeviceScope
|
||||
)
|
||||
{
|
||||
UINT8 Bus;
|
||||
UINT8 Device;
|
||||
UINT8 Function;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
UINT8 SecondaryBusNumber;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = GetPciBusDeviceFunction (DeviceScope->SegmentNumber, &DeviceScope->DeviceScope, &Bus, &Device, &Function);
|
||||
|
||||
if (DeviceScope->DeviceScope.Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE) {
|
||||
//
|
||||
// Need scan the bridge and add all devices.
|
||||
//
|
||||
SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DeviceScope->SegmentNumber, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
|
||||
Status = ScanPciBus (NULL, DeviceScope->SegmentNumber, SecondaryBusNumber, ScanBusCallbackAlwaysEnablePageAttribute);
|
||||
return Status;
|
||||
} else {
|
||||
SourceId.Bits.Bus = Bus;
|
||||
SourceId.Bits.Device = Device;
|
||||
SourceId.Bits.Function = Function;
|
||||
Status = AlwaysEnablePageAttribute (DeviceScope->SegmentNumber, SourceId);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Always enable the VTd page attribute for the device matching DeviceId.
|
||||
|
||||
@param[in] PciDeviceId the input PCI device ID
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device matching DeviceId.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AlwaysEnablePageAttributePciDeviceId (
|
||||
IN EDKII_PLATFORM_VTD_PCI_DEVICE_ID *PciDeviceId
|
||||
)
|
||||
{
|
||||
UINTN VtdIndex;
|
||||
UINTN PciIndex;
|
||||
PCI_DEVICE_DATA *PciDeviceData;
|
||||
EFI_STATUS Status;
|
||||
|
||||
for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {
|
||||
for (PciIndex = 0; PciIndex < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; PciIndex++) {
|
||||
PciDeviceData = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[PciIndex];
|
||||
|
||||
if (((PciDeviceId->VendorId == 0xFFFF) || (PciDeviceId->VendorId == PciDeviceData->PciDeviceId.VendorId)) &&
|
||||
((PciDeviceId->DeviceId == 0xFFFF) || (PciDeviceId->DeviceId == PciDeviceData->PciDeviceId.DeviceId)) &&
|
||||
((PciDeviceId->RevisionId == 0xFF) || (PciDeviceId->RevisionId == PciDeviceData->PciDeviceId.RevisionId)) &&
|
||||
((PciDeviceId->SubsystemVendorId == 0xFFFF) || (PciDeviceId->SubsystemVendorId == PciDeviceData->PciDeviceId.SubsystemVendorId)) &&
|
||||
((PciDeviceId->SubsystemDeviceId == 0xFFFF) || (PciDeviceId->SubsystemDeviceId == PciDeviceData->PciDeviceId.SubsystemDeviceId)) ) {
|
||||
Status = AlwaysEnablePageAttribute (mVtdUnitInformation[VtdIndex].Segment, PciDeviceData->PciSourceId);
|
||||
if (EFI_ERROR(Status)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Always enable the VTd page attribute for the device.
|
||||
|
||||
@param[in] DeviceInfo the exception device information
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device in the device info.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AlwaysEnablePageAttributeExceptionDeviceInfo (
|
||||
IN EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO *DeviceInfo
|
||||
)
|
||||
{
|
||||
switch (DeviceInfo->Type) {
|
||||
case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE:
|
||||
return AlwaysEnablePageAttributeDeviceScope ((VOID *)(DeviceInfo + 1));
|
||||
case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID:
|
||||
return AlwaysEnablePageAttributePciDeviceId ((VOID *)(DeviceInfo + 1));
|
||||
default:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize platform VTd policy.
|
||||
**/
|
||||
VOID
|
||||
InitializePlatformVTdPolicy (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN DeviceInfoCount;
|
||||
VOID *DeviceInfo;
|
||||
EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO *ThisDeviceInfo;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// It is optional.
|
||||
//
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEdkiiPlatformVTdPolicyProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&mPlatformVTdPolicy
|
||||
);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_INFO, "InitializePlatformVTdPolicy\n"));
|
||||
Status = mPlatformVTdPolicy->GetExceptionDeviceList (mPlatformVTdPolicy, &DeviceInfoCount, &DeviceInfo);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
ThisDeviceInfo = DeviceInfo;
|
||||
for (Index = 0; Index < DeviceInfoCount; Index++) {
|
||||
if (ThisDeviceInfo->Type == EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_END) {
|
||||
break;
|
||||
}
|
||||
AlwaysEnablePageAttributeExceptionDeviceInfo (ThisDeviceInfo);
|
||||
ThisDeviceInfo = (VOID *)((UINTN)ThisDeviceInfo + ThisDeviceInfo->Length);
|
||||
}
|
||||
FreePool (DeviceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Setup VTd engine.
|
||||
**/
|
||||
VOID
|
||||
SetupVtd (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *PciEnumerationComplete;
|
||||
UINTN Index;
|
||||
UINT64 Below4GMemoryLimit;
|
||||
UINT64 Above4GMemoryLimit;
|
||||
|
||||
//
|
||||
// PCI Enumeration must be done
|
||||
//
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEfiPciEnumerationCompleteProtocolGuid,
|
||||
NULL,
|
||||
&PciEnumerationComplete
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
ReturnUefiMemoryMap (&Below4GMemoryLimit, &Above4GMemoryLimit);
|
||||
Below4GMemoryLimit = ALIGN_VALUE_UP(Below4GMemoryLimit, SIZE_256MB);
|
||||
DEBUG ((DEBUG_INFO, " Adjusted Below4GMemoryLimit: 0x%016lx\n", Below4GMemoryLimit));
|
||||
|
||||
mBelow4GMemoryLimit = Below4GMemoryLimit;
|
||||
mAbove4GMemoryLimit = Above4GMemoryLimit;
|
||||
|
||||
//
|
||||
// 1. setup
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "ParseDmarAcpiTable\n"));
|
||||
Status = ParseDmarAcpiTableDrhd ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
|
||||
PrepareVtdConfig ();
|
||||
|
||||
//
|
||||
// 2. initialization
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "SetupTranslationTable\n"));
|
||||
Status = SetupTranslationTable ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InitializePlatformVTdPolicy ();
|
||||
|
||||
ParseDmarAcpiTableRmrr ();
|
||||
|
||||
ProcessRequestedAccessAttribute ();
|
||||
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, mVtdUnitInformation[Index].Segment));
|
||||
if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {
|
||||
DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntryTable);
|
||||
}
|
||||
if (mVtdUnitInformation[Index].RootEntryTable != NULL) {
|
||||
DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 3. enable
|
||||
//
|
||||
DEBUG ((DEBUG_INFO, "EnableDmar\n"));
|
||||
Status = EnableDmar ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "DumpVtdRegs\n"));
|
||||
DumpVtdRegsAll ();
|
||||
}
|
||||
|
||||
/**
|
||||
Notification function of ACPI Table change.
|
||||
|
||||
This is a notification function registered on ACPI Table change event.
|
||||
|
||||
@param Event Event whose notification function is being invoked.
|
||||
@param Context Pointer to the notification function's context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
AcpiNotificationFunc (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = GetDmarAcpiTable ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_ALREADY_STARTED) {
|
||||
gBS->CloseEvent (Event);
|
||||
}
|
||||
return;
|
||||
}
|
||||
SetupVtd ();
|
||||
gBS->CloseEvent (Event);
|
||||
}
|
||||
|
||||
/**
|
||||
Exit boot service callback function.
|
||||
|
||||
@param[in] Event The event handle.
|
||||
@param[in] Context The event content.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
OnExitBootServices (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_INFO, "Vtd OnExitBootServices\n"));
|
||||
DumpVtdRegsAll ();
|
||||
|
||||
if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {
|
||||
DisableDmar ();
|
||||
DumpVtdRegsAll ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Legacy boot callback function.
|
||||
|
||||
@param[in] Event The event handle.
|
||||
@param[in] Context The event content.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
OnLegacyBoot (
|
||||
EFI_EVENT Event,
|
||||
VOID *Context
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_INFO, "Vtd OnLegacyBoot\n"));
|
||||
DumpVtdRegsAll ();
|
||||
DisableDmar ();
|
||||
DumpVtdRegsAll ();
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize DMA protection.
|
||||
**/
|
||||
VOID
|
||||
InitializeDmaProtection (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_EVENT ExitBootServicesEvent;
|
||||
EFI_EVENT LegacyBootEvent;
|
||||
EFI_EVENT EventAcpi10;
|
||||
EFI_EVENT EventAcpi20;
|
||||
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
VTD_TPL_LEVEL,
|
||||
AcpiNotificationFunc,
|
||||
NULL,
|
||||
&gEfiAcpi10TableGuid,
|
||||
&EventAcpi10
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
VTD_TPL_LEVEL,
|
||||
AcpiNotificationFunc,
|
||||
NULL,
|
||||
&gEfiAcpi20TableGuid,
|
||||
&EventAcpi20
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Signal the events initially for the case
|
||||
// that DMAR table has been installed.
|
||||
//
|
||||
gBS->SignalEvent (EventAcpi20);
|
||||
gBS->SignalEvent (EventAcpi10);
|
||||
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
OnExitBootServices,
|
||||
NULL,
|
||||
&gEfiEventExitBootServicesGuid,
|
||||
&ExitBootServicesEvent
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = EfiCreateEventLegacyBootEx (
|
||||
TPL_CALLBACK,
|
||||
OnLegacyBoot,
|
||||
NULL,
|
||||
&LegacyBootEvent
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return ;
|
||||
}
|
607
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
Normal file
607
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
Normal file
@@ -0,0 +1,607 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _DMAR_PROTECTION_H_
|
||||
#define _DMAR_PROTECTION_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PciSegmentLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/PerformanceLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/Acpi.h>
|
||||
|
||||
#include <Protocol/DxeSmmReadyToLock.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/PciEnumerationComplete.h>
|
||||
#include <Protocol/PlatformVtdPolicy.h>
|
||||
#include <Protocol/IoMmu.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
|
||||
#define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))
|
||||
|
||||
#define ALIGN_VALUE_UP(Value, Alignment) (((Value) + (Alignment) - 1) & (~((Alignment) - 1)))
|
||||
#define ALIGN_VALUE_LOW(Value, Alignment) ((Value) & (~((Alignment) - 1)))
|
||||
|
||||
#define VTD_TPL_LEVEL TPL_NOTIFY
|
||||
|
||||
//
|
||||
// This is the initial max PCI DATA number.
|
||||
// The number may be enlarged later.
|
||||
//
|
||||
#define MAX_VTD_PCI_DATA_NUMBER 0x100
|
||||
|
||||
typedef struct {
|
||||
UINT8 DeviceType;
|
||||
VTD_SOURCE_ID PciSourceId;
|
||||
EDKII_PLATFORM_VTD_PCI_DEVICE_ID PciDeviceId;
|
||||
// for statistic analysis
|
||||
UINTN AccessCount;
|
||||
} PCI_DEVICE_DATA;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN IncludeAllFlag;
|
||||
UINTN PciDeviceDataNumber;
|
||||
UINTN PciDeviceDataMaxNumber;
|
||||
PCI_DEVICE_DATA *PciDeviceData;
|
||||
} PCI_DEVICE_INFORMATION;
|
||||
|
||||
typedef struct {
|
||||
UINTN VtdUnitBaseAddress;
|
||||
UINT16 Segment;
|
||||
VTD_CAP_REG CapReg;
|
||||
VTD_ECAP_REG ECapReg;
|
||||
VTD_ROOT_ENTRY *RootEntryTable;
|
||||
VTD_EXT_ROOT_ENTRY *ExtRootEntryTable;
|
||||
VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry;
|
||||
BOOLEAN HasDirtyContext;
|
||||
BOOLEAN HasDirtyPages;
|
||||
PCI_DEVICE_INFORMATION PciDeviceInfo;
|
||||
} VTD_UNIT_INFORMATION;
|
||||
|
||||
//
|
||||
// This is the initial max ACCESS request.
|
||||
// The number may be enlarged later.
|
||||
//
|
||||
#define MAX_VTD_ACCESS_REQUEST 0x100
|
||||
|
||||
typedef struct {
|
||||
UINT16 Segment;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
UINT64 BaseAddress;
|
||||
UINT64 Length;
|
||||
UINT64 IoMmuAccess;
|
||||
} VTD_ACCESS_REQUEST;
|
||||
|
||||
|
||||
/**
|
||||
The scan bus callback function.
|
||||
|
||||
It is called in PCI bus scan for each PCI device under the bus.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The specific PCI device is processed in the callback.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *SCAN_BUS_FUNC_CALLBACK_FUNC) (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
);
|
||||
|
||||
extern EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;
|
||||
|
||||
extern UINTN mVtdUnitNumber;
|
||||
extern VTD_UNIT_INFORMATION *mVtdUnitInformation;
|
||||
|
||||
extern UINT64 mBelow4GMemoryLimit;
|
||||
extern UINT64 mAbove4GMemoryLimit;
|
||||
|
||||
extern EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;
|
||||
|
||||
/**
|
||||
Prepare VTD configuration.
|
||||
**/
|
||||
VOID
|
||||
PrepareVtdConfig (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Setup VTd translation table.
|
||||
|
||||
@retval EFI_SUCCESS Setup translation table successfully.
|
||||
@retval EFI_OUT_OF_RESOURCE Setup translation table fail.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetupTranslationTable (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Enable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is enabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not enabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnableDmar (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Disable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is disabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmar (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Invalid VTd global IOTLB.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS VTd global IOTLB is invalidated.
|
||||
@retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateVtdIOTLBGlobal (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegs (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers for all VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegsAll (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd capability registers.
|
||||
|
||||
@param[in] CapReg The capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdCapRegs (
|
||||
IN VTD_CAP_REG *CapReg
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd extended capability registers.
|
||||
|
||||
@param[in] ECapReg The extended capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdECapRegs (
|
||||
IN VTD_ECAP_REG *ECapReg
|
||||
);
|
||||
|
||||
/**
|
||||
Register PCI device to VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] SourceId The SourceId of the source.
|
||||
@param[in] DeviceType The DMAR device scope type.
|
||||
@param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.
|
||||
FALSE: SUCCESS will be returned if the PCI device is registered.
|
||||
|
||||
@retval EFI_SUCCESS The PCI device is registered.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.
|
||||
@retval EFI_ALREADY_STARTED The device is already registered.
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterPciDevice (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT8 DeviceType,
|
||||
IN BOOLEAN CheckExist
|
||||
);
|
||||
|
||||
/**
|
||||
The scan bus callback function to always enable page attribute.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ScanBusCallbackRegisterPciDevice (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
);
|
||||
|
||||
/**
|
||||
Scan PCI bus and invoke callback function for each PCI devices under the bus.
|
||||
|
||||
@param[in] Context The context of the callback function.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Callback The callback function in PCI scan.
|
||||
|
||||
@retval EFI_SUCCESS The PCI devices under the bus are scaned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScanPciBus (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback
|
||||
);
|
||||
|
||||
/**
|
||||
Dump the PCI device information managed by this VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpPciDeviceInfo (
|
||||
IN UINTN VtdIndex
|
||||
);
|
||||
|
||||
/**
|
||||
Find the VTd index by the Segment and SourceId.
|
||||
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] SourceId The SourceId of the source.
|
||||
@param[out] ExtContextEntry The ExtContextEntry of the source.
|
||||
@param[out] ContextEntry The ContextEntry of the source.
|
||||
|
||||
@return The index of the VTd engine.
|
||||
@retval (UINTN)-1 The VTd engine is not found.
|
||||
**/
|
||||
UINTN
|
||||
FindVtdIndexByPciDevice (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,
|
||||
OUT VTD_CONTEXT_ENTRY **ContextEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Get the DMAR ACPI table.
|
||||
|
||||
@retval EFI_SUCCESS The DMAR ACPI table is got.
|
||||
@retval EFI_ALREADY_STARTED The DMAR ACPI table has been got previously.
|
||||
@retval EFI_NOT_FOUND The DMAR ACPI table is not found.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDmarAcpiTable (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@return EFI_SUCCESS The DMAR DRHD table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableDrhd (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR RMRR table.
|
||||
|
||||
@return EFI_SUCCESS The DMAR RMRR table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableRmrr (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR context entry table.
|
||||
|
||||
@param[in] RootEntry DMAR root entry.
|
||||
**/
|
||||
VOID
|
||||
DumpDmarContextEntryTable (
|
||||
IN VTD_ROOT_ENTRY *RootEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR extended context entry table.
|
||||
|
||||
@param[in] ExtRootEntry DMAR extended root entry.
|
||||
**/
|
||||
VOID
|
||||
DumpDmarExtContextEntryTable (
|
||||
IN VTD_EXT_ROOT_ENTRY *ExtRootEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR second level paging entry.
|
||||
|
||||
@param[in] SecondLevelPagingEntry The second level paging entry.
|
||||
**/
|
||||
VOID
|
||||
DumpSecondLevelPagingEntry (
|
||||
IN VOID *SecondLevelPagingEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Set VTd attribute for a system memory.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] DomainIdentifier The domain ID of the source.
|
||||
@param[in] SecondLevelPagingEntry The second level paging entry in VTd table for the device.
|
||||
@param[in] BaseAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetPageAttribute (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 DomainIdentifier,
|
||||
IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
/**
|
||||
Set VTd attribute for a system memory.
|
||||
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
@param[in] BaseAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetAccessAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
/**
|
||||
Return the index of PCI data.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@return The index of the PCI data.
|
||||
@retval (UINTN)-1 The PCI data is not found.
|
||||
**/
|
||||
UINTN
|
||||
GetPciDataIndex (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
Dump VTd registers if there is error.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdIfError (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize platform VTd policy.
|
||||
**/
|
||||
VOID
|
||||
InitializePlatformVTdPolicy (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Always enable the VTd page attribute for the device.
|
||||
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AlwaysEnablePageAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
Convert the DeviceHandle to SourceId and Segment.
|
||||
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[out] Segment The Segment used to identify a VTd engine.
|
||||
@param[out] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@retval EFI_SUCCESS The Segment and SourceId are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
|
||||
@retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DeviceHandleToSourceId (
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
OUT UINT16 *Segment,
|
||||
OUT VTD_SOURCE_ID *SourceId
|
||||
);
|
||||
|
||||
/**
|
||||
Get device information from mapping.
|
||||
|
||||
@param[in] Mapping The mapping.
|
||||
@param[out] DeviceAddress The device address of the mapping.
|
||||
@param[out] NumberOfPages The number of pages of the mapping.
|
||||
|
||||
@retval EFI_SUCCESS The device information is returned.
|
||||
@retval EFI_INVALID_PARAMETER The mapping is invalid.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDeviceInfoFromMapping (
|
||||
IN VOID *Mapping,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT UINTN *NumberOfPages
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize DMA protection.
|
||||
**/
|
||||
VOID
|
||||
InitializeDmaProtection (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Allocate zero pages.
|
||||
|
||||
@param[in] Pages the number of pages.
|
||||
|
||||
@return the page address.
|
||||
@retval NULL No resource to allocate pages.
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateZeroPages (
|
||||
IN UINTN Pages
|
||||
);
|
||||
|
||||
/**
|
||||
Flush VTD page table and context table memory.
|
||||
|
||||
This action is to make sure the IOMMU engine can get final data in memory.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] Base The base address of memory to be flushed.
|
||||
@param[in] Size The size of memory in bytes to be flushed.
|
||||
**/
|
||||
VOID
|
||||
FlushPageTableMemory (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINTN Base,
|
||||
IN UINTN Size
|
||||
);
|
||||
|
||||
/**
|
||||
Get PCI device information from DMAR DevScopeEntry.
|
||||
|
||||
@param[in] Segment The segment number.
|
||||
@param[in] DmarDevScopeEntry DMAR DevScopeEntry
|
||||
@param[out] Bus The bus number.
|
||||
@param[out] Device The device number.
|
||||
@param[out] Function The function number.
|
||||
|
||||
@retval EFI_SUCCESS The PCI device information is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetPciBusDeviceFunction (
|
||||
IN UINT16 Segment,
|
||||
IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry,
|
||||
OUT UINT8 *Bus,
|
||||
OUT UINT8 *Device,
|
||||
OUT UINT8 *Function
|
||||
);
|
||||
|
||||
/**
|
||||
Append VTd Access Request to global.
|
||||
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
@param[in] BaseAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RequestAccessAttribute (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT64 BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
#endif
|
1026
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
Normal file
1026
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
Normal file
File diff suppressed because it is too large
Load Diff
399
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
Normal file
399
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/** @file
|
||||
Intel VTd driver.
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
/**
|
||||
Provides the controller-specific addresses required to access system memory from a
|
||||
DMA bus master.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Operation Indicates if the bus master is going to read or write to system memory.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
|
||||
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuMap (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EDKII_IOMMU_OPERATION Operation,
|
||||
IN VOID *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
@retval EFI_SUCCESS The range was unmapped.
|
||||
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
|
||||
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuUnmap (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN VOID *Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
|
||||
OperationBusMasterCommonBuffer64 mapping.
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Type This parameter is not used and must be ignored.
|
||||
@param MemoryType The type of memory to allocate, EfiBootServicesData or
|
||||
EfiRuntimeServicesData.
|
||||
@param Pages The number of pages to allocate.
|
||||
@param HostAddress A pointer to store the base system memory address of the
|
||||
allocated range.
|
||||
@param Attributes The requested bit mask of attributes for the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were allocated.
|
||||
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
|
||||
MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuAllocateBuffer (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT VOID **HostAddress,
|
||||
IN UINT64 Attributes
|
||||
);
|
||||
|
||||
/**
|
||||
Frees memory that was allocated with AllocateBuffer().
|
||||
|
||||
@param This The protocol instance pointer.
|
||||
@param Pages The number of pages to free.
|
||||
@param HostAddress The base system memory address of the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were freed.
|
||||
@retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
|
||||
was not allocated with AllocateBuffer().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuFreeBuffer (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN UINTN Pages,
|
||||
IN VOID *HostAddress
|
||||
);
|
||||
|
||||
/**
|
||||
This function fills DeviceHandle/IoMmuAccess to the MAP_HANDLE_INFO,
|
||||
based upon the DeviceAddress.
|
||||
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[in] DeviceAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SyncDeviceHandleToMapInfo (
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
IN EFI_PHYSICAL_ADDRESS DeviceAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
);
|
||||
|
||||
/**
|
||||
Convert the DeviceHandle to SourceId and Segment.
|
||||
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[out] Segment The Segment used to identify a VTd engine.
|
||||
@param[out] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@retval EFI_SUCCESS The Segment and SourceId are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
|
||||
@retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DeviceHandleToSourceId (
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
OUT UINT16 *Segment,
|
||||
OUT VTD_SOURCE_ID *SourceId
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINTN Seg;
|
||||
UINTN Bus;
|
||||
UINTN Dev;
|
||||
UINTN Func;
|
||||
EFI_STATUS Status;
|
||||
EDKII_PLATFORM_VTD_DEVICE_INFO DeviceInfo;
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
if (mPlatformVTdPolicy != NULL) {
|
||||
Status = mPlatformVTdPolicy->GetDeviceId (mPlatformVTdPolicy, DeviceHandle, &DeviceInfo);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
*Segment = DeviceInfo.Segment;
|
||||
*SourceId = DeviceInfo.SourceId;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
Status = PciIo->GetLocation (PciIo, &Seg, &Bus, &Dev, &Func);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
*Segment = (UINT16)Seg;
|
||||
SourceId->Bits.Bus = (UINT8)Bus;
|
||||
SourceId->Bits.Device = (UINT8)Dev;
|
||||
SourceId->Bits.Function = (UINT8)Func;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Set IOMMU attribute for a system memory.
|
||||
|
||||
If the IOMMU protocol exists, the system memory cannot be used
|
||||
for DMA by default.
|
||||
|
||||
When a device requests a DMA access for a system memory,
|
||||
the device driver need use SetAttribute() to update the IOMMU
|
||||
attribute to request DMA access (read and/or write).
|
||||
|
||||
The DeviceHandle is used to identify which device submits the request.
|
||||
The IOMMU implementation need translate the device path to an IOMMU device ID,
|
||||
and set IOMMU hardware register accordingly.
|
||||
1) DeviceHandle can be a standard PCI device.
|
||||
The memory for BusMasterRead need set EDKII_IOMMU_ACCESS_READ.
|
||||
The memory for BusMasterWrite need set EDKII_IOMMU_ACCESS_WRITE.
|
||||
The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ACCESS_READ|EDKII_IOMMU_ACCESS_WRITE.
|
||||
After the memory is used, the memory need set 0 to keep it being protected.
|
||||
2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
|
||||
The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_IOMMU_ACCESS_WRITE.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[in] DeviceAddress The base of device memory address to be used as the DMA memory.
|
||||
@param[in] Length The length of device memory address to be used as the DMA memory.
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
|
||||
@retval EFI_INVALID_PARAMETER DeviceAddress is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.
|
||||
@retval EFI_INVALID_PARAMETER Length is 0.
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by DeviceAddress and Length.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
VTdSetAttribute (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
IN EFI_PHYSICAL_ADDRESS DeviceAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINT64 IoMmuAccess
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT16 Segment;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
CHAR8 PerfToken[sizeof("VTD(S0000.B00.D00.F00)")];
|
||||
UINT32 Identifier;
|
||||
|
||||
DumpVtdIfError ();
|
||||
|
||||
Status = DeviceHandleToSourceId (DeviceHandle, &Segment, &SourceId);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "IoMmuSetAttribute: "));
|
||||
DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length, IoMmuAccess));
|
||||
|
||||
if (mAcpiDmarTable == NULL) {
|
||||
//
|
||||
// Record the entry to driver global variable.
|
||||
// As such once VTd is activated, the setting can be adopted.
|
||||
//
|
||||
Status = RequestAccessAttribute (Segment, SourceId, DeviceAddress, Length, IoMmuAccess);
|
||||
} else {
|
||||
PERF_CODE (
|
||||
AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function);
|
||||
Identifier = (Segment << 16) | SourceId.Uint16;
|
||||
PERF_START_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier);
|
||||
);
|
||||
|
||||
Status = SetAccessAttribute (Segment, SourceId, DeviceAddress, Length, IoMmuAccess);
|
||||
|
||||
PERF_CODE (
|
||||
Identifier = (Segment << 16) | SourceId.Uint16;
|
||||
PERF_END_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier);
|
||||
);
|
||||
}
|
||||
|
||||
if (!EFI_ERROR(Status)) {
|
||||
SyncDeviceHandleToMapInfo (
|
||||
DeviceHandle,
|
||||
DeviceAddress,
|
||||
Length,
|
||||
IoMmuAccess
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Set IOMMU attribute for a system memory.
|
||||
|
||||
If the IOMMU protocol exists, the system memory cannot be used
|
||||
for DMA by default.
|
||||
|
||||
When a device requests a DMA access for a system memory,
|
||||
the device driver need use SetAttribute() to update the IOMMU
|
||||
attribute to request DMA access (read and/or write).
|
||||
|
||||
The DeviceHandle is used to identify which device submits the request.
|
||||
The IOMMU implementation need translate the device path to an IOMMU device ID,
|
||||
and set IOMMU hardware register accordingly.
|
||||
1) DeviceHandle can be a standard PCI device.
|
||||
The memory for BusMasterRead need set EDKII_IOMMU_ACCESS_READ.
|
||||
The memory for BusMasterWrite need set EDKII_IOMMU_ACCESS_WRITE.
|
||||
The memory for BusMasterCommonBuffer need set EDKII_IOMMU_ACCESS_READ|EDKII_IOMMU_ACCESS_WRITE.
|
||||
After the memory is used, the memory need set 0 to keep it being protected.
|
||||
2) DeviceHandle can be an ACPI device (ISA, I2C, SPI, etc).
|
||||
The memory for DMA access need set EDKII_IOMMU_ACCESS_READ and/or EDKII_IOMMU_ACCESS_WRITE.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceHandle The device who initiates the DMA access request.
|
||||
@param[in] Mapping The mapping value returned from Map().
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.
|
||||
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IoMmuSetAttribute (
|
||||
IN EDKII_IOMMU_PROTOCOL *This,
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
IN VOID *Mapping,
|
||||
IN UINT64 IoMmuAccess
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS DeviceAddress;
|
||||
UINTN NumberOfPages;
|
||||
EFI_TPL OriginalTpl;
|
||||
|
||||
OriginalTpl = gBS->RaiseTPL (VTD_TPL_LEVEL);
|
||||
|
||||
Status = GetDeviceInfoFromMapping (Mapping, &DeviceAddress, &NumberOfPages);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = VTdSetAttribute (
|
||||
This,
|
||||
DeviceHandle,
|
||||
DeviceAddress,
|
||||
EFI_PAGES_TO_SIZE(NumberOfPages),
|
||||
IoMmuAccess
|
||||
);
|
||||
}
|
||||
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EDKII_IOMMU_PROTOCOL mIntelVTd = {
|
||||
EDKII_IOMMU_PROTOCOL_REVISION,
|
||||
IoMmuSetAttribute,
|
||||
IoMmuMap,
|
||||
IoMmuUnmap,
|
||||
IoMmuAllocateBuffer,
|
||||
IoMmuFreeBuffer,
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize the VTd driver.
|
||||
|
||||
@param[in] ImageHandle ImageHandle of the loaded driver
|
||||
@param[in] SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS The Protocol is installed.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver.
|
||||
@retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IntelVTdInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
InitializeDmaProtection ();
|
||||
|
||||
Handle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Handle,
|
||||
&gEdkiiIoMmuProtocolGuid, &mIntelVTd,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
87
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
Normal file
87
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
Normal file
@@ -0,0 +1,87 @@
|
||||
## @file
|
||||
# Intel VTd DXE Driver.
|
||||
#
|
||||
# This driver initializes VTd engine based upon DMAR ACPI tables
|
||||
# and provide DMA protection to PCI or ACPI device.
|
||||
#
|
||||
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = IntelVTdDxe
|
||||
MODULE_UNI_FILE = IntelVTdDxe.uni
|
||||
FILE_GUID = 987555D6-595D-4CFA-B895-59B89368BD4D
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = IntelVTdInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
#
|
||||
|
||||
[Sources]
|
||||
IntelVTdDxe.c
|
||||
BmDma.c
|
||||
DmaProtection.c
|
||||
DmaProtection.h
|
||||
DmarAcpiTable.c
|
||||
PciInfo.c
|
||||
TranslationTable.c
|
||||
TranslationTableEx.c
|
||||
VtdReg.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelSiliconPkg/IntelSiliconPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
BaseLib
|
||||
IoLib
|
||||
PciSegmentLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
UefiLib
|
||||
CacheMaintenanceLib
|
||||
PerformanceLib
|
||||
PrintLib
|
||||
|
||||
[Guids]
|
||||
gEfiEventExitBootServicesGuid ## CONSUMES ## Event
|
||||
## CONSUMES ## SystemTable
|
||||
## CONSUMES ## Event
|
||||
gEfiAcpi20TableGuid
|
||||
## CONSUMES ## SystemTable
|
||||
## CONSUMES ## Event
|
||||
gEfiAcpi10TableGuid
|
||||
|
||||
[Protocols]
|
||||
gEdkiiIoMmuProtocolGuid ## PRODUCES
|
||||
gEfiPciIoProtocolGuid ## CONSUMES
|
||||
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
|
||||
gEdkiiPlatformVTdPolicyProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPciRootBridgeIoProtocolGuid
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
IntelVTdDxeExtra.uni
|
||||
|
20
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.uni
Normal file
20
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.uni
Normal file
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// IntelVTdDxe Module Localized Abstract and Description Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Intel VTd DXE Driver."
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver initializes VTd engine based upon DMAR ACPI tables and provide DMA protection to PCI or ACPI device."
|
||||
|
20
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxeExtra.uni
Normal file
20
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxeExtra.uni
Normal file
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// IntelVTdDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Intel VTd DXE Driver"
|
||||
|
||||
|
379
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c
Normal file
379
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
/**
|
||||
Return the index of PCI data.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] Segment The Segment used to identify a VTd engine.
|
||||
@param[in] SourceId The SourceId used to identify a VTd engine and table entry.
|
||||
|
||||
@return The index of the PCI data.
|
||||
@retval (UINTN)-1 The PCI data is not found.
|
||||
**/
|
||||
UINTN
|
||||
GetPciDataIndex (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
VTD_SOURCE_ID *PciSourceId;
|
||||
|
||||
if (Segment != mVtdUnitInformation[VtdIndex].Segment) {
|
||||
return (UINTN)-1;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
|
||||
PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
|
||||
if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&
|
||||
(PciSourceId->Bits.Device == SourceId.Bits.Device) &&
|
||||
(PciSourceId->Bits.Function == SourceId.Bits.Function) ) {
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
return (UINTN)-1;
|
||||
}
|
||||
|
||||
/**
|
||||
Register PCI device to VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] SourceId The SourceId of the source.
|
||||
@param[in] DeviceType The DMAR device scope type.
|
||||
@param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.
|
||||
FALSE: SUCCESS will be returned if the PCI device is registered.
|
||||
|
||||
@retval EFI_SUCCESS The PCI device is registered.
|
||||
@retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.
|
||||
@retval EFI_ALREADY_STARTED The device is already registered.
|
||||
**/
|
||||
EFI_STATUS
|
||||
RegisterPciDevice (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
IN UINT8 DeviceType,
|
||||
IN BOOLEAN CheckExist
|
||||
)
|
||||
{
|
||||
PCI_DEVICE_INFORMATION *PciDeviceInfo;
|
||||
VTD_SOURCE_ID *PciSourceId;
|
||||
UINTN PciDataIndex;
|
||||
UINTN Index;
|
||||
PCI_DEVICE_DATA *NewPciDeviceData;
|
||||
EDKII_PLATFORM_VTD_PCI_DEVICE_ID *PciDeviceId;
|
||||
|
||||
PciDeviceInfo = &mVtdUnitInformation[VtdIndex].PciDeviceInfo;
|
||||
|
||||
if (PciDeviceInfo->IncludeAllFlag) {
|
||||
//
|
||||
// Do not register device in other VTD Unit
|
||||
//
|
||||
for (Index = 0; Index < VtdIndex; Index++) {
|
||||
PciDataIndex = GetPciDataIndex (Index, Segment, SourceId);
|
||||
if (PciDataIndex != (UINTN)-1) {
|
||||
DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x already registered by Other Vtd(%d)\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, Index));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);
|
||||
if (PciDataIndex == (UINTN)-1) {
|
||||
//
|
||||
// Register new
|
||||
//
|
||||
|
||||
if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo->PciDeviceDataMaxNumber) {
|
||||
//
|
||||
// Reallocate
|
||||
//
|
||||
NewPciDeviceData = AllocateZeroPool (sizeof(*NewPciDeviceData) * (PciDeviceInfo->PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER));
|
||||
if (NewPciDeviceData == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
PciDeviceInfo->PciDeviceDataMaxNumber += MAX_VTD_PCI_DATA_NUMBER;
|
||||
if (PciDeviceInfo->PciDeviceData != NULL) {
|
||||
CopyMem (NewPciDeviceData, PciDeviceInfo->PciDeviceData, sizeof(*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber);
|
||||
FreePool (PciDeviceInfo->PciDeviceData);
|
||||
}
|
||||
PciDeviceInfo->PciDeviceData = NewPciDeviceData;
|
||||
}
|
||||
|
||||
ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceDataMaxNumber);
|
||||
|
||||
PciSourceId = &PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].PciSourceId;
|
||||
PciSourceId->Bits.Bus = SourceId.Bits.Bus;
|
||||
PciSourceId->Bits.Device = SourceId.Bits.Device;
|
||||
PciSourceId->Bits.Function = SourceId.Bits.Function;
|
||||
|
||||
DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
|
||||
PciDeviceId = &PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].PciDeviceId;
|
||||
if ((DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) ||
|
||||
(DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
|
||||
PciDeviceId->VendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_VENDOR_ID_OFFSET));
|
||||
PciDeviceId->DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_DEVICE_ID_OFFSET));
|
||||
PciDeviceId->RevisionId = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_REVISION_ID_OFFSET));
|
||||
|
||||
DEBUG ((DEBUG_INFO, " (%04x:%04x:%02x", PciDeviceId->VendorId, PciDeviceId->DeviceId, PciDeviceId->RevisionId));
|
||||
|
||||
if (DeviceType == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
|
||||
PciDeviceId->SubsystemVendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_VENDOR_ID_OFFSET));
|
||||
PciDeviceId->SubsystemDeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function, PCI_SUBSYSTEM_ID_OFFSET));
|
||||
DEBUG ((DEBUG_INFO, ":%04x:%04x", PciDeviceId->SubsystemVendorId, PciDeviceId->SubsystemDeviceId));
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, ")"));
|
||||
}
|
||||
|
||||
PciDeviceInfo->PciDeviceData[PciDeviceInfo->PciDeviceDataNumber].DeviceType = DeviceType;
|
||||
|
||||
if ((DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) &&
|
||||
(DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
|
||||
DEBUG ((DEBUG_INFO, " (*)"));
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "\n"));
|
||||
|
||||
PciDeviceInfo->PciDeviceDataNumber++;
|
||||
} else {
|
||||
if (CheckExist) {
|
||||
DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x already registered\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
The scan bus callback function to register PCI device.
|
||||
|
||||
@param[in] Context The context of the callback.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Device The device of the source.
|
||||
@param[in] Function The function of the source.
|
||||
|
||||
@retval EFI_SUCCESS The PCI device is registered.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ScanBusCallbackRegisterPciDevice (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN UINT8 Device,
|
||||
IN UINT8 Function
|
||||
)
|
||||
{
|
||||
VTD_SOURCE_ID SourceId;
|
||||
UINTN VtdIndex;
|
||||
UINT8 BaseClass;
|
||||
UINT8 SubClass;
|
||||
UINT8 DeviceType;
|
||||
EFI_STATUS Status;
|
||||
|
||||
VtdIndex = (UINTN)Context;
|
||||
SourceId.Bits.Bus = Bus;
|
||||
SourceId.Bits.Device = Device;
|
||||
SourceId.Bits.Function = Function;
|
||||
|
||||
DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT;
|
||||
BaseClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 2));
|
||||
if (BaseClass == PCI_CLASS_BRIDGE) {
|
||||
SubClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 1));
|
||||
if (SubClass == PCI_CLASS_BRIDGE_P2P) {
|
||||
DeviceType = EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE;
|
||||
}
|
||||
}
|
||||
|
||||
Status = RegisterPciDevice (VtdIndex, Segment, SourceId, DeviceType, FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Scan PCI bus and invoke callback function for each PCI devices under the bus.
|
||||
|
||||
@param[in] Context The context of the callback function.
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] Bus The bus of the source.
|
||||
@param[in] Callback The callback function in PCI scan.
|
||||
|
||||
@retval EFI_SUCCESS The PCI devices under the bus are scaned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ScanPciBus (
|
||||
IN VOID *Context,
|
||||
IN UINT16 Segment,
|
||||
IN UINT8 Bus,
|
||||
IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback
|
||||
)
|
||||
{
|
||||
UINT8 Device;
|
||||
UINT8 Function;
|
||||
UINT8 SecondaryBusNumber;
|
||||
UINT8 HeaderType;
|
||||
UINT8 BaseClass;
|
||||
UINT8 SubClass;
|
||||
UINT16 VendorID;
|
||||
UINT16 DeviceID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Scan the PCI bus for devices
|
||||
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
|
||||
for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {
|
||||
VendorID = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_VENDOR_ID_OFFSET));
|
||||
DeviceID = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_DEVICE_ID_OFFSET));
|
||||
if (VendorID == 0xFFFF && DeviceID == 0xFFFF) {
|
||||
if (Function == 0) {
|
||||
//
|
||||
// If function 0 is not implemented, do not scan other functions.
|
||||
//
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = Callback (Context, Segment, Bus, Device, Function);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
BaseClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 2));
|
||||
if (BaseClass == PCI_CLASS_BRIDGE) {
|
||||
SubClass = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_CLASSCODE_OFFSET + 1));
|
||||
if (SubClass == PCI_CLASS_BRIDGE_P2P) {
|
||||
SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
|
||||
DEBUG ((DEBUG_INFO," ScanPciBus: PCI bridge S%04x B%02x D%02x F%02x (SecondBus:%02x)\n", Segment, Bus, Device, Function, SecondaryBusNumber));
|
||||
if (SecondaryBusNumber != 0) {
|
||||
Status = ScanPciBus (Context, Segment, SecondaryBusNumber, Callback);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Function == 0) {
|
||||
HeaderType = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, 0, PCI_HEADER_TYPE_OFFSET));
|
||||
if ((HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00) {
|
||||
//
|
||||
// It is not a multi-function device, do not scan other functions.
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump the PCI device information managed by this VTd engine.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpPciDeviceInfo (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll - %d):\n",
|
||||
mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,
|
||||
mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag
|
||||
));
|
||||
for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
|
||||
DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n",
|
||||
mVtdUnitInformation[VtdIndex].Segment,
|
||||
mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Bus,
|
||||
mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Device,
|
||||
mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Function
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Find the VTd index by the Segment and SourceId.
|
||||
|
||||
@param[in] Segment The segment of the source.
|
||||
@param[in] SourceId The SourceId of the source.
|
||||
@param[out] ExtContextEntry The ExtContextEntry of the source.
|
||||
@param[out] ContextEntry The ContextEntry of the source.
|
||||
|
||||
@return The index of the VTd engine.
|
||||
@retval (UINTN)-1 The VTd engine is not found.
|
||||
**/
|
||||
UINTN
|
||||
FindVtdIndexByPciDevice (
|
||||
IN UINT16 Segment,
|
||||
IN VTD_SOURCE_ID SourceId,
|
||||
OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,
|
||||
OUT VTD_CONTEXT_ENTRY **ContextEntry
|
||||
)
|
||||
{
|
||||
UINTN VtdIndex;
|
||||
VTD_ROOT_ENTRY *RootEntry;
|
||||
VTD_CONTEXT_ENTRY *ContextEntryTable;
|
||||
VTD_CONTEXT_ENTRY *ThisContextEntry;
|
||||
VTD_EXT_ROOT_ENTRY *ExtRootEntry;
|
||||
VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable;
|
||||
VTD_EXT_CONTEXT_ENTRY *ThisExtContextEntry;
|
||||
UINTN PciDataIndex;
|
||||
|
||||
for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {
|
||||
if (Segment != mVtdUnitInformation[VtdIndex].Segment) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PciDataIndex = GetPciDataIndex (VtdIndex, Segment, SourceId);
|
||||
if (PciDataIndex == (UINTN)-1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// DEBUG ((DEBUG_INFO,"FindVtdIndex(0x%x) for S%04x B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
|
||||
if (mVtdUnitInformation[VtdIndex].ExtRootEntryTable != 0) {
|
||||
ExtRootEntry = &mVtdUnitInformation[VtdIndex].ExtRootEntryTable[SourceId.Index.RootIndex];
|
||||
ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi) ;
|
||||
ThisExtContextEntry = &ExtContextEntryTable[SourceId.Index.ContextIndex];
|
||||
if (ThisExtContextEntry->Bits.AddressWidth == 0) {
|
||||
continue;
|
||||
}
|
||||
*ExtContextEntry = ThisExtContextEntry;
|
||||
*ContextEntry = NULL;
|
||||
} else {
|
||||
RootEntry = &mVtdUnitInformation[VtdIndex].RootEntryTable[SourceId.Index.RootIndex];
|
||||
ContextEntryTable = (VTD_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi) ;
|
||||
ThisContextEntry = &ContextEntryTable[SourceId.Index.ContextIndex];
|
||||
if (ThisContextEntry->Bits.AddressWidth == 0) {
|
||||
continue;
|
||||
}
|
||||
*ExtContextEntry = NULL;
|
||||
*ContextEntry = ThisContextEntry;
|
||||
}
|
||||
|
||||
return VtdIndex;
|
||||
}
|
||||
|
||||
return (UINTN)-1;
|
||||
}
|
||||
|
1032
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
Normal file
1032
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
Normal file
File diff suppressed because it is too large
Load Diff
158
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c
Normal file
158
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
/**
|
||||
Create extended context entry.
|
||||
|
||||
@param[in] VtdIndex The index of the VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS The extended context entry is created.
|
||||
@retval EFI_OUT_OF_RESOURCE No enough resource to create extended context entry.
|
||||
**/
|
||||
EFI_STATUS
|
||||
CreateExtContextEntry (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
VOID *Buffer;
|
||||
UINTN RootPages;
|
||||
UINTN ContextPages;
|
||||
VTD_EXT_ROOT_ENTRY *ExtRootEntry;
|
||||
VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable;
|
||||
VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
|
||||
VTD_SOURCE_ID *PciSourceId;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
UINTN MaxBusNumber;
|
||||
UINTN EntryTablePages;
|
||||
|
||||
MaxBusNumber = 0;
|
||||
for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
|
||||
PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
|
||||
if (PciSourceId->Bits.Bus > MaxBusNumber) {
|
||||
MaxBusNumber = PciSourceId->Bits.Bus;
|
||||
}
|
||||
}
|
||||
DEBUG ((DEBUG_INFO," MaxBusNumber - 0x%x\n", MaxBusNumber));
|
||||
|
||||
RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_ROOT_ENTRY) * VTD_ROOT_ENTRY_NUMBER);
|
||||
ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_CONTEXT_ENTRY) * VTD_CONTEXT_ENTRY_NUMBER);
|
||||
EntryTablePages = RootPages + ContextPages * (MaxBusNumber + 1);
|
||||
Buffer = AllocateZeroPages (EntryTablePages);
|
||||
if (Buffer == NULL) {
|
||||
DEBUG ((DEBUG_INFO,"Could not Alloc Root Entry Table.. \n"));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
mVtdUnitInformation[VtdIndex].ExtRootEntryTable = (VTD_EXT_ROOT_ENTRY *)Buffer;
|
||||
Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (RootPages);
|
||||
|
||||
for (Index = 0; Index < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
|
||||
PciSourceId = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[Index].PciSourceId;
|
||||
|
||||
SourceId.Bits.Bus = PciSourceId->Bits.Bus;
|
||||
SourceId.Bits.Device = PciSourceId->Bits.Device;
|
||||
SourceId.Bits.Function = PciSourceId->Bits.Function;
|
||||
|
||||
ExtRootEntry = &mVtdUnitInformation[VtdIndex].ExtRootEntryTable[SourceId.Index.RootIndex];
|
||||
if (ExtRootEntry->Bits.LowerPresent == 0) {
|
||||
ExtRootEntry->Bits.LowerContextTablePointerLo = (UINT32) RShiftU64 ((UINT64)(UINTN)Buffer, 12);
|
||||
ExtRootEntry->Bits.LowerContextTablePointerHi = (UINT32) RShiftU64 ((UINT64)(UINTN)Buffer, 32);
|
||||
ExtRootEntry->Bits.LowerPresent = 1;
|
||||
ExtRootEntry->Bits.UpperContextTablePointerLo = (UINT32) RShiftU64 ((UINT64)(UINTN)Buffer, 12) + 1;
|
||||
ExtRootEntry->Bits.UpperContextTablePointerHi = (UINT32) RShiftU64 (RShiftU64 ((UINT64)(UINTN)Buffer, 12) + 1, 20);
|
||||
ExtRootEntry->Bits.UpperPresent = 1;
|
||||
Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
|
||||
}
|
||||
|
||||
ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi) ;
|
||||
ExtContextEntry = &ExtContextEntryTable[SourceId.Index.ContextIndex];
|
||||
ExtContextEntry->Bits.TranslationType = 0;
|
||||
ExtContextEntry->Bits.FaultProcessingDisable = 0;
|
||||
ExtContextEntry->Bits.Present = 0;
|
||||
|
||||
DEBUG ((DEBUG_INFO,"DOMAIN: S%04x, B%02x D%02x F%02x\n", mVtdUnitInformation[VtdIndex].Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
|
||||
switch (mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW) {
|
||||
case BIT1:
|
||||
ExtContextEntry->Bits.AddressWidth = 0x1;
|
||||
break;
|
||||
case BIT2:
|
||||
ExtContextEntry->Bits.AddressWidth = 0x2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FlushPageTableMemory (VtdIndex, (UINTN)mVtdUnitInformation[VtdIndex].ExtRootEntryTable, EFI_PAGES_TO_SIZE(EntryTablePages));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump DMAR extended context entry table.
|
||||
|
||||
@param[in] ExtRootEntry DMAR extended root entry.
|
||||
**/
|
||||
VOID
|
||||
DumpDmarExtContextEntryTable (
|
||||
IN VTD_EXT_ROOT_ENTRY *ExtRootEntry
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN Index2;
|
||||
VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
|
||||
|
||||
DEBUG ((DEBUG_INFO,"=========================\n"));
|
||||
DEBUG ((DEBUG_INFO,"DMAR ExtContext Entry Table:\n"));
|
||||
|
||||
DEBUG ((DEBUG_INFO,"ExtRootEntry Address - 0x%x\n", ExtRootEntry));
|
||||
|
||||
for (Index = 0; Index < VTD_ROOT_ENTRY_NUMBER; Index++) {
|
||||
if ((ExtRootEntry[Index].Uint128.Uint64Lo != 0) || (ExtRootEntry[Index].Uint128.Uint64Hi != 0)) {
|
||||
DEBUG ((DEBUG_INFO," ExtRootEntry(0x%02x) B%02x - 0x%016lx %016lx\n",
|
||||
Index, Index, ExtRootEntry[Index].Uint128.Uint64Hi, ExtRootEntry[Index].Uint128.Uint64Lo));
|
||||
}
|
||||
if (ExtRootEntry[Index].Bits.LowerPresent == 0) {
|
||||
continue;
|
||||
}
|
||||
ExtContextEntry = (VTD_EXT_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(ExtRootEntry[Index].Bits.LowerContextTablePointerLo, ExtRootEntry[Index].Bits.LowerContextTablePointerHi);
|
||||
for (Index2 = 0; Index2 < VTD_CONTEXT_ENTRY_NUMBER/2; Index2++) {
|
||||
if ((ExtContextEntry[Index2].Uint256.Uint64_1 != 0) || (ExtContextEntry[Index2].Uint256.Uint64_2 != 0) ||
|
||||
(ExtContextEntry[Index2].Uint256.Uint64_3 != 0) || (ExtContextEntry[Index2].Uint256.Uint64_4 != 0)) {
|
||||
DEBUG ((DEBUG_INFO," ExtContextEntryLower(0x%02x) D%02xF%02x - 0x%016lx %016lx %016lx %016lx\n",
|
||||
Index2, Index2 >> 3, Index2 & 0x7, ExtContextEntry[Index2].Uint256.Uint64_4, ExtContextEntry[Index2].Uint256.Uint64_3, ExtContextEntry[Index2].Uint256.Uint64_2, ExtContextEntry[Index2].Uint256.Uint64_1));
|
||||
}
|
||||
if (ExtContextEntry[Index2].Bits.Present == 0) {
|
||||
continue;
|
||||
}
|
||||
DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi));
|
||||
}
|
||||
|
||||
if (ExtRootEntry[Index].Bits.UpperPresent == 0) {
|
||||
continue;
|
||||
}
|
||||
ExtContextEntry = (VTD_EXT_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(ExtRootEntry[Index].Bits.UpperContextTablePointerLo, ExtRootEntry[Index].Bits.UpperContextTablePointerHi);
|
||||
for (Index2 = 0; Index2 < VTD_CONTEXT_ENTRY_NUMBER/2; Index2++) {
|
||||
if ((ExtContextEntry[Index2].Uint256.Uint64_1 != 0) || (ExtContextEntry[Index2].Uint256.Uint64_2 != 0) ||
|
||||
(ExtContextEntry[Index2].Uint256.Uint64_3 != 0) || (ExtContextEntry[Index2].Uint256.Uint64_4 != 0)) {
|
||||
DEBUG ((DEBUG_INFO," ExtContextEntryUpper(0x%02x) D%02xF%02x - 0x%016lx %016lx %016lx %016lx\n",
|
||||
Index2, (Index2 + 128) >> 3, (Index2 + 128) & 0x7, ExtContextEntry[Index2].Uint256.Uint64_4, ExtContextEntry[Index2].Uint256.Uint64_3, ExtContextEntry[Index2].Uint256.Uint64_2, ExtContextEntry[Index2].Uint256.Uint64_1));
|
||||
}
|
||||
if (ExtContextEntry[Index2].Bits.Present == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG ((DEBUG_INFO,"=========================\n"));
|
||||
}
|
564
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
Normal file
564
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
Normal file
@@ -0,0 +1,564 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "DmaProtection.h"
|
||||
|
||||
UINTN mVtdUnitNumber;
|
||||
VTD_UNIT_INFORMATION *mVtdUnitInformation;
|
||||
|
||||
BOOLEAN mVtdEnabled;
|
||||
|
||||
/**
|
||||
Flush VTD page table and context table memory.
|
||||
|
||||
This action is to make sure the IOMMU engine can get final data in memory.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
@param[in] Base The base address of memory to be flushed.
|
||||
@param[in] Size The size of memory in bytes to be flushed.
|
||||
**/
|
||||
VOID
|
||||
FlushPageTableMemory (
|
||||
IN UINTN VtdIndex,
|
||||
IN UINTN Base,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
if (mVtdUnitInformation[VtdIndex].ECapReg.Bits.C == 0) {
|
||||
WriteBackDataCacheRange ((VOID *)Base, Size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Flush VTd engine write buffer.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
**/
|
||||
VOID
|
||||
FlushWriteBuffer (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
|
||||
if (mVtdUnitInformation[VtdIndex].CapReg.Bits.RWBF != 0) {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF);
|
||||
do {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while ((Reg32 & B_GSTS_REG_WBF) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Invalidate VTd context cache.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateContextCache (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINT64 Reg64;
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG);
|
||||
if ((Reg64 & B_CCMD_REG_ICC) != 0) {
|
||||
DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%d)\n",VtdIndex));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Reg64 &= ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK));
|
||||
Reg64 |= (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL);
|
||||
MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG, Reg64);
|
||||
|
||||
do {
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG);
|
||||
} while ((Reg64 & B_CCMD_REG_ICC) != 0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Invalidate VTd IOTLB.
|
||||
|
||||
@param[in] VtdIndex The index used to identify a VTd engine.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateIOTLB (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINT64 Reg64;
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
|
||||
if ((Reg64 & B_IOTLB_REG_IVT) != 0) {
|
||||
DEBUG ((DEBUG_ERROR,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%d)\n", VtdIndex));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Reg64 &= ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK));
|
||||
Reg64 |= (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL);
|
||||
MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
|
||||
|
||||
do {
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
|
||||
} while ((Reg64 & B_IOTLB_REG_IVT) != 0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Invalid VTd global IOTLB.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS VTd global IOTLB is invalidated.
|
||||
@retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateVtdIOTLBGlobal (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
if (!mVtdEnabled) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex));
|
||||
|
||||
//
|
||||
// Write Buffer Flush before invalidation
|
||||
//
|
||||
FlushWriteBuffer (VtdIndex);
|
||||
|
||||
//
|
||||
// Invalidate the context cache
|
||||
//
|
||||
if (mVtdUnitInformation[VtdIndex].HasDirtyContext) {
|
||||
InvalidateContextCache (VtdIndex);
|
||||
}
|
||||
|
||||
//
|
||||
// Invalidate the IOTLB cache
|
||||
//
|
||||
if (mVtdUnitInformation[VtdIndex].HasDirtyContext || mVtdUnitInformation[VtdIndex].HasDirtyPages) {
|
||||
InvalidateIOTLB (VtdIndex);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Prepare VTD configuration.
|
||||
**/
|
||||
VOID
|
||||
PrepareVtdConfig (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN DomainNumber;
|
||||
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
DEBUG ((DEBUG_INFO, "Dump VTd Capability (%d)\n", Index));
|
||||
mVtdUnitInformation[Index].CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
|
||||
DumpVtdCapRegs (&mVtdUnitInformation[Index].CapReg);
|
||||
mVtdUnitInformation[Index].ECapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_ECAP_REG);
|
||||
DumpVtdECapRegs (&mVtdUnitInformation[Index].ECapReg);
|
||||
|
||||
if ((mVtdUnitInformation[Index].CapReg.Bits.SLLPS & BIT0) == 0) {
|
||||
DEBUG((DEBUG_WARN, "!!!! 2MB super page is not supported on VTD %d !!!!\n", Index));
|
||||
}
|
||||
if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) == 0) {
|
||||
DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", Index));
|
||||
return ;
|
||||
}
|
||||
|
||||
DomainNumber = (UINTN)1 << (UINT8)((UINTN)mVtdUnitInformation[Index].CapReg.Bits.ND * 2 + 4);
|
||||
if (mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber >= DomainNumber) {
|
||||
DEBUG((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber, DomainNumber));
|
||||
return ;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable PMR in all VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DisablePmr (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
VTD_CAP_REG CapReg;
|
||||
UINTN Index;
|
||||
|
||||
DEBUG ((DEBUG_INFO,"DisablePmr\n"));
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CAP_REG);
|
||||
if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
|
||||
continue ;
|
||||
}
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
if ((Reg32 & BIT0) != 0) {
|
||||
MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);
|
||||
do {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
} while((Reg32 & BIT0) != 0);
|
||||
DEBUG ((DEBUG_INFO,"Pmr(%d) disabled\n", Index));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO,"Pmr(%d) not enabled\n", Index));
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is enabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not enabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnableDmar (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT32 Reg32;
|
||||
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
DEBUG((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%d] \n", Index));
|
||||
|
||||
if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {
|
||||
DEBUG((DEBUG_INFO, "ExtRootEntryTable 0x%x \n", mVtdUnitInformation[Index].ExtRootEntryTable));
|
||||
MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)(UINTN)mVtdUnitInformation[Index].ExtRootEntryTable | BIT11);
|
||||
} else {
|
||||
DEBUG((DEBUG_INFO, "RootEntryTable 0x%x \n", mVtdUnitInformation[Index].RootEntryTable));
|
||||
MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)(UINTN)mVtdUnitInformation[Index].RootEntryTable);
|
||||
}
|
||||
|
||||
MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
|
||||
|
||||
DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"));
|
||||
do {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
|
||||
|
||||
//
|
||||
// Init DMAr Fault Event and Data registers
|
||||
//
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_FEDATA_REG);
|
||||
|
||||
//
|
||||
// Write Buffer Flush before invalidation
|
||||
//
|
||||
FlushWriteBuffer (Index);
|
||||
|
||||
//
|
||||
// Invalidate the context cache
|
||||
//
|
||||
InvalidateContextCache (Index);
|
||||
|
||||
//
|
||||
// Invalidate the IOTLB cache
|
||||
//
|
||||
InvalidateIOTLB (Index);
|
||||
|
||||
//
|
||||
// Enable VTd
|
||||
//
|
||||
MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_TE);
|
||||
DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
|
||||
do {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while ((Reg32 & B_GSTS_REG_TE) == 0);
|
||||
|
||||
DEBUG ((DEBUG_INFO,"VTD (%d) enabled!<<<<<<\n",Index));
|
||||
}
|
||||
|
||||
//
|
||||
// Need disable PMR, since we already setup translation table.
|
||||
//
|
||||
DisablePmr ();
|
||||
|
||||
mVtdEnabled = TRUE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable DMAR translation.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is disabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmar (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN SubIndex;
|
||||
UINT32 Reg32;
|
||||
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n", Index));
|
||||
|
||||
//
|
||||
// Write Buffer Flush before invalidation
|
||||
//
|
||||
FlushWriteBuffer (Index);
|
||||
|
||||
//
|
||||
// Disable VTd
|
||||
//
|
||||
MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
|
||||
do {
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
DEBUG((DEBUG_INFO, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32));
|
||||
|
||||
DEBUG ((DEBUG_INFO,"VTD (%d) Disabled!<<<<<<\n",Index));
|
||||
}
|
||||
|
||||
mVtdEnabled = FALSE;
|
||||
|
||||
for (Index = 0; Index < mVtdUnitNumber; Index++) {
|
||||
DEBUG((DEBUG_INFO, "engine [%d] access\n", Index));
|
||||
for (SubIndex = 0; SubIndex < mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceDataNumber; SubIndex++) {
|
||||
DEBUG ((DEBUG_INFO, " PCI S%04X B%02x D%02x F%02x - %d\n",
|
||||
mVtdUnitInformation[Index].Segment,
|
||||
mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Bus,
|
||||
mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Device,
|
||||
mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].PciSourceId.Bits.Function,
|
||||
mVtdUnitInformation[Index].PciDeviceInfo.PciDeviceData[Index].AccessCount
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump VTd capability registers.
|
||||
|
||||
@param[in] CapReg The capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdCapRegs (
|
||||
IN VTD_CAP_REG *CapReg
|
||||
)
|
||||
{
|
||||
DEBUG((DEBUG_INFO, " CapReg:\n", CapReg->Uint64));
|
||||
DEBUG((DEBUG_INFO, " ND - 0x%x\n", CapReg->Bits.ND));
|
||||
DEBUG((DEBUG_INFO, " AFL - 0x%x\n", CapReg->Bits.AFL));
|
||||
DEBUG((DEBUG_INFO, " RWBF - 0x%x\n", CapReg->Bits.RWBF));
|
||||
DEBUG((DEBUG_INFO, " PLMR - 0x%x\n", CapReg->Bits.PLMR));
|
||||
DEBUG((DEBUG_INFO, " PHMR - 0x%x\n", CapReg->Bits.PHMR));
|
||||
DEBUG((DEBUG_INFO, " CM - 0x%x\n", CapReg->Bits.CM));
|
||||
DEBUG((DEBUG_INFO, " SAGAW - 0x%x\n", CapReg->Bits.SAGAW));
|
||||
DEBUG((DEBUG_INFO, " MGAW - 0x%x\n", CapReg->Bits.MGAW));
|
||||
DEBUG((DEBUG_INFO, " ZLR - 0x%x\n", CapReg->Bits.ZLR));
|
||||
DEBUG((DEBUG_INFO, " FRO - 0x%x\n", CapReg->Bits.FRO));
|
||||
DEBUG((DEBUG_INFO, " SLLPS - 0x%x\n", CapReg->Bits.SLLPS));
|
||||
DEBUG((DEBUG_INFO, " PSI - 0x%x\n", CapReg->Bits.PSI));
|
||||
DEBUG((DEBUG_INFO, " NFR - 0x%x\n", CapReg->Bits.NFR));
|
||||
DEBUG((DEBUG_INFO, " MAMV - 0x%x\n", CapReg->Bits.MAMV));
|
||||
DEBUG((DEBUG_INFO, " DWD - 0x%x\n", CapReg->Bits.DWD));
|
||||
DEBUG((DEBUG_INFO, " DRD - 0x%x\n", CapReg->Bits.DRD));
|
||||
DEBUG((DEBUG_INFO, " FL1GP - 0x%x\n", CapReg->Bits.FL1GP));
|
||||
DEBUG((DEBUG_INFO, " PI - 0x%x\n", CapReg->Bits.PI));
|
||||
}
|
||||
|
||||
/**
|
||||
Dump VTd extended capability registers.
|
||||
|
||||
@param[in] ECapReg The extended capability register.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdECapRegs (
|
||||
IN VTD_ECAP_REG *ECapReg
|
||||
)
|
||||
{
|
||||
DEBUG((DEBUG_INFO, " ECapReg:\n", ECapReg->Uint64));
|
||||
DEBUG((DEBUG_INFO, " C - 0x%x\n", ECapReg->Bits.C));
|
||||
DEBUG((DEBUG_INFO, " QI - 0x%x\n", ECapReg->Bits.QI));
|
||||
DEBUG((DEBUG_INFO, " DT - 0x%x\n", ECapReg->Bits.DT));
|
||||
DEBUG((DEBUG_INFO, " IR - 0x%x\n", ECapReg->Bits.IR));
|
||||
DEBUG((DEBUG_INFO, " EIM - 0x%x\n", ECapReg->Bits.EIM));
|
||||
DEBUG((DEBUG_INFO, " PT - 0x%x\n", ECapReg->Bits.PT));
|
||||
DEBUG((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC));
|
||||
DEBUG((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO));
|
||||
DEBUG((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV));
|
||||
DEBUG((DEBUG_INFO, " ECS - 0x%x\n", ECapReg->Bits.ECS));
|
||||
DEBUG((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS));
|
||||
DEBUG((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST));
|
||||
DEBUG((DEBUG_INFO, " DIS - 0x%x\n", ECapReg->Bits.DIS));
|
||||
DEBUG((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID));
|
||||
DEBUG((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS));
|
||||
DEBUG((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS));
|
||||
DEBUG((DEBUG_INFO, " SRS - 0x%x\n", ECapReg->Bits.SRS));
|
||||
DEBUG((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS));
|
||||
DEBUG((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS));
|
||||
DEBUG((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS));
|
||||
}
|
||||
|
||||
/**
|
||||
Dump VTd registers.
|
||||
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegs (
|
||||
IN UINTN VtdIndex
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT64 Reg64;
|
||||
VTD_FRCD_REG FrcdReg;
|
||||
VTD_CAP_REG CapReg;
|
||||
UINT32 Reg32;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
|
||||
DEBUG((DEBUG_INFO, "#### DumpVtdRegs(%d) Begin ####\n", VtdIndex));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_VER_REG);
|
||||
DEBUG((DEBUG_INFO, " VER_REG - 0x%08x\n", Reg32));
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CAP_REG);
|
||||
DEBUG((DEBUG_INFO, " CAP_REG - 0x%016lx\n", CapReg.Uint64));
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_ECAP_REG);
|
||||
DEBUG((DEBUG_INFO, " ECAP_REG - 0x%016lx\n", Reg64));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG);
|
||||
DEBUG((DEBUG_INFO, " GSTS_REG - 0x%08x \n", Reg32));
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_RTADDR_REG);
|
||||
DEBUG((DEBUG_INFO, " RTADDR_REG - 0x%016lx\n", Reg64));
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_REG);
|
||||
DEBUG((DEBUG_INFO, " CCMD_REG - 0x%016lx\n", Reg64));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FSTS_REG);
|
||||
DEBUG((DEBUG_INFO, " FSTS_REG - 0x%08x\n", Reg32));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FECTL_REG);
|
||||
DEBUG((DEBUG_INFO, " FECTL_REG - 0x%08x\n", Reg32));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FEDATA_REG);
|
||||
DEBUG((DEBUG_INFO, " FEDATA_REG - 0x%08x\n", Reg32));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FEADDR_REG);
|
||||
DEBUG((DEBUG_INFO, " FEADDR_REG - 0x%08x\n",Reg32));
|
||||
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FEUADDR_REG);
|
||||
DEBUG((DEBUG_INFO, " FEUADDR_REG - 0x%08x\n",Reg32));
|
||||
|
||||
for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
|
||||
FrcdReg.Uint64[0] = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG));
|
||||
FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
|
||||
DEBUG((DEBUG_INFO, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index, FrcdReg.Uint64[1], FrcdReg.Uint64[0]));
|
||||
if (FrcdReg.Uint64[1] != 0 || FrcdReg.Uint64[0] != 0) {
|
||||
DEBUG((DEBUG_INFO, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg.Bits.FILo, FrcdReg.Bits.FIHi)));
|
||||
SourceId.Uint16 = (UINT16)FrcdReg.Bits.SID;
|
||||
DEBUG((DEBUG_INFO, " Source - B%02x D%02x F%02x\n", SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
|
||||
DEBUG((DEBUG_INFO, " Type - %x (%a)\n", FrcdReg.Bits.T, FrcdReg.Bits.T ? "read" : "write"));
|
||||
DEBUG((DEBUG_INFO, " Reason - %x (Refer to VTd Spec, Appendix A)\n", FrcdReg.Bits.FR));
|
||||
}
|
||||
}
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IVA_REG);
|
||||
DEBUG((DEBUG_INFO, " IVA_REG - 0x%016lx\n",Reg64));
|
||||
|
||||
Reg64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
|
||||
DEBUG((DEBUG_INFO, " IOTLB_REG - 0x%016lx\n",Reg64));
|
||||
|
||||
DEBUG((DEBUG_INFO, "#### DumpVtdRegs(%d) End ####\n", VtdIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
Dump VTd registers for all VTd engine.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdRegsAll (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Num;
|
||||
|
||||
for (Num = 0; Num < mVtdUnitNumber; Num++) {
|
||||
DumpVtdRegs (Num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Dump VTd registers if there is error.
|
||||
**/
|
||||
VOID
|
||||
DumpVtdIfError (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Num;
|
||||
UINTN Index;
|
||||
VTD_FRCD_REG FrcdReg;
|
||||
VTD_CAP_REG CapReg;
|
||||
UINT32 Reg32;
|
||||
BOOLEAN HasError;
|
||||
|
||||
for (Num = 0; Num < mVtdUnitNumber; Num++) {
|
||||
HasError = FALSE;
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG);
|
||||
if (Reg32 != 0) {
|
||||
HasError = TRUE;
|
||||
}
|
||||
Reg32 = MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FECTL_REG);
|
||||
if ((Reg32 & BIT30) != 0) {
|
||||
HasError = TRUE;
|
||||
}
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_CAP_REG);
|
||||
for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
|
||||
FrcdReg.Uint64[0] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG));
|
||||
FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
|
||||
if (FrcdReg.Bits.F != 0) {
|
||||
HasError = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasError) {
|
||||
DEBUG((DEBUG_INFO, "\n#### ERROR ####\n"));
|
||||
DumpVtdRegs (Num);
|
||||
DEBUG((DEBUG_INFO, "#### ERROR ####\n\n"));
|
||||
//
|
||||
// Clear
|
||||
//
|
||||
for (Index = 0; Index < (UINTN)CapReg.Bits.NFR + 1; Index++) {
|
||||
FrcdReg.Uint64[1] = MmioRead64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)));
|
||||
if (FrcdReg.Bits.F != 0) {
|
||||
FrcdReg.Bits.F = 0;
|
||||
MmioWrite64 (mVtdUnitInformation[Num].VtdUnitBaseAddress + ((CapReg.Bits.FRO * 16) + (Index * 16) + R_FRCD_REG + sizeof(UINT64)), FrcdReg.Uint64[1]);
|
||||
}
|
||||
MmioWrite32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG, MmioRead32 (mVtdUnitInformation[Num].VtdUnitBaseAddress + R_FSTS_REG));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
584
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
Normal file
584
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
Normal file
@@ -0,0 +1,584 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <Ppi/VtdInfo.h>
|
||||
|
||||
#include "IntelVTdPmrPei.h"
|
||||
|
||||
/**
|
||||
Dump DMAR DeviceScopeEntry.
|
||||
|
||||
@param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry
|
||||
**/
|
||||
VOID
|
||||
DumpDmarDeviceScopeEntry (
|
||||
IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry
|
||||
)
|
||||
{
|
||||
UINTN PciPathNumber;
|
||||
UINTN PciPathIndex;
|
||||
EFI_ACPI_DMAR_PCI_PATH *PciPath;
|
||||
|
||||
if (DmarDeviceScopeEntry == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" *************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" * DMA-Remapping Device Scope Entry Structure *\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" *************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
(sizeof(UINTN) == sizeof(UINT64)) ?
|
||||
" DMAR Device Scope Entry address ...................... 0x%016lx\n" :
|
||||
" DMAR Device Scope Entry address ...................... 0x%08x\n",
|
||||
DmarDeviceScopeEntry
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Device Scope Entry Type ............................ 0x%02x\n",
|
||||
DmarDeviceScopeEntry->Type
|
||||
));
|
||||
switch (DmarDeviceScopeEntry->Type) {
|
||||
case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" PCI Endpoint Device\n"
|
||||
));
|
||||
break;
|
||||
case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" PCI Sub-hierachy\n"
|
||||
));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Length ............................................. 0x%02x\n",
|
||||
DmarDeviceScopeEntry->Length
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Enumeration ID ..................................... 0x%02x\n",
|
||||
DmarDeviceScopeEntry->EnumerationId
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Starting Bus Number ................................ 0x%02x\n",
|
||||
DmarDeviceScopeEntry->StartBusNumber
|
||||
));
|
||||
|
||||
PciPathNumber = (DmarDeviceScopeEntry->Length - sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER)) / sizeof(EFI_ACPI_DMAR_PCI_PATH);
|
||||
PciPath = (EFI_ACPI_DMAR_PCI_PATH *)(DmarDeviceScopeEntry + 1);
|
||||
for (PciPathIndex = 0; PciPathIndex < PciPathNumber; PciPathIndex++) {
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Device ............................................. 0x%02x\n",
|
||||
PciPath[PciPathIndex].Device
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Function ........................................... 0x%02x\n",
|
||||
PciPath[PciPathIndex].Function
|
||||
));
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" *************************************************************************\n\n"
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump DMAR RMRR table.
|
||||
|
||||
@param[in] Rmrr DMAR RMRR table
|
||||
**/
|
||||
VOID
|
||||
DumpDmarRmrr (
|
||||
IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
|
||||
INTN RmrrLen;
|
||||
|
||||
if (Rmrr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" * Reserved Memory Region Reporting Structure *\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
(sizeof(UINTN) == sizeof(UINT64)) ?
|
||||
" RMRR address ........................................... 0x%016lx\n" :
|
||||
" RMRR address ........................................... 0x%08x\n",
|
||||
Rmrr
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Type ................................................. 0x%04x\n",
|
||||
Rmrr->Header.Type
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Length ............................................... 0x%04x\n",
|
||||
Rmrr->Header.Length
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Segment Number ....................................... 0x%04x\n",
|
||||
Rmrr->SegmentNumber
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Reserved Memory Region Base Address .................. 0x%016lx\n",
|
||||
Rmrr->ReservedMemoryRegionBaseAddress
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Reserved Memory Region Limit Address ................. 0x%016lx\n",
|
||||
Rmrr->ReservedMemoryRegionLimitAddress
|
||||
));
|
||||
|
||||
RmrrLen = Rmrr->Header.Length - sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
|
||||
DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Rmrr + 1);
|
||||
while (RmrrLen > 0) {
|
||||
DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
|
||||
RmrrLen -= DmarDeviceScopeEntry->Length;
|
||||
DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n\n"
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump DMAR DRHD table.
|
||||
|
||||
@param[in] Drhd DMAR DRHD table
|
||||
**/
|
||||
VOID
|
||||
DumpDmarDrhd (
|
||||
IN EFI_ACPI_DMAR_DRHD_HEADER *Drhd
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
|
||||
INTN DrhdLen;
|
||||
|
||||
if (Drhd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" * DMA-Remapping Hardware Definition Structure *\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
(sizeof(UINTN) == sizeof(UINT64)) ?
|
||||
" DRHD address ........................................... 0x%016lx\n" :
|
||||
" DRHD address ........................................... 0x%08x\n",
|
||||
Drhd
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Type ................................................. 0x%04x\n",
|
||||
Drhd->Header.Type
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Length ............................................... 0x%04x\n",
|
||||
Drhd->Header.Length
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Flags ................................................ 0x%02x\n",
|
||||
Drhd->Flags
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" INCLUDE_PCI_ALL .................................... 0x%02x\n",
|
||||
Drhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Segment Number ....................................... 0x%04x\n",
|
||||
Drhd->SegmentNumber
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Register Base Address ................................ 0x%016lx\n",
|
||||
Drhd->RegisterBaseAddress
|
||||
));
|
||||
|
||||
DrhdLen = Drhd->Header.Length - sizeof(EFI_ACPI_DMAR_DRHD_HEADER);
|
||||
DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Drhd + 1);
|
||||
while (DrhdLen > 0) {
|
||||
DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
|
||||
DrhdLen -= DmarDeviceScopeEntry->Length;
|
||||
DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" ***************************************************************************\n\n"
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump DMAR ACPI table.
|
||||
|
||||
@param[in] Dmar DMAR ACPI table
|
||||
**/
|
||||
VOID
|
||||
DumpAcpiDMAR (
|
||||
IN EFI_ACPI_DMAR_HEADER *Dmar
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
|
||||
INTN DmarLen;
|
||||
|
||||
if (Dmar == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Dump Dmar table
|
||||
//
|
||||
DEBUG ((DEBUG_INFO,
|
||||
"*****************************************************************************\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
"* DMAR Table *\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
"*****************************************************************************\n"
|
||||
));
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
(sizeof(UINTN) == sizeof(UINT64)) ?
|
||||
"DMAR address ............................................. 0x%016lx\n" :
|
||||
"DMAR address ............................................. 0x%08x\n",
|
||||
Dmar
|
||||
));
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Table Contents:\n"
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Host Address Width ................................... 0x%02x\n",
|
||||
Dmar->HostAddressWidth
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" Flags ................................................ 0x%02x\n",
|
||||
Dmar->Flags
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" INTR_REMAP ......................................... 0x%02x\n",
|
||||
Dmar->Flags & EFI_ACPI_DMAR_FLAGS_INTR_REMAP
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" X2APIC_OPT_OUT_SET ................................. 0x%02x\n",
|
||||
Dmar->Flags & EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT
|
||||
));
|
||||
DEBUG ((DEBUG_INFO,
|
||||
" DMA_CTRL_PLATFORM_OPT_IN_FLAG ...................... 0x%02x\n",
|
||||
Dmar->Flags & EFI_ACPI_DMAR_FLAGS_DMA_CTRL_PLATFORM_OPT_IN_FLAG
|
||||
));
|
||||
|
||||
DmarLen = Dmar->Header.Length - sizeof(EFI_ACPI_DMAR_HEADER);
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)(Dmar + 1);
|
||||
while (DmarLen > 0) {
|
||||
switch (DmarHeader->Type) {
|
||||
case EFI_ACPI_DMAR_TYPE_DRHD:
|
||||
DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
|
||||
break;
|
||||
case EFI_ACPI_DMAR_TYPE_RMRR:
|
||||
DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DmarLen -= DmarHeader->Length;
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO,
|
||||
"*****************************************************************************\n\n"
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Get VTd engine number.
|
||||
|
||||
@param[in] AcpiDmarTable DMAR ACPI table
|
||||
|
||||
@return the VTd engine number.
|
||||
**/
|
||||
UINTN
|
||||
GetVtdEngineNumber (
|
||||
IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
|
||||
UINTN VtdIndex;
|
||||
|
||||
VtdIndex = 0;
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
|
||||
while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
|
||||
switch (DmarHeader->Type) {
|
||||
case EFI_ACPI_DMAR_TYPE_DRHD:
|
||||
VtdIndex++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
|
||||
}
|
||||
return VtdIndex ;
|
||||
}
|
||||
|
||||
/**
|
||||
Process DMAR DHRD table.
|
||||
|
||||
@param[in] VTdInfo The VTd engine context information.
|
||||
@param[in] VtdIndex The index of VTd engine.
|
||||
@param[in] DmarDrhd The DRHD table.
|
||||
**/
|
||||
VOID
|
||||
ProcessDhrd (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINTN VtdIndex,
|
||||
IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_INFO," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex, DmarDrhd->RegisterBaseAddress));
|
||||
VTdInfo->VTdEngineAddress[VtdIndex] = DmarDrhd->RegisterBaseAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@param[in] AcpiDmarTable DMAR ACPI table
|
||||
|
||||
@return EFI_SUCCESS The DMAR DRHD table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableDrhd (
|
||||
IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
|
||||
UINTN VtdUnitNumber;
|
||||
UINTN VtdIndex;
|
||||
VTD_INFO *VTdInfo;
|
||||
|
||||
VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
|
||||
if (VtdUnitNumber == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof(VTD_INFO) + (VtdUnitNumber - 1) * sizeof(UINT64));
|
||||
ASSERT(VTdInfo != NULL);
|
||||
if (VTdInfo == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the engine mask to all.
|
||||
//
|
||||
VTdInfo->AcpiDmarTable = AcpiDmarTable;
|
||||
VTdInfo->EngineMask = LShiftU64 (1, VtdUnitNumber) - 1;
|
||||
VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
|
||||
VTdInfo->VTdEngineCount = VtdUnitNumber;
|
||||
|
||||
VtdIndex = 0;
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
|
||||
while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
|
||||
switch (DmarHeader->Type) {
|
||||
case EFI_ACPI_DMAR_TYPE_DRHD:
|
||||
ASSERT (VtdIndex < VtdUnitNumber);
|
||||
ProcessDhrd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
|
||||
VtdIndex++;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
|
||||
}
|
||||
ASSERT (VtdIndex == VtdUnitNumber);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the VTd engine index according to the Segment and DevScopeEntry.
|
||||
|
||||
@param AcpiDmarTable DMAR ACPI table
|
||||
@param Segment The segment of the VTd engine
|
||||
@param DevScopeEntry The DevScopeEntry of the VTd engine
|
||||
|
||||
@return The VTd engine index according to the Segment and DevScopeEntry.
|
||||
@retval -1 The VTd engine is not found.
|
||||
**/
|
||||
UINTN
|
||||
GetVTdEngineFromDevScopeEntry (
|
||||
IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
|
||||
IN UINT16 Segment,
|
||||
IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DevScopeEntry
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
|
||||
UINTN VtdIndex;
|
||||
EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd;
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *ThisDevScopeEntry;
|
||||
|
||||
VtdIndex = 0;
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
|
||||
while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
|
||||
switch (DmarHeader->Type) {
|
||||
case EFI_ACPI_DMAR_TYPE_DRHD:
|
||||
DmarDrhd = (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader;
|
||||
if (DmarDrhd->SegmentNumber != Segment) {
|
||||
// Mismatch
|
||||
break;
|
||||
}
|
||||
if ((DmarDrhd->Header.Length == sizeof(EFI_ACPI_DMAR_DRHD_HEADER)) ||
|
||||
((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0)) {
|
||||
// No DevScopeEntry
|
||||
// Do not handle PCI_ALL
|
||||
break;
|
||||
}
|
||||
ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd + 1));
|
||||
while ((UINTN)ThisDevScopeEntry < (UINTN)DmarDrhd + DmarDrhd->Header.Length) {
|
||||
if ((ThisDevScopeEntry->Length == DevScopeEntry->Length) &&
|
||||
(CompareMem (ThisDevScopeEntry, DevScopeEntry, DevScopeEntry->Length) == 0)) {
|
||||
return VtdIndex;
|
||||
}
|
||||
ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)ThisDevScopeEntry + ThisDevScopeEntry->Length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
|
||||
}
|
||||
return (UINTN)-1;
|
||||
}
|
||||
|
||||
/**
|
||||
Process DMAR RMRR table.
|
||||
|
||||
@param[in] VTdInfo The VTd engine context information.
|
||||
@param[in] DmarRmrr The RMRR table.
|
||||
**/
|
||||
VOID
|
||||
ProcessRmrr (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
|
||||
UINTN VTdIndex;
|
||||
UINT64 RmrrMask;
|
||||
UINTN LowBottom;
|
||||
UINTN LowTop;
|
||||
UINTN HighBottom;
|
||||
UINT64 HighTop;
|
||||
EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
|
||||
|
||||
AcpiDmarTable = VTdInfo->AcpiDmarTable;
|
||||
|
||||
DEBUG ((DEBUG_INFO," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
|
||||
|
||||
if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
|
||||
(DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarRmrr + 1));
|
||||
while ((UINTN)DmarDevScopeEntry < (UINTN)DmarRmrr + DmarRmrr->Header.Length) {
|
||||
ASSERT (DmarDevScopeEntry->Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT);
|
||||
|
||||
VTdIndex = GetVTdEngineFromDevScopeEntry (AcpiDmarTable, DmarRmrr->SegmentNumber, DmarDevScopeEntry);
|
||||
if (VTdIndex != (UINTN)-1) {
|
||||
RmrrMask = LShiftU64 (1, VTdIndex);
|
||||
|
||||
LowBottom = 0;
|
||||
LowTop = (UINTN)DmarRmrr->ReservedMemoryRegionBaseAddress;
|
||||
HighBottom = (UINTN)DmarRmrr->ReservedMemoryRegionLimitAddress + 1;
|
||||
HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
|
||||
|
||||
SetDmaProtectedRange (
|
||||
VTdInfo,
|
||||
RmrrMask,
|
||||
0,
|
||||
(UINT32)(LowTop - LowBottom),
|
||||
HighBottom,
|
||||
HighTop - HighBottom
|
||||
);
|
||||
|
||||
//
|
||||
// Remove the engine from the engine mask.
|
||||
// The assumption is that any other PEI driver does not access
|
||||
// the device covered by this engine.
|
||||
//
|
||||
VTdInfo->EngineMask = VTdInfo->EngineMask & (~RmrrMask);
|
||||
}
|
||||
|
||||
DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDevScopeEntry + DmarDevScopeEntry->Length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@param[in] VTdInfo The VTd engine context information.
|
||||
**/
|
||||
VOID
|
||||
ParseDmarAcpiTableRmrr (
|
||||
IN VTD_INFO *VTdInfo
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
|
||||
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
|
||||
|
||||
AcpiDmarTable = VTdInfo->AcpiDmarTable;
|
||||
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
|
||||
while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
|
||||
switch (DmarHeader->Type) {
|
||||
case EFI_ACPI_DMAR_TYPE_RMRR:
|
||||
ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
|
||||
}
|
||||
}
|
426
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
Normal file
426
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
Normal file
@@ -0,0 +1,426 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License which accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <Ppi/VtdInfo.h>
|
||||
|
||||
#include "IntelVTdPmrPei.h"
|
||||
|
||||
/**
|
||||
Get protected low memory alignment.
|
||||
|
||||
@param HostAddressWidth The host address width.
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@return protected low memory alignment.
|
||||
**/
|
||||
UINT32
|
||||
GetPlmrAlignment (
|
||||
IN UINT8 HostAddressWidth,
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Data32;
|
||||
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, 0xFFFFFFFF);
|
||||
Data32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG);
|
||||
Data32 = ~Data32 + 1;
|
||||
|
||||
return Data32;
|
||||
}
|
||||
|
||||
/**
|
||||
Get protected high memory alignment.
|
||||
|
||||
@param HostAddressWidth The host address width.
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@return protected high memory alignment.
|
||||
**/
|
||||
UINT64
|
||||
GetPhmrAlignment (
|
||||
IN UINT8 HostAddressWidth,
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT64 Data64;
|
||||
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);
|
||||
Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
|
||||
Data64 = ~Data64 + 1;
|
||||
Data64 = Data64 & (LShiftU64 (1, HostAddressWidth) - 1);
|
||||
|
||||
return Data64;
|
||||
}
|
||||
|
||||
/**
|
||||
Get protected low memory alignment.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@return protected low memory alignment.
|
||||
**/
|
||||
UINT32
|
||||
GetLowMemoryAlignment (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT32 Alignment;
|
||||
UINT32 FinalAlignment;
|
||||
|
||||
FinalAlignment = 0;
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
Alignment = GetPlmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
if (FinalAlignment < Alignment) {
|
||||
FinalAlignment = Alignment;
|
||||
}
|
||||
}
|
||||
return FinalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
Get protected high memory alignment.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@return protected high memory alignment.
|
||||
**/
|
||||
UINT64
|
||||
GetHighMemoryAlignment (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT64 Alignment;
|
||||
UINT64 FinalAlignment;
|
||||
|
||||
FinalAlignment = 0;
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
Alignment = GetPhmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
if (FinalAlignment < Alignment) {
|
||||
FinalAlignment = Alignment;
|
||||
}
|
||||
}
|
||||
return FinalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable PMR in the VTd engine.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS The PMR is enabled.
|
||||
@retval EFI_UNSUPPORTED The PMR is not supported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnablePmr (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
VTD_CAP_REG CapReg;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "EnablePmr - %x\n", VtdUnitBaseAddress));
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
|
||||
if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
if (Reg32 == 0xFFFFFFFF) {
|
||||
DEBUG ((DEBUG_ERROR, "R_PMEN_ENABLE_REG - 0x%x\n", Reg32));
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if ((Reg32 & BIT0) == 0) {
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31);
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
} while((Reg32 & BIT0) == 0);
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "EnablePmr - Done\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable PMR in the VTd engine.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS The PMR is disabled.
|
||||
@retval EFI_UNSUPPORTED The PMR is not supported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisablePmr (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
VTD_CAP_REG CapReg;
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
|
||||
if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
if (Reg32 == 0xFFFFFFFF) {
|
||||
DEBUG ((DEBUG_ERROR, "R_PMEN_ENABLE_REG - 0x%x\n", Reg32));
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if ((Reg32 & BIT0) != 0) {
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0);
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
} while((Reg32 & BIT0) != 0);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Set PMR region in the VTd engine.
|
||||
|
||||
@param HostAddressWidth The host address width.
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
@param LowMemoryBase The protected low memory region base.
|
||||
@param LowMemoryLength The protected low memory region length.
|
||||
@param HighMemoryBase The protected high memory region base.
|
||||
@param HighMemoryLength The protected high memory region length.
|
||||
|
||||
@retval EFI_SUCCESS The PMR is set to protected region.
|
||||
@retval EFI_UNSUPPORTED The PMR is not supported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetPmrRegion (
|
||||
IN UINT8 HostAddressWidth,
|
||||
IN UINTN VtdUnitBaseAddress,
|
||||
IN UINT32 LowMemoryBase,
|
||||
IN UINT32 LowMemoryLength,
|
||||
IN UINT64 HighMemoryBase,
|
||||
IN UINT64 HighMemoryLength
|
||||
)
|
||||
{
|
||||
VTD_CAP_REG CapReg;
|
||||
UINT32 PlmrAlignment;
|
||||
UINT64 PhmrAlignment;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "VtdUnitBaseAddress - 0x%x\n", VtdUnitBaseAddress));
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
|
||||
if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
|
||||
DEBUG ((DEBUG_ERROR, "PLMR/PHMR unsupported\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
PlmrAlignment = GetPlmrAlignment (HostAddressWidth, VtdUnitBaseAddress);
|
||||
DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment));
|
||||
PhmrAlignment = GetPhmrAlignment (HostAddressWidth, VtdUnitBaseAddress);
|
||||
DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment));
|
||||
|
||||
if ((LowMemoryBase != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) ||
|
||||
(LowMemoryLength != ALIGN_VALUE(LowMemoryLength, PlmrAlignment)) ||
|
||||
(HighMemoryBase != ALIGN_VALUE(HighMemoryBase, PhmrAlignment)) ||
|
||||
(HighMemoryLength != ALIGN_VALUE(HighMemoryLength, PhmrAlignment))) {
|
||||
DEBUG ((DEBUG_ERROR, "PLMR/PHMR alignment issue\n"));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (LowMemoryBase == 0 && LowMemoryLength == 0) {
|
||||
LowMemoryBase = 0xFFFFFFFF;
|
||||
}
|
||||
if (HighMemoryBase == 0 && HighMemoryLength == 0) {
|
||||
HighMemoryBase = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, LowMemoryBase);
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG, LowMemoryBase + LowMemoryLength - 1);
|
||||
DEBUG ((DEBUG_INFO, "PLMR set done\n"));
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, HighMemoryBase);
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1);
|
||||
DEBUG ((DEBUG_INFO, "PHMR set done\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Set DMA protected region.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
@param LowMemoryBase The protected low memory region base.
|
||||
@param LowMemoryLength The protected low memory region length.
|
||||
@param HighMemoryBase The protected high memory region base.
|
||||
@param HighMemoryLength The protected high memory region length.
|
||||
|
||||
@retval EFI_SUCCESS The DMA protection is set.
|
||||
@retval EFI_UNSUPPORTED The DMA protection is not set.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetDmaProtectedRange (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask,
|
||||
IN UINT32 LowMemoryBase,
|
||||
IN UINT32 LowMemoryLength,
|
||||
IN UINT64 HighMemoryBase,
|
||||
IN UINT64 HighMemoryLength
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SetDmaProtectedRange(0x%lx) - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", EngineMask, LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength));
|
||||
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
Status = SetPmrRegion (
|
||||
VTdInfo->HostAddressWidth,
|
||||
(UINTN)VTdInfo->VTdEngineAddress[Index],
|
||||
LowMemoryBase,
|
||||
LowMemoryLength,
|
||||
HighMemoryBase,
|
||||
HighMemoryLength
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
Status = EnablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Diable DMA protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@retval EFI_SUCCESS DMA protection is disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmaProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "DisableDmaProtection - 0x%lx\n", EngineMask));
|
||||
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
DEBUG ((DEBUG_INFO, "Disabling...%d\n", Index));
|
||||
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
Status = DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Return if the PMR is enabled.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@retval TRUE PMR is enabled.
|
||||
@retval FALSE PMR is disabled or unsupported.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsPmrEnabled (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
VTD_CAP_REG CapReg;
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
|
||||
if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);
|
||||
if ((Reg32 & BIT0) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the mask of the VTd engine which is enabled.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@return the mask of the VTd engine which is enabled.
|
||||
**/
|
||||
UINT64
|
||||
GetDmaProtectionEnabledEngineMask (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
BOOLEAN Result;
|
||||
UINT64 EnabledEngineMask;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "GetDmaProtectionEnabledEngineMask - 0x%lx\n", EngineMask));
|
||||
|
||||
EnabledEngineMask = 0;
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
Result = IsPmrEnabled ((UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
if (Result) {
|
||||
EnabledEngineMask |= LShiftU64(1, Index);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "EnabledEngineMask - 0x%lx\n", EnabledEngineMask));
|
||||
return EnabledEngineMask;
|
||||
}
|
816
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
Normal file
816
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c
Normal file
@@ -0,0 +1,816 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License which accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <Ppi/IoMmu.h>
|
||||
#include <Ppi/VtdInfo.h>
|
||||
#include <Ppi/MemoryDiscovered.h>
|
||||
#include <Ppi/EndOfPeiPhase.h>
|
||||
|
||||
#include "IntelVTdPmrPei.h"
|
||||
|
||||
EFI_GUID mVTdInfoGuid = {
|
||||
0x222f5e30, 0x5cd, 0x49c6, { 0x8a, 0xc, 0x36, 0xd6, 0x58, 0x41, 0xe0, 0x82 }
|
||||
};
|
||||
|
||||
EFI_GUID mDmaBufferInfoGuid = {
|
||||
0x7b624ec7, 0xfb67, 0x4f9c, { 0xb6, 0xb0, 0x4d, 0xfa, 0x9c, 0x88, 0x20, 0x39 }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINTN DmaBufferBase;
|
||||
UINTN DmaBufferSize;
|
||||
UINTN DmaBufferCurrentTop;
|
||||
UINTN DmaBufferCurrentBottom;
|
||||
} DMA_BUFFER_INFO;
|
||||
|
||||
#define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EDKII_IOMMU_OPERATION Operation;
|
||||
UINTN NumberOfBytes;
|
||||
EFI_PHYSICAL_ADDRESS HostAddress;
|
||||
EFI_PHYSICAL_ADDRESS DeviceAddress;
|
||||
} MAP_INFO;
|
||||
|
||||
/**
|
||||
|
||||
PEI Memory Layout:
|
||||
|
||||
+------------------+ <=============== PHMR.Limit (+ alignment) (1 << (HostAddressWidth + 1))
|
||||
| Mem Resource |
|
||||
| |
|
||||
|
||||
+------------------+ <------- EfiMemoryTop
|
||||
| PEI allocated |
|
||||
=========== +==================+ <=============== PHMR.Base
|
||||
^ | Commom Buf |
|
||||
| | -------------- |
|
||||
DMA Buffer | * DMA FREE * |
|
||||
| | -------------- |
|
||||
V | Read/Write Buf |
|
||||
=========== +==================+ <=============== PLMR.Limit (+ alignment)
|
||||
| PEI allocated |
|
||||
| -------------- | <------- EfiFreeMemoryTop
|
||||
| * PEI FREE * |
|
||||
| -------------- | <------- EfiFreeMemoryBottom
|
||||
| hob |
|
||||
| -------------- |
|
||||
| Stack |
|
||||
+------------------+ <------- EfiMemoryBottom / Stack Bottom
|
||||
|
||||
+------------------+
|
||||
| Mem Alloc Hob |
|
||||
+------------------+
|
||||
|
||||
| |
|
||||
| Mem Resource |
|
||||
+------------------+ <=============== PLMR.Base (0)
|
||||
**/
|
||||
|
||||
/**
|
||||
Set IOMMU attribute for a system memory.
|
||||
|
||||
If the IOMMU PPI exists, the system memory cannot be used
|
||||
for DMA by default.
|
||||
|
||||
When a device requests a DMA access for a system memory,
|
||||
the device driver need use SetAttribute() to update the IOMMU
|
||||
attribute to request DMA access (read and/or write).
|
||||
|
||||
@param[in] This The PPI instance pointer.
|
||||
@param[in] Mapping The mapping value returned from Map().
|
||||
@param[in] IoMmuAccess The IOMMU access.
|
||||
|
||||
@retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
|
||||
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
|
||||
@retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
|
||||
@retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
|
||||
@retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
|
||||
@retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
|
||||
@retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
|
||||
not available to be allocated yet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiIoMmuSetAttribute (
|
||||
IN EDKII_IOMMU_PPI *This,
|
||||
IN VOID *Mapping,
|
||||
IN UINT64 IoMmuAccess
|
||||
)
|
||||
{
|
||||
VOID *Hob;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
if (DmaBufferInfo->DmaBufferCurrentTop == 0) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Provides the controller-specific addresses required to access system memory from a
|
||||
DMA bus master.
|
||||
|
||||
@param This The PPI instance pointer.
|
||||
@param Operation Indicates if the bus master is going to read or write to system memory.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
|
||||
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
|
||||
@retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
|
||||
not available to be allocated yet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiIoMmuMap (
|
||||
IN EDKII_IOMMU_PPI *This,
|
||||
IN EDKII_IOMMU_OPERATION Operation,
|
||||
IN VOID *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
{
|
||||
MAP_INFO *MapInfo;
|
||||
UINTN Length;
|
||||
VOID *Hob;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));
|
||||
|
||||
if (DmaBufferInfo->DmaBufferCurrentTop == 0) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
|
||||
Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
|
||||
*DeviceAddress = (UINTN)HostAddress;
|
||||
*Mapping = NULL;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Length = *NumberOfBytes + sizeof(MAP_INFO);
|
||||
if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {
|
||||
DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));
|
||||
ASSERT (FALSE);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*DeviceAddress = DmaBufferInfo->DmaBufferCurrentBottom;
|
||||
DmaBufferInfo->DmaBufferCurrentBottom += Length;
|
||||
|
||||
MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes);
|
||||
MapInfo->Signature = MAP_INFO_SIGNATURE;
|
||||
MapInfo->Operation = Operation;
|
||||
MapInfo->NumberOfBytes = *NumberOfBytes;
|
||||
MapInfo->HostAddress = (UINTN)HostAddress;
|
||||
MapInfo->DeviceAddress = *DeviceAddress;
|
||||
*Mapping = MapInfo;
|
||||
DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, Mapping - %x\n", Operation, (UINTN)*DeviceAddress, MapInfo));
|
||||
|
||||
//
|
||||
// If this is a read operation from the Bus Master's point of view,
|
||||
// then copy the contents of the real buffer into the mapped buffer
|
||||
// so the Bus Master can read the contents of the real buffer.
|
||||
//
|
||||
if (Operation == EdkiiIoMmuOperationBusMasterRead ||
|
||||
Operation == EdkiiIoMmuOperationBusMasterRead64) {
|
||||
CopyMem (
|
||||
(VOID *) (UINTN) MapInfo->DeviceAddress,
|
||||
(VOID *) (UINTN) MapInfo->HostAddress,
|
||||
MapInfo->NumberOfBytes
|
||||
);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
@param This The PPI instance pointer.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
@retval EFI_SUCCESS The range was unmapped.
|
||||
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
|
||||
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
|
||||
@retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
|
||||
not available to be allocated yet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiIoMmuUnmap (
|
||||
IN EDKII_IOMMU_PPI *This,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
{
|
||||
MAP_INFO *MapInfo;
|
||||
UINTN Length;
|
||||
VOID *Hob;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));
|
||||
|
||||
if (DmaBufferInfo->DmaBufferCurrentTop == 0) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
if (Mapping == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
MapInfo = Mapping;
|
||||
ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE);
|
||||
DEBUG ((DEBUG_VERBOSE, " Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes));
|
||||
|
||||
//
|
||||
// If this is a write operation from the Bus Master's point of view,
|
||||
// then copy the contents of the mapped buffer into the real buffer
|
||||
// so the processor can read the contents of the real buffer.
|
||||
//
|
||||
if (MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite ||
|
||||
MapInfo->Operation == EdkiiIoMmuOperationBusMasterWrite64) {
|
||||
CopyMem (
|
||||
(VOID *) (UINTN) MapInfo->HostAddress,
|
||||
(VOID *) (UINTN) MapInfo->DeviceAddress,
|
||||
MapInfo->NumberOfBytes
|
||||
);
|
||||
}
|
||||
|
||||
Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO);
|
||||
if (DmaBufferInfo->DmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) {
|
||||
DmaBufferInfo->DmaBufferCurrentBottom -= Length;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
|
||||
OperationBusMasterCommonBuffer64 mapping.
|
||||
|
||||
@param This The PPI instance pointer.
|
||||
@param MemoryType The type of memory to allocate, EfiBootServicesData or
|
||||
EfiRuntimeServicesData.
|
||||
@param Pages The number of pages to allocate.
|
||||
@param HostAddress A pointer to store the base system memory address of the
|
||||
allocated range.
|
||||
@param Attributes The requested bit mask of attributes for the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were allocated.
|
||||
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
|
||||
MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
||||
@retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
|
||||
not available to be allocated yet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiIoMmuAllocateBuffer (
|
||||
IN EDKII_IOMMU_PPI *This,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT VOID **HostAddress,
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
UINTN Length;
|
||||
VOID *Hob;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));
|
||||
|
||||
if (DmaBufferInfo->DmaBufferCurrentTop == 0) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
Length = EFI_PAGES_TO_SIZE(Pages);
|
||||
if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {
|
||||
DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));
|
||||
ASSERT (FALSE);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
*HostAddress = (VOID *)(UINTN)(DmaBufferInfo->DmaBufferCurrentTop - Length);
|
||||
DmaBufferInfo->DmaBufferCurrentTop -= Length;
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Frees memory that was allocated with AllocateBuffer().
|
||||
|
||||
@param This The PPI instance pointer.
|
||||
@param Pages The number of pages to free.
|
||||
@param HostAddress The base system memory address of the allocated range.
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were freed.
|
||||
@retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
|
||||
was not allocated with AllocateBuffer().
|
||||
@retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
|
||||
not available to be allocated yet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiIoMmuFreeBuffer (
|
||||
IN EDKII_IOMMU_PPI *This,
|
||||
IN UINTN Pages,
|
||||
IN VOID *HostAddress
|
||||
)
|
||||
{
|
||||
UINTN Length;
|
||||
VOID *Hob;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));
|
||||
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));
|
||||
|
||||
if (DmaBufferInfo->DmaBufferCurrentTop == 0) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
}
|
||||
|
||||
Length = EFI_PAGES_TO_SIZE(Pages);
|
||||
if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) {
|
||||
DmaBufferInfo->DmaBufferCurrentTop += Length;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EDKII_IOMMU_PPI mIoMmuPpi = {
|
||||
EDKII_IOMMU_PPI_REVISION,
|
||||
PeiIoMmuSetAttribute,
|
||||
PeiIoMmuMap,
|
||||
PeiIoMmuUnmap,
|
||||
PeiIoMmuAllocateBuffer,
|
||||
PeiIoMmuFreeBuffer,
|
||||
};
|
||||
|
||||
CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = {
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||
&gEdkiiIoMmuPpiGuid,
|
||||
(VOID *) &mIoMmuPpi
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize DMA protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
|
||||
@retval EFI_SUCCESS the DMA protection is initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES no enough resource to initialize DMA protection.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InitDmaProtection (
|
||||
IN VTD_INFO *VTdInfo
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 LowMemoryAlignment;
|
||||
UINT64 HighMemoryAlignment;
|
||||
UINTN MemoryAlignment;
|
||||
UINTN LowBottom;
|
||||
UINTN LowTop;
|
||||
UINTN HighBottom;
|
||||
UINT64 HighTop;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
VOID *Hob;
|
||||
EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
|
||||
EDKII_IOMMU_PPI *OldIoMmuPpi;
|
||||
|
||||
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
|
||||
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
|
||||
|
||||
LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
|
||||
HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask);
|
||||
if (LowMemoryAlignment < HighMemoryAlignment) {
|
||||
MemoryAlignment = (UINTN)HighMemoryAlignment;
|
||||
} else {
|
||||
MemoryAlignment = LowMemoryAlignment;
|
||||
}
|
||||
ASSERT (DmaBufferInfo->DmaBufferSize == ALIGN_VALUE(DmaBufferInfo->DmaBufferSize, MemoryAlignment));
|
||||
DmaBufferInfo->DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize), MemoryAlignment);
|
||||
ASSERT (DmaBufferInfo->DmaBufferBase != 0);
|
||||
if (DmaBufferInfo->DmaBufferBase == 0) {
|
||||
DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n"));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo->DmaBufferBase));
|
||||
|
||||
DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
|
||||
DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
|
||||
|
||||
//
|
||||
// (Re)Install PPI.
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEdkiiIoMmuPpiGuid,
|
||||
0,
|
||||
&OldDescriptor,
|
||||
(VOID **) &OldIoMmuPpi
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PeiServicesReInstallPpi (OldDescriptor, &mIoMmuPpiList);
|
||||
} else {
|
||||
Status = PeiServicesInstallPpi (&mIoMmuPpiList);
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
LowBottom = 0;
|
||||
LowTop = DmaBufferInfo->DmaBufferBase;
|
||||
HighBottom = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
|
||||
HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
|
||||
|
||||
Status = SetDmaProtectedRange (
|
||||
VTdInfo,
|
||||
VTdInfo->EngineMask,
|
||||
(UINT32)LowBottom,
|
||||
(UINT32)(LowTop - LowBottom),
|
||||
HighBottom,
|
||||
HighTop - HighBottom
|
||||
);
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
FreePages ((VOID *)DmaBufferInfo->DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferInfo->DmaBufferSize));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes the Intel VTd Info.
|
||||
|
||||
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InitVTdInfo (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
|
||||
VOID *Hob;
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEdkiiVTdInfoPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&AcpiDmarTable
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
DumpAcpiDMAR (AcpiDmarTable);
|
||||
|
||||
//
|
||||
// Clear old VTdInfo Hob.
|
||||
//
|
||||
Hob = GetFirstGuidHob (&mVTdInfoGuid);
|
||||
if (Hob != NULL) {
|
||||
ZeroMem (&((EFI_HOB_GUID_TYPE *)Hob)->Name, sizeof(EFI_GUID));
|
||||
}
|
||||
|
||||
//
|
||||
// Get DMAR information to local VTdInfo
|
||||
//
|
||||
Status = ParseDmarAcpiTableDrhd (AcpiDmarTable);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: Do not parse RMRR here, because RMRR may cause PMR programming.
|
||||
//
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes the Intel VTd PMR for all memory.
|
||||
|
||||
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InitVTdPmrForAll (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Hob;
|
||||
VTD_INFO *VTdInfo;
|
||||
UINTN LowBottom;
|
||||
UINTN LowTop;
|
||||
UINTN HighBottom;
|
||||
UINT64 HighTop;
|
||||
|
||||
Hob = GetFirstGuidHob (&mVTdInfoGuid);
|
||||
VTdInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
LowBottom = 0;
|
||||
LowTop = 0;
|
||||
HighBottom = 0;
|
||||
HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
|
||||
|
||||
Status = SetDmaProtectedRange (
|
||||
VTdInfo,
|
||||
VTdInfo->EngineMask,
|
||||
(UINT32)LowBottom,
|
||||
(UINT32)(LowTop - LowBottom),
|
||||
HighBottom,
|
||||
HighTop - HighBottom
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes the Intel VTd PMR for DMA buffer.
|
||||
|
||||
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InitVTdPmrForDma (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Hob;
|
||||
VTD_INFO *VTdInfo;
|
||||
|
||||
Hob = GetFirstGuidHob (&mVTdInfoGuid);
|
||||
VTdInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
//
|
||||
// If there is RMRR memory, parse it here.
|
||||
//
|
||||
ParseDmarAcpiTableRmrr (VTdInfo);
|
||||
|
||||
//
|
||||
// Allocate a range in PEI memory as DMA buffer
|
||||
// Mark others to be DMA protected.
|
||||
//
|
||||
Status = InitDmaProtection (VTdInfo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function handles S3 resume task at the end of PEI
|
||||
|
||||
@param[in] PeiServices Pointer to PEI Services Table.
|
||||
@param[in] NotifyDesc Pointer to the descriptor for the Notification event that
|
||||
caused this function to execute.
|
||||
@param[in] Ppi Pointer to the PPI data associated with this function.
|
||||
|
||||
@retval EFI_STATUS Always return EFI_SUCCESS
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
S3EndOfPeiNotify(
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
VOID *Hob;
|
||||
VTD_INFO *VTdInfo;
|
||||
UINT64 EngineMask;
|
||||
|
||||
DEBUG((DEBUG_INFO, "VTdPmr S3EndOfPeiNotify\n"));
|
||||
|
||||
if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {
|
||||
Hob = GetFirstGuidHob (&mVTdInfoGuid);
|
||||
if (Hob == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
VTdInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
|
||||
DisableDmaProtection (VTdInfo, EngineMask);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiEndOfPeiSignalPpiGuid,
|
||||
S3EndOfPeiNotify
|
||||
};
|
||||
|
||||
/**
|
||||
This function handles VTd engine setup
|
||||
|
||||
@param[in] PeiServices Pointer to PEI Services Table.
|
||||
@param[in] NotifyDesc Pointer to the descriptor for the Notification event that
|
||||
caused this function to execute.
|
||||
@param[in] Ppi Pointer to the PPI data associated with this function.
|
||||
|
||||
@retval EFI_STATUS Always return EFI_SUCCESS
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
VTdInfoNotify (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *MemoryDiscovered;
|
||||
UINT64 EnabledEngineMask;
|
||||
VOID *Hob;
|
||||
VTD_INFO *VTdInfo;
|
||||
BOOLEAN MemoryInitialized;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "VTdInfoNotify\n"));
|
||||
|
||||
//
|
||||
// Check if memory is initialized.
|
||||
//
|
||||
MemoryInitialized = FALSE;
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiMemoryDiscoveredPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
&MemoryDiscovered
|
||||
);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
MemoryInitialized = TRUE;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized));
|
||||
|
||||
if (!MemoryInitialized) {
|
||||
//
|
||||
// If the memory is not initialized,
|
||||
// Protect all system memory
|
||||
//
|
||||
InitVTdInfo ();
|
||||
InitVTdPmrForAll ();
|
||||
|
||||
//
|
||||
// Install PPI.
|
||||
//
|
||||
Status = PeiServicesInstallPpi (&mIoMmuPpiList);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
} else {
|
||||
//
|
||||
// If the memory is initialized,
|
||||
// Allocate DMA buffer and protect rest system memory
|
||||
//
|
||||
|
||||
//
|
||||
// NOTE: We need reinit VTdInfo because previous information might be overriden.
|
||||
//
|
||||
InitVTdInfo ();
|
||||
|
||||
Hob = GetFirstGuidHob (&mVTdInfoGuid);
|
||||
VTdInfo = GET_GUID_HOB_DATA(Hob);
|
||||
|
||||
//
|
||||
// NOTE: We need check if PMR is enabled or not.
|
||||
//
|
||||
EnabledEngineMask = GetDmaProtectionEnabledEngineMask (VTdInfo, VTdInfo->EngineMask);
|
||||
if (EnabledEngineMask != 0) {
|
||||
EnableVTdTranslationProtection (VTdInfo, EnabledEngineMask);
|
||||
DisableDmaProtection (VTdInfo, EnabledEngineMask);
|
||||
}
|
||||
InitVTdPmrForDma ();
|
||||
if (EnabledEngineMask != 0) {
|
||||
DisableVTdTranslationProtection (VTdInfo, EnabledEngineMask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR mVTdInfoNotifyDesc = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEdkiiVTdInfoPpiGuid,
|
||||
VTdInfoNotify
|
||||
};
|
||||
|
||||
/**
|
||||
Initializes the Intel VTd PMR PEIM.
|
||||
|
||||
@param FileHandle Handle of the file being invoked.
|
||||
@param PeiServices Describes the list of possible PEI Services.
|
||||
|
||||
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
IntelVTdPmrInitialize (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_BOOT_MODE BootMode;
|
||||
DMA_BUFFER_INFO *DmaBufferInfo;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "IntelVTdPmrInitialize\n"));
|
||||
|
||||
if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
DmaBufferInfo = BuildGuidHob (&mDmaBufferInfoGuid, sizeof(DMA_BUFFER_INFO));
|
||||
ASSERT(DmaBufferInfo != NULL);
|
||||
if (DmaBufferInfo == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
ZeroMem (DmaBufferInfo, sizeof(DMA_BUFFER_INFO));
|
||||
|
||||
PeiServicesGetBootMode (&BootMode);
|
||||
|
||||
if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSizeS3);
|
||||
} else {
|
||||
DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSize);
|
||||
}
|
||||
|
||||
Status = PeiServicesNotifyPpi (&mVTdInfoNotifyDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Register EndOfPei Notify for S3
|
||||
//
|
||||
if (BootMode == BOOT_ON_S3_RESUME) {
|
||||
Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
165
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h
Normal file
165
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/** @file
|
||||
The definition for DMA access Library.
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __DMA_ACCESS_LIB_H__
|
||||
#define __DMA_ACCESS_LIB_H__
|
||||
|
||||
typedef struct {
|
||||
EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
|
||||
UINT64 EngineMask;
|
||||
UINT8 HostAddressWidth;
|
||||
UINTN VTdEngineCount;
|
||||
UINT64 VTdEngineAddress[1];
|
||||
} VTD_INFO;
|
||||
|
||||
/**
|
||||
Set DMA protected region.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
@param LowMemoryBase The protected low memory region base.
|
||||
@param LowMemoryLength The protected low memory region length.
|
||||
@param HighMemoryBase The protected high memory region base.
|
||||
@param HighMemoryLength The protected high memory region length.
|
||||
|
||||
@retval EFI_SUCCESS The DMA protection is set.
|
||||
@retval EFI_UNSUPPORTED The DMA protection is not set.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SetDmaProtectedRange (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask,
|
||||
IN UINT32 LowMemoryBase,
|
||||
IN UINT32 LowMemoryLength,
|
||||
IN UINT64 HighMemoryBase,
|
||||
IN UINT64 HighMemoryLength
|
||||
);
|
||||
|
||||
/**
|
||||
Diable DMA protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@retval DMA protection is disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmaProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Return if the DMA protection is enabled.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@retval TRUE DMA protection is enabled in at least one VTd engine.
|
||||
@retval FALSE DMA protection is disabled in all VTd engines.
|
||||
**/
|
||||
UINT64
|
||||
GetDmaProtectionEnabledEngineMask (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Get protected low memory alignment.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@return protected low memory alignment.
|
||||
**/
|
||||
UINT32
|
||||
GetLowMemoryAlignment (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Get protected high memory alignment.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
|
||||
@return protected high memory alignment.
|
||||
**/
|
||||
UINT64
|
||||
GetHighMemoryAlignment (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Enable VTd translation table protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
**/
|
||||
VOID
|
||||
EnableVTdTranslationProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Disable VTd translation table protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
**/
|
||||
VOID
|
||||
DisableVTdTranslationProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@param[in] AcpiDmarTable DMAR ACPI table
|
||||
|
||||
@return EFI_SUCCESS The DMAR DRHD table is parsed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDmarAcpiTableDrhd (
|
||||
IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
|
||||
);
|
||||
|
||||
/**
|
||||
Parse DMAR DRHD table.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
**/
|
||||
VOID
|
||||
ParseDmarAcpiTableRmrr (
|
||||
IN VTD_INFO *VTdInfo
|
||||
);
|
||||
|
||||
/**
|
||||
Dump DMAR ACPI table.
|
||||
|
||||
@param[in] Dmar DMAR ACPI table
|
||||
**/
|
||||
VOID
|
||||
DumpAcpiDMAR (
|
||||
IN EFI_ACPI_DMAR_HEADER *Dmar
|
||||
);
|
||||
|
||||
extern EFI_GUID mVTdInfoGuid;
|
||||
|
||||
#endif
|
||||
|
@@ -0,0 +1,66 @@
|
||||
## @file
|
||||
# Component INF file for the Intel VTd PMR PEIM.
|
||||
#
|
||||
# This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI
|
||||
# and provide DMA protection in PEI.
|
||||
#
|
||||
# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010017
|
||||
BASE_NAME = IntelVTdPmrPei
|
||||
MODULE_UNI_FILE = IntelVTdPmrPei.uni
|
||||
FILE_GUID = F906769F-4AED-4A0D-8C7C-FF21B9D1051A
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = IntelVTdPmrInitialize
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelSiliconPkg/IntelSiliconPkg.dec
|
||||
|
||||
[Sources]
|
||||
IntelVTdPmrPei.c
|
||||
IntelVTdPmrPei.h
|
||||
IntelVTdPmr.c
|
||||
DmarTable.c
|
||||
VtdReg.c
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
BaseMemoryLib
|
||||
BaseLib
|
||||
PeimEntryPoint
|
||||
PeiServicesLib
|
||||
HobLib
|
||||
IoLib
|
||||
CacheMaintenanceLib
|
||||
|
||||
[Ppis]
|
||||
gEdkiiIoMmuPpiGuid ## PRODUCES
|
||||
gEdkiiVTdInfoPpiGuid ## CONSUMES
|
||||
gEfiPeiMemoryDiscoveredPpiGuid ## CONSUMES
|
||||
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSize ## CONSUMES
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSizeS3 ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMasterBootModePpiGuid AND
|
||||
gEdkiiVTdInfoPpiGuid
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
IntelVTdPmrPeiExtra.uni
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// IntelVTdPmrPei Module Localized Abstract and Description Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Intel VTd PMR PEI Driver."
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver initializes VTd engine based upon EDKII_VTD_INFO_PPI and provide DMA protection to device in PEI."
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// IntelVTdPmrPei Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Intel VTd PMR PEI Driver"
|
||||
|
||||
|
293
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
Normal file
293
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License which accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <Ppi/VtdInfo.h>
|
||||
|
||||
#include "IntelVTdPmrPei.h"
|
||||
|
||||
/**
|
||||
Flush VTD page table and context table memory.
|
||||
|
||||
This action is to make sure the IOMMU engine can get final data in memory.
|
||||
|
||||
@param[in] Base The base address of memory to be flushed.
|
||||
@param[in] Size The size of memory in bytes to be flushed.
|
||||
**/
|
||||
VOID
|
||||
FlushPageTableMemory (
|
||||
IN UINTN Base,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
WriteBackDataCacheRange ((VOID *)Base, Size);
|
||||
}
|
||||
|
||||
/**
|
||||
Flush VTd engine write buffer.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
**/
|
||||
VOID
|
||||
FlushWriteBuffer (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
VTD_CAP_REG CapReg;
|
||||
|
||||
CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
|
||||
|
||||
if (CapReg.Bits.RWBF != 0) {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF);
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while ((Reg32 & B_GSTS_REG_WBF) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Invalidate VTd context cache.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateContextCache (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT64 Reg64;
|
||||
|
||||
Reg64 = MmioRead64 (VtdUnitBaseAddress + R_CCMD_REG);
|
||||
if ((Reg64 & B_CCMD_REG_ICC) != 0) {
|
||||
DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%x)\n",VtdUnitBaseAddress));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Reg64 &= ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK));
|
||||
Reg64 |= (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL);
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_CCMD_REG, Reg64);
|
||||
|
||||
do {
|
||||
Reg64 = MmioRead64 (VtdUnitBaseAddress + R_CCMD_REG);
|
||||
} while ((Reg64 & B_CCMD_REG_ICC) != 0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Invalidate VTd IOTLB.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InvalidateIOTLB (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT64 Reg64;
|
||||
VTD_ECAP_REG ECapReg;
|
||||
|
||||
ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
|
||||
|
||||
Reg64 = MmioRead64 (VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
|
||||
if ((Reg64 & B_IOTLB_REG_IVT) != 0) {
|
||||
DEBUG ((DEBUG_ERROR,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%x)\n", VtdUnitBaseAddress));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Reg64 &= ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK));
|
||||
Reg64 |= (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL);
|
||||
MmioWrite64 (VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
|
||||
|
||||
do {
|
||||
Reg64 = MmioRead64 (VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
|
||||
} while ((Reg64 & B_IOTLB_REG_IVT) != 0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable DMAR translation.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
@param RootEntryTable The address of the VTd RootEntryTable.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is enabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not enabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnableDmar (
|
||||
IN UINTN VtdUnitBaseAddress,
|
||||
IN UINTN RootEntryTable
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
|
||||
DEBUG((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n", VtdUnitBaseAddress));
|
||||
|
||||
DEBUG((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64)(UINTN)RootEntryTable);
|
||||
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
|
||||
|
||||
DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"));
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
|
||||
|
||||
//
|
||||
// Init DMAr Fault Event and Data registers
|
||||
//
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);
|
||||
|
||||
//
|
||||
// Write Buffer Flush before invalidation
|
||||
//
|
||||
FlushWriteBuffer (VtdUnitBaseAddress);
|
||||
|
||||
//
|
||||
// Invalidate the context cache
|
||||
//
|
||||
InvalidateContextCache (VtdUnitBaseAddress);
|
||||
|
||||
//
|
||||
// Invalidate the IOTLB cache
|
||||
//
|
||||
InvalidateIOTLB (VtdUnitBaseAddress);
|
||||
|
||||
//
|
||||
// Enable VTd
|
||||
//
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_TE);
|
||||
DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while ((Reg32 & B_GSTS_REG_TE) == 0);
|
||||
|
||||
DEBUG ((DEBUG_INFO,"VTD () enabled!<<<<<<\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable DMAR translation.
|
||||
|
||||
@param VtdUnitBaseAddress The base address of the VTd engine.
|
||||
|
||||
@retval EFI_SUCCESS DMAR translation is disabled.
|
||||
@retval EFI_DEVICE_ERROR DMAR translation is not disabled.
|
||||
**/
|
||||
EFI_STATUS
|
||||
DisableDmar (
|
||||
IN UINTN VtdUnitBaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 Reg32;
|
||||
|
||||
DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%x] \n", VtdUnitBaseAddress));
|
||||
|
||||
//
|
||||
// Write Buffer Flush before invalidation
|
||||
//
|
||||
FlushWriteBuffer (VtdUnitBaseAddress);
|
||||
|
||||
//
|
||||
// Disable VTd
|
||||
//
|
||||
MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, B_GMCD_REG_SRTP);
|
||||
do {
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
|
||||
|
||||
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
|
||||
DEBUG((DEBUG_INFO, "DisableDmar: GSTS_REG - 0x%08x\n", Reg32));
|
||||
|
||||
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, 0);
|
||||
|
||||
DEBUG ((DEBUG_INFO,"VTD () Disabled!<<<<<<\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable VTd translation table protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
**/
|
||||
VOID
|
||||
EnableVTdTranslationProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
VOID *RootEntryTable;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtection - 0x%lx\n", EngineMask));
|
||||
|
||||
RootEntryTable = AllocatePages (1);
|
||||
ASSERT (RootEntryTable != NULL);
|
||||
if (RootEntryTable == NULL) {
|
||||
DEBUG ((DEBUG_INFO, " EnableVTdTranslationProtection : OutOfResource\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
ZeroMem (RootEntryTable, EFI_PAGES_TO_SIZE(1));
|
||||
FlushPageTableMemory ((UINTN)RootEntryTable, EFI_PAGES_TO_SIZE(1));
|
||||
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
EnableDmar ((UINTN)VTdInfo->VTdEngineAddress[Index], (UINTN)RootEntryTable);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable VTd translation table protection.
|
||||
|
||||
@param VTdInfo The VTd engine context information.
|
||||
@param EngineMask The mask of the VTd engine to be accessed.
|
||||
**/
|
||||
VOID
|
||||
DisableVTdTranslationProtection (
|
||||
IN VTD_INFO *VTdInfo,
|
||||
IN UINT64 EngineMask
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - 0x%lx\n", EngineMask));
|
||||
|
||||
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
|
||||
if ((EngineMask & LShiftU64(1, Index)) == 0) {
|
||||
continue;
|
||||
}
|
||||
DisableDmar ((UINTN)VTdInfo->VTdEngineAddress[Index]);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
@@ -0,0 +1,367 @@
|
||||
/** @file
|
||||
Platform VTd Info Sample PEI driver.
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
|
||||
#include <Ppi/VtdInfo.h>
|
||||
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PciLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#define R_SA_MCHBAR (0x48)
|
||||
#define R_SA_GGC (0x50)
|
||||
#define N_SKL_SA_GGC_GGMS_OFFSET (0x6)
|
||||
#define B_SKL_SA_GGC_GGMS_MASK (0xc0)
|
||||
#define N_SKL_SA_GGC_GMS_OFFSET (0x8)
|
||||
#define B_SKL_SA_GGC_GMS_MASK (0xff00)
|
||||
#define V_SKL_SA_GGC_GGMS_8MB 3
|
||||
#define R_SA_TOLUD (0xbc)
|
||||
|
||||
#define R_SA_MCHBAR_VTD1_OFFSET 0x5400 ///< HW UNIT for IGD
|
||||
#define R_SA_MCHBAR_VTD2_OFFSET 0x5410 ///< HW UNIT for all other - PEG, USB, SATA etc
|
||||
|
||||
EFI_GUID gEdkiiSiliconInitializedPpiGuid = {0x82a72dc8, 0x61ec, 0x403e, {0xb1, 0x5a, 0x8d, 0x7a, 0x3a, 0x71, 0x84, 0x98}};
|
||||
|
||||
typedef struct {
|
||||
EFI_ACPI_DMAR_HEADER DmarHeader;
|
||||
//
|
||||
// VTd engine 1 - integrated graphic
|
||||
//
|
||||
EFI_ACPI_DMAR_DRHD_HEADER Drhd1;
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER Drhd11;
|
||||
EFI_ACPI_DMAR_PCI_PATH Drhd111;
|
||||
//
|
||||
// VTd engine 2 - all rest
|
||||
//
|
||||
EFI_ACPI_DMAR_DRHD_HEADER Drhd2;
|
||||
//
|
||||
// RMRR 1 - integrated graphic
|
||||
//
|
||||
EFI_ACPI_DMAR_RMRR_HEADER Rmrr1;
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER Rmrr11;
|
||||
EFI_ACPI_DMAR_PCI_PATH Rmrr111;
|
||||
} MY_VTD_INFO_PPI;
|
||||
|
||||
MY_VTD_INFO_PPI mPlatformVTdSample = {
|
||||
{ // DmarHeader
|
||||
{ // Header
|
||||
EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE,
|
||||
sizeof(MY_VTD_INFO_PPI),
|
||||
EFI_ACPI_DMAR_REVISION,
|
||||
},
|
||||
0x26, // HostAddressWidth
|
||||
},
|
||||
|
||||
{ // Drhd1
|
||||
{ // Header
|
||||
EFI_ACPI_DMAR_TYPE_DRHD,
|
||||
sizeof(EFI_ACPI_DMAR_DRHD_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_PCI_PATH)
|
||||
},
|
||||
0, // Flags
|
||||
0, // Reserved
|
||||
0, // SegmentNumber
|
||||
0xFED90000 // RegisterBaseAddress -- TO BE PATCHED
|
||||
},
|
||||
{ // Drhd11
|
||||
EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,
|
||||
sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_PCI_PATH),
|
||||
0, // Reserved2
|
||||
0, // EnumerationId
|
||||
0 // StartBusNumber
|
||||
},
|
||||
{ // Drhd111
|
||||
2, // Device
|
||||
0 // Function
|
||||
},
|
||||
|
||||
{ // Drhd2
|
||||
{ // Header
|
||||
EFI_ACPI_DMAR_TYPE_DRHD,
|
||||
sizeof(EFI_ACPI_DMAR_DRHD_HEADER)
|
||||
},
|
||||
EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL, // Flags
|
||||
0, // Reserved
|
||||
0, // SegmentNumber
|
||||
0xFED91000 // RegisterBaseAddress -- TO BE PATCHED
|
||||
},
|
||||
|
||||
{ // Rmrr1
|
||||
{ // Header
|
||||
EFI_ACPI_DMAR_TYPE_RMRR,
|
||||
sizeof(EFI_ACPI_DMAR_RMRR_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_PCI_PATH)
|
||||
},
|
||||
{0}, // Reserved
|
||||
0, // SegmentNumber
|
||||
0x0, // ReservedMemoryRegionBaseAddress -- TO BE PATCHED
|
||||
0x0 // ReservedMemoryRegionLimitAddress -- TO BE PATCHED
|
||||
},
|
||||
{ // Rmrr11
|
||||
EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,
|
||||
sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
|
||||
sizeof(EFI_ACPI_DMAR_PCI_PATH),
|
||||
0, // Reserved2
|
||||
0, // EnumerationId
|
||||
0 // StartBusNumber
|
||||
},
|
||||
{ // Rmrr111
|
||||
2, // Device
|
||||
0 // Function
|
||||
},
|
||||
};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR mPlatformVTdInfoSampleDesc = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEdkiiVTdInfoPpiGuid,
|
||||
&mPlatformVTdSample
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EFI_ACPI_DMAR_HEADER DmarHeader;
|
||||
//
|
||||
// VTd engine 2 - all rest
|
||||
//
|
||||
EFI_ACPI_DMAR_DRHD_HEADER Drhd2;
|
||||
} MY_VTD_INFO_NO_IGD_PPI;
|
||||
|
||||
MY_VTD_INFO_NO_IGD_PPI mPlatformVTdNoIgdSample = {
|
||||
{ // DmarHeader
|
||||
{ // Header
|
||||
EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE,
|
||||
sizeof(MY_VTD_INFO_NO_IGD_PPI),
|
||||
EFI_ACPI_DMAR_REVISION,
|
||||
},
|
||||
0x26, // HostAddressWidth
|
||||
},
|
||||
|
||||
{ // Drhd2
|
||||
{ // Header
|
||||
EFI_ACPI_DMAR_TYPE_DRHD,
|
||||
sizeof(EFI_ACPI_DMAR_DRHD_HEADER)
|
||||
},
|
||||
EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL, // Flags
|
||||
0, // Reserved
|
||||
0, // SegmentNumber
|
||||
0xFED91000 // RegisterBaseAddress -- TO BE PATCHED
|
||||
},
|
||||
};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR mPlatformVTdNoIgdInfoSampleDesc = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEdkiiVTdInfoPpiGuid,
|
||||
&mPlatformVTdNoIgdSample
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize VTd register.
|
||||
**/
|
||||
VOID
|
||||
InitDmar (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 MchBar;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "InitDmar\n"));
|
||||
|
||||
MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0;
|
||||
PciWrite32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR), 0xFED10000 | BIT0);
|
||||
DEBUG ((DEBUG_INFO, "MchBar - %x\n", MchBar));
|
||||
|
||||
MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)mPlatformVTdSample.Drhd2.RegisterBaseAddress | 1);
|
||||
DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET))));
|
||||
}
|
||||
|
||||
/**
|
||||
Patch Graphic UMA address in RMRR and base address.
|
||||
**/
|
||||
EFI_PEI_PPI_DESCRIPTOR *
|
||||
PatchDmar (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 MchBar;
|
||||
UINT16 IgdMode;
|
||||
UINT16 GttMode;
|
||||
UINT32 IgdMemSize;
|
||||
UINT32 GttMemSize;
|
||||
MY_VTD_INFO_PPI *PlatformVTdSample;
|
||||
EFI_PEI_PPI_DESCRIPTOR *PlatformVTdInfoSampleDesc;
|
||||
MY_VTD_INFO_NO_IGD_PPI *PlatformVTdNoIgdSample;
|
||||
EFI_PEI_PPI_DESCRIPTOR *PlatformVTdNoIgdInfoSampleDesc;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "PatchDmar\n"));
|
||||
|
||||
if (PciRead16 (PCI_LIB_ADDRESS(0, 2, 0, 0)) != 0xFFFF) {
|
||||
PlatformVTdSample = AllocateCopyPool (sizeof(MY_VTD_INFO_PPI), &mPlatformVTdSample);
|
||||
ASSERT(PlatformVTdSample != NULL);
|
||||
PlatformVTdInfoSampleDesc = AllocateCopyPool (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdInfoSampleDesc);
|
||||
ASSERT(PlatformVTdInfoSampleDesc != NULL);
|
||||
PlatformVTdInfoSampleDesc->Ppi = PlatformVTdSample;
|
||||
|
||||
///
|
||||
/// Calculate IGD memsize
|
||||
///
|
||||
IgdMode = ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF;
|
||||
if (IgdMode < 0xF0) {
|
||||
IgdMemSize = IgdMode * 32 * (1024) * (1024);
|
||||
} else {
|
||||
IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
|
||||
}
|
||||
|
||||
///
|
||||
/// Calculate GTT mem size
|
||||
///
|
||||
GttMemSize = 0;
|
||||
GttMode = (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET;
|
||||
if (GttMode <= V_SKL_SA_GGC_GGMS_8MB) {
|
||||
GttMemSize = (1 << GttMode) * (1024) * (1024);
|
||||
}
|
||||
|
||||
PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress = (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize - GttMemSize;
|
||||
PlatformVTdSample->Rmrr1.ReservedMemoryRegionLimitAddress = PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
|
||||
|
||||
///
|
||||
/// Update DRHD structures of DmarTable
|
||||
///
|
||||
MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0;
|
||||
|
||||
if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1) != 0) {
|
||||
PlatformVTdSample->Drhd1.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
|
||||
} else {
|
||||
MmioWrite32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET, (UINT32)PlatformVTdSample->Drhd1.RegisterBaseAddress | 1);
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "VTd1 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET))));
|
||||
|
||||
if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) != 0) {
|
||||
PlatformVTdSample->Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1);
|
||||
} else {
|
||||
MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)PlatformVTdSample->Drhd2.RegisterBaseAddress | 1);
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET))));
|
||||
|
||||
return PlatformVTdInfoSampleDesc;
|
||||
} else {
|
||||
PlatformVTdNoIgdSample = AllocateCopyPool (sizeof(MY_VTD_INFO_NO_IGD_PPI), &mPlatformVTdNoIgdSample);
|
||||
ASSERT(PlatformVTdNoIgdSample != NULL);
|
||||
PlatformVTdNoIgdInfoSampleDesc = AllocateCopyPool (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdNoIgdInfoSampleDesc);
|
||||
ASSERT(PlatformVTdNoIgdInfoSampleDesc != NULL);
|
||||
PlatformVTdNoIgdInfoSampleDesc->Ppi = PlatformVTdNoIgdSample;
|
||||
|
||||
///
|
||||
/// Update DRHD structures of DmarTable
|
||||
///
|
||||
MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0;
|
||||
|
||||
if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) != 0) {
|
||||
PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1);
|
||||
} else {
|
||||
MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, (UINT32)PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress | 1);
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET))));
|
||||
|
||||
return PlatformVTdNoIgdInfoSampleDesc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The callback function for SiliconInitializedPpi.
|
||||
It reinstalls VTD_INFO_PPI.
|
||||
|
||||
@param[in] PeiServices General purpose services available to every PEIM.
|
||||
@param[in] NotifyDescriptor Notify that this module published.
|
||||
@param[in] Ppi PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS The function completed successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SiliconInitializedPpiNotifyCallback (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_PPI_DESCRIPTOR *PpiDesc;
|
||||
|
||||
PpiDesc = PatchDmar ();
|
||||
|
||||
Status = PeiServicesReInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc, PpiDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR mSiliconInitializedNotifyList = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEdkiiSiliconInitializedPpiGuid,
|
||||
(EFI_PEIM_NOTIFY_ENTRY_POINT) SiliconInitializedPpiNotifyCallback
|
||||
};
|
||||
|
||||
/**
|
||||
Platform VTd Info sample driver.
|
||||
|
||||
@param[in] FileHandle Handle of the file being invoked.
|
||||
@param[in] PeiServices Describes the list of possible PEI Services.
|
||||
|
||||
@retval EFI_SUCCESS if it completed successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformVTdInfoSampleInitialize (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN SiliconInitialized;
|
||||
VOID *SiliconInitializedPpi;
|
||||
EFI_PEI_PPI_DESCRIPTOR *PpiDesc;
|
||||
|
||||
SiliconInitialized = FALSE;
|
||||
//
|
||||
// Check if silicon is initialized.
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEdkiiSiliconInitializedPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
&SiliconInitializedPpi
|
||||
);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
SiliconInitialized = TRUE;
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "SiliconInitialized - %x\n", SiliconInitialized));
|
||||
if (!SiliconInitialized) {
|
||||
Status = PeiServicesNotifyPpi (&mSiliconInitializedNotifyList);
|
||||
InitDmar ();
|
||||
|
||||
Status = PeiServicesInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
PpiDesc = PatchDmar ();
|
||||
|
||||
Status = PeiServicesInstallPpi (PpiDesc);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
## @file
|
||||
# Platform VTd Info Sample PEI driver.
|
||||
#
|
||||
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PlatformVTdInfoSamplePei
|
||||
MODULE_UNI_FILE = PlatformVTdInfoSamplePei.uni
|
||||
FILE_GUID = 839EB770-5C64-4EED-A6D5-EC515B2B2B23
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = PlatformVTdInfoSampleInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
#
|
||||
|
||||
[Sources]
|
||||
PlatformVTdInfoSamplePei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelSiliconPkg/IntelSiliconPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
PeimEntryPoint
|
||||
PeiServicesLib
|
||||
DebugLib
|
||||
PciLib
|
||||
IoLib
|
||||
|
||||
[Ppis]
|
||||
gEdkiiVTdInfoPpiGuid ## PRODUCES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMasterBootModePpiGuid
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
PlatformVTdInfoSamplePeiExtra.uni
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// PlatformVTdInfoSamplePei Module Localized Abstract and Description Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Platform VTd Info PEI Driver."
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver provides sample on how to produce Platform VTd Info PPI."
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// PlatformVTdInfoSamplePei Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Platform VTd Info Sample PEI Driver"
|
||||
|
||||
|
@@ -0,0 +1,413 @@
|
||||
/** @file
|
||||
Platform VTd Sample driver.
|
||||
|
||||
Note: This module should only be used for dev/debug purposes.
|
||||
It MUST never be used for production builds.
|
||||
|
||||
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <Protocol/PlatformVtdPolicy.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/DevicePath.h>
|
||||
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
|
||||
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
||||
|
||||
typedef struct {
|
||||
ACPI_EXTENDED_HID_DEVICE_PATH I2cController;
|
||||
UINT8 HidStr[8];
|
||||
UINT8 UidStr[1];
|
||||
UINT8 CidStr[8];
|
||||
} PLATFORM_I2C_CONTROLLER_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_EXTENDED_HID_DEVICE_PATH I2cDevice;
|
||||
UINT8 HidStr[13];
|
||||
UINT8 UidStr[1];
|
||||
UINT8 CidStr[13];
|
||||
} PLATFORM_I2C_DEVICE_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
PLATFORM_I2C_CONTROLLER_DEVICE_PATH I2cController;
|
||||
PLATFORM_I2C_DEVICE_DEVICE_PATH I2cDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL End;
|
||||
} PLATFORM_I2C_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH PciDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
|
||||
} PLATFORM_PCI_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
ACPI_HID_DEVICE_PATH PciRootBridge;
|
||||
PCI_DEVICE_PATH PciBridge;
|
||||
PCI_DEVICE_PATH PciDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
|
||||
} PLATFORM_PCI_BRIDGE_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINT16 Segment;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
} PLATFORM_ACPI_DEVICE_MAPPING;
|
||||
|
||||
#define PLATFORM_PCI_ROOT_BRIDGE \
|
||||
{ \
|
||||
{ \
|
||||
ACPI_DEVICE_PATH, \
|
||||
ACPI_DP, \
|
||||
{ \
|
||||
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
|
||||
}, \
|
||||
}, \
|
||||
EISA_PNP_ID (0x0A03), \
|
||||
0 \
|
||||
}
|
||||
|
||||
#define PLATFORM_END_ENTIRE \
|
||||
{ \
|
||||
END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
|
||||
}
|
||||
|
||||
#define PLATFORM_PCI(Device, Function) \
|
||||
{ \
|
||||
{ \
|
||||
HARDWARE_DEVICE_PATH, \
|
||||
HW_PCI_DP, \
|
||||
{ \
|
||||
(UINT8) (sizeof (PCI_DEVICE_PATH)), \
|
||||
(UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
|
||||
} \
|
||||
}, \
|
||||
(Function), \
|
||||
(Device) \
|
||||
}
|
||||
|
||||
#define PLATFORM_I2C(Hid, Uid, Cid, HidStr, UidStr, CidStr) \
|
||||
{ \
|
||||
{ \
|
||||
{ \
|
||||
ACPI_DEVICE_PATH, \
|
||||
ACPI_EXTENDED_DP, \
|
||||
{sizeof(ACPI_EXTENDED_HID_DEVICE_PATH) + sizeof(HidStr) + sizeof(UidStr) + sizeof(CidStr), 0} \
|
||||
}, \
|
||||
Hid, \
|
||||
Uid, \
|
||||
Cid \
|
||||
}, \
|
||||
HidStr, \
|
||||
UidStr, \
|
||||
CidStr \
|
||||
}
|
||||
|
||||
PLATFORM_I2C_DEVICE_PATH mPlatformI2CDevicePath = {
|
||||
PLATFORM_I2C(0, 2, 0, "INT33C3", "", "INT33C3"),
|
||||
PLATFORM_I2C(0, 1, 0, "I2C01\\TPANEL", "", "I2C01\\TPANEL"),
|
||||
PLATFORM_END_ENTIRE
|
||||
};
|
||||
|
||||
PLATFORM_ACPI_DEVICE_MAPPING mAcpiDeviceMapping[] = {
|
||||
{
|
||||
(EFI_DEVICE_PATH_PROTOCOL *)&mPlatformI2CDevicePath,
|
||||
0x0, // Segment
|
||||
{{0x01, 0x15, 0x00}} // Function, Device, Bus
|
||||
}
|
||||
};
|
||||
|
||||
PLATFORM_PCI_BRIDGE_DEVICE_PATH mPlatformPciBridgeDevicePath = {
|
||||
PLATFORM_PCI_ROOT_BRIDGE,
|
||||
PLATFORM_PCI(0x1C, 1),
|
||||
PLATFORM_PCI(0, 0),
|
||||
PLATFORM_END_ENTIRE
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO ExceptionDeviceInfo;
|
||||
EDKII_PLATFORM_VTD_DEVICE_SCOPE DeviceScope;
|
||||
EFI_ACPI_DMAR_PCI_PATH PciBridge;
|
||||
EFI_ACPI_DMAR_PCI_PATH PciDevice;
|
||||
} PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT;
|
||||
|
||||
typedef struct {
|
||||
EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO ExceptionDeviceInfo;
|
||||
EDKII_PLATFORM_VTD_PCI_DEVICE_ID PciDeviceId;
|
||||
} PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT mExceptionDeviceScopeList[] = {
|
||||
{
|
||||
{
|
||||
EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE,
|
||||
sizeof(PLATFORM_EXCEPTION_DEVICE_SCOPE_STRUCT)
|
||||
}, // ExceptionDeviceInfo
|
||||
{
|
||||
0, // SegmentNumber
|
||||
{
|
||||
EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT, // Type
|
||||
sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
|
||||
2 * sizeof(EFI_ACPI_DMAR_PCI_PATH), // Length
|
||||
0, // Reserved2
|
||||
0, // EnumerationId
|
||||
0, // StartBusNumber
|
||||
},
|
||||
}, // DeviceScope
|
||||
{ 0x1C, 1 }, // PciBridge
|
||||
{ 0x0, 0 }, // PciDevice
|
||||
},
|
||||
};
|
||||
|
||||
PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT mExceptionPciDeviceIdList[] = {
|
||||
{
|
||||
{
|
||||
EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID,
|
||||
sizeof(PLATFORM_EXCEPTION_PCI_DEVICE_ID_STRUCT)
|
||||
}, // ExceptionDeviceInfo
|
||||
{
|
||||
0x8086, // VendorId
|
||||
0x9D2F, // DeviceId
|
||||
0x21, // RevisionId
|
||||
0x8086, // SubsystemVendorId
|
||||
0x7270, // SubsystemDeviceId
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
Compares 2 device path.
|
||||
|
||||
@param[in] DevicePath1 A device path with EndDevicePath node.
|
||||
@param[in] DevicePath2 A device path with EndDevicePath node.
|
||||
|
||||
@retval TRUE 2 device path are identical.
|
||||
@retval FALSE 2 device path are not identical.
|
||||
**/
|
||||
BOOLEAN
|
||||
CompareDevicePath (
|
||||
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
|
||||
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2
|
||||
)
|
||||
{
|
||||
UINTN Size1;
|
||||
UINTN Size2;
|
||||
|
||||
Size1 = GetDevicePathSize (DevicePath1);
|
||||
Size2 = GetDevicePathSize (DevicePath2);
|
||||
if (Size1 != Size2) {
|
||||
return FALSE;
|
||||
}
|
||||
if (CompareMem (DevicePath1, DevicePath2, Size1) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the VTD SourceId from the device handler.
|
||||
This function is required for non PCI device handler.
|
||||
|
||||
Pseudo-algo in Intel VTd driver:
|
||||
Status = PlatformGetVTdDeviceId ();
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (DeviceHandle is PCI) {
|
||||
Get SourceId from Bus/Device/Function
|
||||
} else {
|
||||
return EFI_UNSUPPORTED
|
||||
}
|
||||
}
|
||||
Get VTd engine by Segment/Bus/Device/Function.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceHandle Device Identifier in UEFI.
|
||||
@param[out] DeviceInfo DeviceInfo for indentify the VTd engine in ACPI Table
|
||||
and the VTd page entry.
|
||||
|
||||
@retval EFI_SUCCESS The VtdIndex and SourceId are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is not a valid handler.
|
||||
@retval EFI_INVALID_PARAMETER DeviceInfo is NULL.
|
||||
@retval EFI_NOT_FOUND The Segment or SourceId information is NOT found.
|
||||
@retval EFI_UNSUPPORTED This function is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformVTdGetDeviceId (
|
||||
IN EDKII_PLATFORM_VTD_POLICY_PROTOCOL *This,
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
OUT EDKII_PLATFORM_VTD_DEVICE_INFO *DeviceInfo
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
UINTN Seg;
|
||||
UINTN Bus;
|
||||
UINTN Dev;
|
||||
UINTN Func;
|
||||
EFI_STATUS Status;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINTN Index;
|
||||
|
||||
DEBUG ((DEBUG_VERBOSE, "PlatformVTdGetDeviceId\n"));
|
||||
|
||||
if (DeviceInfo == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (DeviceHandle == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle PCI device
|
||||
//
|
||||
Status = gBS->HandleProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
Status = PciIo->GetLocation (PciIo, &Seg, &Bus, &Dev, &Func);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
DeviceInfo->Segment = (UINT16)Seg;
|
||||
DeviceInfo->SourceId.Bits.Bus = (UINT8)Bus;
|
||||
DeviceInfo->SourceId.Bits.Device = (UINT8)Dev;
|
||||
DeviceInfo->SourceId.Bits.Function = (UINT8)Func;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle ACPI device
|
||||
//
|
||||
Status = gBS->HandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
for (Index = 0; Index < ARRAY_SIZE(mAcpiDeviceMapping); Index++) {
|
||||
if (CompareDevicePath (mAcpiDeviceMapping[Index].DevicePath, DevicePath)) {
|
||||
DeviceInfo->Segment = mAcpiDeviceMapping[Index].Segment;
|
||||
DeviceInfo->SourceId = mAcpiDeviceMapping[Index].SourceId;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Get a list of the exception devices.
|
||||
|
||||
The VTd driver should always set ALLOW for the device in this list.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[out] DeviceInfoCount The count of the list of DeviceInfo.
|
||||
@param[out] DeviceInfo A callee allocated buffer to hold a list of DeviceInfo.
|
||||
Each DeviceInfo pointer points to EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
|
||||
|
||||
@retval EFI_SUCCESS The DeviceInfoCount and DeviceInfo are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is NULL.
|
||||
@retval EFI_UNSUPPORTED This function is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformVTdGetExceptionDeviceList (
|
||||
IN EDKII_PLATFORM_VTD_POLICY_PROTOCOL *This,
|
||||
OUT UINTN *DeviceInfoCount,
|
||||
OUT VOID **DeviceInfo
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_VERBOSE, "PlatformVTdGetExceptionDeviceList\n"));
|
||||
|
||||
if (DeviceInfoCount == NULL || DeviceInfo == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Sample codes for device scope based exception list.
|
||||
// Uncomment to take affect and comment the sample codes for PCI vendor id
|
||||
// based exception list.
|
||||
//
|
||||
/*
|
||||
*DeviceInfo = AllocateZeroPool (sizeof(mExceptionDeviceScopeList));
|
||||
if (*DeviceInfo == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (*DeviceInfo, mExceptionDeviceScopeList, sizeof(mExceptionDeviceScopeList));
|
||||
|
||||
*DeviceInfoCount = ARRAY_SIZE(mExceptionDeviceScopeList);
|
||||
*/
|
||||
|
||||
//
|
||||
// Sample codes for PCI vendor id based exception list.
|
||||
// Uncomment to take affect and comment the sample codes for device scope
|
||||
// based exception list.
|
||||
//
|
||||
/*
|
||||
*DeviceInfo = AllocateZeroPool (sizeof(mExceptionPciDeviceIdList));
|
||||
if (*DeviceInfo == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
CopyMem (*DeviceInfo, mExceptionPciDeviceIdList, sizeof(mExceptionPciDeviceIdList));
|
||||
|
||||
*DeviceInfoCount = ARRAY_SIZE(mExceptionPciDeviceIdList);
|
||||
*/
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
EDKII_PLATFORM_VTD_POLICY_PROTOCOL mPlatformVTdSample = {
|
||||
EDKII_PLATFORM_VTD_POLICY_PROTOCOL_REVISION,
|
||||
PlatformVTdGetDeviceId,
|
||||
PlatformVTdGetExceptionDeviceList,
|
||||
};
|
||||
|
||||
/**
|
||||
Platform VTd sample driver.
|
||||
|
||||
@param[in] ImageHandle ImageHandle of the loaded driver
|
||||
@param[in] SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS The Protocol is installed.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver.
|
||||
@retval EFI_DEVICE_ERROR A device error occurred attempting to initialize the driver.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PlatformVTdSampleInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
Handle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Handle,
|
||||
&gEdkiiPlatformVTdPolicyProtocolGuid, &mPlatformVTdSample,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
## @file
|
||||
# Platform VTd Sample driver.
|
||||
#
|
||||
# Note: This module should only be used for dev/debug purposes.
|
||||
# It MUST never be used for production builds.
|
||||
#
|
||||
# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PlatformVTdSampleDxe
|
||||
MODULE_UNI_FILE = PlatformVTdSampleDxe.uni
|
||||
FILE_GUID = 5DFAE03E-9C19-4996-85BF-65297BD4137F
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = PlatformVTdSampleInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
#
|
||||
|
||||
[Sources]
|
||||
PlatformVTdSampleDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelSiliconPkg/IntelSiliconPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
BaseLib
|
||||
IoLib
|
||||
PciSegmentLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
DevicePathLib
|
||||
|
||||
[Protocols]
|
||||
gEdkiiPlatformVTdPolicyProtocolGuid ## PRODUCES
|
||||
gEfiPciIoProtocolGuid ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPciRootBridgeIoProtocolGuid
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
PlatformVTdSampleDxeExtra.uni
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// PlatformVTdSampleDxe Module Localized Abstract and Description Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Platform VTd Sample DXE Driver."
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver provides sample on how to produce Platform VTd policy protocol."
|
||||
|
@@ -0,0 +1,20 @@
|
||||
// /** @file
|
||||
// PlatformVTdSampleDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials are
|
||||
// licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Platform VTd Sample DXE Driver"
|
||||
|
||||
|
361
IntelSiliconPkg/Include/IndustryStandard/Vtd.h
Normal file
361
IntelSiliconPkg/Include/IndustryStandard/Vtd.h
Normal file
@@ -0,0 +1,361 @@
|
||||
/** @file
|
||||
The definition for VTD register.
|
||||
It is defined in "Intel VT for Direct IO Architecture Specification".
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __VTD_REG_H__
|
||||
#define __VTD_REG_H__
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
//
|
||||
// Translation Structure Formats
|
||||
//
|
||||
#define VTD_ROOT_ENTRY_NUMBER 256
|
||||
#define VTD_CONTEXT_ENTRY_NUMBER 256
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Present:1;
|
||||
UINT32 Reserved_1:11;
|
||||
UINT32 ContextTablePointerLo:20;
|
||||
UINT32 ContextTablePointerHi:32;
|
||||
|
||||
UINT64 Reserved_64;
|
||||
} Bits;
|
||||
struct {
|
||||
UINT64 Uint64Lo;
|
||||
UINT64 Uint64Hi;
|
||||
} Uint128;
|
||||
} VTD_ROOT_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 LowerPresent:1;
|
||||
UINT32 Reserved_1:11;
|
||||
UINT32 LowerContextTablePointerLo:20;
|
||||
UINT32 LowerContextTablePointerHi:32;
|
||||
|
||||
UINT32 UpperPresent:1;
|
||||
UINT32 Reserved_65:11;
|
||||
UINT32 UpperContextTablePointerLo:20;
|
||||
UINT32 UpperContextTablePointerHi:32;
|
||||
} Bits;
|
||||
struct {
|
||||
UINT64 Uint64Lo;
|
||||
UINT64 Uint64Hi;
|
||||
} Uint128;
|
||||
} VTD_EXT_ROOT_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Present:1;
|
||||
UINT32 FaultProcessingDisable:1;
|
||||
UINT32 TranslationType:2;
|
||||
UINT32 Reserved_4:8;
|
||||
UINT32 SecondLevelPageTranslationPointerLo:20;
|
||||
UINT32 SecondLevelPageTranslationPointerHi:32;
|
||||
|
||||
UINT32 AddressWidth:3;
|
||||
UINT32 Ignored_67:4;
|
||||
UINT32 Reserved_71:1;
|
||||
UINT32 DomainIdentifier:16;
|
||||
UINT32 Reserved_88:8;
|
||||
UINT32 Reserved_96:32;
|
||||
} Bits;
|
||||
struct {
|
||||
UINT64 Uint64Lo;
|
||||
UINT64 Uint64Hi;
|
||||
} Uint128;
|
||||
} VTD_CONTEXT_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Present:1;
|
||||
UINT32 FaultProcessingDisable:1;
|
||||
UINT32 TranslationType:3;
|
||||
UINT32 ExtendedMemoryType:3;
|
||||
UINT32 DeferredInvalidateEnable:1;
|
||||
UINT32 PageRequestEnable:1;
|
||||
UINT32 NestedTranslationEnable:1;
|
||||
UINT32 PASIDEnable:1;
|
||||
UINT32 SecondLevelPageTranslationPointerLo:20;
|
||||
UINT32 SecondLevelPageTranslationPointerHi:32;
|
||||
|
||||
UINT32 AddressWidth:3;
|
||||
UINT32 PageGlobalEnable:1;
|
||||
UINT32 NoExecuteEnable:1;
|
||||
UINT32 WriteProtectEnable:1;
|
||||
UINT32 CacheDisable:1;
|
||||
UINT32 ExtendedMemoryTypeEnable:1;
|
||||
UINT32 DomainIdentifier:16;
|
||||
UINT32 SupervisorModeExecuteProtection:1;
|
||||
UINT32 ExtendedAccessedFlagEnable:1;
|
||||
UINT32 ExecuteRequestsEnable:1;
|
||||
UINT32 SecondLevelExecuteEnable:1;
|
||||
UINT32 Reserved_92:4;
|
||||
UINT32 PageAttributeTable0:3;
|
||||
UINT32 Reserved_Pat0:1;
|
||||
UINT32 PageAttributeTable1:3;
|
||||
UINT32 Reserved_Pat1:1;
|
||||
UINT32 PageAttributeTable2:3;
|
||||
UINT32 Reserved_Pat2:1;
|
||||
UINT32 PageAttributeTable3:3;
|
||||
UINT32 Reserved_Pat3:1;
|
||||
UINT32 PageAttributeTable4:3;
|
||||
UINT32 Reserved_Pat4:1;
|
||||
UINT32 PageAttributeTable5:3;
|
||||
UINT32 Reserved_Pat5:1;
|
||||
UINT32 PageAttributeTable6:3;
|
||||
UINT32 Reserved_Pat6:1;
|
||||
UINT32 PageAttributeTable7:3;
|
||||
UINT32 Reserved_Pat7:1;
|
||||
|
||||
UINT32 PASIDTableSize:4;
|
||||
UINT32 Reserved_132:8;
|
||||
UINT32 PASIDTablePointerLo:20;
|
||||
UINT32 PASIDTablePointerHi:32;
|
||||
|
||||
UINT32 Reserved_192:12;
|
||||
UINT32 PASIDStateTablePointerLo:20;
|
||||
UINT32 PASIDStateTablePointerHi:32;
|
||||
} Bits;
|
||||
struct {
|
||||
UINT64 Uint64_1;
|
||||
UINT64 Uint64_2;
|
||||
UINT64 Uint64_3;
|
||||
UINT64 Uint64_4;
|
||||
} Uint256;
|
||||
} VTD_EXT_CONTEXT_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Present:1;
|
||||
UINT32 Reserved_1:2;
|
||||
UINT32 PageLevelCacheDisable:1;
|
||||
UINT32 PageLevelWriteThrough:1;
|
||||
UINT32 Reserved_5:6;
|
||||
UINT32 SupervisorRequestsEnable:1;
|
||||
UINT32 FirstLevelPageTranslationPointerLo:20;
|
||||
UINT32 FirstLevelPageTranslationPointerHi:32;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_PASID_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Reserved_0:32;
|
||||
UINT32 ActiveReferenceCount:16;
|
||||
UINT32 Reserved_48:15;
|
||||
UINT32 DeferredInvalidate:1;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_PASID_STATE_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Present:1;
|
||||
UINT32 ReadWrite:1;
|
||||
UINT32 UserSupervisor:1;
|
||||
UINT32 PageLevelWriteThrough:1;
|
||||
UINT32 PageLevelCacheDisable:1;
|
||||
UINT32 Accessed:1;
|
||||
UINT32 Dirty:1;
|
||||
UINT32 PageSize:1; // It is PageAttribute:1 for 4K page entry
|
||||
UINT32 Global:1;
|
||||
UINT32 Ignored_9:1;
|
||||
UINT32 ExtendedAccessed:1;
|
||||
UINT32 Ignored_11:1;
|
||||
// NOTE: There is PageAttribute:1 as bit12 for 1G page entry and 2M page entry
|
||||
UINT32 AddressLo:20;
|
||||
UINT32 AddressHi:20;
|
||||
UINT32 Ignored_52:11;
|
||||
UINT32 ExecuteDisable:1;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_FIRST_LEVEL_PAGING_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Read:1;
|
||||
UINT32 Write:1;
|
||||
UINT32 Execute:1;
|
||||
UINT32 ExtendedMemoryType:3;
|
||||
UINT32 IgnorePAT:1;
|
||||
UINT32 PageSize:1;
|
||||
UINT32 Ignored_8:3;
|
||||
UINT32 Snoop:1;
|
||||
UINT32 AddressLo:20;
|
||||
UINT32 AddressHi:20;
|
||||
UINT32 Ignored_52:10;
|
||||
UINT32 TransientMapping:1;
|
||||
UINT32 Ignored_63:1;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_SECOND_LEVEL_PAGING_ENTRY;
|
||||
|
||||
//
|
||||
// Register Descriptions
|
||||
//
|
||||
#define R_VER_REG 0x00
|
||||
#define R_CAP_REG 0x08
|
||||
#define B_CAP_REG_RWBF BIT4
|
||||
#define R_ECAP_REG 0x10
|
||||
#define R_GCMD_REG 0x18
|
||||
#define B_GMCD_REG_WBF BIT27
|
||||
#define B_GMCD_REG_SRTP BIT30
|
||||
#define B_GMCD_REG_TE BIT31
|
||||
#define R_GSTS_REG 0x1C
|
||||
#define B_GSTS_REG_WBF BIT27
|
||||
#define B_GSTS_REG_RTPS BIT30
|
||||
#define B_GSTS_REG_TE BIT31
|
||||
#define R_RTADDR_REG 0x20
|
||||
#define R_CCMD_REG 0x28
|
||||
#define B_CCMD_REG_CIRG_MASK (BIT62|BIT61)
|
||||
#define V_CCMD_REG_CIRG_GLOBAL BIT61
|
||||
#define V_CCMD_REG_CIRG_DOMAIN BIT62
|
||||
#define V_CCMD_REG_CIRG_DEVICE (BIT62|BIT61)
|
||||
#define B_CCMD_REG_ICC BIT63
|
||||
#define R_FSTS_REG 0x34
|
||||
#define R_FECTL_REG 0x38
|
||||
#define R_FEDATA_REG 0x3C
|
||||
#define R_FEADDR_REG 0x40
|
||||
#define R_FEUADDR_REG 0x44
|
||||
#define R_AFLOG_REG 0x58
|
||||
|
||||
#define R_IVA_REG 0x00 // + IRO
|
||||
#define B_IVA_REG_AM_MASK (BIT0|BIT1|BIT2|BIT3|BIT4|BIT5)
|
||||
#define B_IVA_REG_AM_4K 0 // 1 page
|
||||
#define B_IVA_REG_AM_2M 9 // 2M page
|
||||
#define B_IVA_REG_IH BIT6
|
||||
#define R_IOTLB_REG 0x08 // + IRO
|
||||
#define B_IOTLB_REG_IIRG_MASK (BIT61|BIT60)
|
||||
#define V_IOTLB_REG_IIRG_GLOBAL BIT60
|
||||
#define V_IOTLB_REG_IIRG_DOMAIN BIT61
|
||||
#define V_IOTLB_REG_IIRG_PAGE (BIT61|BIT60)
|
||||
#define B_IOTLB_REG_IVT BIT63
|
||||
|
||||
#define R_FRCD_REG 0x00 // + FRO
|
||||
|
||||
#define R_PMEN_ENABLE_REG 0x64
|
||||
#define R_PMEN_LOW_BASE_REG 0x68
|
||||
#define R_PMEN_LOW_LIMITE_REG 0x6C
|
||||
#define R_PMEN_HIGH_BASE_REG 0x70
|
||||
#define R_PMEN_HIGH_LIMITE_REG 0x78
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT8 ND:3; // Number of domains supported
|
||||
UINT8 AFL:1; // Advanced Fault Logging
|
||||
UINT8 RWBF:1; // Required Write-Buffer Flushing
|
||||
UINT8 PLMR:1; // Protected Low-Memory Region
|
||||
UINT8 PHMR:1; // Protected High-Memory Region
|
||||
UINT8 CM:1; // Caching Mode
|
||||
|
||||
UINT8 SAGAW:5; // Supported Adjusted Guest Address Widths
|
||||
UINT8 Rsvd_13:3;
|
||||
|
||||
UINT8 MGAW:6; // Maximum Guest Address Width
|
||||
UINT8 ZLR:1; // Zero Length Read
|
||||
UINT8 Rsvd_23:1;
|
||||
|
||||
UINT16 FRO:10; // Fault-recording Register offset
|
||||
UINT16 SLLPS:4; // Second Level Large Page Support
|
||||
UINT16 Rsvd_38:1;
|
||||
UINT16 PSI:1; // Page Selective Invalidation
|
||||
|
||||
UINT8 NFR:8; // Number of Fault-recording Registers
|
||||
|
||||
UINT8 MAMV:6; // Maximum Address Mask Value
|
||||
UINT8 DWD:1; // Write Draining
|
||||
UINT8 DRD:1; // Read Draining
|
||||
|
||||
UINT8 FL1GP:1; // First Level 1-GByte Page Support
|
||||
UINT8 Rsvd_57:2;
|
||||
UINT8 PI:1; // Posted Interrupts Support
|
||||
UINT8 Rsvd_60:4;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_CAP_REG;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT8 C:1; // Page-walk Coherency
|
||||
UINT8 QI:1; // Queued Invalidation support
|
||||
UINT8 DT:1; // Device-TLB support
|
||||
UINT8 IR:1; // Interrupt Remapping support
|
||||
UINT8 EIM:1; // Extended Interrupt Mode
|
||||
UINT8 Rsvd_5:1;
|
||||
UINT8 PT:1; // Pass Through
|
||||
UINT8 SC:1; // Snoop Control
|
||||
|
||||
UINT16 IRO:10; // IOTLB Register Offset
|
||||
UINT16 Rsvd_18:2;
|
||||
UINT16 MHMV:4; // Maximum Handle Mask Value
|
||||
|
||||
UINT8 ECS:1; // Extended Context Support
|
||||
UINT8 MTS:1; // Memory Type Support
|
||||
UINT8 NEST:1; // Nested Translation Support
|
||||
UINT8 DIS:1; // Deferred Invalidate Support
|
||||
UINT8 PASID:1; // Process Address Space ID Support
|
||||
UINT8 PRS:1; // Page Request Support
|
||||
UINT8 ERS:1; // Execute Request Support
|
||||
UINT8 SRS:1; // Supervisor Request Support
|
||||
|
||||
UINT32 Rsvd_32:1;
|
||||
UINT32 NWFS:1; // No Write Flag Support
|
||||
UINT32 EAFS:1; // Extended Accessed Flag Support
|
||||
UINT32 PSS:5; // PASID Size Supported
|
||||
UINT32 Rsvd_40:24;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} VTD_ECAP_REG;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Rsvd_0:12;
|
||||
UINT32 FILo:20; // FaultInfo
|
||||
UINT32 FIHi:32; // FaultInfo
|
||||
|
||||
UINT32 SID:16; // Source Identifier
|
||||
UINT32 Rsvd_80:13;
|
||||
UINT32 PRIV:1; // Privilege Mode Requested
|
||||
UINT32 EXE:1; // Execute Permission Requested
|
||||
UINT32 PP:1; // PASID Present
|
||||
|
||||
UINT32 FR:8; // Fault Reason
|
||||
UINT32 PV:20; // PASID Value
|
||||
UINT32 AT:2; // Address Type
|
||||
UINT32 T:1; // Type (0: Write, 1: Read)
|
||||
UINT32 F:1; // Fault
|
||||
} Bits;
|
||||
UINT64 Uint64[2];
|
||||
} VTD_FRCD_REG;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT8 Function:3;
|
||||
UINT8 Device:5;
|
||||
UINT8 Bus;
|
||||
} Bits;
|
||||
struct {
|
||||
UINT8 ContextIndex;
|
||||
UINT8 RootIndex;
|
||||
} Index;
|
||||
UINT16 Uint16;
|
||||
} VTD_SOURCE_ID;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
43
IntelSiliconPkg/Include/Ppi/VtdInfo.h
Normal file
43
IntelSiliconPkg/Include/Ppi/VtdInfo.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/** @file
|
||||
The definition for VTD information PPI.
|
||||
|
||||
This is a lightweight VTd information report in PEI phase.
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __VTD_INFO_PPI_H__
|
||||
#define __VTD_INFO_PPI_H__
|
||||
|
||||
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
||||
|
||||
#define EDKII_VTD_INFO_PPI_GUID \
|
||||
{ \
|
||||
0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } \
|
||||
}
|
||||
|
||||
//
|
||||
// VTD info PPI just use same data structure as DMAR table.
|
||||
//
|
||||
// The reported information must include what is needed in PEI phase, e.g.
|
||||
// the VTd engine (such as DRHD)
|
||||
// the reserved DMA address in PEI for eary graphic (such as RMRR for graphic UMA)
|
||||
//
|
||||
// The reported information can be and might be a subset of full DMAR table, e.g.
|
||||
// if some data is not avaiable (such as ANDD),
|
||||
// if some data is not needed (such as RMRR for legacy USB).
|
||||
//
|
||||
typedef EFI_ACPI_DMAR_HEADER EDKII_VTD_INFO_PPI;
|
||||
|
||||
extern EFI_GUID gEdkiiVTdInfoPpiGuid;
|
||||
|
||||
#endif
|
||||
|
149
IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h
Normal file
149
IntelSiliconPkg/Include/Protocol/PlatformVtdPolicy.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/** @file
|
||||
The definition for platform VTD policy.
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __PLATFORM_VTD_POLICY_PROTOCOL_H__
|
||||
#define __PLATFORM_VTD_POLICY_PROTOCOL_H__
|
||||
|
||||
#include <IndustryStandard/Vtd.h>
|
||||
#include <IndustryStandard/DmaRemappingReportingTable.h>
|
||||
|
||||
#define EDKII_PLATFORM_VTD_POLICY_PROTOCOL_GUID \
|
||||
{ \
|
||||
0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 } \
|
||||
}
|
||||
|
||||
typedef struct _EDKII_PLATFORM_VTD_POLICY_PROTOCOL EDKII_PLATFORM_VTD_POLICY_PROTOCOL;
|
||||
|
||||
#define EDKII_PLATFORM_VTD_POLICY_PROTOCOL_REVISION 0x00010000
|
||||
|
||||
typedef struct {
|
||||
UINT16 Segment;
|
||||
VTD_SOURCE_ID SourceId;
|
||||
} EDKII_PLATFORM_VTD_DEVICE_INFO;
|
||||
|
||||
/**
|
||||
Get the VTD SourceId from the device handler.
|
||||
This function is required for non PCI device handler.
|
||||
|
||||
Pseudo-algo in Intel VTd driver:
|
||||
Status = PlatformGetVTdDeviceId ();
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (DeviceHandle is PCI) {
|
||||
Get SourceId from Bus/Device/Function
|
||||
} else {
|
||||
return EFI_UNSUPPORTED
|
||||
}
|
||||
}
|
||||
Get VTd engine by Segment/Bus/Device/Function.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceHandle Device Identifier in UEFI.
|
||||
@param[out] DeviceInfo DeviceInfo for indentify the VTd engine in ACPI Table
|
||||
and the VTd page entry.
|
||||
|
||||
@retval EFI_SUCCESS The VtdIndex and SourceId are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceHandle is not a valid handler.
|
||||
@retval EFI_INVALID_PARAMETER DeviceInfo is NULL.
|
||||
@retval EFI_NOT_FOUND The Segment or SourceId information is NOT found.
|
||||
@retval EFI_UNSUPPORTED This function is not supported.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_PLATFORM_VTD_POLICY_GET_DEVICE_ID) (
|
||||
IN EDKII_PLATFORM_VTD_POLICY_PROTOCOL *This,
|
||||
IN EFI_HANDLE DeviceHandle,
|
||||
OUT EDKII_PLATFORM_VTD_DEVICE_INFO *DeviceInfo
|
||||
);
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
//
|
||||
// The segment number of the device
|
||||
//
|
||||
UINT16 SegmentNumber;
|
||||
//
|
||||
// Device scope definition in DMAR table
|
||||
//
|
||||
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER DeviceScope;
|
||||
//
|
||||
// Pci path definition in DMAR table
|
||||
//
|
||||
//EFI_ACPI_DMAR_PCI_PATH PciPath[];
|
||||
} EDKII_PLATFORM_VTD_DEVICE_SCOPE;
|
||||
|
||||
typedef struct {
|
||||
UINT16 VendorId;
|
||||
UINT16 DeviceId;
|
||||
UINT8 RevisionId;
|
||||
UINT16 SubsystemVendorId;
|
||||
UINT16 SubsystemDeviceId;
|
||||
} EDKII_PLATFORM_VTD_PCI_DEVICE_ID;
|
||||
|
||||
#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_END 0
|
||||
#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE 1
|
||||
#define EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID 2
|
||||
|
||||
typedef struct {
|
||||
//
|
||||
// EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_xxx defined above.
|
||||
//
|
||||
UINT8 Type;
|
||||
//
|
||||
// The length of the full data structure including EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO and Data.
|
||||
//
|
||||
UINT8 Length;
|
||||
//
|
||||
// Data can be EDKII_PLATFORM_VTD_DEVICE_SCOPE or EDKII_PLATFORM_VTD_PCI_DEVICE_ID
|
||||
//
|
||||
//UINT8 Data[Length - sizeof(EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO)];
|
||||
} EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/**
|
||||
Get a list of the exception devices.
|
||||
|
||||
The VTd driver should always set ALLOW for the device in this list.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[out] DeviceInfoCount The count of the list of DeviceInfo.
|
||||
@param[out] DeviceInfo A callee allocated buffer to hold a list of DeviceInfo.
|
||||
Each DeviceInfo pointer points to EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO.
|
||||
|
||||
@retval EFI_SUCCESS The DeviceInfoCount and DeviceInfo are returned.
|
||||
@retval EFI_INVALID_PARAMETER DeviceInfoCount is NULL, or DeviceInfo is NULL.
|
||||
@retval EFI_UNSUPPORTED This function is not supported.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_PLATFORM_VTD_POLICY_GET_EXCEPTION_DEVICE_LIST) (
|
||||
IN EDKII_PLATFORM_VTD_POLICY_PROTOCOL *This,
|
||||
OUT UINTN *DeviceInfoCount,
|
||||
OUT VOID **DeviceInfo
|
||||
);
|
||||
|
||||
struct _EDKII_PLATFORM_VTD_POLICY_PROTOCOL {
|
||||
UINT64 Revision;
|
||||
EDKII_PLATFORM_VTD_POLICY_GET_DEVICE_ID GetDeviceId;
|
||||
EDKII_PLATFORM_VTD_POLICY_GET_EXCEPTION_DEVICE_LIST GetExceptionDeviceList;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEdkiiPlatformVTdPolicyProtocolGuid;
|
||||
|
||||
#endif
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# This package provides common open source Intel silicon modules.
|
||||
#
|
||||
# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials are licensed and made available under
|
||||
# the terms and conditions of the BSD License that accompanies this distribution.
|
||||
# The full text of the license may be found at
|
||||
@@ -33,6 +33,12 @@
|
||||
# Generic DXE Library / Driver can locate HOB(s) and add SMBIOS records into SMBIOS table
|
||||
gIntelSmbiosDataHobGuid = { 0x798e722e, 0x15b2, 0x4e13, { 0x8a, 0xe9, 0x6b, 0xa3, 0x0f, 0xf7, 0xf1, 0x67 }}
|
||||
|
||||
[Ppis]
|
||||
gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } }
|
||||
|
||||
[Protocols]
|
||||
gEdkiiPlatformVTdPolicyProtocolGuid = { 0x3d17e448, 0x466, 0x4e20, { 0x99, 0x9f, 0xb2, 0xe1, 0x34, 0x88, 0xee, 0x22 }}
|
||||
|
||||
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||
## This is the GUID of the FFS which contains the Graphics Video BIOS Table (VBT)
|
||||
# The VBT content is stored as a RAW section which is consumed by GOP PEI/UEFI driver.
|
||||
@@ -41,3 +47,25 @@
|
||||
# { 0x56752da9, 0xde6b, 0x4895, 0x88, 0x19, 0x19, 0x45, 0xb6, 0xb7, 0x6c, 0x22 }
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid|{ 0xa9, 0x2d, 0x75, 0x56, 0x6b, 0xde, 0x95, 0x48, 0x88, 0x19, 0x19, 0x45, 0xb6, 0xb7, 0x6c, 0x22 }|VOID*|0x00000001
|
||||
|
||||
## The mask is used to control VTd behavior.<BR><BR>
|
||||
# BIT0: Enable IOMMU during boot (If DMAR table is installed in DXE. If VTD_INFO_PPI is installed in PEI.)
|
||||
# BIT1: Enable IOMMU when transfer control to OS (ExitBootService in normal boot. EndOfPEI in S3)
|
||||
# @Prompt The policy for VTd driver behavior.
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask|1|UINT8|0x00000002
|
||||
|
||||
## Declares VTd PEI DMA buffer size.<BR><BR>
|
||||
# When this PCD value is referred by platform to calculate the required
|
||||
# memory size for PEI (InstallPeiMemory), the PMR alignment requirement
|
||||
# needs be considered to be added with this PCD value for alignment
|
||||
# adjustment need by AllocateAlignedPages.
|
||||
# @Prompt The VTd PEI DMA buffer size.
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSize|0x00400000|UINT32|0x00000003
|
||||
|
||||
## Declares VTd PEI DMA buffer size for S3.<BR><BR>
|
||||
# When this PCD value is referred by platform to calculate the required
|
||||
# memory size for PEI S3 (InstallPeiMemory), the PMR alignment requirement
|
||||
# needs be considered to be added with this PCD value for alignment
|
||||
# adjustment need by AllocateAlignedPages.
|
||||
# @Prompt The VTd PEI DMA buffer size for S3.
|
||||
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPeiDmaBufferSizeS3|0x00200000|UINT32|0x00000004
|
||||
|
||||
|
89
IntelSiliconPkg/IntelSiliconPkg.dsc
Normal file
89
IntelSiliconPkg/IntelSiliconPkg.dsc
Normal file
@@ -0,0 +1,89 @@
|
||||
## @file
|
||||
# This package provides common open source Intel silicon modules.
|
||||
#
|
||||
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
PLATFORM_NAME = IntelSiliconPkg
|
||||
PLATFORM_GUID = 9B96228E-1155-4967-8E16-D0ED8E1B4297
|
||||
PLATFORM_VERSION = 0.1
|
||||
DSC_SPECIFICATION = 0x00010005
|
||||
OUTPUT_DIRECTORY = Build/IntelSiliconPkg
|
||||
SUPPORTED_ARCHITECTURES = IA32|X64
|
||||
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
|
||||
SKUID_IDENTIFIER = DEFAULT
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
|
||||
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
|
||||
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
|
||||
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
|
||||
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
|
||||
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
|
||||
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
||||
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
|
||||
|
||||
[LibraryClasses.common.PEIM]
|
||||
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||
|
||||
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
|
||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
|
||||
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||
|
||||
###################################################################################################
|
||||
#
|
||||
# Components Section - list of the modules and components that will be processed by compilation
|
||||
# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
|
||||
#
|
||||
# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
|
||||
# into firmware volume images. This section is just a list of modules to compile from
|
||||
# source into UEFI-compliant binaries.
|
||||
# It is the FDF file that contains information on combining binary files into firmware
|
||||
# volume images, whose concept is beyond UEFI and is described in PI specification.
|
||||
# Binary modules do not need to be listed in this section, as they should be
|
||||
# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
|
||||
# Logo (Logo.bmp), and etc.
|
||||
# There may also be modules listed in this section that are not required in the FDF file,
|
||||
# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
|
||||
# generated for it, but the binary will not be put into any firmware volume.
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
[Components]
|
||||
IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf
|
||||
IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
|
||||
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
|
||||
IntelSiliconPkg/Feature/VTd/PlatformVTdSampleDxe/PlatformVTdSampleDxe.inf
|
||||
IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
|
||||
|
||||
[BuildOptions]
|
||||
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
A shell application that triggers capsule update process.
|
||||
|
||||
Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -653,7 +653,7 @@ CleanGatherList (
|
||||
break;
|
||||
}
|
||||
|
||||
TempBlockPtr2 = (VOID *) ((UINTN) TempBlockPtr->Union.ContinuationPointer);
|
||||
TempBlockPtr2 = (VOID *) ((UINTN) TempBlockPtr[Index].Union.ContinuationPointer);
|
||||
FreePool(TempBlockPtr1);
|
||||
TempBlockPtr1 = TempBlockPtr2;
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
|
||||
USB 2.0 device inserts.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -1220,6 +1220,7 @@ EhcSyncInterruptTransfer (
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EhcFreeUrb (Ehc, Urb);
|
||||
ON_EXIT:
|
||||
Ehc->PciIo->Flush (Ehc->PciIo);
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
250
MdeModulePkg/Bus/Pci/EhciPei/DmaMem.c
Normal file
250
MdeModulePkg/Bus/Pci/EhciPei/DmaMem.c
Normal file
@@ -0,0 +1,250 @@
|
||||
/** @file
|
||||
The DMA memory help functions.
|
||||
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
of the BSD License which accompanies this distribution. The
|
||||
full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "EhcPeim.h"
|
||||
|
||||
/**
|
||||
Provides the controller-specific addresses required to access system memory from a
|
||||
DMA bus master.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Operation Indicates if the bus master is going to read or write to system memory.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
|
||||
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IoMmuMap (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN EDKII_IOMMU_OPERATION Operation,
|
||||
IN VOID *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 Attribute;
|
||||
|
||||
if (IoMmu != NULL) {
|
||||
Status = IoMmu->Map (
|
||||
IoMmu,
|
||||
Operation,
|
||||
HostAddress,
|
||||
NumberOfBytes,
|
||||
DeviceAddress,
|
||||
Mapping
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
switch (Operation) {
|
||||
case EdkiiIoMmuOperationBusMasterRead:
|
||||
case EdkiiIoMmuOperationBusMasterRead64:
|
||||
Attribute = EDKII_IOMMU_ACCESS_READ;
|
||||
break;
|
||||
case EdkiiIoMmuOperationBusMasterWrite:
|
||||
case EdkiiIoMmuOperationBusMasterWrite64:
|
||||
Attribute = EDKII_IOMMU_ACCESS_WRITE;
|
||||
break;
|
||||
case EdkiiIoMmuOperationBusMasterCommonBuffer:
|
||||
case EdkiiIoMmuOperationBusMasterCommonBuffer64:
|
||||
Attribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
Status = IoMmu->SetAttribute (
|
||||
IoMmu,
|
||||
*Mapping,
|
||||
Attribute
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
IoMmu->Unmap (IoMmu, Mapping);
|
||||
*Mapping = NULL;
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
*DeviceAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
|
||||
*Mapping = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuUnmap (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
{
|
||||
if (IoMmu != NULL) {
|
||||
IoMmu->SetAttribute (IoMmu, Mapping, 0);
|
||||
IoMmu->Unmap (IoMmu, Mapping);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
|
||||
OperationBusMasterCommonBuffer64 mapping.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Pages The number of pages to allocate.
|
||||
@param HostAddress A pointer to store the base system memory address of the
|
||||
allocated range.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were allocated.
|
||||
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
|
||||
MEMORY_WRITE_COMBINE and MEMORY_CACHED.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IoMmuAllocateBuffer (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN UINTN Pages,
|
||||
OUT VOID **HostAddress,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN NumberOfBytes;
|
||||
EFI_PHYSICAL_ADDRESS HostPhyAddress;
|
||||
|
||||
*HostAddress = NULL;
|
||||
*DeviceAddress = 0;
|
||||
*Mapping = NULL;
|
||||
|
||||
if (IoMmu != NULL) {
|
||||
Status = IoMmu->AllocateBuffer (
|
||||
IoMmu,
|
||||
EfiBootServicesData,
|
||||
Pages,
|
||||
HostAddress,
|
||||
0
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
|
||||
Status = IoMmu->Map (
|
||||
IoMmu,
|
||||
EdkiiIoMmuOperationBusMasterCommonBuffer,
|
||||
*HostAddress,
|
||||
&NumberOfBytes,
|
||||
DeviceAddress,
|
||||
Mapping
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
|
||||
*HostAddress = NULL;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
Status = IoMmu->SetAttribute (
|
||||
IoMmu,
|
||||
*Mapping,
|
||||
EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
IoMmu->Unmap (IoMmu, *Mapping);
|
||||
IoMmu->FreeBuffer (IoMmu, Pages, *HostAddress);
|
||||
*Mapping = NULL;
|
||||
*HostAddress = NULL;
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
Status = PeiServicesAllocatePages (
|
||||
EfiBootServicesCode,
|
||||
Pages,
|
||||
&HostPhyAddress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
*HostAddress = (VOID *) (UINTN) HostPhyAddress;
|
||||
*DeviceAddress = HostPhyAddress;
|
||||
*Mapping = NULL;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Frees memory that was allocated with AllocateBuffer().
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Pages The number of pages to free.
|
||||
@param HostAddress The base system memory address of the allocated range.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuFreeBuffer (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN UINTN Pages,
|
||||
IN VOID *HostAddress,
|
||||
IN VOID *Mapping
|
||||
)
|
||||
{
|
||||
if (IoMmu != NULL) {
|
||||
IoMmu->SetAttribute (IoMmu, Mapping, 0);
|
||||
IoMmu->Unmap (IoMmu, Mapping);
|
||||
IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize IOMMU.
|
||||
|
||||
@param IoMmu Pointer to pointer to IOMMU PPI.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuInit (
|
||||
OUT EDKII_IOMMU_PPI **IoMmu
|
||||
)
|
||||
{
|
||||
PeiServicesLocatePpi (
|
||||
&gEdkiiIoMmuPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **) IoMmu
|
||||
);
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
which is used to enable recovery function from USB Drivers.
|
||||
|
||||
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -1140,6 +1140,36 @@ ON_EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
One notified function to stop the Host Controller at the end of PEI
|
||||
|
||||
@param[in] PeiServices Pointer to PEI Services Table.
|
||||
@param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that
|
||||
caused this function to execute.
|
||||
@param[in] Ppi Pointer to the PPI data associated with this function.
|
||||
|
||||
@retval EFI_SUCCESS The function completes successfully
|
||||
@retval others
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EhcEndOfPei (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
PEI_USB2_HC_DEV *Ehc;
|
||||
|
||||
Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_THIS_NOTIFY (NotifyDescriptor);
|
||||
|
||||
EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
|
||||
|
||||
EhcFreeSched (Ehc);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@param FileHandle Handle of the file being invoked.
|
||||
@param PeiServices Describes the list of possible PEI Services.
|
||||
@@ -1219,6 +1249,8 @@ EhcPeimEntry (
|
||||
|
||||
EhcDev->Signature = USB2_HC_DEV_SIGNATURE;
|
||||
|
||||
IoMmuInit (&EhcDev->IoMmu);
|
||||
|
||||
EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
|
||||
|
||||
|
||||
@@ -1250,6 +1282,12 @@ EhcPeimEntry (
|
||||
continue;
|
||||
}
|
||||
|
||||
EhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
|
||||
EhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;
|
||||
EhcDev->EndOfPeiNotifyList.Notify = EhcEndOfPei;
|
||||
|
||||
PeiServicesNotifyPpi (&EhcDev->EndOfPeiNotifyList);
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Private Header file for Usb Host Controller PEIM
|
||||
|
||||
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -21,6 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include <Ppi/UsbController.h>
|
||||
#include <Ppi/Usb2HostController.h>
|
||||
#include <Ppi/IoMmu.h>
|
||||
#include <Ppi/EndOfPeiPhase.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeimEntryPoint.h>
|
||||
@@ -94,7 +96,13 @@ typedef struct _PEI_USB2_HC_DEV PEI_USB2_HC_DEV;
|
||||
struct _PEI_USB2_HC_DEV {
|
||||
UINTN Signature;
|
||||
PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi;
|
||||
EDKII_IOMMU_PPI *IoMmu;
|
||||
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
|
||||
//
|
||||
// EndOfPei callback is used to stop the EHC DMA operation
|
||||
// after exit PEI phase.
|
||||
//
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList;
|
||||
UINT32 UsbHostControllerBaseAddress;
|
||||
PEI_URB *Urb;
|
||||
USBHC_MEM_POOL *MemPool;
|
||||
@@ -122,7 +130,6 @@ struct _PEI_USB2_HC_DEV {
|
||||
// Periodic (interrupt) transfer schedule data:
|
||||
//
|
||||
VOID *PeriodFrame; // Mapped as common buffer
|
||||
VOID *PeriodFrameHost;
|
||||
VOID *PeriodFrameMap;
|
||||
|
||||
PEI_EHC_QH *PeriodOne;
|
||||
@@ -138,6 +145,7 @@ struct _PEI_USB2_HC_DEV {
|
||||
};
|
||||
|
||||
#define PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(a) CR (a, PEI_USB2_HC_DEV, Usb2HostControllerPpi, USB2_HC_DEV_SIGNATURE)
|
||||
#define PEI_RECOVERY_USB_EHC_DEV_FROM_THIS_NOTIFY(a) CR (a, PEI_USB2_HC_DEV, EndOfPeiNotifyList, USB2_HC_DEV_SIGNATURE)
|
||||
|
||||
/**
|
||||
@param EhcDev EHCI Device.
|
||||
@@ -174,6 +182,7 @@ UsbHcInitMemPool (
|
||||
/**
|
||||
Release the memory management pool.
|
||||
|
||||
@param Ehc The EHCI device.
|
||||
@param Pool The USB memory pool to free.
|
||||
|
||||
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
||||
@@ -182,6 +191,7 @@ UsbHcInitMemPool (
|
||||
**/
|
||||
EFI_STATUS
|
||||
UsbHcFreeMemPool (
|
||||
IN PEI_USB2_HC_DEV *Ehc,
|
||||
IN USBHC_MEM_POOL *Pool
|
||||
)
|
||||
;
|
||||
@@ -208,6 +218,7 @@ UsbHcAllocateMem (
|
||||
/**
|
||||
Free the allocated memory back to the memory pool.
|
||||
|
||||
@param Ehc The EHCI device.
|
||||
@param Pool The memory pool of the host controller.
|
||||
@param Mem The memory to free.
|
||||
@param Size The size of the memory to free.
|
||||
@@ -215,10 +226,110 @@ UsbHcAllocateMem (
|
||||
**/
|
||||
VOID
|
||||
UsbHcFreeMem (
|
||||
IN PEI_USB2_HC_DEV *Ehc,
|
||||
IN USBHC_MEM_POOL *Pool,
|
||||
IN VOID *Mem,
|
||||
IN UINTN Size
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Provides the controller-specific addresses required to access system memory from a
|
||||
DMA bus master.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Operation Indicates if the bus master is going to read or write to system memory.
|
||||
@param HostAddress The system memory address to map to the PCI controller.
|
||||
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes
|
||||
that were mapped.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
|
||||
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IoMmuMap (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN EDKII_IOMMU_OPERATION Operation,
|
||||
IN VOID *HostAddress,
|
||||
IN OUT UINTN *NumberOfBytes,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Completes the Map() operation and releases any corresponding resources.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuUnmap (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN VOID *Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
|
||||
OperationBusMasterCommonBuffer64 mapping.
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Pages The number of pages to allocate.
|
||||
@param HostAddress A pointer to store the base system memory address of the
|
||||
allocated range.
|
||||
@param DeviceAddress The resulting map address for the bus master PCI controller to use to
|
||||
access the hosts HostAddress.
|
||||
@param Mapping A resulting value to pass to Unmap().
|
||||
|
||||
@retval EFI_SUCCESS The requested memory pages were allocated.
|
||||
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
|
||||
MEMORY_WRITE_COMBINE and MEMORY_CACHED.
|
||||
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
IoMmuAllocateBuffer (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN UINTN Pages,
|
||||
OUT VOID **HostAddress,
|
||||
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
||||
OUT VOID **Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Frees memory that was allocated with AllocateBuffer().
|
||||
|
||||
@param IoMmu Pointer to IOMMU PPI.
|
||||
@param Pages The number of pages to free.
|
||||
@param HostAddress The base system memory address of the allocated range.
|
||||
@param Mapping The mapping value returned from Map().
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuFreeBuffer (
|
||||
IN EDKII_IOMMU_PPI *IoMmu,
|
||||
IN UINTN Pages,
|
||||
IN VOID *HostAddress,
|
||||
IN VOID *Mapping
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize IOMMU.
|
||||
|
||||
@param IoMmu Pointer to pointer to IOMMU PPI.
|
||||
|
||||
**/
|
||||
VOID
|
||||
IoMmuInit (
|
||||
OUT EDKII_IOMMU_PPI **IoMmu
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@@ -4,7 +4,7 @@
|
||||
# It produces gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
# which is used to enable recovery function from USB Drivers.
|
||||
#
|
||||
# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions
|
||||
@@ -43,6 +43,7 @@
|
||||
EhciSched.h
|
||||
EhciUrb.h
|
||||
UsbHcMem.h
|
||||
DmaMem.c
|
||||
|
||||
|
||||
[Packages]
|
||||
@@ -61,7 +62,8 @@
|
||||
[Ppis]
|
||||
gPeiUsb2HostControllerPpiGuid ## PRODUCES
|
||||
gPeiUsbControllerPpiGuid ## CONSUMES
|
||||
|
||||
gEdkiiIoMmuPpiGuid ## CONSUMES
|
||||
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
|
||||
|
@@ -2,7 +2,7 @@
|
||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
which is used to enable recovery function from USB Drivers.
|
||||
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -107,11 +107,13 @@ EhcInitSched (
|
||||
IN PEI_USB2_HC_DEV *Ehc
|
||||
)
|
||||
{
|
||||
VOID *Buf;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
VOID *Map;
|
||||
UINTN Index;
|
||||
UINT32 *Desc;
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS PciAddr;
|
||||
|
||||
//
|
||||
// First initialize the periodical schedule data:
|
||||
@@ -124,15 +126,19 @@ EhcInitSched (
|
||||
// The Frame List ocupies 4K bytes,
|
||||
// and must be aligned on 4-Kbyte boundaries.
|
||||
//
|
||||
Status = PeiServicesAllocatePages (
|
||||
EfiBootServicesCode,
|
||||
Status = IoMmuAllocateBuffer (
|
||||
Ehc->IoMmu,
|
||||
1,
|
||||
&PhyAddr
|
||||
&Buf,
|
||||
&PhyAddr,
|
||||
&Map
|
||||
);
|
||||
|
||||
Map = NULL;
|
||||
Ehc->PeriodFrameHost = (VOID *)(UINTN)PhyAddr;
|
||||
Ehc->PeriodFrame = (VOID *)(UINTN)PhyAddr;
|
||||
if (EFI_ERROR (Status) || (Buf == NULL)) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Ehc->PeriodFrame = Buf;
|
||||
Ehc->PeriodFrameMap = Map;
|
||||
Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr);
|
||||
|
||||
@@ -161,19 +167,20 @@ EhcInitSched (
|
||||
// Initialize the frame list entries then set the registers
|
||||
//
|
||||
Desc = (UINT32 *) Ehc->PeriodFrame;
|
||||
|
||||
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (PEI_EHC_QH));
|
||||
for (Index = 0; Index < EHC_FRAME_LEN; Index++) {
|
||||
Desc[Index] = QH_LINK (Ehc->PeriodOne, EHC_TYPE_QH, FALSE);
|
||||
Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
|
||||
}
|
||||
|
||||
EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));
|
||||
EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (PhyAddr));
|
||||
|
||||
//
|
||||
// Second initialize the asynchronous schedule:
|
||||
// Only need to set the AsynListAddr register to
|
||||
// the reclamation header
|
||||
//
|
||||
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (Ehc->ReclaimHead));
|
||||
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (PEI_EHC_QH));
|
||||
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -192,26 +199,27 @@ EhcFreeSched (
|
||||
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, 0);
|
||||
|
||||
if (Ehc->PeriodOne != NULL) {
|
||||
UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (PEI_EHC_QH));
|
||||
UsbHcFreeMem (Ehc, Ehc->MemPool, Ehc->PeriodOne, sizeof (PEI_EHC_QH));
|
||||
Ehc->PeriodOne = NULL;
|
||||
}
|
||||
|
||||
if (Ehc->ReclaimHead != NULL) {
|
||||
UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (PEI_EHC_QH));
|
||||
UsbHcFreeMem (Ehc, Ehc->MemPool, Ehc->ReclaimHead, sizeof (PEI_EHC_QH));
|
||||
Ehc->ReclaimHead = NULL;
|
||||
}
|
||||
|
||||
if (Ehc->ShortReadStop != NULL) {
|
||||
UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (PEI_EHC_QTD));
|
||||
UsbHcFreeMem (Ehc, Ehc->MemPool, Ehc->ShortReadStop, sizeof (PEI_EHC_QTD));
|
||||
Ehc->ShortReadStop = NULL;
|
||||
}
|
||||
|
||||
if (Ehc->MemPool != NULL) {
|
||||
UsbHcFreeMemPool (Ehc->MemPool);
|
||||
UsbHcFreeMemPool (Ehc, Ehc->MemPool);
|
||||
Ehc->MemPool = NULL;
|
||||
}
|
||||
|
||||
if (Ehc->PeriodFrame != NULL) {
|
||||
IoMmuFreeBuffer (Ehc->IoMmu, 1, Ehc->PeriodFrame, Ehc->PeriodFrameMap);
|
||||
Ehc->PeriodFrame = NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
which is used to enable recovery function from USB Drivers.
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -301,7 +301,7 @@ EhcFreeQtds (
|
||||
Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);
|
||||
|
||||
RemoveEntryList (&Qtd->QtdList);
|
||||
UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));
|
||||
UsbHcFreeMem (Ehc, Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,13 +318,21 @@ EhcFreeUrb (
|
||||
IN PEI_URB *Urb
|
||||
)
|
||||
{
|
||||
if (Urb->RequestPhy != NULL) {
|
||||
IoMmuUnmap (Ehc->IoMmu, Urb->RequestMap);
|
||||
}
|
||||
|
||||
if (Urb->DataMap != NULL) {
|
||||
IoMmuUnmap (Ehc->IoMmu, Urb->DataMap);
|
||||
}
|
||||
|
||||
if (Urb->Qh != NULL) {
|
||||
//
|
||||
// Ensure that this queue head has been unlinked from the
|
||||
// schedule data structures. Free all the associated QTDs
|
||||
//
|
||||
EhcFreeQtds (Ehc, &Urb->Qh->Qtds);
|
||||
UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));
|
||||
UsbHcFreeMem (Ehc, Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,14 +535,12 @@ EhcCreateUrb (
|
||||
{
|
||||
USB_ENDPOINT *Ep;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
EDKII_IOMMU_OPERATION MapOp;
|
||||
EFI_STATUS Status;
|
||||
UINTN Len;
|
||||
PEI_URB *Urb;
|
||||
VOID *Map;
|
||||
|
||||
|
||||
Map = NULL;
|
||||
|
||||
Urb = Ehc->Urb;
|
||||
Urb->Signature = EHC_URB_SIG;
|
||||
InitializeListHead (&Urb->UrbList);
|
||||
@@ -571,13 +577,20 @@ EhcCreateUrb (
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Urb->RequestPhy = NULL;
|
||||
Urb->RequestMap = NULL;
|
||||
Urb->DataPhy = NULL;
|
||||
Urb->DataMap = NULL;
|
||||
|
||||
//
|
||||
// Map the request and user data
|
||||
//
|
||||
if (Request != NULL) {
|
||||
Len = sizeof (EFI_USB_DEVICE_REQUEST);
|
||||
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Request ;
|
||||
if ( (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
|
||||
MapOp = EdkiiIoMmuOperationBusMasterRead;
|
||||
Status = IoMmuMap (Ehc->IoMmu, MapOp, Request, &Len, &PhyAddr, &Map);
|
||||
|
||||
if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
@@ -587,8 +600,16 @@ EhcCreateUrb (
|
||||
|
||||
if (Data != NULL) {
|
||||
Len = DataLen;
|
||||
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Data ;
|
||||
if ( (Len != DataLen)) {
|
||||
|
||||
if (Ep->Direction == EfiUsbDataIn) {
|
||||
MapOp = EdkiiIoMmuOperationBusMasterWrite;
|
||||
} else {
|
||||
MapOp = EdkiiIoMmuOperationBusMasterRead;
|
||||
}
|
||||
|
||||
Status = IoMmuMap (Ehc->IoMmu, MapOp, Data, &Len, &PhyAddr, &Map);
|
||||
|
||||
if (EFI_ERROR (Status) || (Len != DataLen)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||
which is used to enable recovery function from USB Drivers.
|
||||
|
||||
Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -79,16 +79,18 @@ UsbHcAllocMemBlock (
|
||||
|
||||
Block->Bits = (UINT8 *)(UINTN)TempPtr;
|
||||
|
||||
|
||||
Status = PeiServicesAllocatePages (
|
||||
EfiBootServicesCode,
|
||||
Status = IoMmuAllocateBuffer (
|
||||
Ehc->IoMmu,
|
||||
Pages,
|
||||
&TempPtr
|
||||
(VOID **) &BufHost,
|
||||
&MappedAddr,
|
||||
&Mapping
|
||||
);
|
||||
ZeroMem ((VOID *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
ZeroMem (BufHost, Pages*EFI_PAGE_SIZE);
|
||||
|
||||
BufHost = (VOID *)(UINTN)TempPtr;
|
||||
MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost;
|
||||
//
|
||||
// Check whether the data structure used by the host controller
|
||||
// should be restricted into the same 4G
|
||||
@@ -109,17 +111,21 @@ UsbHcAllocMemBlock (
|
||||
/**
|
||||
Free the memory block from the memory pool.
|
||||
|
||||
@param Ehc The EHCI device.
|
||||
@param Pool The memory pool to free the block from.
|
||||
@param Block The memory block to free.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UsbHcFreeMemBlock (
|
||||
IN PEI_USB2_HC_DEV *Ehc,
|
||||
IN USBHC_MEM_POOL *Pool,
|
||||
IN USBHC_MEM_BLOCK *Block
|
||||
)
|
||||
{
|
||||
ASSERT ((Pool != NULL) && (Block != NULL));
|
||||
|
||||
IoMmuFreeBuffer (Ehc->IoMmu, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost, Block->Mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,6 +201,54 @@ UsbHcAllocMemFromBlock (
|
||||
return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the corresponding pci bus address according to the Mem parameter.
|
||||
|
||||
@param Pool The memory pool of the host controller.
|
||||
@param Mem The pointer to host memory.
|
||||
@param Size The size of the memory region.
|
||||
|
||||
@return the pci memory address
|
||||
**/
|
||||
EFI_PHYSICAL_ADDRESS
|
||||
UsbHcGetPciAddressForHostMem (
|
||||
IN USBHC_MEM_POOL *Pool,
|
||||
IN VOID *Mem,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
USBHC_MEM_BLOCK *Head;
|
||||
USBHC_MEM_BLOCK *Block;
|
||||
UINTN AllocSize;
|
||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||
UINTN Offset;
|
||||
|
||||
Head = Pool->Head;
|
||||
AllocSize = USBHC_MEM_ROUND (Size);
|
||||
|
||||
if (Mem == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (Block = Head; Block != NULL; Block = Block->Next) {
|
||||
//
|
||||
// scan the memory block list for the memory block that
|
||||
// completely contains the allocated memory.
|
||||
//
|
||||
if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT ((Block != NULL));
|
||||
//
|
||||
// calculate the pci memory address for host memory address.
|
||||
//
|
||||
Offset = (UINT8 *)Mem - Block->BufHost;
|
||||
PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
|
||||
return PhyAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
Insert the memory block to the pool's list of the blocks.
|
||||
|
||||
@@ -317,6 +371,7 @@ UsbHcInitMemPool (
|
||||
/**
|
||||
Release the memory management pool.
|
||||
|
||||
@param Ehc The EHCI device.
|
||||
@param Pool The USB memory pool to free.
|
||||
|
||||
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
||||
@@ -325,6 +380,7 @@ UsbHcInitMemPool (
|
||||
**/
|
||||
EFI_STATUS
|
||||
UsbHcFreeMemPool (
|
||||
IN PEI_USB2_HC_DEV *Ehc,
|
||||
IN USBHC_MEM_POOL *Pool
|
||||
)
|
||||
{
|
||||
@@ -337,11 +393,11 @@ UsbHcFreeMemPool (
|
||||
// UsbHcUnlinkMemBlock can't be used to unlink and free the
|
||||
// first block.
|
||||
//
|
||||
for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
|
||||
UsbHcFreeMemBlock (Pool, Block);
|
||||
for (Block = Pool->Head->Next; Block != NULL; Block = Block->Next) {
|
||||
UsbHcFreeMemBlock (Ehc, Pool, Block);
|
||||
}
|
||||
|
||||
UsbHcFreeMemBlock (Pool, Pool->Head);
|
||||
UsbHcFreeMemBlock (Ehc, Pool, Pool->Head);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -425,6 +481,7 @@ UsbHcAllocateMem (
|
||||
/**
|
||||
Free the allocated memory back to the memory pool.
|
||||
|
||||
@param Ehc The EHCI device.
|
||||
@param Pool The memory pool of the host controller.
|
||||
@param Mem The memory to free.
|
||||
@param Size The size of the memory to free.
|
||||
@@ -432,6 +489,7 @@ UsbHcAllocateMem (
|
||||
**/
|
||||
VOID
|
||||
UsbHcFreeMem (
|
||||
IN PEI_USB2_HC_DEV *Ehc,
|
||||
IN USBHC_MEM_POOL *Pool,
|
||||
IN VOID *Mem,
|
||||
IN UINTN Size
|
||||
@@ -486,7 +544,7 @@ UsbHcFreeMem (
|
||||
// Release the current memory block if it is empty and not the head
|
||||
//
|
||||
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
|
||||
UsbHcFreeMemBlock (Pool, Block);
|
||||
UsbHcFreeMemBlock (Ehc, Pool, Block);
|
||||
}
|
||||
|
||||
return ;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Private Header file for Usb Host Controller PEIM
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@@ -74,4 +74,20 @@ typedef struct _USBHC_MEM_POOL {
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
Calculate the corresponding pci bus address according to the Mem parameter.
|
||||
|
||||
@param Pool The memory pool of the host controller.
|
||||
@param Mem The pointer to host memory.
|
||||
@param Size The size of the memory region.
|
||||
|
||||
@return the pci memory address
|
||||
**/
|
||||
EFI_PHYSICAL_ADDRESS
|
||||
UsbHcGetPciAddressForHostMem (
|
||||
IN USBHC_MEM_POOL *Pool,
|
||||
IN VOID *Mem,
|
||||
IN UINTN Size
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@@ -3,7 +3,7 @@
|
||||
NVM Express specification.
|
||||
|
||||
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
|
||||
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -359,6 +359,7 @@ NvmExpressPassThru (
|
||||
{
|
||||
NVME_CONTROLLER_PRIVATE_DATA *Private;
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS PreviousStatus;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
NVME_SQ *Sq;
|
||||
NVME_CQ *Cq;
|
||||
@@ -498,7 +499,8 @@ NvmExpressPassThru (
|
||||
// these two cmds are special which requires their data buffer must support simultaneous access by both the
|
||||
// processor and a PCI Bus Master. It's caller's responsbility to ensure this.
|
||||
//
|
||||
if (((Sq->Opc & (BIT0 | BIT1)) != 0) && (Sq->Opc != NVME_ADMIN_CRIOCQ_CMD) && (Sq->Opc != NVME_ADMIN_CRIOSQ_CMD)) {
|
||||
if (((Sq->Opc & (BIT0 | BIT1)) != 0) &&
|
||||
!((Packet->QueueType == NVME_ADMIN_QUEUE) && ((Sq->Opc == NVME_ADMIN_CRIOCQ_CMD) || (Sq->Opc == NVME_ADMIN_CRIOSQ_CMD)))) {
|
||||
if ((Packet->TransferLength == 0) || (Packet->TransferBuffer == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
@@ -692,13 +694,14 @@ NvmExpressPassThru (
|
||||
NvmeDumpStatus(Cq);
|
||||
DEBUG_CODE_END();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Private->CqHdbl[QueueId].Cqh ^= 1) == 0) {
|
||||
Private->Pt[QueueId] ^= 1;
|
||||
}
|
||||
|
||||
Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);
|
||||
PreviousStatus = Status;
|
||||
Status = PciIo->Mem.Write (
|
||||
PciIo,
|
||||
EfiPciIoWidthUint32,
|
||||
@@ -707,6 +710,9 @@ NvmExpressPassThru (
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
// The return status of PciIo->Mem.Write should not override
|
||||
// previous status if previous status contains error.
|
||||
Status = EFI_ERROR (PreviousStatus) ? PreviousStatus : Status;
|
||||
|
||||
//
|
||||
// For now, the code does not support the non-blocking feature for admin queue.
|
||||
|
@@ -8,7 +8,7 @@
|
||||
PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each
|
||||
PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol.
|
||||
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@@ -42,6 +42,7 @@ UINT64 gAllZero = 0;
|
||||
|
||||
EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
|
||||
EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
|
||||
EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
|
||||
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {
|
||||
@@ -239,8 +240,14 @@ PciBusDriverBindingStart (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||
EFI_STATUS Status;
|
||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||
|
||||
//
|
||||
// Initialize PciRootBridgeIo to suppress incorrect compiler warning.
|
||||
//
|
||||
PciRootBridgeIo = NULL;
|
||||
|
||||
//
|
||||
// Check RemainingDevicePath validation
|
||||
@@ -284,6 +291,14 @@ PciBusDriverBindingStart (
|
||||
);
|
||||
}
|
||||
|
||||
if (mIoMmuProtocol == NULL) {
|
||||
gBS->LocateProtocol (
|
||||
&gEdkiiIoMmuProtocolGuid,
|
||||
NULL,
|
||||
(VOID **) &mIoMmuProtocol
|
||||
);
|
||||
}
|
||||
|
||||
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
|
||||
gFullEnumeration = FALSE;
|
||||
} else {
|
||||
@@ -312,12 +327,34 @@ PciBusDriverBindingStart (
|
||||
ParentDevicePath
|
||||
);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
//
|
||||
// Enumerate the entire host bridge
|
||||
// After enumeration, a database that records all the device information will be created
|
||||
//
|
||||
//
|
||||
Status = PciEnumerator (Controller);
|
||||
if (gFullEnumeration) {
|
||||
//
|
||||
// Get the rootbridge Io protocol to find the host bridge handle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller,
|
||||
&gEfiPciRootBridgeIoProtocolGuid,
|
||||
(VOID **) &PciRootBridgeIo,
|
||||
gPciBusDriverBinding.DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = PciEnumerator (Controller, PciRootBridgeIo->ParentHandle);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// If PCI bus has already done the full enumeration, never do it again
|
||||
//
|
||||
Status = PciEnumeratorLight (Controller);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
@@ -328,7 +365,19 @@ PciBusDriverBindingStart (
|
||||
//
|
||||
StartPciDevices (Controller);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
if (gFullEnumeration) {
|
||||
gFullEnumeration = FALSE;
|
||||
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&PciRootBridgeIo->ParentHandle,
|
||||
&gEfiPciEnumerationCompleteProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Protocol/IncompatiblePciDeviceSupport.h>
|
||||
#include <Protocol/PciOverride.h>
|
||||
#include <Protocol/PciEnumerationComplete.h>
|
||||
#include <Protocol/IoMmu.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
|
@@ -95,6 +95,7 @@
|
||||
gEfiPciRootBridgeIoProtocolGuid ## TO_START
|
||||
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
||||
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user