Date   

post-ExitBootServices memory protection of RT_Data (ARM)

Michael Zimmermann
 

Hi,

a friend of mine works with a hacked Luma WP device. he can already boot
Android by replacing UEFI with a linux bootloader.
What would be nice however is using UEFI's LinuxLoader. The problem with
that seems to be that even after ExitBootServices, booting linux from
addresses previously allocated as RT_Data seems to just not work(no UART
output etc and we don't have jtag).

So, how can UEFI have such an influence at that point? Is there a ARM/TZ
feature for that? Can it be disabled?
I thought respecting the memory map would just be needed in case you want
to be able to call RuntimeServices and that you don't need to do that if
you don't need them.

Thanks
Michael


Re: [PATCH 0/3] ArmPkg: introduce IsZeroGuid() and IsZeroBuffer()

Leif Lindholm <leif.lindholm@...>
 

On Fri, Sep 02, 2016 at 01:33:21PM +0200, Laszlo Ersek wrote:
Maybe this is a good point at which to move these into MdePkg, in the
hope that the ARM versions won't be overlooked in future API
revisions?
I strongly suggest / request that your (good) suggestion be implemented
as a separate endeavor. Moving this stuff into MdePkg is definitely
justified, but it will almost certainly take a good chunk of time.
Meanwhile the ArmVirtQemu builds remain broken.

I suggest to go ahead and commit patches #2 and #3 as well, and swiftly
at that. And, in order to keep ourselves honest about the longer term
goal, I propose to file a bug for the code movement in our Bugzilla
instance. (The affected packages should be MdePkg + ArmPkg.)
Surely if we're doing a panic fix, that should be to revert
313831d-72388f9?

If we're not doing that, let's do the thing that will reduce the
likelihood of this breaking again.
In the interest of speeding this up, I would propose to wait with
Ard's latest set (which deserves and is likely to see some more
discussion) and go ahead with:
- Nuking BaseMemoryLibVstm
- Moving BaseMemoryLibStm to MdePkg
- Updating platforms in edk2 to reflect new location of
BaseMemoryLibStm
- Add the new functions to BaseMemoryLibStm

This will interfere with nothing else under MdePkg, so could hopefully
be merged today anyway.

Would that be an acceptable compromise?

Regards,

Leif

For patches #2 and #3:

Reviewed-by: Laszlo Ersek <lersek@...>

Can we please commit these patches today?

Thanks,
Laszlo


/
Leif

Ard Biesheuvel (3):
ArmPkg: remove BaseMemoryLibVstm implementation of BaseMemoryLib
ArmPkg/BaseMemoryLibStm: implement new IsZeroGuid() API function
ArmPkg/BaseMemoryLibStm: implement new IsZeroBuffer() API function

ArmPkg/ArmPkg.dsc | 2 -
ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf | 1 +
ArmPkg/Library/{BaseMemoryLibVstm/ZeroMemWrapper.c => BaseMemoryLibStm/IsZeroBufferWrapper.c} | 28 ++-
ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c | 29 +++
ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c | 29 +++
ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h | 17 ++
ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S | 112 ---------
ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm | 114 ---------
ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S | 76 ------
ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm | 78 ------
ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf | 70 ------
ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c | 66 -----
ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c | 62 -----
ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c | 63 -----
ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c | 264 --------------------
ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c | 132 ----------
ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h | 234 -----------------
ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c | 67 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c | 66 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c | 67 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c | 99 --------
ArmPkg/Library/BaseMemoryLibVstm/SetMem.c | 53 ----
ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c | 91 -------
26 files changed, 91 insertions(+), 1921 deletions(-)
rename ArmPkg/Library/{BaseMemoryLibVstm/ZeroMemWrapper.c => BaseMemoryLibStm/IsZeroBufferWrapper.c} (53%)
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c

--
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@...
https://lists.01.org/mailman/listinfo/edk2-devel


[PATCH 2/2] MdeModulePkg PCD: Update PCD database structure definition to match BaseTools

Star Zeng <star.zeng@...>
 

To follow PI1.4a, BaseTools has be updated to fix artificial limitation of
SkuId range.

This patch is to update PCD database structure definition to match BaseTools.

Note: The source code and BaseTools need to be upgraded at the same time,
and if they are not upgraded at the same time, build error like below will
be triggered to help user identify the problem.

"Please make sure the version of PCD PEIM Service and the generated
PCD PEI Database match."

