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) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
# Portions copyright (c) 2011 - 2014, ARM Ltd. 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>
|
# 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_DLL = ENV(VS2015_PREFIX)Common7\IDE;DEF(VS2015x86_BIN)
|
||||||
DEFINE VS2015x86_BINX64 = DEF(VS2015x86_BIN)\x86_amd64
|
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 WINSDK_BIN = ENV(WINSDK_PREFIX)
|
||||||
DEFINE WINSDKx86_BIN = ENV(WINSDKx86_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 WINSDK81_BIN = ENV(WINSDK81_PREFIX)x86\
|
||||||
DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x64
|
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
|
# These defines are needed for certain Microsoft Visual Studio tools that
|
||||||
# are used by other toolchains. An example is that ICC on Windows normally
|
# are used by other toolchains. An example is that ICC on Windows normally
|
||||||
# uses Microsoft's nmake.exe.
|
# 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:
|
# Required to build platforms or ACPI tables:
|
||||||
# Intel(r) ACPI Compiler (iasl.exe) from
|
# Intel(r) ACPI Compiler (iasl.exe) from
|
||||||
# https://acpica.org/downloads
|
# 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:
|
# DDK3790 -win32- Requires:
|
||||||
# Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830
|
# Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830
|
||||||
# Optional:
|
# 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
|
*_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)
|
# 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
|
*_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 support
|
||||||
#
|
#
|
||||||
|
|
||||||
*_XCODE5_*_*_FAMILY = GCC
|
*_XCODE5_*_*_FAMILY = GCC
|
||||||
*_XCODE5_*_*_BUILDRULEFAMILY = XCODE
|
*_XCODE5_*_*_BUILDRULEFAMILY = XCODE
|
||||||
*_XCODE5_*_*_BUILDRULEORDER = S s nasm
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# use xcode-select to change Xcode version of command line tools
|
# 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
|
*_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)
|
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 -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 -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
|
# 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_*_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
|
*_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)
|
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 -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 -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
|
## @file
|
||||||
# GNU/Linux makefile for Base Tools project build.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
@@ -24,12 +24,10 @@ subdirs: $(SUBDIRS)
|
|||||||
$(SUBDIRS):
|
$(SUBDIRS):
|
||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
|
Tests: $(SOURCE_SUBDIRS)
|
||||||
|
|
||||||
.PHONY: $(CLEAN_SUBDIRS)
|
.PHONY: $(CLEAN_SUBDIRS)
|
||||||
$(CLEAN_SUBDIRS):
|
$(CLEAN_SUBDIRS):
|
||||||
-$(MAKE) -C $(@:-clean=) clean
|
-$(MAKE) -C $(@:-clean=) clean
|
||||||
|
|
||||||
clean: $(CLEAN_SUBDIRS)
|
clean: $(CLEAN_SUBDIRS)
|
||||||
|
|
||||||
test:
|
|
||||||
@$(MAKE) -C Tests
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = BootSectImage
|
APPNAME = BootSectImage
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = Brotli
|
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) {
|
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) {
|
if (Sd->mCompSize > 0) {
|
||||||
//
|
//
|
||||||
@@ -194,12 +194,16 @@ Returns:
|
|||||||
UINT16 Avail;
|
UINT16 Avail;
|
||||||
UINT16 NextCode;
|
UINT16 NextCode;
|
||||||
UINT16 Mask;
|
UINT16 Mask;
|
||||||
|
UINT16 MaxTableLength;
|
||||||
|
|
||||||
for (Index = 1; Index <= 16; Index++) {
|
for (Index = 1; Index <= 16; Index++) {
|
||||||
Count[Index] = 0;
|
Count[Index] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Index = 0; Index < NumOfChar; Index++) {
|
for (Index = 0; Index < NumOfChar; Index++) {
|
||||||
|
if (BitLen[Index] > 16) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Count[BitLen[Index]]++;
|
Count[BitLen[Index]]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,6 +241,7 @@ Returns:
|
|||||||
|
|
||||||
Avail = NumOfChar;
|
Avail = NumOfChar;
|
||||||
Mask = (UINT16) (1U << (15 - TableBits));
|
Mask = (UINT16) (1U << (15 - TableBits));
|
||||||
|
MaxTableLength = (UINT16) (1U << TableBits);
|
||||||
|
|
||||||
for (Char = 0; Char < NumOfChar; Char++) {
|
for (Char = 0; Char < NumOfChar; Char++) {
|
||||||
|
|
||||||
@@ -250,6 +255,9 @@ Returns:
|
|||||||
if (Len <= TableBits) {
|
if (Len <= TableBits) {
|
||||||
|
|
||||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||||
|
if (Index >= MaxTableLength) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Table[Index] = Char;
|
Table[Index] = Char;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,13 +651,23 @@ Returns: (VOID)
|
|||||||
|
|
||||||
BytesRemain--;
|
BytesRemain--;
|
||||||
while ((INT16) (BytesRemain) >= 0) {
|
while ((INT16) (BytesRemain) >= 0) {
|
||||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
|
||||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
if (DataIdx >= Sd->mOrigSize) {
|
||||||
|
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||||
|
|
||||||
BytesRemain--;
|
BytesRemain--;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// Once mOutBuf is fully filled, directly return
|
||||||
|
//
|
||||||
|
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,6 +702,7 @@ Returns:
|
|||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
UINT8 *Src;
|
UINT8 *Src;
|
||||||
|
UINT32 CompSize;
|
||||||
|
|
||||||
*ScratchSize = sizeof (SCRATCH_DATA);
|
*ScratchSize = sizeof (SCRATCH_DATA);
|
||||||
|
|
||||||
@@ -692,7 +711,13 @@ Returns:
|
|||||||
return EFI_INVALID_PARAMETER;
|
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);
|
*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;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,7 +777,7 @@ Returns:
|
|||||||
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
|
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
|
||||||
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 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;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
# VPATH = ..
|
# VPATH = ..
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = EfiLdrImage
|
APPNAME = EfiLdrImage
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = EfiRom
|
APPNAME = EfiRom
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# GNU/Linux makefile for C tools build.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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.
|
# 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
|
# If HOST_ARCH is not defined, then we use 'uname -m' to attempt
|
||||||
# try to figure out the appropriate ARCH.
|
# try to figure out the appropriate HOST_ARCH.
|
||||||
#
|
#
|
||||||
uname_m = $(shell uname -m)
|
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)))
|
ifneq (,$(strip $(filter $(uname_m), x86_64 amd64)))
|
||||||
ARCH=X64
|
HOST_ARCH=X64
|
||||||
endif
|
endif
|
||||||
ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
|
ifeq ($(patsubst i%86,IA32,$(uname_m)),IA32)
|
||||||
ARCH=IA32
|
HOST_ARCH=IA32
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring aarch64,$(uname_m)))
|
ifneq (,$(findstring aarch64,$(uname_m)))
|
||||||
ARCH=AARCH64
|
HOST_ARCH=AARCH64
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring arm,$(uname_m)))
|
ifneq (,$(findstring arm,$(uname_m)))
|
||||||
ARCH=ARM
|
HOST_ARCH=ARM
|
||||||
endif
|
endif
|
||||||
ifndef ARCH
|
ifndef HOST_ARCH
|
||||||
$(info Could not detected ARCH from uname results)
|
$(info Could not detected HOST_ARCH from uname results)
|
||||||
$(error ARCH is not defined!)
|
$(error HOST_ARCH is not defined!)
|
||||||
endif
|
endif
|
||||||
$(info Detected ARCH of $(ARCH) using uname.)
|
$(info Detected HOST_ARCH of $(HOST_ARCH) using uname.)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
export ARCH
|
export HOST_ARCH
|
||||||
|
|
||||||
MAKEROOT = .
|
MAKEROOT = .
|
||||||
|
|
||||||
include Makefiles/header.makefile
|
include Makefiles/header.makefile
|
||||||
|
|
||||||
all: makerootdir subdirs $(MAKEROOT)/libs
|
all: makerootdir subdirs
|
||||||
@echo Finished building BaseTools C Tools with ARCH=$(ARCH)
|
@echo Finished building BaseTools C Tools with HOST_ARCH=$(HOST_ARCH)
|
||||||
|
|
||||||
LIBRARIES = Common
|
LIBRARIES = Common
|
||||||
|
VFRAUTOGEN = VfrCompile/VfrLexer.h
|
||||||
# NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage
|
# NON_BUILDABLE_APPLICATIONS = GenBootSector BootSectImage
|
||||||
APPLICATIONS = \
|
APPLICATIONS = \
|
||||||
|
BrotliCompress \
|
||||||
|
VfrCompile \
|
||||||
GnuGenBootSector \
|
GnuGenBootSector \
|
||||||
BootSectImage \
|
BootSectImage \
|
||||||
BrotliCompress \
|
|
||||||
EfiLdrImage \
|
EfiLdrImage \
|
||||||
EfiRom \
|
EfiRom \
|
||||||
GenFfs \
|
GenFfs \
|
||||||
@@ -65,11 +67,13 @@ APPLICATIONS = \
|
|||||||
LzmaCompress \
|
LzmaCompress \
|
||||||
Split \
|
Split \
|
||||||
TianoCompress \
|
TianoCompress \
|
||||||
VolInfo \
|
VolInfo
|
||||||
VfrCompile
|
|
||||||
|
|
||||||
SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
|
SUBDIRS := $(LIBRARIES) $(APPLICATIONS)
|
||||||
|
|
||||||
|
$(LIBRARIES): $(MAKEROOT)/libs
|
||||||
|
$(APPLICATIONS): $(LIBRARIES) $(MAKEROOT)/bin $(VFRAUTOGEN)
|
||||||
|
|
||||||
.PHONY: outputdirs
|
.PHONY: outputdirs
|
||||||
makerootdir:
|
makerootdir:
|
||||||
-mkdir -p $(MAKEROOT)
|
-mkdir -p $(MAKEROOT)
|
||||||
@@ -83,6 +87,9 @@ $(SUBDIRS):
|
|||||||
$(patsubst %,%-clean,$(sort $(SUBDIRS))):
|
$(patsubst %,%-clean,$(sort $(SUBDIRS))):
|
||||||
-$(MAKE) -C $(@:-clean=) clean
|
-$(MAKE) -C $(@:-clean=) clean
|
||||||
|
|
||||||
|
$(VFRAUTOGEN): VfrCompile/VfrSyntax.g
|
||||||
|
$(MAKE) -C VfrCompile VfrLexer.h
|
||||||
|
|
||||||
clean: $(patsubst %,%-clean,$(sort $(SUBDIRS)))
|
clean: $(patsubst %,%-clean,$(sort $(SUBDIRS)))
|
||||||
|
|
||||||
clean: localClean
|
clean: localClean
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenCrc32
|
APPNAME = GenCrc32
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenFfs
|
APPNAME = GenFfs
|
||||||
|
|||||||
@@ -48,14 +48,17 @@ STATIC CHAR8 *mFfsFileType[] = {
|
|||||||
|
|
||||||
STATIC CHAR8 *mAlignName[] = {
|
STATIC CHAR8 *mAlignName[] = {
|
||||||
"1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
|
"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[] = {
|
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};
|
STATIC EFI_GUID mZeroGuid = {0};
|
||||||
|
|
||||||
@@ -140,12 +143,13 @@ Returns:
|
|||||||
fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");
|
fprintf (stdout, " -s, --checksum Indicates to calculate file checksum.\n");
|
||||||
fprintf (stdout, " -a FileAlign, --align FileAlign\n\
|
fprintf (stdout, " -a FileAlign, --align FileAlign\n\
|
||||||
FileAlign points to file alignment, which only support\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\
|
fprintf (stdout, " -i SectionFile, --sectionfile SectionFile\n\
|
||||||
Section file will be contained in this FFS file.\n");
|
Section file will be contained in this FFS file.\n");
|
||||||
fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\
|
fprintf (stdout, " -n SectionAlign, --sectionalign SectionAlign\n\
|
||||||
SectionAlign points to section alignment, which support\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");
|
with sectionfile to point its alignment in FFS file.\n");
|
||||||
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\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");
|
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
|
||||||
@@ -164,7 +168,7 @@ StringtoAlignment (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Converts Align String to align value (1~64K).
|
Converts Align String to align value (1~16M).
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
@@ -889,7 +893,12 @@ Returns:
|
|||||||
}
|
}
|
||||||
VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
|
VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
|
||||||
|
|
||||||
|
//FfsAlign larger than 7, set FFS_ATTRIB_DATA_ALIGNMENT2
|
||||||
|
if (FfsAlign < 8) {
|
||||||
FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
|
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
|
// 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,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenFv
|
APPNAME = GenFv
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
This file contains the internal functions required to generate a Firmware Volume.
|
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) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
||||||
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
|
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
@@ -464,57 +464,97 @@ Returns:
|
|||||||
case 0:
|
case 0:
|
||||||
//
|
//
|
||||||
// 1 byte alignment
|
// 1 byte alignment
|
||||||
|
//if bit 1 have set, 128K byte alignmnet
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 17;
|
||||||
|
} else {
|
||||||
*Alignment = 0;
|
*Alignment = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
//
|
//
|
||||||
// 16 byte alignment
|
// 16 byte alignment
|
||||||
|
//if bit 1 have set, 256K byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 18;
|
||||||
|
} else {
|
||||||
*Alignment = 4;
|
*Alignment = 4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
//
|
//
|
||||||
// 128 byte alignment
|
// 128 byte alignment
|
||||||
|
//if bit 1 have set, 512K byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 19;
|
||||||
|
} else {
|
||||||
*Alignment = 7;
|
*Alignment = 7;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
//
|
//
|
||||||
// 512 byte alignment
|
// 512 byte alignment
|
||||||
|
//if bit 1 have set, 1M byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 20;
|
||||||
|
} else {
|
||||||
*Alignment = 9;
|
*Alignment = 9;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
//
|
//
|
||||||
// 1K byte alignment
|
// 1K byte alignment
|
||||||
|
//if bit 1 have set, 2M byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 21;
|
||||||
|
} else {
|
||||||
*Alignment = 10;
|
*Alignment = 10;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
//
|
//
|
||||||
// 4K byte alignment
|
// 4K byte alignment
|
||||||
|
//if bit 1 have set, 4M byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 22;
|
||||||
|
} else {
|
||||||
*Alignment = 12;
|
*Alignment = 12;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
//
|
//
|
||||||
// 32K byte alignment
|
// 32K byte alignment
|
||||||
|
//if bit 1 have set , 8M byte alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 23;
|
||||||
|
} else {
|
||||||
*Alignment = 15;
|
*Alignment = 15;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
//
|
//
|
||||||
// 64K byte alignment
|
// 64K byte alignment
|
||||||
|
//if bit 1 have set, 16M alignment
|
||||||
//
|
//
|
||||||
|
if (FfsFile->Attributes & FFS_ATTRIB_DATA_ALIGNMENT2) {
|
||||||
|
*Alignment = 24;
|
||||||
|
} else {
|
||||||
*Alignment = 16;
|
*Alignment = 16;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1060,7 +1100,7 @@ Returns:
|
|||||||
// Clear the alignment bits: these have become meaningless now that we have
|
// Clear the alignment bits: these have become meaningless now that we have
|
||||||
// adjusted the padding section.
|
// 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
|
// 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,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenFw
|
APPNAME = GenFw
|
||||||
|
|||||||
@@ -2781,6 +2781,7 @@ Returns:
|
|||||||
EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;
|
EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;
|
||||||
EFI_IMAGE_SECTION_HEADER *SectionHeader;
|
EFI_IMAGE_SECTION_HEADER *SectionHeader;
|
||||||
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
|
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
|
||||||
|
EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry;
|
||||||
UINT32 *NewTimeStamp;
|
UINT32 *NewTimeStamp;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -2809,6 +2810,7 @@ Returns:
|
|||||||
// Resource Directory entry need to review.
|
// Resource Directory entry need to review.
|
||||||
//
|
//
|
||||||
Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
|
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) {
|
if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
|
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
|
||||||
if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
||||||
@@ -2828,7 +2830,6 @@ Returns:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
|
|
||||||
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
|
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
|
||||||
if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \
|
||||||
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
|
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {
|
||||||
@@ -2892,6 +2893,19 @@ Returns:
|
|||||||
memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
|
memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
|
||||||
memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
|
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;
|
return EFI_SUCCESS;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenPage
|
APPNAME = GenPage
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenSec
|
APPNAME = GenSec
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED",
|
|||||||
|
|
||||||
STATIC CHAR8 *mAlignName[] = {
|
STATIC CHAR8 *mAlignName[] = {
|
||||||
"1", "2", "4", "8", "16", "32", "64", "128", "256", "512",
|
"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");
|
used in Ver section.\n");
|
||||||
fprintf (stdout, " --sectionalign SectionAlign\n\
|
fprintf (stdout, " --sectionalign SectionAlign\n\
|
||||||
SectionAlign points to section alignment, which support\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");
|
order that the section file is input.\n");
|
||||||
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\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");
|
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
|
||||||
@@ -356,7 +357,7 @@ StringtoAlignment (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Converts Align String to align value (1~64K).
|
Converts Align String to align value (1~16M).
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GenVtf
|
APPNAME = GenVtf
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = GnuGenBootSector
|
APPNAME = GnuGenBootSector
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
@par Revision Reference:
|
@par Revision Reference:
|
||||||
Version 1.4.
|
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
|
This program and the accompanying materials are licensed and made available
|
||||||
under the terms and conditions of the BSD License which accompanies this
|
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.
|
// FFS File Attributes.
|
||||||
//
|
//
|
||||||
#define FFS_ATTRIB_LARGE_FILE 0x01
|
#define FFS_ATTRIB_LARGE_FILE 0x01
|
||||||
|
#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02
|
||||||
#define FFS_ATTRIB_FIXED 0x04
|
#define FFS_ATTRIB_FIXED 0x04
|
||||||
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
|
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
|
||||||
#define FFS_ATTRIB_CHECKSUM 0x40
|
#define FFS_ATTRIB_CHECKSUM 0x40
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = LzmaCompress
|
APPNAME = LzmaCompress
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH = IA32
|
HOST_ARCH = IA32
|
||||||
|
|
||||||
!INCLUDE Makefiles\ms.common
|
!INCLUDE Makefiles\ms.common
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
DEPFILES = $(OBJECTS:%.o=%.d)
|
DEPFILES = $(OBJECTS:%.o=%.d)
|
||||||
|
|
||||||
$(MAKEROOT)/libs-$(ARCH):
|
$(MAKEROOT)/libs-$(HOST_ARCH):
|
||||||
mkdir -p $(MAKEROOT)/libs-$(ARCH)
|
mkdir -p $(MAKEROOT)/libs-$(HOST_ARCH)
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: $(MAKEROOT)/libs-$(ARCH) $(LIBRARY)
|
install: $(MAKEROOT)/libs-$(HOST_ARCH) $(LIBRARY)
|
||||||
cp $(LIBRARY) $(MAKEROOT)/libs-$(ARCH)
|
cp $(LIBRARY) $(MAKEROOT)/libs-$(HOST_ARCH)
|
||||||
|
|
||||||
$(LIBRARY): $(OBJECTS)
|
$(LIBRARY): $(OBJECTS)
|
||||||
$(BUILD_AR) crs $@ $^
|
$(BUILD_AR) crs $@ $^
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
## @file
|
## @file
|
||||||
#
|
#
|
||||||
# The makefile can be invoked with
|
# The makefile can be invoked with
|
||||||
# ARCH = x86_64 or x64 for EM64T build
|
# HOST_ARCH = x86_64 or x64 for EM64T build
|
||||||
# ARCH = ia32 or IA32 for IA32 build
|
# HOST_ARCH = ia32 or IA32 for IA32 build
|
||||||
# ARCH = ia64 or IA64 for IA64 build
|
# HOST_ARCH = ia64 or IA64 for IA64 build
|
||||||
# ARCH = Arm or ARM for ARM build
|
# HOST_ARCH = Arm or ARM for ARM build
|
||||||
#
|
#
|
||||||
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
|
|
||||||
CYGWIN:=$(findstring CYGWIN, $(shell uname -s))
|
CYGWIN:=$(findstring CYGWIN, $(shell uname -s))
|
||||||
LINUX:=$(findstring Linux, $(shell uname -s))
|
LINUX:=$(findstring Linux, $(shell uname -s))
|
||||||
@@ -27,19 +27,19 @@ BUILD_AS ?= gcc
|
|||||||
BUILD_AR ?= ar
|
BUILD_AR ?= ar
|
||||||
BUILD_LD ?= ld
|
BUILD_LD ?= ld
|
||||||
LINKER ?= $(BUILD_CC)
|
LINKER ?= $(BUILD_CC)
|
||||||
ifeq ($(ARCH), IA32)
|
ifeq ($(HOST_ARCH), IA32)
|
||||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Ia32/
|
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Ia32/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH), X64)
|
ifeq ($(HOST_ARCH), X64)
|
||||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/X64/
|
ARCH_INCLUDE = -I $(MAKEROOT)/Include/X64/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH), ARM)
|
ifeq ($(HOST_ARCH), ARM)
|
||||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Arm/
|
ARCH_INCLUDE = -I $(MAKEROOT)/Include/Arm/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH), AARCH64)
|
ifeq ($(HOST_ARCH), AARCH64)
|
||||||
ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
|
ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ endif
|
|||||||
BUILD_LFLAGS =
|
BUILD_LFLAGS =
|
||||||
BUILD_CXXFLAGS = -Wno-unused-result
|
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
|
# 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
|
# 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!"
|
!ERROR "BASE_TOOLS_PATH is not set! Please run build_tools.bat at first!"
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IFNDEF ARCH
|
!IFNDEF HOST_ARCH
|
||||||
ARCH = IA32
|
HOST_ARCH = IA32
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
MAKE = nmake -nologo
|
MAKE = nmake -nologo
|
||||||
@@ -36,7 +36,7 @@ LIB_PATH = $(BASE_TOOLS_PATH)\Lib
|
|||||||
SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin
|
SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin
|
||||||
SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib
|
SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib
|
||||||
|
|
||||||
!IF "$(ARCH)"=="IA32"
|
!IF "$(HOST_ARCH)"=="IA32"
|
||||||
ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32
|
ARCH_INCLUDE = $(SOURCE_PATH)\Include\Ia32
|
||||||
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32
|
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32
|
||||||
LIB_PATH = $(BASE_TOOLS_PATH)\Lib\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
|
SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF "$(ARCH)"=="X64"
|
!IF "$(HOST_ARCH)"=="X64"
|
||||||
ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64
|
ARCH_INCLUDE = $(SOURCE_PATH)\Include\X64
|
||||||
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64
|
BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64
|
||||||
LIB_PATH = $(BASE_TOOLS_PATH)\Lib\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,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = Split
|
APPNAME = Split
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = TianoCompress
|
APPNAME = TianoCompress
|
||||||
|
|||||||
@@ -1753,6 +1753,7 @@ Returns:
|
|||||||
SCRATCH_DATA *Scratch;
|
SCRATCH_DATA *Scratch;
|
||||||
UINT8 *Src;
|
UINT8 *Src;
|
||||||
UINT32 OrigSize;
|
UINT32 OrigSize;
|
||||||
|
UINT32 CompSize;
|
||||||
|
|
||||||
SetUtilityName(UTILITY_NAME);
|
SetUtilityName(UTILITY_NAME);
|
||||||
|
|
||||||
@@ -1761,6 +1762,7 @@ Returns:
|
|||||||
OutBuffer = NULL;
|
OutBuffer = NULL;
|
||||||
Scratch = NULL;
|
Scratch = NULL;
|
||||||
OrigSize = 0;
|
OrigSize = 0;
|
||||||
|
CompSize = 0;
|
||||||
InputLength = 0;
|
InputLength = 0;
|
||||||
InputFileName = NULL;
|
InputFileName = NULL;
|
||||||
OutputFileName = NULL;
|
OutputFileName = NULL;
|
||||||
@@ -1979,15 +1981,25 @@ Returns:
|
|||||||
if (DebugMode) {
|
if (DebugMode) {
|
||||||
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
|
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
|
// Get Compressed file original size
|
||||||
//
|
//
|
||||||
Src = (UINT8 *)FileBuffer;
|
Src = (UINT8 *)FileBuffer;
|
||||||
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
|
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
|
// 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);
|
OutBuffer = (UINT8 *)malloc(OrigSize);
|
||||||
if (OutBuffer == NULL) {
|
if (OutBuffer == NULL) {
|
||||||
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
|
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) {
|
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) {
|
if (Sd->mCompSize > 0) {
|
||||||
//
|
//
|
||||||
@@ -2171,12 +2183,16 @@ Returns:
|
|||||||
UINT16 Mask;
|
UINT16 Mask;
|
||||||
UINT16 WordOfStart;
|
UINT16 WordOfStart;
|
||||||
UINT16 WordOfCount;
|
UINT16 WordOfCount;
|
||||||
|
UINT16 MaxTableLength;
|
||||||
|
|
||||||
for (Index = 0; Index <= 16; Index++) {
|
for (Index = 0; Index <= 16; Index++) {
|
||||||
Count[Index] = 0;
|
Count[Index] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Index = 0; Index < NumOfChar; Index++) {
|
for (Index = 0; Index < NumOfChar; Index++) {
|
||||||
|
if (BitLen[Index] > 16) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Count[BitLen[Index]]++;
|
Count[BitLen[Index]]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2220,6 +2236,7 @@ Returns:
|
|||||||
|
|
||||||
Avail = NumOfChar;
|
Avail = NumOfChar;
|
||||||
Mask = (UINT16) (1U << (15 - TableBits));
|
Mask = (UINT16) (1U << (15 - TableBits));
|
||||||
|
MaxTableLength = (UINT16) (1U << TableBits);
|
||||||
|
|
||||||
for (Char = 0; Char < NumOfChar; Char++) {
|
for (Char = 0; Char < NumOfChar; Char++) {
|
||||||
|
|
||||||
@@ -2233,6 +2250,9 @@ Returns:
|
|||||||
if (Len <= TableBits) {
|
if (Len <= TableBits) {
|
||||||
|
|
||||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||||
|
if (Index >= MaxTableLength) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Table[Index] = Char;
|
Table[Index] = Char;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2617,14 +2637,25 @@ Returns: (VOID)
|
|||||||
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
|
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
|
||||||
|
|
||||||
BytesRemain--;
|
BytesRemain--;
|
||||||
|
|
||||||
while ((INT16) (BytesRemain) >= 0) {
|
while ((INT16) (BytesRemain) >= 0) {
|
||||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
|
||||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||||
goto Done ;
|
goto Done ;
|
||||||
}
|
}
|
||||||
|
if (DataIdx >= Sd->mOrigSize) {
|
||||||
|
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||||
|
goto Done ;
|
||||||
|
}
|
||||||
|
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||||
|
|
||||||
BytesRemain--;
|
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.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
|
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = VfrCompile
|
APPNAME = VfrCompile
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#
|
#
|
||||||
ARCH ?= IA32
|
HOST_ARCH ?= IA32
|
||||||
MAKEROOT ?= ..
|
MAKEROOT ?= ..
|
||||||
|
|
||||||
APPNAME = VolInfo
|
APPNAME = VolInfo
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# parse FDF 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -2340,7 +2340,8 @@ class FdfParser(object):
|
|||||||
|
|
||||||
AlignValue = None
|
AlignValue = None
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
AlignValue = self.__Token
|
AlignValue = self.__Token
|
||||||
|
|
||||||
@@ -2608,7 +2609,8 @@ class FdfParser(object):
|
|||||||
|
|
||||||
AlignValue = None
|
AlignValue = None
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
AlignValue = self.__Token
|
AlignValue = self.__Token
|
||||||
|
|
||||||
@@ -2924,7 +2926,8 @@ class FdfParser(object):
|
|||||||
|
|
||||||
AlignValue = ""
|
AlignValue = ""
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||||
AlignValue = self.__Token
|
AlignValue = self.__Token
|
||||||
|
|
||||||
@@ -2988,7 +2991,8 @@ class FdfParser(object):
|
|||||||
CheckSum = True
|
CheckSum = True
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
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)
|
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
|
FvImageSectionObj.FvFileType = self.__Token
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment At Line ", self.FileName, self.CurrentLineNumber)
|
||||||
FvImageSectionObj.Alignment = self.__Token
|
FvImageSectionObj.Alignment = self.__Token
|
||||||
|
|
||||||
@@ -3129,7 +3134,8 @@ class FdfParser(object):
|
|||||||
EfiSectionObj.BuildNum = self.__Token
|
EfiSectionObj.BuildNum = self.__Token
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
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)
|
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
|
if (firstline.startswith("Archive member included ") and
|
||||||
firstline.endswith(" file (symbol)")):
|
firstline.endswith(" file (symbol)")):
|
||||||
return _parseForGCC(lines, efifilepath, varnames)
|
return _parseForGCC(lines, efifilepath, varnames)
|
||||||
|
if firstline.startswith("# Path:"):
|
||||||
|
return _parseForXcode(lines, efifilepath, varnames)
|
||||||
return _parseGeneral(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):
|
def _parseForGCC(lines, efifilepath, varnames):
|
||||||
""" Parse map file generated by GCC linker """
|
""" Parse map file generated by GCC linker """
|
||||||
status = 0
|
status = 0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# process data section generation
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -79,8 +79,10 @@ class DataSection (DataSectionClassObject):
|
|||||||
ImageObj = PeImageClass (Filename)
|
ImageObj = PeImageClass (Filename)
|
||||||
if ImageObj.SectionAlignment < 0x400:
|
if ImageObj.SectionAlignment < 0x400:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment)
|
self.Alignment = str (ImageObj.SectionAlignment)
|
||||||
else:
|
elif ImageObj.SectionAlignment < 0x100000:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||||
|
else:
|
||||||
|
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||||
|
|
||||||
NoStrip = True
|
NoStrip = True
|
||||||
if self.SecType in ('TE', 'PE32'):
|
if self.SecType in ('TE', 'PE32'):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# process rule section generation
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -231,8 +231,10 @@ class EfiSection (EfiSectionClassObject):
|
|||||||
ImageObj = PeImageClass (File)
|
ImageObj = PeImageClass (File)
|
||||||
if ImageObj.SectionAlignment < 0x400:
|
if ImageObj.SectionAlignment < 0x400:
|
||||||
Align = str (ImageObj.SectionAlignment)
|
Align = str (ImageObj.SectionAlignment)
|
||||||
else:
|
elif ImageObj.SectionAlignment < 0x100000:
|
||||||
Align = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
Align = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||||
|
else:
|
||||||
|
Align = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||||
|
|
||||||
if File[(len(File)-4):] == '.efi':
|
if File[(len(File)-4):] == '.efi':
|
||||||
MapFile = File.replace('.efi', '.map')
|
MapFile = File.replace('.efi', '.map')
|
||||||
|
|||||||
@@ -2763,7 +2763,8 @@ class FdfParser:
|
|||||||
while True:
|
while True:
|
||||||
AlignValue = None
|
AlignValue = None
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
#For FFS, Auto is default option same to ""
|
#For FFS, Auto is default option same to ""
|
||||||
if not self.__Token == "Auto":
|
if not self.__Token == "Auto":
|
||||||
@@ -2822,7 +2823,8 @@ class FdfParser:
|
|||||||
FfsFileObj.CheckSum = True
|
FfsFileObj.CheckSum = True
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
#For FFS, Auto is default option same to ""
|
#For FFS, Auto is default option same to ""
|
||||||
if not self.__Token == "Auto":
|
if not self.__Token == "Auto":
|
||||||
@@ -2893,7 +2895,8 @@ class FdfParser:
|
|||||||
|
|
||||||
AlignValue = None
|
AlignValue = None
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
AlignValue = self.__Token
|
AlignValue = self.__Token
|
||||||
|
|
||||||
@@ -3182,7 +3185,8 @@ class FdfParser:
|
|||||||
|
|
||||||
AlignValue = None
|
AlignValue = None
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
AlignValue = self.__Token
|
AlignValue = self.__Token
|
||||||
|
|
||||||
@@ -3773,7 +3777,8 @@ class FdfParser:
|
|||||||
|
|
||||||
AlignValue = ""
|
AlignValue = ""
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
#For FFS, Auto is default option same to ""
|
#For FFS, Auto is default option same to ""
|
||||||
if not self.__Token == "Auto":
|
if not self.__Token == "Auto":
|
||||||
@@ -3822,7 +3827,8 @@ class FdfParser:
|
|||||||
|
|
||||||
SectAlignment = ""
|
SectAlignment = ""
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
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)
|
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
|
FvImageSectionObj.FvFileType = self.__Token
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
FvImageSectionObj.Alignment = self.__Token
|
FvImageSectionObj.Alignment = self.__Token
|
||||||
|
|
||||||
@@ -3968,7 +3975,8 @@ class FdfParser:
|
|||||||
EfiSectionObj.BuildNum = self.__Token
|
EfiSectionObj.BuildNum = self.__Token
|
||||||
|
|
||||||
if self.__GetAlignment():
|
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)
|
raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||||
if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
|
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)
|
raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# process FFS generation from INF statement
|
# 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>
|
# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
@@ -728,8 +728,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||||||
ImageObj = PeImageClass (File)
|
ImageObj = PeImageClass (File)
|
||||||
if ImageObj.SectionAlignment < 0x400:
|
if ImageObj.SectionAlignment < 0x400:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment)
|
self.Alignment = str (ImageObj.SectionAlignment)
|
||||||
else:
|
elif ImageObj.SectionAlignment < 0x100000:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||||
|
else:
|
||||||
|
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||||
|
|
||||||
if not NoStrip:
|
if not NoStrip:
|
||||||
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
||||||
@@ -767,8 +769,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||||||
ImageObj = PeImageClass (GenSecInputFile)
|
ImageObj = PeImageClass (GenSecInputFile)
|
||||||
if ImageObj.SectionAlignment < 0x400:
|
if ImageObj.SectionAlignment < 0x400:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment)
|
self.Alignment = str (ImageObj.SectionAlignment)
|
||||||
else:
|
elif ImageObj.SectionAlignment < 0x100000:
|
||||||
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
|
||||||
|
else:
|
||||||
|
self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'
|
||||||
|
|
||||||
if not NoStrip:
|
if not NoStrip:
|
||||||
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
|
||||||
|
|||||||
@@ -196,9 +196,12 @@ class FV (FvClassObject):
|
|||||||
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
||||||
# FvAlignmentValue is larger than or equal to 1K
|
# FvAlignmentValue is larger than or equal to 1K
|
||||||
if FvAlignmentValue >= 0x400:
|
if FvAlignmentValue >= 0x400:
|
||||||
if FvAlignmentValue >= 0x10000:
|
if FvAlignmentValue >= 0x100000:
|
||||||
#The max alignment supported by FFS is 64K.
|
#The max alignment supported by FFS is 16M.
|
||||||
self.FvAlignment = "64K"
|
if FvAlignmentValue >= 0x1000000:
|
||||||
|
self.FvAlignment = "16M"
|
||||||
|
else:
|
||||||
|
self.FvAlignment = str(FvAlignmentValue / 0x100000) + "M"
|
||||||
else:
|
else:
|
||||||
self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"
|
self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# process FV image section generation
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# MaxFvAlignment is larger than or equal to 1K
|
||||||
if MaxFvAlignment >= 0x400:
|
if MaxFvAlignment >= 0x400:
|
||||||
if MaxFvAlignment >= 0x10000:
|
if MaxFvAlignment >= 0x100000:
|
||||||
#The max alignment supported by FFS is 64K.
|
#The max alignment supported by FFS is 16M.
|
||||||
self.Alignment = "64K"
|
if MaxFvAlignment >=1000000:
|
||||||
|
self.Alignment = "16M"
|
||||||
|
else:
|
||||||
|
self.Alignment = str(MaxFvAlignment / 0x100000) + "M"
|
||||||
else:
|
else:
|
||||||
self.Alignment = str (MaxFvAlignment / 0x400) + "K"
|
self.Alignment = str (MaxFvAlignment / 0x400) + "K"
|
||||||
else:
|
else:
|
||||||
@@ -117,9 +120,12 @@ class FvImageSection(FvImageSectionClassObject):
|
|||||||
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)
|
||||||
# FvAlignmentValue is larger than or equal to 1K
|
# FvAlignmentValue is larger than or equal to 1K
|
||||||
if FvAlignmentValue >= 0x400:
|
if FvAlignmentValue >= 0x400:
|
||||||
if FvAlignmentValue >= 0x10000:
|
if FvAlignmentValue >= 0x100000:
|
||||||
#The max alignment supported by FFS is 64K.
|
#The max alignment supported by FFS is 16M.
|
||||||
self.Alignment = "64K"
|
if FvAlignmentValue >= 0x1000000:
|
||||||
|
self.Alignment = "16M"
|
||||||
|
else:
|
||||||
|
self.Alignment = str(FvAlignmentValue / 0x100000) + "M"
|
||||||
else:
|
else:
|
||||||
self.Alignment = str (FvAlignmentValue / 0x400) + "K"
|
self.Alignment = str (FvAlignmentValue / 0x400) + "K"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# Global variables for GenFds
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -420,8 +420,10 @@ class GenFdsGlobalVariable:
|
|||||||
def GetAlignment (AlignString):
|
def GetAlignment (AlignString):
|
||||||
if AlignString == None:
|
if AlignString == None:
|
||||||
return 0
|
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
|
return int (AlignString.rstrip('K')) * 1024
|
||||||
|
elif AlignString in ("1M", "2M", "4M", "8M", "16M"):
|
||||||
|
return int (AlignString.rstrip('M')) * 1024 * 1024
|
||||||
else:
|
else:
|
||||||
return int (AlignString)
|
return int (AlignString)
|
||||||
|
|
||||||
@@ -429,7 +431,7 @@ class GenFdsGlobalVariable:
|
|||||||
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
|
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
|
||||||
SectionAlign=None):
|
SectionAlign=None):
|
||||||
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
|
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:
|
if Fixed == True:
|
||||||
Cmd += ["-x"]
|
Cmd += ["-x"]
|
||||||
if CheckSum:
|
if CheckSum:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# PCD Name Offset in binary
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# 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
|
if (firstline.startswith("Archive member included ") and
|
||||||
firstline.endswith(" file (symbol)")):
|
firstline.endswith(" file (symbol)")):
|
||||||
return _parseForGCC(lines, efifilepath)
|
return _parseForGCC(lines, efifilepath)
|
||||||
|
if firstline.startswith("# Path:"):
|
||||||
|
return _parseForXcode(lines, efifilepath)
|
||||||
return _parseGeneral(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):
|
def _parseForGCC(lines, efifilepath):
|
||||||
""" Parse map file generated by GCC linker """
|
""" Parse map file generated by GCC linker """
|
||||||
status = 0
|
status = 0
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf}}
|
# {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf}}
|
||||||
# This tool has been tested with OpenSSL 1.0.1e 11 Feb 2013
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# 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
|
# 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
|
# 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]
|
Signature = Process.communicate(input=FullInputFileBuffer)[0]
|
||||||
if Process.returncode <> 0:
|
if Process.returncode <> 0:
|
||||||
sys.exit(Process.returncode)
|
sys.exit(Process.returncode)
|
||||||
@@ -225,7 +225,7 @@ if __name__ == '__main__':
|
|||||||
#
|
#
|
||||||
# Verify signature
|
# 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)
|
Process.communicate(input=FullInputFileBuffer)
|
||||||
if Process.returncode <> 0:
|
if Process.returncode <> 0:
|
||||||
print 'ERROR: Verification failed'
|
print 'ERROR: Verification failed'
|
||||||
|
|||||||
@@ -16,6 +16,12 @@
|
|||||||
@echo off
|
@echo off
|
||||||
goto :main
|
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
|
:read_vsvars
|
||||||
@rem Do nothing if already found, otherwise call vsvars32.bat if there
|
@rem Do nothing if already found, otherwise call vsvars32.bat if there
|
||||||
if defined VCINSTALLDIR goto :EOF
|
if defined VCINSTALLDIR goto :EOF
|
||||||
@@ -33,6 +39,8 @@ REM (Or invoke the relevant vsvars32 file beforehand).
|
|||||||
|
|
||||||
:main
|
:main
|
||||||
if defined VCINSTALLDIR goto :done
|
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 VS140COMNTOOLS call :read_vsvars "%VS140COMNTOOLS%"
|
||||||
if defined VS120COMNTOOLS call :read_vsvars "%VS120COMNTOOLS%"
|
if defined VS120COMNTOOLS call :read_vsvars "%VS120COMNTOOLS%"
|
||||||
if defined VS110COMNTOOLS call :read_vsvars "%VS110COMNTOOLS%"
|
if defined VS110COMNTOOLS call :read_vsvars "%VS110COMNTOOLS%"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
@REM however it may be executed directly from the BaseTools project folder
|
@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 if the file is not executed within a WORKSPACE\BaseTools folder.
|
||||||
@REM
|
@REM
|
||||||
@REM Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
@REM Copyright (c) 2016-2017, Intel Corporation. All rights reserved.<BR>
|
||||||
@REM
|
@REM
|
||||||
@REM This program and the accompanying materials are licensed and made available
|
@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
|
@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 (
|
if not defined WINDDK3790_PREFIX (
|
||||||
set WINDDK3790_PREFIX=C:\WINDDK\3790.1830\bin\
|
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) {
|
while (NumOfBits > Sd->mBitCount) {
|
||||||
|
NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
|
||||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
|
||||||
|
|
||||||
if (Sd->mCompSize > 0) {
|
if (Sd->mCompSize > 0) {
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -137,6 +137,7 @@
|
|||||||
gEfiLegacyBiosProtocolGuid ## PRODUCES
|
gEfiLegacyBiosProtocolGuid ## PRODUCES
|
||||||
gEfiSerialIoProtocolGuid ## CONSUMES
|
gEfiSerialIoProtocolGuid ## CONSUMES
|
||||||
gEfiSioProtocolGuid ## CONSUMES
|
gEfiSioProtocolGuid ## CONSUMES
|
||||||
|
gEdkiiIoMmuProtocolGuid ## CONSUMES
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion ## CONSUMES
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion ## CONSUMES
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Protocol/PciRootBridgeIo.h>
|
#include <Protocol/PciRootBridgeIo.h>
|
||||||
#include <Protocol/SerialIo.h>
|
#include <Protocol/SerialIo.h>
|
||||||
#include <Protocol/SuperIo.h>
|
#include <Protocol/SuperIo.h>
|
||||||
|
#include <Protocol/IoMmu.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ BOOLEAN mIgnoreBbsUpdateFlag;
|
|||||||
BOOLEAN mVgaInstallationInProgress = FALSE;
|
BOOLEAN mVgaInstallationInProgress = FALSE;
|
||||||
UINT32 mRomCount = 0x00;
|
UINT32 mRomCount = 0x00;
|
||||||
ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES];
|
ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES];
|
||||||
|
EDKII_IOMMU_PROTOCOL *mIoMmu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Query shadowed legacy ROM parameters registered by RomShadow() previously.
|
Query shadowed legacy ROM parameters registered by RomShadow() previously.
|
||||||
@@ -2696,6 +2696,61 @@ Done:
|
|||||||
return Status;
|
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
|
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
|
about how many disks were added by the OPROM and the shadow address and
|
||||||
@@ -2978,6 +3033,21 @@ LegacyBiosInstallPciRom (
|
|||||||
RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;
|
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.
|
// Shadow and initialize the OpROM.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ FillBuf (
|
|||||||
//
|
//
|
||||||
// Left shift NumOfBits of bits in advance
|
// 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
|
// Copy data needed in bytes into mSbuBitBuf
|
||||||
//
|
//
|
||||||
while (NumOfBits > Sd->mBitCount) {
|
while (NumOfBits > Sd->mBitCount) {
|
||||||
|
NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount);
|
||||||
Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
|
Sd->mBitBuf |= (UINT32) LShiftU64 (((UINT64)Sd->mSubBitBuf), NumOfBits);
|
||||||
|
|
||||||
if (Sd->mCompSize > 0) {
|
if (Sd->mCompSize > 0) {
|
||||||
//
|
//
|
||||||
@@ -143,6 +143,7 @@ MakeTable (
|
|||||||
UINT16 Mask;
|
UINT16 Mask;
|
||||||
UINT16 WordOfStart;
|
UINT16 WordOfStart;
|
||||||
UINT16 WordOfCount;
|
UINT16 WordOfCount;
|
||||||
|
UINT16 MaxTableLength;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The maximum mapping table width supported by this internal
|
// The maximum mapping table width supported by this internal
|
||||||
@@ -155,6 +156,9 @@ MakeTable (
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Index = 0; Index < NumOfChar; Index++) {
|
for (Index = 0; Index < NumOfChar; Index++) {
|
||||||
|
if (BitLen[Index] > 16) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Count[BitLen[Index]]++;
|
Count[BitLen[Index]]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +200,7 @@ MakeTable (
|
|||||||
|
|
||||||
Avail = NumOfChar;
|
Avail = NumOfChar;
|
||||||
Mask = (UINT16) (1U << (15 - TableBits));
|
Mask = (UINT16) (1U << (15 - TableBits));
|
||||||
|
MaxTableLength = (UINT16) (1U << TableBits);
|
||||||
|
|
||||||
for (Char = 0; Char < NumOfChar; Char++) {
|
for (Char = 0; Char < NumOfChar; Char++) {
|
||||||
|
|
||||||
@@ -209,6 +214,9 @@ MakeTable (
|
|||||||
if (Len <= TableBits) {
|
if (Len <= TableBits) {
|
||||||
|
|
||||||
for (Index = Start[Len]; Index < NextCode; Index++) {
|
for (Index = Start[Len]; Index < NextCode; Index++) {
|
||||||
|
if (Index >= MaxTableLength) {
|
||||||
|
return (UINT16) BAD_TABLE;
|
||||||
|
}
|
||||||
Table[Index] = Char;
|
Table[Index] = Char;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,13 +623,23 @@ Decode (
|
|||||||
//
|
//
|
||||||
BytesRemain--;
|
BytesRemain--;
|
||||||
while ((INT16) (BytesRemain) >= 0) {
|
while ((INT16) (BytesRemain) >= 0) {
|
||||||
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
|
||||||
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||||
goto Done ;
|
goto Done ;
|
||||||
}
|
}
|
||||||
|
if (DataIdx >= Sd->mOrigSize) {
|
||||||
|
Sd->mBadTableFlag = (UINT16) BAD_TABLE;
|
||||||
|
goto Done ;
|
||||||
|
}
|
||||||
|
Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
|
||||||
|
|
||||||
BytesRemain--;
|
BytesRemain--;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// Once mOutBuf is fully filled, directly return
|
||||||
|
//
|
||||||
|
if (Sd->mOutBuf >= Sd->mOrigSize) {
|
||||||
|
goto Done ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +706,7 @@ UefiDecompressGetInfo (
|
|||||||
}
|
}
|
||||||
|
|
||||||
CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
|
CompressedSize = ReadUnaligned32 ((UINT32 *)Source);
|
||||||
if (SourceSize < (CompressedSize + 8)) {
|
if (SourceSize < (CompressedSize + 8) || (CompressedSize + 8) < 8) {
|
||||||
return RETURN_INVALID_PARAMETER;
|
return RETURN_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,17 @@ ASM_PFX(AsmGetPeiCoreOffset):
|
|||||||
mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
|
mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; TempRamInit API
|
||||||
|
;
|
||||||
|
; Empty function for WHOLEARCHIVE build option
|
||||||
|
;
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
global ASM_PFX(TempRamInitApi)
|
||||||
|
ASM_PFX(TempRamInitApi):
|
||||||
|
jmp $
|
||||||
|
ret
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
; Module Entrypoint API
|
; Module Entrypoint API
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -53,6 +53,17 @@ ASM_PFX(FspApiCommonContinue):
|
|||||||
jmp $
|
jmp $
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; TempRamInit API
|
||||||
|
;
|
||||||
|
; Empty function for WHOLEARCHIVE build option
|
||||||
|
;
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
global ASM_PFX(TempRamInitApi)
|
||||||
|
ASM_PFX(TempRamInitApi):
|
||||||
|
jmp $
|
||||||
|
ret
|
||||||
|
|
||||||
;----------------------------------------------------------------------------
|
;----------------------------------------------------------------------------
|
||||||
; Module Entrypoint API
|
; 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
|
; This program and the accompanying materials
|
||||||
; are licensed and made available under the terms and conditions of the BSD License
|
; 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
|
; 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
|
mov rax, dword 0x10 ; load long mode selector
|
||||||
shl rax, 32
|
shl rax, 32
|
||||||
mov r9, ReloadCS ;Assume the ReloadCS is under 4G
|
lea r9, [ReloadCS] ;Assume the ReloadCS is under 4G
|
||||||
or rax, r9
|
or rax, r9
|
||||||
push rax
|
push rax
|
||||||
;
|
;
|
||||||
@@ -95,7 +95,7 @@ ASM_PFX(AsmExecute32BitCode):
|
|||||||
; save the 32-bit function entry and the return address into stack which will be
|
; save the 32-bit function entry and the return address into stack which will be
|
||||||
; retrieve in compatibility mode.
|
; 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
|
shl rax, 32
|
||||||
or rax, rcx
|
or rax, rcx
|
||||||
push rax
|
push rax
|
||||||
@@ -110,7 +110,7 @@ ASM_PFX(AsmExecute32BitCode):
|
|||||||
;
|
;
|
||||||
mov rcx, dword 0x8 ; load compatible mode selector
|
mov rcx, dword 0x8 ; load compatible mode selector
|
||||||
shl rcx, 32
|
shl rcx, 32
|
||||||
mov rdx, Compatible ; assume address < 4G
|
lea rdx, [Compatible] ; assume address < 4G
|
||||||
or rcx, rdx
|
or rcx, rdx
|
||||||
push rcx
|
push rcx
|
||||||
retf
|
retf
|
||||||
@@ -208,7 +208,7 @@ ReloadCS:
|
|||||||
;
|
;
|
||||||
pop r9 ; get CS
|
pop r9 ; get CS
|
||||||
shl r9, 32 ; rcx[32..47] <- Cs
|
shl r9, 32 ; rcx[32..47] <- Cs
|
||||||
mov rcx, .0
|
lea rcx, [.0]
|
||||||
or rcx, r9
|
or rcx, r9
|
||||||
push rcx
|
push rcx
|
||||||
retf
|
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.
|
# 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
|
# 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 terms and conditions of the BSD License that accompanies this distribution.
|
||||||
# The full text of the license may be found at
|
# 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
|
# 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 }}
|
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]
|
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||||
## This is the GUID of the FFS which contains the Graphics Video BIOS Table (VBT)
|
## 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.
|
# 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 }
|
# { 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
|
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
|
/** @file
|
||||||
A shell application that triggers capsule update process.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@@ -653,7 +653,7 @@ CleanGatherList (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempBlockPtr2 = (VOID *) ((UINTN) TempBlockPtr->Union.ContinuationPointer);
|
TempBlockPtr2 = (VOID *) ((UINTN) TempBlockPtr[Index].Union.ContinuationPointer);
|
||||||
FreePool(TempBlockPtr1);
|
FreePool(TempBlockPtr1);
|
||||||
TempBlockPtr1 = TempBlockPtr2;
|
TempBlockPtr1 = TempBlockPtr2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
|
and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
|
||||||
USB 2.0 device inserts.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@@ -1220,6 +1220,7 @@ EhcSyncInterruptTransfer (
|
|||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EhcFreeUrb (Ehc, Urb);
|
||||||
ON_EXIT:
|
ON_EXIT:
|
||||||
Ehc->PciIo->Flush (Ehc->PciIo);
|
Ehc->PciIo->Flush (Ehc->PciIo);
|
||||||
gBS->RestoreTPL (OldTpl);
|
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
|
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||||
which is used to enable recovery function from USB Drivers.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
are licensed and made available under the terms and conditions
|
||||||
@@ -1140,6 +1140,36 @@ ON_EXIT:
|
|||||||
return Status;
|
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 FileHandle Handle of the file being invoked.
|
||||||
@param PeiServices Describes the list of possible PEI Services.
|
@param PeiServices Describes the list of possible PEI Services.
|
||||||
@@ -1219,6 +1249,8 @@ EhcPeimEntry (
|
|||||||
|
|
||||||
EhcDev->Signature = USB2_HC_DEV_SIGNATURE;
|
EhcDev->Signature = USB2_HC_DEV_SIGNATURE;
|
||||||
|
|
||||||
|
IoMmuInit (&EhcDev->IoMmu);
|
||||||
|
|
||||||
EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
|
EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
|
||||||
|
|
||||||
|
|
||||||
@@ -1250,6 +1282,12 @@ EhcPeimEntry (
|
|||||||
continue;
|
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++;
|
Index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Private Header file for Usb Host Controller PEIM
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
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/UsbController.h>
|
||||||
#include <Ppi/Usb2HostController.h>
|
#include <Ppi/Usb2HostController.h>
|
||||||
|
#include <Ppi/IoMmu.h>
|
||||||
|
#include <Ppi/EndOfPeiPhase.h>
|
||||||
|
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/PeimEntryPoint.h>
|
#include <Library/PeimEntryPoint.h>
|
||||||
@@ -94,7 +96,13 @@ typedef struct _PEI_USB2_HC_DEV PEI_USB2_HC_DEV;
|
|||||||
struct _PEI_USB2_HC_DEV {
|
struct _PEI_USB2_HC_DEV {
|
||||||
UINTN Signature;
|
UINTN Signature;
|
||||||
PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi;
|
PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi;
|
||||||
|
EDKII_IOMMU_PPI *IoMmu;
|
||||||
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
|
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;
|
UINT32 UsbHostControllerBaseAddress;
|
||||||
PEI_URB *Urb;
|
PEI_URB *Urb;
|
||||||
USBHC_MEM_POOL *MemPool;
|
USBHC_MEM_POOL *MemPool;
|
||||||
@@ -122,7 +130,6 @@ struct _PEI_USB2_HC_DEV {
|
|||||||
// Periodic (interrupt) transfer schedule data:
|
// Periodic (interrupt) transfer schedule data:
|
||||||
//
|
//
|
||||||
VOID *PeriodFrame; // Mapped as common buffer
|
VOID *PeriodFrame; // Mapped as common buffer
|
||||||
VOID *PeriodFrameHost;
|
|
||||||
VOID *PeriodFrameMap;
|
VOID *PeriodFrameMap;
|
||||||
|
|
||||||
PEI_EHC_QH *PeriodOne;
|
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_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.
|
@param EhcDev EHCI Device.
|
||||||
@@ -174,6 +182,7 @@ UsbHcInitMemPool (
|
|||||||
/**
|
/**
|
||||||
Release the memory management pool.
|
Release the memory management pool.
|
||||||
|
|
||||||
|
@param Ehc The EHCI device.
|
||||||
@param Pool The USB memory pool to free.
|
@param Pool The USB memory pool to free.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
||||||
@@ -182,6 +191,7 @@ UsbHcInitMemPool (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UsbHcFreeMemPool (
|
UsbHcFreeMemPool (
|
||||||
|
IN PEI_USB2_HC_DEV *Ehc,
|
||||||
IN USBHC_MEM_POOL *Pool
|
IN USBHC_MEM_POOL *Pool
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
@@ -208,6 +218,7 @@ UsbHcAllocateMem (
|
|||||||
/**
|
/**
|
||||||
Free the allocated memory back to the memory pool.
|
Free the allocated memory back to the memory pool.
|
||||||
|
|
||||||
|
@param Ehc The EHCI device.
|
||||||
@param Pool The memory pool of the host controller.
|
@param Pool The memory pool of the host controller.
|
||||||
@param Mem The memory to free.
|
@param Mem The memory to free.
|
||||||
@param Size The size of the memory to free.
|
@param Size The size of the memory to free.
|
||||||
@@ -215,10 +226,110 @@ UsbHcAllocateMem (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
UsbHcFreeMem (
|
UsbHcFreeMem (
|
||||||
|
IN PEI_USB2_HC_DEV *Ehc,
|
||||||
IN USBHC_MEM_POOL *Pool,
|
IN USBHC_MEM_POOL *Pool,
|
||||||
IN VOID *Mem,
|
IN VOID *Mem,
|
||||||
IN UINTN Size
|
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
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# It produces gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
# It produces gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||||
# which is used to enable recovery function from USB Drivers.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions
|
# are licensed and made available under the terms and conditions
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
EhciSched.h
|
EhciSched.h
|
||||||
EhciUrb.h
|
EhciUrb.h
|
||||||
UsbHcMem.h
|
UsbHcMem.h
|
||||||
|
DmaMem.c
|
||||||
|
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
@@ -61,7 +62,8 @@
|
|||||||
[Ppis]
|
[Ppis]
|
||||||
gPeiUsb2HostControllerPpiGuid ## PRODUCES
|
gPeiUsb2HostControllerPpiGuid ## PRODUCES
|
||||||
gPeiUsbControllerPpiGuid ## CONSUMES
|
gPeiUsbControllerPpiGuid ## CONSUMES
|
||||||
|
gEdkiiIoMmuPpiGuid ## CONSUMES
|
||||||
|
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
|
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||||
which is used to enable recovery function from USB Drivers.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
are licensed and made available under the terms and conditions
|
||||||
@@ -107,11 +107,13 @@ EhcInitSched (
|
|||||||
IN PEI_USB2_HC_DEV *Ehc
|
IN PEI_USB2_HC_DEV *Ehc
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
VOID *Buf;
|
||||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||||
VOID *Map;
|
VOID *Map;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT32 *Desc;
|
UINT32 *Desc;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
EFI_PHYSICAL_ADDRESS PciAddr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// First initialize the periodical schedule data:
|
// First initialize the periodical schedule data:
|
||||||
@@ -124,15 +126,19 @@ EhcInitSched (
|
|||||||
// The Frame List ocupies 4K bytes,
|
// The Frame List ocupies 4K bytes,
|
||||||
// and must be aligned on 4-Kbyte boundaries.
|
// and must be aligned on 4-Kbyte boundaries.
|
||||||
//
|
//
|
||||||
Status = PeiServicesAllocatePages (
|
Status = IoMmuAllocateBuffer (
|
||||||
EfiBootServicesCode,
|
Ehc->IoMmu,
|
||||||
1,
|
1,
|
||||||
&PhyAddr
|
&Buf,
|
||||||
|
&PhyAddr,
|
||||||
|
&Map
|
||||||
);
|
);
|
||||||
|
|
||||||
Map = NULL;
|
if (EFI_ERROR (Status) || (Buf == NULL)) {
|
||||||
Ehc->PeriodFrameHost = (VOID *)(UINTN)PhyAddr;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
Ehc->PeriodFrame = (VOID *)(UINTN)PhyAddr;
|
}
|
||||||
|
|
||||||
|
Ehc->PeriodFrame = Buf;
|
||||||
Ehc->PeriodFrameMap = Map;
|
Ehc->PeriodFrameMap = Map;
|
||||||
Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr);
|
Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr);
|
||||||
|
|
||||||
@@ -161,19 +167,20 @@ EhcInitSched (
|
|||||||
// Initialize the frame list entries then set the registers
|
// Initialize the frame list entries then set the registers
|
||||||
//
|
//
|
||||||
Desc = (UINT32 *) Ehc->PeriodFrame;
|
Desc = (UINT32 *) Ehc->PeriodFrame;
|
||||||
|
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (PEI_EHC_QH));
|
||||||
for (Index = 0; Index < EHC_FRAME_LEN; Index++) {
|
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:
|
// Second initialize the asynchronous schedule:
|
||||||
// Only need to set the AsynListAddr register to
|
// Only need to set the AsynListAddr register to
|
||||||
// the reclamation header
|
// 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;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,26 +199,27 @@ EhcFreeSched (
|
|||||||
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, 0);
|
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, 0);
|
||||||
|
|
||||||
if (Ehc->PeriodOne != NULL) {
|
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;
|
Ehc->PeriodOne = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ehc->ReclaimHead != 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;
|
Ehc->ReclaimHead = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ehc->ShortReadStop != 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;
|
Ehc->ShortReadStop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ehc->MemPool != NULL) {
|
if (Ehc->MemPool != NULL) {
|
||||||
UsbHcFreeMemPool (Ehc->MemPool);
|
UsbHcFreeMemPool (Ehc, Ehc->MemPool);
|
||||||
Ehc->MemPool = NULL;
|
Ehc->MemPool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ehc->PeriodFrame != NULL) {
|
if (Ehc->PeriodFrame != NULL) {
|
||||||
|
IoMmuFreeBuffer (Ehc->IoMmu, 1, Ehc->PeriodFrame, Ehc->PeriodFrameMap);
|
||||||
Ehc->PeriodFrame = NULL;
|
Ehc->PeriodFrame = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||||
which is used to enable recovery function from USB Drivers.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
are licensed and made available under the terms and conditions
|
||||||
@@ -301,7 +301,7 @@ EhcFreeQtds (
|
|||||||
Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);
|
Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);
|
||||||
|
|
||||||
RemoveEntryList (&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
|
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) {
|
if (Urb->Qh != NULL) {
|
||||||
//
|
//
|
||||||
// Ensure that this queue head has been unlinked from the
|
// Ensure that this queue head has been unlinked from the
|
||||||
// schedule data structures. Free all the associated QTDs
|
// schedule data structures. Free all the associated QTDs
|
||||||
//
|
//
|
||||||
EhcFreeQtds (Ehc, &Urb->Qh->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;
|
USB_ENDPOINT *Ep;
|
||||||
EFI_PHYSICAL_ADDRESS PhyAddr;
|
EFI_PHYSICAL_ADDRESS PhyAddr;
|
||||||
|
EDKII_IOMMU_OPERATION MapOp;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Len;
|
UINTN Len;
|
||||||
PEI_URB *Urb;
|
PEI_URB *Urb;
|
||||||
VOID *Map;
|
VOID *Map;
|
||||||
|
|
||||||
|
|
||||||
Map = NULL;
|
|
||||||
|
|
||||||
Urb = Ehc->Urb;
|
Urb = Ehc->Urb;
|
||||||
Urb->Signature = EHC_URB_SIG;
|
Urb->Signature = EHC_URB_SIG;
|
||||||
InitializeListHead (&Urb->UrbList);
|
InitializeListHead (&Urb->UrbList);
|
||||||
@@ -571,13 +577,20 @@ EhcCreateUrb (
|
|||||||
goto ON_ERROR;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Urb->RequestPhy = NULL;
|
||||||
|
Urb->RequestMap = NULL;
|
||||||
|
Urb->DataPhy = NULL;
|
||||||
|
Urb->DataMap = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Map the request and user data
|
// Map the request and user data
|
||||||
//
|
//
|
||||||
if (Request != NULL) {
|
if (Request != NULL) {
|
||||||
Len = sizeof (EFI_USB_DEVICE_REQUEST);
|
Len = sizeof (EFI_USB_DEVICE_REQUEST);
|
||||||
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Request ;
|
MapOp = EdkiiIoMmuOperationBusMasterRead;
|
||||||
if ( (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
|
Status = IoMmuMap (Ehc->IoMmu, MapOp, Request, &Len, &PhyAddr, &Map);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
|
||||||
goto ON_ERROR;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,8 +600,16 @@ EhcCreateUrb (
|
|||||||
|
|
||||||
if (Data != NULL) {
|
if (Data != NULL) {
|
||||||
Len = DataLen;
|
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;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
|
||||||
which is used to enable recovery function from USB Drivers.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
are licensed and made available under the terms and conditions
|
||||||
@@ -79,16 +79,18 @@ UsbHcAllocMemBlock (
|
|||||||
|
|
||||||
Block->Bits = (UINT8 *)(UINTN)TempPtr;
|
Block->Bits = (UINT8 *)(UINTN)TempPtr;
|
||||||
|
|
||||||
|
Status = IoMmuAllocateBuffer (
|
||||||
Status = PeiServicesAllocatePages (
|
Ehc->IoMmu,
|
||||||
EfiBootServicesCode,
|
|
||||||
Pages,
|
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
|
// Check whether the data structure used by the host controller
|
||||||
// should be restricted into the same 4G
|
// should be restricted into the same 4G
|
||||||
@@ -109,17 +111,21 @@ UsbHcAllocMemBlock (
|
|||||||
/**
|
/**
|
||||||
Free the memory block from the memory pool.
|
Free the memory block from the memory pool.
|
||||||
|
|
||||||
|
@param Ehc The EHCI device.
|
||||||
@param Pool The memory pool to free the block from.
|
@param Pool The memory pool to free the block from.
|
||||||
@param Block The memory block to free.
|
@param Block The memory block to free.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
UsbHcFreeMemBlock (
|
UsbHcFreeMemBlock (
|
||||||
|
IN PEI_USB2_HC_DEV *Ehc,
|
||||||
IN USBHC_MEM_POOL *Pool,
|
IN USBHC_MEM_POOL *Pool,
|
||||||
IN USBHC_MEM_BLOCK *Block
|
IN USBHC_MEM_BLOCK *Block
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ASSERT ((Pool != NULL) && (Block != NULL));
|
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;
|
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.
|
Insert the memory block to the pool's list of the blocks.
|
||||||
|
|
||||||
@@ -317,6 +371,7 @@ UsbHcInitMemPool (
|
|||||||
/**
|
/**
|
||||||
Release the memory management pool.
|
Release the memory management pool.
|
||||||
|
|
||||||
|
@param Ehc The EHCI device.
|
||||||
@param Pool The USB memory pool to free.
|
@param Pool The USB memory pool to free.
|
||||||
|
|
||||||
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
|
||||||
@@ -325,6 +380,7 @@ UsbHcInitMemPool (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UsbHcFreeMemPool (
|
UsbHcFreeMemPool (
|
||||||
|
IN PEI_USB2_HC_DEV *Ehc,
|
||||||
IN USBHC_MEM_POOL *Pool
|
IN USBHC_MEM_POOL *Pool
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -337,11 +393,11 @@ UsbHcFreeMemPool (
|
|||||||
// UsbHcUnlinkMemBlock can't be used to unlink and free the
|
// UsbHcUnlinkMemBlock can't be used to unlink and free the
|
||||||
// first block.
|
// first block.
|
||||||
//
|
//
|
||||||
for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
|
for (Block = Pool->Head->Next; Block != NULL; Block = Block->Next) {
|
||||||
UsbHcFreeMemBlock (Pool, Block);
|
UsbHcFreeMemBlock (Ehc, Pool, Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
UsbHcFreeMemBlock (Pool, Pool->Head);
|
UsbHcFreeMemBlock (Ehc, Pool, Pool->Head);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -425,6 +481,7 @@ UsbHcAllocateMem (
|
|||||||
/**
|
/**
|
||||||
Free the allocated memory back to the memory pool.
|
Free the allocated memory back to the memory pool.
|
||||||
|
|
||||||
|
@param Ehc The EHCI device.
|
||||||
@param Pool The memory pool of the host controller.
|
@param Pool The memory pool of the host controller.
|
||||||
@param Mem The memory to free.
|
@param Mem The memory to free.
|
||||||
@param Size The size of the memory to free.
|
@param Size The size of the memory to free.
|
||||||
@@ -432,6 +489,7 @@ UsbHcAllocateMem (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
UsbHcFreeMem (
|
UsbHcFreeMem (
|
||||||
|
IN PEI_USB2_HC_DEV *Ehc,
|
||||||
IN USBHC_MEM_POOL *Pool,
|
IN USBHC_MEM_POOL *Pool,
|
||||||
IN VOID *Mem,
|
IN VOID *Mem,
|
||||||
IN UINTN Size
|
IN UINTN Size
|
||||||
@@ -486,7 +544,7 @@ UsbHcFreeMem (
|
|||||||
// Release the current memory block if it is empty and not the head
|
// Release the current memory block if it is empty and not the head
|
||||||
//
|
//
|
||||||
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
|
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
|
||||||
UsbHcFreeMemBlock (Pool, Block);
|
UsbHcFreeMemBlock (Ehc, Pool, Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Private Header file for Usb Host Controller PEIM
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions
|
are licensed and made available under the terms and conditions
|
||||||
@@ -74,4 +74,20 @@ typedef struct _USBHC_MEM_POOL {
|
|||||||
} while (0)
|
} 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
|
#endif
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
NVM Express specification.
|
NVM Express specification.
|
||||||
|
|
||||||
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
|
(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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@@ -359,6 +359,7 @@ NvmExpressPassThru (
|
|||||||
{
|
{
|
||||||
NVME_CONTROLLER_PRIVATE_DATA *Private;
|
NVME_CONTROLLER_PRIVATE_DATA *Private;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
EFI_STATUS PreviousStatus;
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
NVME_SQ *Sq;
|
NVME_SQ *Sq;
|
||||||
NVME_CQ *Cq;
|
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
|
// 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.
|
// 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)) {
|
if ((Packet->TransferLength == 0) || (Packet->TransferBuffer == NULL)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
@@ -699,6 +701,7 @@ NvmExpressPassThru (
|
|||||||
}
|
}
|
||||||
|
|
||||||
Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);
|
Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);
|
||||||
|
PreviousStatus = Status;
|
||||||
Status = PciIo->Mem.Write (
|
Status = PciIo->Mem.Write (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoWidthUint32,
|
EfiPciIoWidthUint32,
|
||||||
@@ -707,6 +710,9 @@ NvmExpressPassThru (
|
|||||||
1,
|
1,
|
||||||
&Data
|
&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.
|
// 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 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.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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_PLATFORM_PROTOCOL *gPciPlatformProtocol;
|
||||||
EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
|
EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
|
||||||
|
EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
|
||||||
|
|
||||||
|
|
||||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = {
|
||||||
@@ -241,6 +242,12 @@ PciBusDriverBindingStart (
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize PciRootBridgeIo to suppress incorrect compiler warning.
|
||||||
|
//
|
||||||
|
PciRootBridgeIo = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check RemainingDevicePath validation
|
// Check RemainingDevicePath validation
|
||||||
@@ -284,6 +291,14 @@ PciBusDriverBindingStart (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mIoMmuProtocol == NULL) {
|
||||||
|
gBS->LocateProtocol (
|
||||||
|
&gEdkiiIoMmuProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
(VOID **) &mIoMmuProtocol
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
|
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
|
||||||
gFullEnumeration = FALSE;
|
gFullEnumeration = FALSE;
|
||||||
} else {
|
} else {
|
||||||
@@ -312,12 +327,34 @@ PciBusDriverBindingStart (
|
|||||||
ParentDevicePath
|
ParentDevicePath
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
//
|
//
|
||||||
// Enumerate the entire host bridge
|
// Enumerate the entire host bridge
|
||||||
// After enumeration, a database that records all the device information will be created
|
// 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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
@@ -328,7 +365,19 @@ PciBusDriverBindingStart (
|
|||||||
//
|
//
|
||||||
StartPciDevices (Controller);
|
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/IncompatiblePciDeviceSupport.h>
|
||||||
#include <Protocol/PciOverride.h>
|
#include <Protocol/PciOverride.h>
|
||||||
#include <Protocol/PciEnumerationComplete.h>
|
#include <Protocol/PciEnumerationComplete.h>
|
||||||
|
#include <Protocol/IoMmu.h>
|
||||||
|
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
|
|||||||
@@ -95,6 +95,7 @@
|
|||||||
gEfiPciRootBridgeIoProtocolGuid ## TO_START
|
gEfiPciRootBridgeIoProtocolGuid ## TO_START
|
||||||
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES
|
||||||
|
gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
|
||||||
[FeaturePcd]
|
[FeaturePcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES
|
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