Cc: Liming Gao <liming.gao@...>
Cc: Yonghong Zhu <yonghong.zhu@...>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@...>
---
MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h | 14 +++++++-------
MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 2 +-
MdeModulePkg/Universal/PCD/Dxe/Service.c | 2 +-
MdeModulePkg/Universal/PCD/Dxe/Service.h | 4 ++--
MdeModulePkg/Universal/PCD/Pei/Pcd.c | 2 +-
MdeModulePkg/Universal/PCD/Pei/Service.c | 4 ++--
MdeModulePkg/Universal/PCD/Pei/Service.h | 4 ++--
7 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
index ac95f7e21ae8..d2e848800b75 100644
--- a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
+++ b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
@@ -1,7 +1,7 @@
/** @file
Guid for Pcd DataBase Signature.

-Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -23,7 +23,7 @@ extern EFI_GUID gPcdDataBaseSignatureGuid;
//
// Common definitions
//
-typedef UINT8 SKU_ID;
+typedef UINT64 SKU_ID;

#define PCD_TYPE_SHIFT 28

@@ -62,7 +62,7 @@ typedef struct {
} DYNAMICEX_MAPPING;

typedef struct {
- UINT32 SkuDataStartOffset; // Offset(with TYPE info) from the PCD_DB.
+ UINT32 SkuDataStartOffset; // Offset(with DATUM TYPE info) from the PCD_DB.
UINT32 SkuIdTableOffset; // Offset from the PCD_DB.
} SKU_HEAD;

@@ -95,6 +95,7 @@ typedef struct {
GUID Signature; // PcdDataBaseGuid.
UINT32 BuildVersion;
UINT32 Length;
+ SKU_ID SystemSkuId; // Current SkuId value.
UINT32 UninitDataBaseSize; // Total size for PCD those default value with 0.
TABLE_OFFSET LocalTokenNumberTableOffset;
TABLE_OFFSET ExMapTableOffset;
@@ -106,14 +107,15 @@ typedef struct {
UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all.
UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx.
UINT16 GuidTableCount; // The Number of Guid in GuidTable.
- SKU_ID SystemSkuId; // Current SkuId value.
- UINT8 Pad; // Pad bytes to satisfy the alignment.
+ UINT8 Pad[2]; // Pad bytes to satisfy the alignment.

//
// Default initialized external PCD database binary structure
//
// Padding is needed to keep necessary alignment
//
+ //SKU_ID SkuIdTable[]; // SkuIds system supports.
+ //SKU_ID SkuIndexTable[]; // SkuIds for each PCD with SKU enable.
//UINT64 ValueUint64[];
//UINT32 ValueUint32[];
//VPD_HEAD VpdHead[]; // VPD Offset
@@ -129,8 +131,6 @@ typedef struct {
//UINT16 ValueUint16[];
//UINT8 ValueUint8[];
//BOOLEAN ValueBoolean[];
- //UINT8 SkuIdTable[]; // SkuIds system supports.
- //UINT8 SkuIndexTable[]; // SkuIds for each PCD with SKU enable.

} PCD_DATABASE_INIT;

diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
index b9cf9e4e7646..1bb9098c04cf 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
@@ -239,7 +239,7 @@ DxeGetPcdInfoGetSku (
VOID
)
{
- return mPcdDatabase.DxeDb->SystemSkuId;
+ return (UINTN) mPcdDatabase.DxeDb->SystemSkuId;
}

/**
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
index 9ab456624fc7..6d0b0f8adec6 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c
@@ -958,7 +958,7 @@ GetSkuEnabledTokenNumber (
{
SKU_HEAD *SkuHead;
SKU_ID *SkuIdTable;
- INTN Index;
+ UINTN Index;
UINT8 *Value;
UINT8 *PcdDb;
BOOLEAN FoundSku;
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h
index 4d8ab0f13fd6..0257a3487cc4 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.h
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h
@@ -1,7 +1,7 @@
/** @file
Private functions used by PCD DXE driver.

-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, 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
@@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Please make sure the PCD Serivce DXE Version is consistent with
// the version of the generated DXE PCD Database by build tool.
//
-#define PCD_SERVICE_DXE_VERSION 5
+#define PCD_SERVICE_DXE_VERSION 6

//
// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h.
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
index 4d0caed5a94e..7a486b7d1d05 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
@@ -226,7 +226,7 @@ PeiGetPcdInfoGetSku (
VOID
)
{
- return GetPcdDatabase()->SystemSkuId;
+ return (UINTN) GetPcdDatabase()->SystemSkuId;
}

/**
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c
index 45ce01b1fa73..66ca892ed2e0 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.c
@@ -2,7 +2,7 @@
The driver internal functions are implmented here.
They build Pei PCD database, and provide access service to PCD database.

-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, 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
@@ -550,7 +550,7 @@ GetSkuEnabledTokenNumber (
PEI_PCD_DATABASE *PeiPcdDb;
SKU_HEAD *SkuHead;
SKU_ID *SkuIdTable;
- INTN Index;
+ UINTN Index;
UINT8 *Value;
BOOLEAN FoundSku;

diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h
index c75187c2b117..fa14abeaa3b1 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.h
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.h
@@ -1,7 +1,7 @@
/** @file
The internal header file declares the private functions used by PeiPcd driver.

-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2016, 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
@@ -36,7 +36,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Please make sure the PCD Serivce PEIM Version is consistent with
// the version of the generated PEIM PCD Database by build tool.
//
-#define PCD_SERVICE_PEIM_VERSION 5
+#define PCD_SERVICE_PEIM_VERSION 6

//
// PCD_PEI_SERVICE_DRIVER_VERSION is defined in Autogen.h.
--
2.7.0.windows.1


[PATCH 1/2] BaseTools: Follow PI1.4a to fix artificial limitation of PCD SkuId range

Star Zeng <star.zeng@...>
 

From: Yonghong Zhu <yonghong.zhu@...>

Current BaseTools follow previous PI spec to use UINT8 for SkuId, to
follow PI1.4a, BaseTools need to be updated to fix artificial limitation
of PCD SkuId range.

This patch is to update BaseTools to use UINT64 for SkuId, since the
PCD database structure needs to be naturally aligned, the PCD database
structure layout is adjusted to keep the natural alignment and version
is updated to 6.

Note: As the PCD database structure layout is adjusted, the structure
definition in MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h and
PCD drivers also need to be updated. That means the source code and
BaseTools need to be upgraded at the same time, and if they are not
upgraded at the same time, build error like below will be triggered
to help user identify the problem.

"Please make sure the version of PCD PEIM Service and the generated
PCD PEI Database match."

Cc: Liming Gao <liming.gao@...>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@...>
---
BaseTools/Source/Python/AutoGen/GenPcdDb.py | 91 ++++++++++++++++++-----------
1 file changed, 57 insertions(+), 34 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
index d5997f0e66aa..fc9ac7178f61 100644
--- a/BaseTools/Source/Python/AutoGen/GenPcdDb.py
+++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
@@ -19,7 +19,7 @@ from ValidCheckingInfoObject import VAR_CHECK_PCD_VARIABLE_TAB
from ValidCheckingInfoObject import VAR_VALID_OBJECT_FACTORY
from Common.VariableAttributes import VariableAttributes

-DATABASE_VERSION = 5
+DATABASE_VERSION = 6

gPcdDatabaseAutoGenC = TemplateString("""
//
@@ -27,6 +27,8 @@ gPcdDatabaseAutoGenC = TemplateString("""
//
#if 0
${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+ /* SkuIdTable */
+ { ${BEGIN}${SKUID_VALUE}, ${END} },
${BEGIN} { ${INIT_VALUE_UINT64} }, /* ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
${END}
${BEGIN} ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
@@ -86,8 +88,6 @@ ${BEGIN} { ${INIT_VALUE_BOOLEAN} }, /* ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_
${END}
${BEGIN} ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
${END}
- /* SkuIdTable */
- { ${BEGIN}${SKUID_VALUE}, ${END} },
${SYSTEM_SKU_ID_VALUE}
};
#endif
@@ -122,6 +122,7 @@ gPcdDatabaseAutoGenH = TemplateString("""
#define ${PHASE}_EXMAP_TABLE_EMPTY ${EXMAP_TABLE_EMPTY}

typedef struct {
+ UINT64 SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
${BEGIN} UINT64 ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
${END}
${BEGIN} UINT64 ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
@@ -156,7 +157,6 @@ ${BEGIN} BOOLEAN ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN
${END}
${BEGIN} BOOLEAN ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
${END}
- UINT8 SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
${SYSTEM_SKU_ID}
} ${PHASE}_PCD_DATABASE_INIT;

@@ -176,7 +176,9 @@ ${END}

typedef struct {
//GUID Signature; // PcdDataBaseGuid
+ //UINT32 BuildVersion;
//UINT32 Length;
+ //SKU_ID SystemSkuId; // Current SkuId value.
//UINT32 UninitDataBaseSize;// Total size for PCD those default value with 0.
//TABLE_OFFSET LocalTokenNumberTableOffset;
//TABLE_OFFSET ExMapTableOffset;
@@ -184,11 +186,11 @@ typedef struct {
//TABLE_OFFSET StringTableOffset;
//TABLE_OFFSET SizeTableOffset;
//TABLE_OFFSET SkuIdTableOffset;
+ //TABLE_OFFSET PcdNameTableOffset;
//UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all
//UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx
//UINT16 GuidTableCount; // The Number of Guid in GuidTable
- //SKU_ID SystemSkuId; // Current SkuId value.
- //UINT8 Pad;
+ //UINT8 Pad[2];
${PHASE}_PCD_DATABASE_INIT Init;
${PHASE}_PCD_DATABASE_UNINIT Uninit;
} ${PHASE}_PCD_DATABASE;
@@ -204,6 +206,8 @@ gEmptyPcdDatabaseAutoGenC = TemplateString("""
//
#if 0
${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+ /* SkuIdTable */
+ { 0 },
/* ExMapTable */
{
{0, 0, 0}
@@ -226,8 +230,6 @@ ${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
{
0, 0
},
- /* SkuIdTable */
- { 0 },
${SYSTEM_SKU_ID_VALUE}
};
#endif
@@ -760,9 +762,9 @@ def BuildExDataBase(Dict):
VardefValueBoolean = Dict['VARDEF_DB_VALUE_BOOLEAN']
DbVardefValueBoolean = DbItemList(1, RawDataList = VardefValueBoolean)
SkuidValue = Dict['SKUID_VALUE']
- DbSkuidValue = DbItemList(1, RawDataList = SkuidValue)
+ DbSkuidValue = DbItemList(8, RawDataList = SkuidValue)
SkuIndexValue = Dict['SKU_INDEX_VALUE']
- DbSkuIndexValue = DbItemList(0,RawDataList = SkuIndexValue)
+ DbSkuIndexValue = DbItemList(8,RawDataList = SkuIndexValue)

# Unit Db Items
UnInitValueUint64 = Dict['UNINIT_GUID_DECL_UINT64']
@@ -777,24 +779,24 @@ def BuildExDataBase(Dict):
DbUnInitValueBoolean = DbItemList(1, RawDataList = UnInitValueBoolean)
PcdTokenNumberMap = Dict['PCD_ORDER_TOKEN_NUMBER_MAP']

- DbNameTotle = ["InitValueUint64", "VardefValueUint64", "InitValueUint32", "VardefValueUint32", "VpdHeadValue", "ExMapTable",
+ DbNameTotle = ["SkuidValue", "SkuIndexValue", "InitValueUint64", "VardefValueUint64", "InitValueUint32", "VardefValueUint32", "VpdHeadValue", "ExMapTable",
"LocalTokenNumberTable", "GuidTable", "StringHeadValue", "PcdNameOffsetTable","VariableTable","SkuTable", "StringTableLen", "PcdTokenTable", "PcdCNameTable",
"SizeTableValue", "InitValueUint16", "VardefValueUint16", "InitValueUint8", "VardefValueUint8", "InitValueBoolean",
- "VardefValueBoolean", "SkuidValue", "SkuIndexValue","UnInitValueUint64", "UnInitValueUint32", "UnInitValueUint16", "UnInitValueUint8", "UnInitValueBoolean"]
+ "VardefValueBoolean", "UnInitValueUint64", "UnInitValueUint32", "UnInitValueUint16", "UnInitValueUint8", "UnInitValueBoolean"]

- DbTotal = [InitValueUint64, VardefValueUint64, InitValueUint32, VardefValueUint32, VpdHeadValue, ExMapTable,
+ DbTotal = [SkuidValue, SkuIndexValue, InitValueUint64, VardefValueUint64, InitValueUint32, VardefValueUint32, VpdHeadValue, ExMapTable,
LocalTokenNumberTable, GuidTable, StringHeadValue, PcdNameOffsetTable,VariableTable,SkuTable, StringTableLen, PcdTokenTable,PcdCNameTable,
SizeTableValue, InitValueUint16, VardefValueUint16, InitValueUint8, VardefValueUint8, InitValueBoolean,
- VardefValueBoolean, SkuidValue, SkuIndexValue, UnInitValueUint64, UnInitValueUint32, UnInitValueUint16, UnInitValueUint8, UnInitValueBoolean]
- DbItemTotal = [DbInitValueUint64, DbVardefValueUint64, DbInitValueUint32, DbVardefValueUint32, DbVpdHeadValue, DbExMapTable,
+ VardefValueBoolean, UnInitValueUint64, UnInitValueUint32, UnInitValueUint16, UnInitValueUint8, UnInitValueBoolean]
+ DbItemTotal = [DbSkuidValue, DbSkuIndexValue, DbInitValueUint64, DbVardefValueUint64, DbInitValueUint32, DbVardefValueUint32, DbVpdHeadValue, DbExMapTable,
DbLocalTokenNumberTable, DbGuidTable, DbStringHeadValue, DbPcdNameOffsetTable,DbVariableTable,DbSkuTable, DbStringTableLen, DbPcdTokenTable, DbPcdCNameTable,
DbSizeTableValue, DbInitValueUint16, DbVardefValueUint16, DbInitValueUint8, DbVardefValueUint8, DbInitValueBoolean,
- DbVardefValueBoolean, DbSkuidValue, DbSkuIndexValue, DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean]
+ DbVardefValueBoolean, DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean]

- # SkuidValue is the last table in the init table items
- InitTableNum = DbTotal.index(SkuidValue) + 1 + 1 # +1 is for SkuIndexValue table
+ # VardefValueBoolean is the last table in the init table items
+ InitTableNum = DbNameTotle.index("VardefValueBoolean") + 1
# The FixedHeader length of the PCD_DATABASE_INIT, from Signature to Pad
- FixedHeaderLen = 64
+ FixedHeaderLen = 72

# Get offset of SkuId table in the database
SkuIdTableOffset = FixedHeaderLen
@@ -809,18 +811,15 @@ def BuildExDataBase(Dict):
for DbIndex in xrange(len(DbTotal)):
if DbTotal[DbIndex] is SkuTable:
break
+ elif DbItemTotal[DbIndex] is DbSkuIndexValue:
+ if DbItemTotal[DbIndex].RawDataList:
+ Count = 0
+ for item in DbItemTotal[DbIndex].RawDataList:
+ Count += len(item)
+ SkuTableOffset += DbItemTotal[DbIndex].ItemSize * Count
+ continue
SkuTableOffset += DbItemTotal[DbIndex].GetListSize()
- PcdTokenTableDbOffset = FixedHeaderLen
- for DbIndex in xrange(len(DbTotal)):
- if DbTotal[DbIndex] is PcdTokenTable:
- break
- PcdTokenTableDbOffset += DbItemTotal[DbIndex].GetListSize()
-
- PcdCNameTableDbOffset = FixedHeaderLen
- for DbIndex in xrange(len(DbTotal)):
- if DbTotal[DbIndex] is PcdCNameTable:
- break
- PcdCNameTableDbOffset += DbItemTotal[DbIndex].GetListSize()
+
# Fix up the LocalTokenNumberTable, SkuHeader table
SkuHeaderIndex = 0
if len(Dict['SKU_INDEX_VALUE']) > 0:
@@ -835,6 +834,13 @@ def BuildExDataBase(Dict):
if DbTotal[DbIndex] is Table:
DbOffset += DbItemTotal[DbIndex].GetInterOffset(Offset)
break
+ elif DbItemTotal[DbIndex] is DbSkuIndexValue:
+ if DbItemTotal[DbIndex].RawDataList:
+ Count = 0
+ for item in DbItemTotal[DbIndex].RawDataList:
+ Count += len(item)
+ DbOffset += DbItemTotal[DbIndex].ItemSize * Count
+ continue
DbOffset += DbItemTotal[DbIndex].GetListSize()
if DbIndex + 1 == InitTableNum:
if DbOffset % 8:
@@ -847,9 +853,9 @@ def BuildExDataBase(Dict):
LocalTokenNumberTable[LocalTokenNumberTableIndex] = DbOffset|int(TokenTypeValue)
# if PCD_TYPE_SKU_ENABLED, then we need to fix up the SkuTable

- SkuIndexTabalOffset = SkuIdTableOffset + Dict['SKUID_VALUE'][0] + 1
+ SkuIndexTabalOffset = SkuIdTableOffset + len(Dict['SKUID_VALUE']) * 8
if (TokenTypeValue & (0x2 << 28)):
- SkuTable[SkuHeaderIndex] = (DbOffset|int(TokenTypeValue & ~(0x2<<28)), SkuIndexTabalOffset + SkuIndexIndexTable[PcdTokenNumberMap[LocalTokenNumberTableIndex]])
+ SkuTable[SkuHeaderIndex] = (DbOffset|int(TokenTypeValue & ~(0x2<<28)), SkuIndexTabalOffset + SkuIndexIndexTable[PcdTokenNumberMap[LocalTokenNumberTableIndex]] * 8)
LocalTokenNumberTable[LocalTokenNumberTableIndex] = (SkuTableOffset + SkuHeaderIndex * 8) | int(TokenTypeValue)
SkuHeaderIndex += 1

@@ -869,6 +875,13 @@ def BuildExDataBase(Dict):
if DbTotal[DbIndex] is VariableRefTable:
DbOffset += DbItemTotal[DbIndex].GetInterOffset(VariableOffset)
break
+ elif DbItemTotal[DbIndex] is DbSkuIndexValue:
+ if DbItemTotal[DbIndex].RawDataList:
+ Count = 0
+ for item in DbItemTotal[DbIndex].RawDataList:
+ Count += len(item)
+ DbOffset += DbItemTotal[DbIndex].ItemSize * Count
+ continue
DbOffset += DbItemTotal[DbIndex].GetListSize()
if DbIndex + 1 == InitTableNum:
if DbOffset % 8:
@@ -900,6 +913,13 @@ def BuildExDataBase(Dict):
SkuIdTableOffset = DbTotalLength
elif DbItemTotal[DbIndex] is DbPcdNameOffsetTable:
DbPcdNameOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbSkuIndexValue:
+ if DbItemTotal[DbIndex].RawDataList:
+ Count = 0
+ for item in DbItemTotal[DbIndex].RawDataList:
+ Count += len(item)
+ DbTotalLength += DbItemTotal[DbIndex].ItemSize * Count
+ continue

DbTotalLength += DbItemTotal[DbIndex].GetListSize()
if not Dict['PCD_INFO_FLAG']:
@@ -939,6 +959,9 @@ def BuildExDataBase(Dict):
b = pack('=L', DbTotalLength - UninitDataBaseSize)

Buffer += b
+ b = pack('=Q', SystemSkuId)
+
+ Buffer += b
b = pack('=L', UninitDataBaseSize)

Buffer += b
@@ -972,8 +995,8 @@ def BuildExDataBase(Dict):
b = pack('=H', GuidTableCount)

Buffer += b
- b = pack('=B', SystemSkuId)
-
+ b = pack('=B', Pad)
+
Buffer += b
b = pack('=B', Pad)

--
2.7.0.windows.1


[PATCH 0/2] Follow PI1.4a to fix artificial limitation of PCD SkuId range

Star Zeng <star.zeng@...>
 

Current BaseTools follow previous PI spec to use UINT8 for SkuId, to
follow PI1.4a, BaseTools need to be updated to fix artificial limitation
of PCD SkuId range.

BaseTools is updated to use UINT64 for SkuId, since the PCD database
structure needs to be naturally aligned, the PCD database structure
layout is adjusted to keep the natural alignment and version
is updated to 6.

The structure definition in MdeModulePkg/Include/Guid/
PcdDataBaseSignatureGuid.h and PCD drivers are also updated to match BaseTools.

Note: The source code and BaseTools need to be upgraded at the same time,
and if they are not upgraded at the same time, build error like below will
be triggered to help user identify the problem.

"Please make sure the version of PCD PEIM Service and the generated
PCD PEI Database match."

Star Zeng (1):
MdeModulePkg PCD: Update PCD database structure definition to match
BaseTools

Yonghong Zhu (1):
BaseTools: Follow PI1.4a to fix artificial limitation of PCD SkuId
range

BaseTools/Source/Python/AutoGen/GenPcdDb.py | 91 ++++++++++++++--------
.../Include/Guid/PcdDataBaseSignatureGuid.h | 14 ++--
MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 2 +-
MdeModulePkg/Universal/PCD/Dxe/Service.c | 2 +-
MdeModulePkg/Universal/PCD/Dxe/Service.h | 4 +-
MdeModulePkg/Universal/PCD/Pei/Pcd.c | 2 +-
MdeModulePkg/Universal/PCD/Pei/Service.c | 4 +-
MdeModulePkg/Universal/PCD/Pei/Service.h | 4 +-
8 files changed, 73 insertions(+), 50 deletions(-)

--
2.7.0.windows.1


[PATCH 2/2] MdePkg/BaseMemoryLibOptDxe: added accelerated AARCH64 routines

Ard Biesheuvel
 

This adds AARCH64 support to BaseMemoryLibOptDxe, based on the cortex-strings
library. All string routines are accelerated except ScanMem16, ScanMem32,
ScanMem64 and IsZeroBuffer, which can wait for another day. (Very few
occurrences exist in the codebase)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
---
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S | 149 +++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S | 283 ++++++++++++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S | 161 +++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S | 244 +++++++++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf | 24 +-
5 files changed, 847 insertions(+), 14 deletions(-)

diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S
new file mode 100644
index 000000000000..e9a60263a902
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S
@@ -0,0 +1,149 @@
+//
+// Copyright (c) 2013, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64
+//
+
+
+// Parameters and result.
+#define src1 x0
+#define src2 x1
+#define limit x2
+#define result x0
+
+// Internal variables.
+#define data1 x3
+#define data1w w3
+#define data2 x4
+#define data2w w4
+#define has_nul x5
+#define diff x6
+#define endloop x7
+#define tmp1 x8
+#define tmp2 x9
+#define tmp3 x10
+#define pos x11
+#define limit_wd x12
+#define mask x13
+
+ .p2align 6
+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)
+ASM_PFX(InternalMemCompareMem):
+ cbz limit, .Lret0
+ eor tmp1, src1, src2
+ tst tmp1, #7
+ b.ne .Lmisaligned8
+ ands tmp1, src1, #7
+ b.ne .Lmutual_align
+ add limit_wd, limit, #7
+ lsr limit_wd, limit_wd, #3
+
+ // Start of performance-critical section -- one 64B cache line.
+.Lloop_aligned:
+ ldr data1, [src1], #8
+ ldr data2, [src2], #8
+.Lstart_realigned:
+ subs limit_wd, limit_wd, #1
+ eor diff, data1, data2 // Non-zero if differences found.
+ csinv endloop, diff, xzr, ne // Last Dword or differences.
+ cbz endloop, .Lloop_aligned
+ // End of performance-critical section -- one 64B cache line.
+
+ // Not reached the limit, must have found a diff.
+ cbnz limit_wd, .Lnot_limit
+
+ // Limit % 8 == 0 => all bytes significant.
+ ands limit, limit, #7
+ b.eq .Lnot_limit
+
+ lsl limit, limit, #3 // Bits -> bytes.
+ mov mask, #~0
+ lsl mask, mask, limit
+ bic data1, data1, mask
+ bic data2, data2, mask
+
+ orr diff, diff, mask
+
+.Lnot_limit:
+ rev diff, diff
+ rev data1, data1
+ rev data2, data2
+
+ // The MS-non-zero bit of DIFF marks either the first bit
+ // that is different, or the end of the significant data.
+ // Shifting left now will bring the critical information into the
+ // top bits.
+ clz pos, diff
+ lsl data1, data1, pos
+ lsl data2, data2, pos
+
+ // But we need to zero-extend (char is unsigned) the value and then
+ // perform a signed 32-bit subtraction.
+ lsr data1, data1, #56
+ sub result, data1, data2, lsr #56
+ ret
+
+.Lmutual_align:
+ // Sources are mutually aligned, but are not currently at an
+ // alignment boundary. Round down the addresses and then mask off
+ // the bytes that precede the start point.
+ bic src1, src1, #7
+ bic src2, src2, #7
+ add limit, limit, tmp1 // Adjust the limit for the extra.
+ lsl tmp1, tmp1, #3 // Bytes beyond alignment -> bits.
+ ldr data1, [src1], #8
+ neg tmp1, tmp1 // Bits to alignment -64.
+ ldr data2, [src2], #8
+ mov tmp2, #~0
+
+ // Little-endian. Early bytes are at LSB.
+ lsr tmp2, tmp2, tmp1 // Shift (tmp1 & 63).
+ add limit_wd, limit, #7
+ orr data1, data1, tmp2
+ orr data2, data2, tmp2
+ lsr limit_wd, limit_wd, #3
+ b .Lstart_realigned
+
+.Lret0:
+ mov result, #0
+ ret
+
+ .p2align 6
+.Lmisaligned8:
+ sub limit, limit, #1
+1:
+ // Perhaps we can do better than this.
+ ldrb data1w, [src1], #1
+ ldrb data2w, [src2], #1
+ subs limit, limit, #1
+ ccmp data1w, data2w, #0, cs // NZCV = 0b0000.
+ b.eq 1b
+ sub result, data1, data2
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S
new file mode 100644
index 000000000000..9d812de8807b
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S
@@ -0,0 +1,283 @@
+//
+// Copyright (c) 2012 - 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// Copyright (c) 2015 ARM Ltd
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the company may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64, unaligned accesses.
+//
+//
+
+#define dstin x0
+#define src x1
+#define count x2
+#define dst x3
+#define srcend x4
+#define dstend x5
+#define A_l x6
+#define A_lw w6
+#define A_h x7
+#define A_hw w7
+#define B_l x8
+#define B_lw w8
+#define B_h x9
+#define C_l x10
+#define C_h x11
+#define D_l x12
+#define D_h x13
+#define E_l src
+#define E_h count
+#define F_l srcend
+#define F_h dst
+#define tmp1 x9
+
+#define L(l) .L ## l
+
+// Copies are split into 3 main cases: small copies of up to 16 bytes,
+// medium copies of 17..96 bytes which are fully unrolled. Large copies
+// of more than 96 bytes align the destination and use an unrolled loop
+// processing 64 bytes per iteration.
+// Small and medium copies read all data before writing, allowing any
+// kind of overlap, and memmove tailcalls memcpy for these cases as
+// well as non-overlapping copies.
+
+__memcpy:
+ prfm PLDL1KEEP, [src]
+ add srcend, src, count
+ add dstend, dstin, count
+ cmp count, 16
+ b.ls L(copy16)
+ cmp count, 96
+ b.hi L(copy_long)
+
+ // Medium copies: 17..96 bytes.
+ sub tmp1, count, 1
+ ldp A_l, A_h, [src]
+ tbnz tmp1, 6, L(copy96)
+ ldp D_l, D_h, [srcend, -16]
+ tbz tmp1, 5, 1f
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [srcend, -32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstend, -32]
+1:
+ stp A_l, A_h, [dstin]
+ stp D_l, D_h, [dstend, -16]
+ ret
+
+ .p2align 4
+ // Small copies: 0..16 bytes.
+L(copy16):
+ cmp count, 8
+ b.lo 1f
+ ldr A_l, [src]
+ ldr A_h, [srcend, -8]
+ str A_l, [dstin]
+ str A_h, [dstend, -8]
+ ret
+ .p2align 4
+1:
+ tbz count, 2, 1f
+ ldr A_lw, [src]
+ ldr A_hw, [srcend, -4]
+ str A_lw, [dstin]
+ str A_hw, [dstend, -4]
+ ret
+
+ // Copy 0..3 bytes. Use a branchless sequence that copies the same
+ // byte 3 times if count==1, or the 2nd byte twice if count==2.
+1:
+ cbz count, 2f
+ lsr tmp1, count, 1
+ ldrb A_lw, [src]
+ ldrb A_hw, [srcend, -1]
+ ldrb B_lw, [src, tmp1]
+ strb A_lw, [dstin]
+ strb B_lw, [dstin, tmp1]
+ strb A_hw, [dstend, -1]
+2: ret
+
+ .p2align 4
+ // Copy 64..96 bytes. Copy 64 bytes from the start and
+ // 32 bytes from the end.
+L(copy96):
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [src, 32]
+ ldp D_l, D_h, [src, 48]
+ ldp E_l, E_h, [srcend, -32]
+ ldp F_l, F_h, [srcend, -16]
+ stp A_l, A_h, [dstin]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin, 32]
+ stp D_l, D_h, [dstin, 48]
+ stp E_l, E_h, [dstend, -32]
+ stp F_l, F_h, [dstend, -16]
+ ret
+
+ // Align DST to 16 byte alignment so that we don't cross cache line
+ // boundaries on both loads and stores. There are at least 96 bytes
+ // to copy, so copy 16 bytes unaligned and then align. The loop
+ // copies 64 bytes per iteration and prefetches one iteration ahead.
+
+ .p2align 4
+L(copy_long):
+ and tmp1, dstin, 15
+ bic dst, dstin, 15
+ ldp D_l, D_h, [src]
+ sub src, src, tmp1
+ add count, count, tmp1 // Count is now 16 too large.
+ ldp A_l, A_h, [src, 16]
+ stp D_l, D_h, [dstin]
+ ldp B_l, B_h, [src, 32]
+ ldp C_l, C_h, [src, 48]
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 128 + 16 // Test and readjust count.
+ b.ls 2f
+1:
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [src, 16]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [src, 32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [src, 48]
+ stp D_l, D_h, [dst, 64]!
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 64
+ b.hi 1b
+
+ // Write the last full set of 64 bytes. The remainder is at most 64
+ // bytes, so it is safe to always copy 64 bytes from the end even if
+ // there is just 1 byte left.
+2:
+ ldp E_l, E_h, [srcend, -64]
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [srcend, -48]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [srcend, -16]
+ stp D_l, D_h, [dst, 64]
+ stp E_l, E_h, [dstend, -64]
+ stp A_l, A_h, [dstend, -48]
+ stp B_l, B_h, [dstend, -32]
+ stp C_l, C_h, [dstend, -16]
+ ret
+
+
+//
+// All memmoves up to 96 bytes are done by memcpy as it supports overlaps.
+// Larger backwards copies are also handled by memcpy. The only remaining
+// case is forward large copies. The destination is aligned, and an
+// unrolled loop processes 64 bytes per iteration.
+//
+
+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+ sub tmp1, dstin, src
+ cmp count, 96
+ ccmp tmp1, count, 2, hi
+ b.hs __memcpy
+
+ cbz tmp1, 3f
+ add dstend, dstin, count
+ add srcend, src, count
+
+ // Align dstend to 16 byte alignment so that we don't cross cache line
+ // boundaries on both loads and stores. There are at least 96 bytes
+ // to copy, so copy 16 bytes unaligned and then align. The loop
+ // copies 64 bytes per iteration and prefetches one iteration ahead.
+
+ and tmp1, dstend, 15
+ ldp D_l, D_h, [srcend, -16]
+ sub srcend, srcend, tmp1
+ sub count, count, tmp1
+ ldp A_l, A_h, [srcend, -16]
+ stp D_l, D_h, [dstend, -16]
+ ldp B_l, B_h, [srcend, -32]
+ ldp C_l, C_h, [srcend, -48]
+ ldp D_l, D_h, [srcend, -64]!
+ sub dstend, dstend, tmp1
+ subs count, count, 128
+ b.ls 2f
+ nop
+1:
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [srcend, -16]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [srcend, -48]
+ stp D_l, D_h, [dstend, -64]!
+ ldp D_l, D_h, [srcend, -64]!
+ subs count, count, 64
+ b.hi 1b
+
+ // Write the last full set of 64 bytes. The remainder is at most 64
+ // bytes, so it is safe to always copy 64 bytes from the start even if
+ // there is just 1 byte left.
+2:
+ ldp E_l, E_h, [src, 48]
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [src, 32]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [src, 16]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [src]
+ stp D_l, D_h, [dstend, -64]
+ stp E_l, E_h, [dstin, 48]
+ stp A_l, A_h, [dstin, 32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin]
+3: ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S
new file mode 100644
index 000000000000..e9029546d762
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S
@@ -0,0 +1,161 @@
+//
+// Copyright (c) 2014, ARM Limited
+// All rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the company nor the names of its contributors
+// may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64
+// Neon Available.
+//
+
+// Arguments and results.
+#define srcin x0
+#define cntin x1
+#define chrin w2
+
+#define result x0
+
+#define src x3
+#define tmp x4
+#define wtmp2 w5
+#define synd x6
+#define soff x9
+#define cntrem x10
+
+#define vrepchr v0
+#define vdata1 v1
+#define vdata2 v2
+#define vhas_chr1 v3
+#define vhas_chr2 v4
+#define vrepmask v5
+#define vend v6
+
+//
+// Core algorithm:
+//
+// For each 32-byte chunk we calculate a 64-bit syndrome value, with two bits
+// per byte. For each tuple, bit 0 is set if the relevant byte matched the
+// requested character and bit 1 is not used (faster than using a 32bit
+// syndrome). Since the bits in the syndrome reflect exactly the order in which
+// things occur in the original string, counting trailing zeros allows to
+// identify exactly which byte has matched.
+//
+
+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)
+ASM_PFX(InternalMemScanMem8):
+ // Do not dereference srcin if no bytes to compare.
+ cbz cntin, .Lzero_length
+ //
+ // Magic constant 0x40100401 allows us to identify which lane matches
+ // the requested byte.
+ //
+ mov wtmp2, #0x0401
+ movk wtmp2, #0x4010, lsl #16
+ dup vrepchr.16b, chrin
+ // Work with aligned 32-byte chunks
+ bic src, srcin, #31
+ dup vrepmask.4s, wtmp2
+ ands soff, srcin, #31
+ and cntrem, cntin, #31
+ b.eq .Lloop
+
+ //
+ // Input string is not 32-byte aligned. We calculate the syndrome
+ // value for the aligned 32 bytes block containing the first bytes
+ // and mask the irrelevant part.
+ //
+
+ ld1 {vdata1.16b, vdata2.16b}, [src], #32
+ sub tmp, soff, #32
+ adds cntin, cntin, tmp
+ cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
+ cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
+ and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
+ and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
+ addp vend.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
+ addp vend.16b, vend.16b, vend.16b // 128->64
+ mov synd, vend.2d[0]
+ // Clear the soff*2 lower bits
+ lsl tmp, soff, #1
+ lsr synd, synd, tmp
+ lsl synd, synd, tmp
+ // The first block can also be the last
+ b.ls .Lmasklast
+ // Have we found something already?
+ cbnz synd, .Ltail
+
+.Lloop:
+ ld1 {vdata1.16b, vdata2.16b}, [src], #32
+ subs cntin, cntin, #32
+ cmeq vhas_chr1.16b, vdata1.16b, vrepchr.16b
+ cmeq vhas_chr2.16b, vdata2.16b, vrepchr.16b
+ // If we're out of data we finish regardless of the result
+ b.ls .Lend
+ // Use a fast check for the termination condition
+ orr vend.16b, vhas_chr1.16b, vhas_chr2.16b
+ addp vend.2d, vend.2d, vend.2d
+ mov synd, vend.2d[0]
+ // We're not out of data, loop if we haven't found the character
+ cbz synd, .Lloop
+
+.Lend:
+ // Termination condition found, let's calculate the syndrome value
+ and vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
+ and vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
+ addp vend.16b, vhas_chr1.16b, vhas_chr2.16b // 256->128
+ addp vend.16b, vend.16b, vend.16b // 128->64
+ mov synd, vend.2d[0]
+ // Only do the clear for the last possible block
+ b.hi .Ltail
+
+.Lmasklast:
+ // Clear the (32 - ((cntrem + soff) % 32)) * 2 upper bits
+ add tmp, cntrem, soff
+ and tmp, tmp, #31
+ sub tmp, tmp, #32
+ neg tmp, tmp, lsl #1
+ lsl synd, synd, tmp
+ lsr synd, synd, tmp
+
+.Ltail:
+ // Count the trailing zeros using bit reversing
+ rbit synd, synd
+ // Compensate the last post-increment
+ sub src, src, #32
+ // Check that we have found a character
+ cmp synd, #0
+ // And count the leading zeros
+ clz synd, synd
+ // Compute the potential result
+ add result, src, synd, lsr #1
+ // Select result or NULL
+ csel result, xzr, result, eq
+ ret
+
+.Lzero_length:
+ mov result, #0
+ ret
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S
new file mode 100644
index 000000000000..7f361110d4fe
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2012 - 2016, Linaro Limited
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Linaro nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+//
+// Copyright (c) 2015 ARM Ltd
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the company may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Assumptions:
+//
+// ARMv8-a, AArch64, unaligned accesses
+//
+//
+
+#define dstin x0
+#define count x1
+#define val x2
+#define valw w2
+#define dst x3
+#define dstend x4
+#define tmp1 x5
+#define tmp1w w5
+#define tmp2 x6
+#define tmp2w w6
+#define zva_len x7
+#define zva_lenw w7
+
+#define L(l) .L ## l
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)
+ASM_PFX(InternalMemSetMem16):
+ dup v0.8H, valw
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)
+ASM_PFX(InternalMemSetMem32):
+ dup v0.4S, valw
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)
+ASM_PFX(InternalMemSetMem64):
+ dup v0.2D, val
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)
+ASM_PFX(InternalMemZeroMem):
+ movi v0.16B, #0
+ b 0f
+
+ASM_GLOBAL ASM_PFX(InternalMemSetMem)
+ASM_PFX(InternalMemSetMem):
+ dup v0.16B, valw
+0: add dstend, dstin, count
+ mov val, v0.D[0]
+
+ cmp count, 96
+ b.hi L(set_long)
+ cmp count, 16
+ b.hs L(set_medium)
+
+ // Set 0..15 bytes.
+ tbz count, 3, 1f
+ str val, [dstin]
+ str val, [dstend, -8]
+ ret
+ nop
+1: tbz count, 2, 2f
+ str valw, [dstin]
+ str valw, [dstend, -4]
+ ret
+2: cbz count, 3f
+ strb valw, [dstin]
+ tbz count, 1, 3f
+ strh valw, [dstend, -2]
+3: ret
+
+ // Set 17..96 bytes.
+L(set_medium):
+ str q0, [dstin]
+ tbnz count, 6, L(set96)
+ str q0, [dstend, -16]
+ tbz count, 5, 1f
+ str q0, [dstin, 16]
+ str q0, [dstend, -32]
+1: ret
+
+ .p2align 4
+ // Set 64..96 bytes. Write 64 bytes from the start and
+ // 32 bytes from the end.
+L(set96):
+ str q0, [dstin, 16]
+ stp q0, q0, [dstin, 32]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+ nop
+L(set_long):
+ bic dst, dstin, 15
+ str q0, [dstin]
+ cmp count, 256
+ ccmp val, 0, 0, cs
+ b.eq L(try_zva)
+L(no_zva):
+ sub count, dstend, dst // Count is 16 too large.
+ add dst, dst, 16
+ sub count, count, 64 + 16 // Adjust count and bias for loop.
+1: stp q0, q0, [dst], 64
+ stp q0, q0, [dst, -32]
+L(tail64):
+ subs count, count, 64
+ b.hi 1b
+2: stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+L(try_zva):
+ mrs tmp1, dczid_el0
+ tbnz tmp1w, 4, L(no_zva)
+ and tmp1w, tmp1w, 15
+ cmp tmp1w, 4 // ZVA size is 64 bytes.
+ b.ne L(zva_128)
+
+ // Write the first and last 64 byte aligned block using stp rather
+ // than using DC ZVA. This is faster on some cores.
+L(zva_64):
+ str q0, [dst, 16]
+ stp q0, q0, [dst, 32]
+ bic dst, dst, 63
+ stp q0, q0, [dst, 64]
+ stp q0, q0, [dst, 96]
+ sub count, dstend, dst // Count is now 128 too large.
+ sub count, count, 128+64+64 // Adjust count and bias for loop.
+ add dst, dst, 128
+ nop
+1: dc zva, dst
+ add dst, dst, 64
+ subs count, count, 64
+ b.hi 1b
+ stp q0, q0, [dst, 0]
+ stp q0, q0, [dst, 32]
+ stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+ .p2align 3
+L(zva_128):
+ cmp tmp1w, 5 // ZVA size is 128 bytes.
+ b.ne L(zva_other)
+
+ str q0, [dst, 16]
+ stp q0, q0, [dst, 32]
+ stp q0, q0, [dst, 64]
+ stp q0, q0, [dst, 96]
+ bic dst, dst, 127
+ sub count, dstend, dst // Count is now 128 too large.
+ sub count, count, 128+128 // Adjust count and bias for loop.
+ add dst, dst, 128
+1: dc zva, dst
+ add dst, dst, 128
+ subs count, count, 128
+ b.hi 1b
+ stp q0, q0, [dstend, -128]
+ stp q0, q0, [dstend, -96]
+ stp q0, q0, [dstend, -64]
+ stp q0, q0, [dstend, -32]
+ ret
+
+L(zva_other):
+ mov tmp2w, 4
+ lsl zva_lenw, tmp2w, tmp1w
+ add tmp1, zva_len, 64 // Max alignment bytes written.
+ cmp count, tmp1
+ blo L(no_zva)
+
+ sub tmp2, zva_len, 1
+ add tmp1, dst, zva_len
+ add dst, dst, 16
+ subs count, tmp1, dst // Actual alignment bytes to write.
+ bic tmp1, tmp1, tmp2 // Aligned dc zva start address.
+ beq 2f
+1: stp q0, q0, [dst], 64
+ stp q0, q0, [dst, -32]
+ subs count, count, 64
+ b.hi 1b
+2: mov dst, tmp1
+ sub count, dstend, tmp1 // Remaining bytes to write.
+ subs count, count, zva_len
+ b.lo 4f
+3: dc zva, dst
+ add dst, dst, zva_len
+ subs count, count, zva_len
+ b.hs 3b
+4: add count, count, zva_len
+ b L(tail64)
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
index 71691b9859e3..4f69df0b0155 100644
--- a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
@@ -27,7 +27,7 @@ [Defines]


#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#

[Sources]
@@ -79,19 +79,6 @@ [Sources.Ia32]
Ia32/CopyMem.nasm
Ia32/CopyMem.asm
Ia32/IsZeroBuffer.nasm
- ScanMem64Wrapper.c
- ScanMem32Wrapper.c
- ScanMem16Wrapper.c
- ScanMem8Wrapper.c
- ZeroMemWrapper.c
- CompareMemWrapper.c
- SetMem64Wrapper.c
- SetMem32Wrapper.c
- SetMem16Wrapper.c
- SetMemWrapper.c
- CopyMemWrapper.c
- IsZeroBufferWrapper.c
- MemLibGuid.c

[Sources.X64]
X64/ScanMem64.nasm
@@ -128,6 +115,15 @@ [Sources.X64]
X64/CopyMem.asm
X64/CopyMem.S
X64/IsZeroBuffer.nasm
+
+[Sources.AARCH64]
+ AArch64/ScanMem.S
+ AArch64/ScanMemGeneric.c
+ AArch64/SetMem.S
+ AArch64/CopyMem.S
+ AArch64/CompareMem.S
+
+[Sources]
ScanMem64Wrapper.c
ScanMem32Wrapper.c
ScanMem16Wrapper.c
--
2.7.4


[PATCH 1/2] MdePkg/BaseMemoryLib: widen aligned accesses to 32 or 64 bits

Ard Biesheuvel
 

Since the default BaseMemoryLib should be callable from any context,
including ones where unaligned accesses are not allowed, it implements
InternalCopyMem() and InternalSetMem() using byte accesses only.
However, especially in a context where the MMU is off, such narrow
accesses may be disproportionately costly, and so if the size and
alignment of the access allow it, use 32-bit or even 64-bit loads and
stores (the latter may be beneficial even on a 32-bit architectures like
ARM, which has load pair/store pair instructions)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
---
MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf | 2 +-
MdePkg/Library/BaseMemoryLib/CopyMem.c | 112 ++++++++++++++++++--
MdePkg/Library/BaseMemoryLib/SetMem.c | 40 ++++++-
3 files changed, 140 insertions(+), 14 deletions(-)

diff --git a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
index 6d906e93faf3..358eeed4f449 100644
--- a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+++ b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -26,7 +26,7 @@ [Defines]


#
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64
#

[Sources]
diff --git a/MdePkg/Library/BaseMemoryLib/CopyMem.c b/MdePkg/Library/BaseMemoryLib/CopyMem.c
index 37f03660df5f..6f4fd900df5d 100644
--- a/MdePkg/Library/BaseMemoryLib/CopyMem.c
+++ b/MdePkg/Library/BaseMemoryLib/CopyMem.c
@@ -4,6 +4,9 @@
particular platform easily if an optimized version is desired.

Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. 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
@@ -44,18 +47,107 @@ InternalMemCopyMem (
//
volatile UINT8 *Destination8;
CONST UINT8 *Source8;
+ volatile UINT32 *Destination32;
+ CONST UINT32 *Source32;
+ volatile UINT64 *Destination64;
+ CONST UINT64 *Source64;
+ UINTN Alignment;
+
+ if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer & 0x7) == 0) && (Length >= 8)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination64 = (UINT64*)DestinationBuffer;
+ Source64 = (CONST UINT64*)SourceBuffer;
+ while (Length >= 8) {
+ *(Destination64++) = *(Source64++);
+ Length -= 8;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);
+ Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);
+
+ // Destination64 and Source64 were aligned on a 64-bit boundary
+ // but if length is not a multiple of 8 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x7;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+
+ while (Alignment-- != 0) {
+ *(--Destination8) = *(--Source8);
+ --Length;
+ }
+ Destination64 = (UINT64*)Destination8;
+ Source64 = (CONST UINT64*)Source8;
+ }
+
+ while (Length > 0) {
+ *(--Destination64) = *(--Source64);
+ Length -= 8;
+ }
+ }
+ } else if ((((UINTN)DestinationBuffer & 0x3) == 0) && (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination32 = (UINT32*)DestinationBuffer;
+ Source32 = (CONST UINT32*)SourceBuffer;
+ while (Length >= 4) {
+ *(Destination32++) = *(Source32++);
+ Length -= 4;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);
+ Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);
+
+ // Destination32 and Source32 were aligned on a 32-bit boundary
+ // but if length is not a multiple of 4 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x3;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+
+ while (Alignment-- != 0) {
+ *(--Destination8) = *(--Source8);
+ --Length;
+ }
+ Destination32 = (UINT32*)Destination8;
+ Source32 = (CONST UINT32*)Source8;
+ }

- if (SourceBuffer > DestinationBuffer) {
- Destination8 = (UINT8*)DestinationBuffer;
- Source8 = (CONST UINT8*)SourceBuffer;
- while (Length-- != 0) {
- *(Destination8++) = *(Source8++);
+ while (Length > 0) {
+ *(--Destination32) = *(--Source32);
+ Length -= 4;
+ }
}
- } else if (SourceBuffer < DestinationBuffer) {
- Destination8 = (UINT8*)DestinationBuffer + Length;
- Source8 = (CONST UINT8*)SourceBuffer + Length;
- while (Length-- != 0) {
- *(--Destination8) = *(--Source8);
+ } else {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer;
+ Source8 = (CONST UINT8*)SourceBuffer;
+ while (Length-- != 0) {
+ *(Destination8++) = *(Source8++);
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer + Length;
+ Source8 = (CONST UINT8*)SourceBuffer + Length;
+ while (Length-- != 0) {
+ *(--Destination8) = *(--Source8);
+ }
}
}
return DestinationBuffer;
diff --git a/MdePkg/Library/BaseMemoryLib/SetMem.c b/MdePkg/Library/BaseMemoryLib/SetMem.c
index 5e74085c56f0..932c61e959f3 100644
--- a/MdePkg/Library/BaseMemoryLib/SetMem.c
+++ b/MdePkg/Library/BaseMemoryLib/SetMem.c
@@ -5,6 +5,9 @@
is desired.

Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. 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
@@ -43,11 +46,42 @@ InternalMemSetMem (
// volatile to prevent the optimizer from replacing this function with
// the intrinsic memset()
//
- volatile UINT8 *Pointer;
+ volatile UINT8 *Pointer8;
+ volatile UINT32 *Pointer32;
+ volatile UINT64 *Pointer64;
+ UINT32 Value32;
+ UINT64 Value64;
+
+ if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {
+ // Generate the 64bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+ Value64 = (((UINT64)Value32) << 32) | Value32;
+
+ Pointer64 = (UINT64*)Buffer;
+ while (Length >= 8) {
+ *(Pointer64++) = Value64;
+ Length -= 8;
+ }

- Pointer = (UINT8*)Buffer;
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer64;
+ } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {
+ // Generate the 32bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+
+ Pointer32 = (UINT32*)Buffer;
+ while (Length >= 4) {
+ *(Pointer32++) = Value32;
+ Length -= 4;
+ }
+
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer32;
+ } else {
+ Pointer8 = (UINT8*)Buffer;
+ }
while (Length-- > 0) {
- *(Pointer++) = Value;
+ *(Pointer8++) = Value;
}
return Buffer;
}
--
2.7.4


[PATCH 0/2] MdePkg: add AARCH64 support to BaseMemoryLib

Ard Biesheuvel
 

Now that ArmPkg's BaseMemoryLib implementation is broken due to upstream
API changes, now is a good time to move to the MdePkg versions.

So add AARCH64 support to both BaseMemoryLib (generic C) and
BaseMemoryLibOptDxe (accelerated). The former can be used anywhere, the
latter only in places where the caches are guaranteed to be on, not only
due to the unaligned accesses but also due to the fact that it uses
DC ZVA instructions for clearing memory.

Ard Biesheuvel (2):
MdePkg/BaseMemoryLib: widen aligned accesses to 32 or 64 bits
MdePkg/BaseMemoryLibOptDxe: added accelerated AARCH64 routines

MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf | 2 +-
MdePkg/Library/BaseMemoryLib/CopyMem.c | 112 +++++++-
MdePkg/Library/BaseMemoryLib/SetMem.c | 40 ++-
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S | 149 +++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S | 283 ++++++++++++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S | 161 +++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S | 244 +++++++++++++++++
MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf | 24 +-
8 files changed, 987 insertions(+), 28 deletions(-)
create mode 100644 MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CompareMem.S
create mode 100644 MdePkg/Library/BaseMemoryLibOptDxe/AArch64/CopyMem.S
create mode 100644 MdePkg/Library/BaseMemoryLibOptDxe/AArch64/ScanMem.S
create mode 100644 MdePkg/Library/BaseMemoryLibOptDxe/AArch64/SetMem.S

--
2.7.4


Re: [PATCH 0/3] ArmPkg: introduce IsZeroGuid() and IsZeroBuffer()

Laszlo Ersek
 

On 08/31/16 14:48, Leif Lindholm wrote:
On Wed, Aug 31, 2016 at 10:07:30AM +0100, Ard Biesheuvel wrote:
The BaseMemoryLib API has recently been extended with IsZeroGuid() and
IsZeroBuffer(), so copy the generic implementations into the ArmPkg version
of this library.
Maybe this is a good point at which to move these into MdePkg, in the
hope that the ARM versions won't be overlooked in future API
revisions?
I strongly suggest / request that your (good) suggestion be implemented
as a separate endeavor. Moving this stuff into MdePkg is definitely
justified, but it will almost certainly take a good chunk of time.
Meanwhile the ArmVirtQemu builds remain broken.

I suggest to go ahead and commit patches #2 and #3 as well, and swiftly
at that. And, in order to keep ourselves honest about the longer term
goal, I propose to file a bug for the code movement in our Bugzilla
instance. (The affected packages should be MdePkg + ArmPkg.)

For patches #2 and #3:

Reviewed-by: Laszlo Ersek <lersek@...>

Can we please commit these patches today?

Thanks,
Laszlo


/
Leif

Ard Biesheuvel (3):
ArmPkg: remove BaseMemoryLibVstm implementation of BaseMemoryLib
ArmPkg/BaseMemoryLibStm: implement new IsZeroGuid() API function
ArmPkg/BaseMemoryLibStm: implement new IsZeroBuffer() API function

ArmPkg/ArmPkg.dsc | 2 -
ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf | 1 +
ArmPkg/Library/{BaseMemoryLibVstm/ZeroMemWrapper.c => BaseMemoryLibStm/IsZeroBufferWrapper.c} | 28 ++-
ArmPkg/Library/BaseMemoryLibStm/MemLibGeneric.c | 29 +++
ArmPkg/Library/BaseMemoryLibStm/MemLibGuid.c | 29 +++
ArmPkg/Library/BaseMemoryLibStm/MemLibInternals.h | 17 ++
ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S | 112 ---------
ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm | 114 ---------
ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S | 76 ------
ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm | 78 ------
ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf | 70 ------
ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c | 66 -----
ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c | 62 -----
ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c | 63 -----
ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c | 264 --------------------
ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c | 132 ----------
ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h | 234 -----------------
ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c | 67 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c | 66 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c | 67 -----
ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c | 99 --------
ArmPkg/Library/BaseMemoryLibVstm/SetMem.c | 53 ----
ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c | 64 -----
ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c | 91 -------
26 files changed, 91 insertions(+), 1921 deletions(-)
rename ArmPkg/Library/{BaseMemoryLibVstm/ZeroMemWrapper.c => BaseMemoryLibStm/IsZeroBufferWrapper.c} (53%)
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.S
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/CopyMem.asm
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.S
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/Arm/SetMem.asm
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CompareMemWrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CopyMem.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/CopyMemWrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibGeneric.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibGuid.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/MemLibInternals.h
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem16Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem32Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem64Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/ScanMem8Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem16Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem32Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMem64Wrapper.c
delete mode 100644 ArmPkg/Library/BaseMemoryLibVstm/SetMemWrapper.c

--
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@...
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [PATCH v2 2/6] ArmVirtPkg/FdtPciPcdProducerLib: add handling of PcdPciIoTranslation

Laszlo Ersek
 

On 08/31/16 19:59, Ard Biesheuvel wrote:

+ if (!EFI_ERROR (Status) && RegSize == 2 * sizeof(UINT64)) {
Before you commit this patch, please insert a space character between
"sizeof" and "(".

Reviewed-by: Laszlo Ersek <lersek@...>

Please hold on for a little while before committing the series, I'd like
to test it quickly.

Thanks!
Laszlo


Re: [RFC] Email tags for Bugzilla and administrative events

Laszlo Ersek
 

Hi Mike,

On 07/06/16 20:52, Kinney, Michael D wrote:
Laszlo,

Good timing. I was going to send a status update today.

We are working diligently to get Bugzilla online for all bugs. There
are a few logistics that are still being worked this week related to
an email list for bug state changes that Jordan is helping with and
setting up tianocore domain name for the Bugzilla server.
May I ask if / how the tianocore domain name for the Bugzilla server is
coming along?

Thanks!
Laszlo


Re: [PATCH v2 5/6] ArmVirtPkg/FdtPciHostBridgeLib: add MMIO64 support

Laszlo Ersek
 

On 08/31/16 19:59, Ard Biesheuvel wrote:

@@ -308,8 +329,21 @@ PciHostBridgeGetRootBridges (
mRootBridge.Io.Limit = IoBase + IoSize - 1;
mRootBridge.Mem.Base = Mmio32Base;
mRootBridge.Mem.Limit = Mmio32Base + Mmio32Size - 1;
- mRootBridge.MemAbove4G.Base = MAX_UINT64;
- mRootBridge.MemAbove4G.Limit = 0;
+
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ mRootBridge.MemAbove4G.Base = Mmio64Base;
+ mRootBridge.MemAbove4G.Limit = Mmio64Base + Mmio64Size - 1;
+ mRootBridge.AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+ } else {
+ //
+ // UEFI mandates a 1:1 virtual-to-physical mapping, so on a 32-bit
+ // architecture such as ARM, we will not be able to access 64-bit MMIO
+ // BARs unless they are allocated below 4 GB. So ignore the range above
+ // 4 GB in this case.
+ //
+ mRootBridge.MemAbove4G.Base = MAX_UINT64;
+ mRootBridge.MemAbove4G.Limit = 0;
+ }

//
// No separate ranges for prefetchable and non-prefetchable BARs
Please further restrict the one assignment

mRootBridge.AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;

(while keeping it in its current location) with the following condition:

if (Mmio64Size > 0) {
mRootBridge.AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
}

We should only set this bit if there's actually a 64-bit MMIO aperture.

With that,

Reviewed-by: Laszlo Ersek <lersek@...>

(No need to repost the series just because of this; you can implement the above on commit.)

Thanks!
Laszlo


Re: [PATCH v2 3/6] ArmVirtPkg: implement FdtPciHostBridgeLib

Laszlo Ersek
 

On 08/31/16 19:59, Ard Biesheuvel wrote:
Implement PciHostBridgeLib for DT platforms that expose a PCI root bridge
via a pci-host-ecam-generic DT node. The DT parsing logic is copied from
the PciHostBridgeDxe implementation in ArmVirtPkg, with the one notable
difference that we don't set the various legacy PCI attributes for IDE
and VGA I/O ranges.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@...>
Ref: https://tianocore.acgmultimedia.com/show_bug.cgi?id=65
---
ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c | 400 ++++++++++++++++++++
ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf | 56 +++
2 files changed, 456 insertions(+)
Reviewed-by: Laszlo Ersek <lersek@...>

Thanks
Laszlo

diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
new file mode 100644
index 000000000000..c2aa4a339c19
--- /dev/null
+++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c
@@ -0,0 +1,400 @@
+/** @file
+ PCI Host Bridge Library instance for pci-ecam-generic DT nodes
+
+ Copyright (c) 2016, Linaro Ltd. 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 <Library/PciHostBridgeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/FdtClient.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID(0x0A08), // PCI Express
+ 0
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+ L"Mem", L"I/O", L"Bus"
+};
+
+//
+// We expect the "ranges" property of "pci-host-ecam-generic" to consist of
+// records like this.
+//
+#pragma pack (1)
+typedef struct {
+ UINT32 Type;
+ UINT64 ChildBase;
+ UINT64 CpuBase;
+ UINT64 Size;
+} DTB_PCI_HOST_RANGE_RECORD;
+#pragma pack ()
+
+#define DTB_PCI_HOST_RANGE_RELOCATABLE BIT31
+#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30
+#define DTB_PCI_HOST_RANGE_ALIASED BIT29
+#define DTB_PCI_HOST_RANGE_MMIO32 BIT25
+#define DTB_PCI_HOST_RANGE_MMIO64 (BIT25 | BIT24)
+#define DTB_PCI_HOST_RANGE_IO BIT24
+#define DTB_PCI_HOST_RANGE_TYPEMASK (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)
+
+STATIC
+EFI_STATUS
+ProcessPciHost (
+ OUT UINT64 *IoBase,
+ OUT UINT64 *IoSize,
+ OUT UINT64 *MmioBase,
+ OUT UINT64 *MmioSize,
+ OUT UINT32 *BusMin,
+ OUT UINT32 *BusMax
+ )
+{
+ FDT_CLIENT_PROTOCOL *FdtClient;
+ INT32 Node;
+ UINT64 ConfigBase, ConfigSize;
+ CONST VOID *Prop;
+ UINT32 Len;
+ UINT32 RecordIdx;
+ EFI_STATUS Status;
+ UINT64 IoTranslation;
+ UINT64 MmioTranslation;
+
+ //
+ // The following output arguments are initialized only in
+ // order to suppress '-Werror=maybe-uninitialized' warnings
+ // *incorrectly* emitted by some gcc versions.
+ //
+ *IoBase = 0;
+ *MmioBase = 0;
+ *BusMin = 0;
+ *BusMax = 0;
+
+ //
+ // *IoSize, *MmioSize and IoTranslation are initialized to zero because the
+ // logic below requires it. However, since they are also affected by the issue
+ // reported above, they are initialized early.
+ //
+ *IoSize = 0;
+ *MmioSize = 0;
+ IoTranslation = 0;
+
+ Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
+ (VOID **)&FdtClient);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic",
+ &Node);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO,
+ "%a: No 'pci-host-ecam-generic' compatible DT node found\n",
+ __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG_CODE (
+ INT32 Tmp;
+
+ //
+ // A DT can legally describe multiple PCI host bridges, but we are not
+ // equipped to deal with that. So assert that there is only one.
+ //
+ Status = FdtClient->FindNextCompatibleNode (FdtClient,
+ "pci-host-ecam-generic", Node, &Tmp);
+ ASSERT (Status == EFI_NOT_FOUND);
+ );
+
+ Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", &Prop, &Len);
+ if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT64)) {
+ DEBUG ((EFI_D_ERROR, "%a: 'reg' property not found or invalid\n",
+ __FUNCTION__));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ //
+ // Fetch the ECAM window.
+ //
+ ConfigBase = SwapBytes64 (((CONST UINT64 *)Prop)[0]);
+ ConfigSize = SwapBytes64 (((CONST UINT64 *)Prop)[1]);
+
+ //
+ // Fetch the bus range (note: inclusive).
+ //
+ Status = FdtClient->GetNodeProperty (FdtClient, Node, "bus-range", &Prop,
+ &Len);
+ if (EFI_ERROR (Status) || Len != 2 * sizeof (UINT32)) {
+ DEBUG ((EFI_D_ERROR, "%a: 'bus-range' not found or invalid\n",
+ __FUNCTION__));
+ return EFI_PROTOCOL_ERROR;
+ }
+ *BusMin = SwapBytes32 (((CONST UINT32 *)Prop)[0]);
+ *BusMax = SwapBytes32 (((CONST UINT32 *)Prop)[1]);
+
+ //
+ // Sanity check: the config space must accommodate all 4K register bytes of
+ // all 8 functions of all 32 devices of all buses.
+ //
+ if (*BusMax < *BusMin || *BusMax - *BusMin == MAX_UINT32 ||
+ DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < *BusMax - *BusMin + 1) {
+ DEBUG ((EFI_D_ERROR, "%a: invalid 'bus-range' and/or 'reg'\n",
+ __FUNCTION__));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ //
+ // Iterate over "ranges".
+ //
+ Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);
+ if (EFI_ERROR (Status) || Len == 0 ||
+ Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {
+ DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);
+ ++RecordIdx) {
+ CONST DTB_PCI_HOST_RANGE_RECORD *Record;
+
+ Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;
+ switch (SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {
+ case DTB_PCI_HOST_RANGE_IO:
+ *IoBase = SwapBytes64 (Record->ChildBase);
+ *IoSize = SwapBytes64 (Record->Size);
+ IoTranslation = SwapBytes64 (Record->CpuBase) - *IoBase;
+
+ ASSERT (PcdGet64 (PcdPciIoTranslation) == IoTranslation);
+ break;
+
+ case DTB_PCI_HOST_RANGE_MMIO32:
+ *MmioBase = SwapBytes64 (Record->ChildBase);
+ *MmioSize = SwapBytes64 (Record->Size);
+ MmioTranslation = SwapBytes64 (Record->CpuBase) - *MmioBase;
+
+ if (*MmioBase > MAX_UINT32 || *MmioSize > MAX_UINT32 ||
+ *MmioBase + *MmioSize > SIZE_4GB) {
+ DEBUG ((EFI_D_ERROR, "%a: MMIO32 space invalid\n", __FUNCTION__));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ ASSERT (PcdGet64 (PcdPciMmio32Translation) == MmioTranslation);
+
+ if (MmioTranslation != 0) {
+ DEBUG ((EFI_D_ERROR, "%a: unsupported nonzero MMIO32 translation "
+ "0x%Lx\n", __FUNCTION__, MmioTranslation));
+ return EFI_UNSUPPORTED;
+ }
+
+ break;
+ }
+ }
+ if (*IoSize == 0 || *MmioSize == 0) {
+ DEBUG ((EFI_D_ERROR, "%a: %a space empty\n", __FUNCTION__,
+ (*IoSize == 0) ? "IO" : "MMIO32"));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ //
+ // The dynamic PCD PcdPciExpressBaseAddress should have already been set,
+ // and should match the value we found in the DT node.
+ //
+ ASSERT (PcdGet64 (PcdPciExpressBaseAddress) == ConfigBase);
+
+ DEBUG ((EFI_D_INFO, "%a: Config[0x%Lx+0x%Lx) Bus[0x%x..0x%x] "
+ "Io[0x%Lx+0x%Lx)@0x%Lx Mem[0x%Lx+0x%Lx)@0x0\n", __FUNCTION__, ConfigBase,
+ ConfigSize, *BusMin, *BusMax, *IoBase, *IoSize, IoTranslation, *MmioBase,
+ *MmioSize));
+ return EFI_SUCCESS;
+}
+
+STATIC PCI_ROOT_BRIDGE mRootBridge;
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ UINTN *Count
+ )
+{
+ UINT64 IoBase, IoSize;
+ UINT64 Mmio32Base, Mmio32Size;
+ UINT32 BusMin, BusMax;
+ EFI_STATUS Status;
+
+ if (PcdGet64 (PcdPciExpressBaseAddress) == 0) {
+ DEBUG ((EFI_D_INFO, "%a: PCI host bridge not present\n", __FUNCTION__));
+
+ *Count = 0;
+ return NULL;
+ }
+
+ Status = ProcessPciHost (&IoBase, &IoSize, &Mmio32Base, &Mmio32Size, &BusMin,
+ &BusMax);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to discover PCI host bridge: %r\n",
+ __FUNCTION__, Status));
+ *Count = 0;
+ return NULL;
+ }
+
+ *Count = 1;
+
+ mRootBridge.Segment = 0;
+ mRootBridge.Supports = EFI_PCI_ATTRIBUTE_ISA_IO_16 |
+ EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+ mRootBridge.Attributes = mRootBridge.Supports;
+
+ mRootBridge.DmaAbove4G = TRUE;
+ mRootBridge.NoExtendedConfigSpace = FALSE;
+ mRootBridge.ResourceAssigned = FALSE;
+
+ mRootBridge.AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
+
+ mRootBridge.Bus.Base = BusMin;
+ mRootBridge.Bus.Limit = BusMax;
+ mRootBridge.Io.Base = IoBase;
+ mRootBridge.Io.Limit = IoBase + IoSize - 1;
+ mRootBridge.Mem.Base = Mmio32Base;
+ mRootBridge.Mem.Limit = Mmio32Base + Mmio32Size - 1;
+ mRootBridge.MemAbove4G.Base = MAX_UINT64;
+ mRootBridge.MemAbove4G.Limit = 0;
+
+ //
+ // No separate ranges for prefetchable and non-prefetchable BARs
+ //
+ mRootBridge.PMem.Base = MAX_UINT64;
+ mRootBridge.PMem.Limit = 0;
+ mRootBridge.PMemAbove4G.Base = MAX_UINT64;
+ mRootBridge.PMemAbove4G.Limit = 0;
+
+ mRootBridge.DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath;
+
+ return &mRootBridge;
+}
+
+/**
+ Free the root bridge instances array returned from
+ PciHostBridgeGetRootBridges().
+
+ @param Bridges The root bridge instances array.
+ @param Count The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+ ASSERT (Count == 1);
+}
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
+ sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
+ )
+ );
+ DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+}
diff --git a/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
new file mode 100644
index 000000000000..fc1d37fb3c23
--- /dev/null
+++ b/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
@@ -0,0 +1,56 @@
+## @file
+# PCI Host Bridge Library instance for pci-ecam-generic DT nodes
+#
+# Copyright (c) 2016, Linaro Ltd. 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 = FdtPciHostBridgeLib
+ FILE_GUID = 59fcb139-2558-4cf0-8d7c-ebac499da727
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = AARCH64 ARM
+#
+
+[Sources]
+ FdtPciHostBridgeLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciPcdProducerLib
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdPciMmio32Translation
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdPciIoTranslation
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Depex]
+ gFdtClientProtocolGuid


Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Ard Biesheuvel
 

On 2 September 2016 at 07:37, Tian, Feng <feng.tian@...> wrote:
Reviewed-by: Feng Tian <feng.tian@...>

Thanks
Feng

-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@...]
Sent: Friday, September 2, 2016 2:26 PM
To: edk2-devel-01 <edk2-devel@...>; Tian, Feng <feng.tian@...>; Zeng, Star <star.zeng@...>
Cc: Leif Lindholm <leif.lindholm@...>; Ard Biesheuvel <ard.biesheuvel@...>
Subject: Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Feng, Star: any comments?

On 31 August 2016 at 09:45, Ard Biesheuvel <ard.biesheuvel@...> wrote:
This is v5 of my proposed changes to the AARCH64 implementation of
EbcDxe contributed by Jeff Brasen, which has recently been merged into Tianocore.

Changes since v5:
- added Leif's ack (#3)
- cc MdeModulePkg maintainers

Changes since v3:
- fix typo in comment (#1)
- clarify comments around computed goto in EBC to native thunk, and make sure
the jump target is 32-bit aligned (#3)
- fix comment and constify Args9_16[] in EbcInterpret() prototype (#4)
- add Leif's R-b (#1, #2, #4)

Feng, Star: I know you will not be able to review or test this code in
detail, but please let me know if you are happy for me to merge it. Thanks.

Ard Biesheuvel (4):
MdeModulePkg/EbcDxe AARCH64: clean up comment style in ASM file
MdeModulePkg/EbcDxe AARCH64: use a fixed size thunk structure
MdeModulePkg/EbcDxe AARCH64: use tail call for EBC to native thunk
MdeModulePkg/EbcDxe AARCH64: simplify interpreter entry point thunks

MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 285
+++++++++++---------
MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c | 193
++++---------
2 files changed, 210 insertions(+), 268 deletions(-)

--
2.7.4
Thanks all

Committed as

72b0eaa02679 MdeModulePkg/EbcDxe AARCH64: clean up comment style in ASM file
4d1f5a214bb3 MdeModulePkg/EbcDxe AARCH64: use a fixed size thunk structure
3226e315d20c MdeModulePkg/EbcDxe AARCH64: use tail call for EBC to native thunk
4a2aaff2fca6 MdeModulePkg/EbcDxe AARCH64: simplify interpreter entry
point thunks


Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Tian, Feng <feng.tian@...>
 

Reviewed-by: Feng Tian <feng.tian@...>

Thanks
Feng

-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@...]
Sent: Friday, September 2, 2016 2:26 PM
To: edk2-devel-01 <edk2-devel@...>; Tian, Feng <feng.tian@...>; Zeng, Star <star.zeng@...>
Cc: Leif Lindholm <leif.lindholm@...>; Ard Biesheuvel <ard.biesheuvel@...>
Subject: Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Feng, Star: any comments?

On 31 August 2016 at 09:45, Ard Biesheuvel <ard.biesheuvel@...> wrote:
This is v5 of my proposed changes to the AARCH64 implementation of
EbcDxe contributed by Jeff Brasen, which has recently been merged into Tianocore.

Changes since v5:
- added Leif's ack (#3)
- cc MdeModulePkg maintainers

Changes since v3:
- fix typo in comment (#1)
- clarify comments around computed goto in EBC to native thunk, and make sure
the jump target is 32-bit aligned (#3)
- fix comment and constify Args9_16[] in EbcInterpret() prototype (#4)
- add Leif's R-b (#1, #2, #4)

Feng, Star: I know you will not be able to review or test this code in
detail, but please let me know if you are happy for me to merge it. Thanks.

Ard Biesheuvel (4):
MdeModulePkg/EbcDxe AARCH64: clean up comment style in ASM file
MdeModulePkg/EbcDxe AARCH64: use a fixed size thunk structure
MdeModulePkg/EbcDxe AARCH64: use tail call for EBC to native thunk
MdeModulePkg/EbcDxe AARCH64: simplify interpreter entry point thunks

MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 285
+++++++++++---------
MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c | 193
++++---------
2 files changed, 210 insertions(+), 268 deletions(-)

--
2.7.4


Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Zeng, Star <star.zeng@...>
 

I am fine. :)

Thanks,
Star

-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheuvel@...]
Sent: Friday, September 2, 2016 2:26 PM
To: edk2-devel-01 <edk2-devel@...>; Tian, Feng <feng.tian@...>; Zeng, Star <star.zeng@...>
Cc: Leif Lindholm <leif.lindholm@...>; Ard Biesheuvel <ard.biesheuvel@...>
Subject: Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Feng, Star: any comments?

On 31 August 2016 at 09:45, Ard Biesheuvel <ard.biesheuvel@...> wrote:
This is v5 of my proposed changes to the AARCH64 implementation of
EbcDxe contributed by Jeff Brasen, which has recently been merged into Tianocore.

Changes since v5:
- added Leif's ack (#3)
- cc MdeModulePkg maintainers

Changes since v3:
- fix typo in comment (#1)
- clarify comments around computed goto in EBC to native thunk, and make sure
the jump target is 32-bit aligned (#3)
- fix comment and constify Args9_16[] in EbcInterpret() prototype (#4)
- add Leif's R-b (#1, #2, #4)

Feng, Star: I know you will not be able to review or test this code in
detail, but please let me know if you are happy for me to merge it. Thanks.

Ard Biesheuvel (4):
MdeModulePkg/EbcDxe AARCH64: clean up comment style in ASM file
MdeModulePkg/EbcDxe AARCH64: use a fixed size thunk structure
MdeModulePkg/EbcDxe AARCH64: use tail call for EBC to native thunk
MdeModulePkg/EbcDxe AARCH64: simplify interpreter entry point thunks

MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 285
+++++++++++---------
MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c | 193
++++---------
2 files changed, 210 insertions(+), 268 deletions(-)

--
2.7.4


Re: [PATCH v5 0/4] deModulePkg/EbcDxe: AARCH64 improvements

Ard Biesheuvel
 

Feng, Star: any comments?

On 31 August 2016 at 09:45, Ard Biesheuvel <ard.biesheuvel@...> wrote:
This is v5 of my proposed changes to the AARCH64 implementation of EbcDxe
contributed by Jeff Brasen, which has recently been merged into Tianocore.

Changes since v5:
- added Leif's ack (#3)
- cc MdeModulePkg maintainers

Changes since v3:
- fix typo in comment (#1)
- clarify comments around computed goto in EBC to native thunk, and make sure
the jump target is 32-bit aligned (#3)
- fix comment and constify Args9_16[] in EbcInterpret() prototype (#4)
- add Leif's R-b (#1, #2, #4)

Feng, Star: I know you will not be able to review or test this code in detail,
but please let me know if you are happy for me to merge it. Thanks.

Ard Biesheuvel (4):
MdeModulePkg/EbcDxe AARCH64: clean up comment style in ASM file
MdeModulePkg/EbcDxe AARCH64: use a fixed size thunk structure
MdeModulePkg/EbcDxe AARCH64: use tail call for EBC to native thunk
MdeModulePkg/EbcDxe AARCH64: simplify interpreter entry point thunks

MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 285 +++++++++++---------
MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c | 193 ++++---------
2 files changed, 210 insertions(+), 268 deletions(-)

--
2.7.4


Re: [Patch] MdeModulePkg: Support classless IP for DHCPv4 TransmitReceive()

Santhapur Naveen <naveens@...>
 

Hello Jiaxin,

My sincere apologies for the delayed response.

I've verified the patch from my side and PXE boot is happening successfully even in classless IP network.

May I know whether this will be included in EDK2? If yes, can you please provide any schedule for the same?

Best regards,
Naveen

-----Original Message-----
From: Santhapur Naveen
Sent: Thursday, August 18, 2016 11:14 AM
To: 'Wu, Jiaxin'; edk2-devel@...
Cc: Ye, Ting; Fu, Siyuan; Sivaraman Nainar; Madhan B. Santharam
Subject: RE: [edk2] [Patch] MdeModulePkg: Support classless IP for DHCPv4 TransmitReceive()

Jiaxin,

We will verify the patch and update you the result.

Thanks,
Naveen

-----Original Message-----
From: Wu, Jiaxin [mailto:jiaxin.wu@...]
Sent: Thursday, August 18, 2016 11:12 AM
To: Santhapur Naveen; Wu, Jiaxin; edk2-devel@...
Cc: Ye, Ting; Fu, Siyuan; Sivaraman Nainar; Madhan B. Santharam
Subject: RE: [edk2] [Patch] MdeModulePkg: Support classless IP for DHCPv4 TransmitReceive()

Naveen,

Can you help to verify this patch to support the classless IP.

Thanks,
Jiaxin

-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@...] On Behalf Of
Jiaxin Wu
Sent: Thursday, August 18, 2016 1:39 PM
To: edk2-devel@...
Cc: Ye, Ting <ting.ye@...>; Fu, Siyuan <siyuan.fu@...>;
Santhapur Naveen <naveens@...>
Subject: [edk2] [Patch] MdeModulePkg: Support classless IP for DHCPv4
TransmitReceive()

The IP address should not be treated as classful one if DHCP options
contain a classless IP with its true subnet mask. Otherwise, DHCPv4
TransmitReceive() will failed. This real subnet mask will be parsed
and recorded in DhcpSb->Netmask. So, we need check it before get the
IP's corresponding subnet mask.

Cc: Santhapur Naveen <naveens@...>
Cc: Ye Ting <ting.ye@...>
Cc: Fu Siyuan <siyuan.fu@...>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@...>
---
.../Universal/Network/Dhcp4Dxe/Dhcp4Impl.c | 28 +++++++++++++++-
------
1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
index 4f491b4..79f7cde 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
@@ -1,9 +1,9 @@
/** @file
This file implement the EFI_DHCP4_PROTOCOL interface.

-Copyright (c) 2006 - 2015, Intel Corporation. All rights
reserved.<BR>
+Copyright (c) 2006 - 2016, 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

@@ -1186,18 +1186,20 @@ Dhcp4InstanceConfigUdpIo (
IN UDP_IO *UdpIo,
IN VOID *Context
)
{
DHCP_PROTOCOL *Instance;
+ DHCP_SERVICE *DhcpSb;
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
EFI_UDP4_CONFIG_DATA UdpConfigData;
IP4_ADDR ClientAddr;
IP4_ADDR Ip;
INTN Class;
IP4_ADDR SubnetMask;

Instance = (DHCP_PROTOCOL *) Context;
+ DhcpSb = Instance->Service;
Token = Instance->Token;

ZeroMem (&UdpConfigData, sizeof (EFI_UDP4_CONFIG_DATA));

UdpConfigData.AcceptBroadcast = TRUE;
@@ -1206,14 +1208,19 @@ Dhcp4InstanceConfigUdpIo (
UdpConfigData.DoNotFragment = TRUE;

ClientAddr = EFI_NTOHL (Token->Packet->Dhcp4.Header.ClientAddr);
Ip = HTONL (ClientAddr);
CopyMem (&UdpConfigData.StationAddress, &Ip, sizeof
(EFI_IPv4_ADDRESS));
-
- Class = NetGetIpClass (ClientAddr);
- ASSERT (Class < IP4_ADDR_CLASSE);
- SubnetMask = gIp4AllMasks[Class << 3];
+
+ if (DhcpSb->Netmask == 0) {
+ Class = NetGetIpClass (ClientAddr);
+ ASSERT (Class < IP4_ADDR_CLASSE);
+ SubnetMask = gIp4AllMasks[Class << 3]; } else {
+ SubnetMask = DhcpSb->Netmask;
+ }
+
Ip = HTONL (SubnetMask);
CopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof
(EFI_IPv4_ADDRESS));

if ((Token->ListenPointCount == 0) ||
(Token->ListenPoints[0].ListenPort
== 0)) {
UdpConfigData.StationPort = DHCP_CLIENT_PORT; @@ -1574,16
+1581,21 @@ EfiDhcp4TransmitReceive (
EndPoint.RemotePort = DHCP_SERVER_PORT;
} else {
EndPoint.RemotePort = Token->RemotePort;
}

+ if (DhcpSb->Netmask == 0) {
+ Class = NetGetIpClass (ClientAddr);
+ ASSERT (Class < IP4_ADDR_CLASSE);
+ SubnetMask = gIp4AllMasks[Class << 3]; } else {
+ SubnetMask = DhcpSb->Netmask;
+ }
+
//
// Get the gateway.
//
- Class = NetGetIpClass (ClientAddr);
- ASSERT (Class < IP4_ADDR_CLASSE);
- SubnetMask = gIp4AllMasks[Class << 3];
ZeroMem (&Gateway, sizeof (Gateway));
if (!IP4_NET_EQUAL (ClientAddr, EndPoint.RemoteAddr.Addr[0],
SubnetMask)) {
CopyMem (&Gateway.v4, &Token->GatewayAddress, sizeof
(EFI_IPv4_ADDRESS));
Gateway.Addr[0] = NTOHL (Gateway.Addr[0]);
}
--
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@...
https://lists.01.org/mailman/listinfo/edk2-devel


Re: DxeCapsuleLib returns Status Issue

Yao, Jiewen
 

Thanks. We reviewed bug till 107 last time, unfortunately.
That is why I did not find it. It will be reviewed next time.

Thank you
Yao Jiewen

From: edk2-devel [mailto:edk2-devel-bounces@...] On Behalf Of Ankit_Singh3@...
Sent: Friday, September 2, 2016 11:25 AM
To: Yao, Jiewen <jiewen.yao@...>; edk2-devel@...
Cc: Dileesh_Onniyil@...; Sumanth_Vidyadhara@...
Subject: Re: [edk2] [EDK2] DxeCapsuleLib returns Status Issue

Hi Jiewen,

Already logged defect for Capsule Status Variable on bugzillar tracker (EDK II) on 31th August.
https://tianocore.acgmultimedia.com/show_bug.cgi?id=108

Regards,
Ankit Singh

From: Yao, Jiewen [mailto:jiewen.yao@...]
Sent: Friday, September 02, 2016 7:21 AM
To: Singh3, Ankit <Ankit_Singh3@...<mailto:Ankit_Singh3@...>>; edk2-devel@...<mailto:edk2-devel@...>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi Ankit Singh
A reminder: We haven't seen you filing a Bugzilla yet.

At same time, we reviewed UEFI spec and raised an open to USWG. (For your information only)


Thank you
Yao Jiewen

From: Yao, Jiewen
Sent: Wednesday, August 31, 2016 8:55 AM
To: Ankit_Singh3@...<mailto:Ankit_Singh3@...<mailto:Ankit_Singh3@...%3cmailto:Ankit_Singh3@...>>; edk2-devel@...<mailto:edk2-devel@...<mailto:edk2-devel@...%3cmailto:edk2-devel@...>>
Cc: Yao, Jiewen <jiewen.yao@...<mailto:jiewen.yao@...<mailto:jiewen.yao@...%3cmailto:jiewen.yao@...>>>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi Ankit Singh
This seems a missing feature in current EDKII. Thanks to catch that.

Would you please file a bugzillar tracker, so that it can recorded?

The Bugzilla is introduced @ http://www.tianocore.org/news/2016/07/22/Bugzilla.html

The URL for Bugzilla is @ https://tianocore.acgmultimedia.com/

Thank you
Yao Jiewen


From: Ankit_Singh3@...<mailto:Ankit_Singh3@...<mailto:Ankit_Singh3@...%3cmailto:Ankit_Singh3@...>> [mailto:Ankit_Singh3@...]
Sent: Tuesday, August 30, 2016 12:05 AM
To: Yao, Jiewen <jiewen.yao@...<mailto:jiewen.yao@...<mailto:jiewen.yao@...%3cmailto:jiewen.yao@...>>>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue


Dell - Internal Use - Confidential
Hi Jiewen,

Thanks for pointing me to Capsule Status Variable (UEFI spec - Section 7.5.6), looks like it exactly what I was expecting. But I looked into latest EDK2 code and could not find it being populated and stored/saved anywhere.

Regards,
Ankit Singh

-----Original Message-----
From: Yao, Jiewen [mailto:jiewen.yao@...]
Sent: Monday, August 29, 2016 1:29 PM
To: Singh3, Ankit ; edk2-devel@...<mailto:edk2-devel@...<mailto:edk2-devel@...%3cmailto:edk2-devel@...>>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi
That is good problem statement.

Do you think we can use Capsule Status Variable to record such information?
It is defined in UEFI spec - "7.5.6 UEFI variable reporting on the Success or any Errors encountered in processing of capsules after restart"

The application can use this standard way to check status.

Thank you
Yao Jiewen


-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@...] On Behalf Of
Ankit_Singh3@...<mailto:Ankit_Singh3@...<mailto:Ankit_Singh3@...%3cmailto:Ankit_Singh3@...>>
Sent: Monday, August 29, 2016 3:51 PM
To: edk2-devel@...<mailto:edk2-devel@...<mailto:edk2-devel@...%3cmailto:edk2-devel@...>>
Subject: [edk2] [EDK2] DxeCapsuleLib returns Status Issue

Dell - Internal Use - Confidential
Hi EDK2 Developers,

We are incorporating DxeCapsuleLib for FMP Capsule Update into our
UEFI product, but we are hitting few issues as described below.

In case of Capsule Update "SetImage" is randomly done for all the FMP
Handles in case Image Type Id GUID and Image Index matches (this is
expected as there might be multiple similar hardware), but looks like
the returns of each FMP update is not handled.
For example if there are 5 FMP handles (can be for different-different
devices) and assume that any particular device handle is at 3rd index,
therefore the update goes through successfully on the 3rd attempt but
since HandleCount value is 5 it tries further with 4th and 5th Handle.
This 4th & 5th Handle attempt can fail for any of the calls within the FMP Handle "for loop"
(HandleProtocol/GetImageInfo) and hence the final status is returned
as FAILURE to application layer.

Below is the code-snippet from DxeCapsuleLib.c , in case of
HandleProtocol & GetImageInfo failure, "for" loop for Handle count is
continued and the previous Status value is over-written with this new
return (return from HandleProtocol & GetImageInfo) and finally returned to application.
[cid:image001.jpg@...]


Proposed Solution:-
Can ProcessFmpCapsuleImage() have an extra OUT parameter which gives
the list of all successful FMP Handles along with the updated GUID
values, so that any application can make the judgment of Update
SUCCESS/FAILURE based on FMP Handle and proceed accordingly at application layer.

Regards,
Ankit Singh

_______________________________________________
edk2-devel mailing list
edk2-devel@...<mailto:edk2-devel@...<mailto:edk2-devel@...%3cmailto:edk2-devel@...>>
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@...<mailto:edk2-devel@...>
https://lists.01.org/mailman/listinfo/edk2-devel


Re: DxeCapsuleLib returns Status Issue

Ankit_Singh3@...
 

Hi Jiewen,

Already logged defect for Capsule Status Variable on bugzillar tracker (EDK II) on 31th August.
https://tianocore.acgmultimedia.com/show_bug.cgi?id=108

Regards,
Ankit Singh

From: Yao, Jiewen [mailto:jiewen.yao@...]
Sent: Friday, September 02, 2016 7:21 AM
To: Singh3, Ankit <Ankit_Singh3@...>; edk2-devel@...
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi Ankit Singh
A reminder: We haven't seen you filing a Bugzilla yet.

At same time, we reviewed UEFI spec and raised an open to USWG. (For your information only)


Thank you
Yao Jiewen

From: Yao, Jiewen
Sent: Wednesday, August 31, 2016 8:55 AM
To: Ankit_Singh3@...<mailto:Ankit_Singh3@...>; edk2-devel@...<mailto:edk2-devel@...>
Cc: Yao, Jiewen <jiewen.yao@...<mailto:jiewen.yao@...>>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi Ankit Singh
This seems a missing feature in current EDKII. Thanks to catch that.

Would you please file a bugzillar tracker, so that it can recorded?

The Bugzilla is introduced @ http://www.tianocore.org/news/2016/07/22/Bugzilla.html

The URL for Bugzilla is @ https://tianocore.acgmultimedia.com/

Thank you
Yao Jiewen


From: Ankit_Singh3@...<mailto:Ankit_Singh3@...> [mailto:Ankit_Singh3@...]
Sent: Tuesday, August 30, 2016 12:05 AM
To: Yao, Jiewen <jiewen.yao@...<mailto:jiewen.yao@...>>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue


Dell - Internal Use - Confidential
Hi Jiewen,

Thanks for pointing me to Capsule Status Variable (UEFI spec - Section 7.5.6), looks like it exactly what I was expecting. But I looked into latest EDK2 code and could not find it being populated and stored/saved anywhere.

Regards,
Ankit Singh

-----Original Message-----
From: Yao, Jiewen [mailto:jiewen.yao@...]
Sent: Monday, August 29, 2016 1:29 PM
To: Singh3, Ankit ; edk2-devel@...<mailto:edk2-devel@...>
Subject: RE: [EDK2] DxeCapsuleLib returns Status Issue

Hi
That is good problem statement.

Do you think we can use Capsule Status Variable to record such information?
It is defined in UEFI spec - "7.5.6 UEFI variable reporting on the Success or any Errors encountered in processing of capsules after restart"

The application can use this standard way to check status.

Thank you
Yao Jiewen


-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@...] On Behalf Of
Ankit_Singh3@...<mailto:Ankit_Singh3@...>
Sent: Monday, August 29, 2016 3:51 PM
To: edk2-devel@...<mailto:edk2-devel@...>
Subject: [edk2] [EDK2] DxeCapsuleLib returns Status Issue

Dell - Internal Use - Confidential
Hi EDK2 Developers,

We are incorporating DxeCapsuleLib for FMP Capsule Update into our
UEFI product, but we are hitting few issues as described below.

In case of Capsule Update "SetImage" is randomly done for all the FMP
Handles in case Image Type Id GUID and Image Index matches (this is
expected as there might be multiple similar hardware), but looks like
the returns of each FMP update is not handled.
For example if there are 5 FMP handles (can be for different-different
devices) and assume that any particular device handle is at 3rd index,
therefore the update goes through successfully on the 3rd attempt but
since HandleCount value is 5 it tries further with 4th and 5th Handle.
This 4th & 5th Handle attempt can fail for any of the calls within the FMP Handle "for loop"
(HandleProtocol/GetImageInfo) and hence the final status is returned
as FAILURE to application layer.

Below is the code-snippet from DxeCapsuleLib.c , in case of
HandleProtocol & GetImageInfo failure, "for" loop for Handle count is
continued and the previous Status value is over-written with this new
return (return from HandleProtocol & GetImageInfo) and finally returned to application.
[cid:image001.jpg@...]


Proposed Solution:-
Can ProcessFmpCapsuleImage() have an extra OUT parameter which gives
the list of all successful FMP Handles along with the updated GUID
values, so that any application can make the judgment of Update
SUCCESS/FAILURE based on FMP Handle and proceed accordingly at application layer.

Regards,
Ankit Singh

_______________________________________________
edk2-devel mailing list
edk2-devel@...<mailto:edk2-devel@...>
https://lists.01.org/mailman/listinfo/edk2-devel