summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrCompiler.cpp4
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrFormPkg.h73
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrSyntax.g147
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c18
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c22
-rw-r--r--CryptoPkg/Library/OpensslLib/EDKII_openssl-0.9.8w.patch17
-rw-r--r--EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c54
-rw-r--r--EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf1
-rw-r--r--EmulatorPkg/Library/EmuBdsLib/BdsPlatform.h6
-rw-r--r--EmulatorPkg/Library/EmuBdsLib/PlatformData.c4
-rw-r--r--EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c55
-rw-r--r--EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf1
-rw-r--r--EmulatorPkg/Unix/Host/EmuThunk.c20
-rw-r--r--FatPkg/EnhancedFatDxe/DiskCache.c4
-rw-r--r--IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c17
-rw-r--r--IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf2
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec13
-rw-r--r--IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoHighLevel.c42
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c1
-rw-r--r--MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c31
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c35
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c150
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c62
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeLoad.c23
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.c41
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.h23
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf2
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c6
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf1
-rw-r--r--MdeModulePkg/Include/Library/NetLib.h89
-rw-r--r--MdeModulePkg/Library/DxeNetLib/DxeNetLib.c214
-rw-r--r--MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c573
-rw-r--r--MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c382
-rw-r--r--MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf1
-rw-r--r--MdeModulePkg/Library/UefiHiiLib/HiiLib.c29
-rw-r--r--MdeModulePkg/MdeModulePkg.dec6
-rw-r--r--MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c4
-rw-r--r--MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c13
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h14
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c2
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c148
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c32
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c71
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c4
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h4
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c53
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c129
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c89
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h3
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c30
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h1
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c40
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c126
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h5
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c164
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h9
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c6
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c208
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c108
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h28
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c29
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c171
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h3
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c62
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c88
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h8
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c125
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c157
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h1
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c6
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h9
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c35
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c125
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/Snp.c6
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/Snp.h4
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c127
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c8
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h3
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c30
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c85
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h8
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c126
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c112
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c4
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h12
-rw-r--r--MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c64
-rw-r--r--MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c4
-rw-r--r--MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c29
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c8
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c2
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c151
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h13
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c3
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c10
-rw-r--r--MdePkg/Include/Guid/EventGroup.h9
-rw-r--r--MdePkg/Include/Library/BaseLib.h30
-rw-r--r--MdePkg/Include/Library/IoLib.h42
-rw-r--r--MdePkg/Include/Library/PciCf8Lib.h17
-rw-r--r--MdePkg/Include/Library/PciExpressLib.h17
-rw-r--r--MdePkg/Include/Library/PciLib.h17
-rw-r--r--MdePkg/Include/Library/PciSegmentLib.h18
-rw-r--r--MdePkg/Include/Library/S3IoLib.h42
-rw-r--r--MdePkg/Include/Library/S3PciLib.h19
-rw-r--r--MdePkg/Include/Pi/PiBootMode.h5
-rw-r--r--MdePkg/Include/Protocol/SmmEndOfDxe.h28
-rw-r--r--MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c42
-rw-r--r--MdePkg/Library/BaseLib/BitField.c38
-rw-r--r--MdePkg/Library/BaseLib/X86Msr.c12
-rw-r--r--MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c17
-rw-r--r--MdePkg/Library/BasePciExpressLib/PciExpressLib.c17
-rw-r--r--MdePkg/Library/BasePciLibCf8/PciLib.c17
-rw-r--r--MdePkg/Library/BasePciLibPciExpress/PciLib.c17
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoff.c388
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h8
-rw-r--r--MdePkg/Library/BaseS3IoLib/S3IoLib.c42
-rw-r--r--MdePkg/Library/BaseS3PciLib/S3PciLib.c17
-rw-r--r--MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c42
-rw-r--r--MdePkg/Library/DxeIoLibEsal/IoHighLevel.c42
-rw-r--r--MdePkg/Library/DxePciLibEsal/PciLib.c17
-rw-r--r--MdePkg/Library/DxePciSegmentLibEsal/PciLib.c17
-rw-r--r--MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c17
-rw-r--r--MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c42
-rw-r--r--MdePkg/Library/PeiPciLibPciCfg2/PciLib.c17
-rw-r--r--MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c18
-rw-r--r--MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c42
-rw-r--r--MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c17
-rw-r--r--MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c17
-rw-r--r--MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c18
-rw-r--r--MdePkg/MdePkg.dec13
-rw-r--r--NetworkPkg/Dhcp6Dxe/ComponentName.c130
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c90
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h3
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c3
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h4
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Io.c6
-rw-r--r--NetworkPkg/IScsiDxe/ComponentName.c148
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDhcp6.c28
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDhcp6.h3
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.c23
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.h5
-rw-r--r--NetworkPkg/IScsiDxe/IScsiIbft.c8
-rw-r--r--NetworkPkg/Ip6Dxe/ComponentName.c139
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Common.c71
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Common.h7
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Driver.c146
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Driver.h7
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6If.c6
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Impl.c6
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Impl.h5
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Nd.c8
-rw-r--r--NetworkPkg/IpSecDxe/ComponentName.c45
-rw-r--r--NetworkPkg/Mtftp6Dxe/ComponentName.c126
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c118
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h3
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c15
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h8
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c16
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Support.c8
-rw-r--r--NetworkPkg/TcpDxe/ComponentName.c226
-rw-r--r--NetworkPkg/TcpDxe/SockInterface.c6
-rw-r--r--NetworkPkg/TcpDxe/Socket.h2
-rw-r--r--NetworkPkg/TcpDxe/TcpDispatcher.c42
-rw-r--r--NetworkPkg/TcpDxe/TcpDriver.c81
-rw-r--r--NetworkPkg/TcpDxe/TcpMain.h10
-rw-r--r--NetworkPkg/Udp6Dxe/ComponentName.c122
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Driver.c101
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Impl.c10
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Impl.h12
-rw-r--r--NetworkPkg/UefiPxeBcDxe/ComponentName.c52
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c2
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h27
-rw-r--r--OptionRomPkg/UndiRuntimeDxe/ComponentName.c365
-rw-r--r--OptionRomPkg/UndiRuntimeDxe/Init.c6
-rw-r--r--OptionRomPkg/UndiRuntimeDxe/Undi32.h6
-rw-r--r--OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf4
-rw-r--r--OvmfPkg/AcpiPlatformDxe/Qemu.c112
-rw-r--r--OvmfPkg/AcpiTables/Dsdt.asl8
-rw-r--r--OvmfPkg/README5
-rwxr-xr-xPandaBoardPkg/build.sh5
-rwxr-xr-xSamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh85
-rw-r--r--SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c7
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c153
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h13
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c10
-rw-r--r--ShellPkg/Application/Shell/Shell.unibin4612 -> 4588 bytes
-rw-r--r--ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c45
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c4
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c2
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c6
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.unibin96884 -> 97104 bytes
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c2
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.unibin153084 -> 152966 bytes
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.unibin70090 -> 69812 bytes
-rw-r--r--ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.unibin38214 -> 38016 bytes
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.unibin111570 -> 111322 bytes
-rw-r--r--ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c48
-rw-r--r--ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.unibin42584 -> 42418 bytes
-rw-r--r--StdLib/Include/Containers/Fifo.h206
-rw-r--r--StdLib/Include/Containers/ModuloUtil.h105
-rw-r--r--StdLib/Include/sys/termios.h154
-rw-r--r--StdLib/LibC/Containers/Common/ModuloUtil.c149
-rw-r--r--StdLib/LibC/Containers/ContainerLib.inf46
-rw-r--r--StdLib/LibC/Containers/Queues/Fifo.c526
-rw-r--r--StdLib/LibC/Main/Main.c4
-rw-r--r--StdLib/LibC/Stdio/fvwrite.c5
-rw-r--r--StdLib/LibC/Uefi/Devices/Console/daConsole.c316
-rw-r--r--StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c32
-rw-r--r--StdLib/LibC/Uefi/Devices/daConsole.inf7
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/CanonRead.c161
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIO.c373
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIO.inf51
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIOecho.c141
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h33
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c288
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h129
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c210
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c89
-rw-r--r--StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c285
-rw-r--r--StdLib/LibC/Uefi/SysCalls.c313
-rw-r--r--StdLib/StdLib.dsc4
-rw-r--r--StdLib/StdLib.inc4
-rw-r--r--StdLibPrivateInternalFiles/Include/Device/IIO.h81
223 files changed, 10791 insertions, 1953 deletions
diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
index d87653f0c4..55fdb05270 100644
--- a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
@@ -596,6 +596,10 @@ CVfrCompiler::AdjustBin (
{
EFI_VFR_RETURN_CODE Status;
+ if (!IS_RUN_STATUS(STATUS_COMPILEED)) {
+ return;
+ }
+
UpdateInfoForDynamicOpcode ();
//
diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
index 09f7cdf30a..614471060d 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -2,7 +2,7 @@
The definition of CFormPkg's member function
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, 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
@@ -433,6 +433,10 @@ public:
return _FLAGS_ZERO (Flags) ? VFR_RETURN_SUCCESS : VFR_RETURN_FLAGS_UNSUPPORTED;
}
+
+ VOID UpdateCIfrQuestionHeader (IN EFI_IFR_QUESTION_HEADER *Header) {
+ mHeader = Header;
+ }
};
/*
@@ -583,6 +587,10 @@ public:
BOOLEAN IsNumericOpcode () {
return IsNumeric;
}
+
+ VOID UpdateCIfrMinMaxStepData (IN MINMAXSTEP_DATA *MinMaxStepData) {
+ mMinMaxStepData = MinMaxStepData;
+ }
};
static CIfrQuestionHeader *gCurrentQuestion = NULL;
@@ -922,14 +930,15 @@ private:
public:
CIfrDefault (
+ IN UINT8 Size,
IN UINT16 DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD,
IN UINT8 Type = EFI_IFR_TYPE_OTHER,
IN EFI_IFR_TYPE_VALUE Value = gZeroEfiIfrTypeValue
- ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)&mDefault),
- CIfrOpHeader (EFI_IFR_DEFAULT_OP, &mDefault->Header) {
+ ) : CIfrObj (EFI_IFR_DEFAULT_OP, (CHAR8 **)&mDefault, Size),
+ CIfrOpHeader (EFI_IFR_DEFAULT_OP, &mDefault->Header, Size) {
mDefault->Type = Type;
- mDefault->Value = Value;
mDefault->DefaultId = DefaultId;
+ memcpy (&(mDefault->Value), &Value, Size - OFFSET_OF (EFI_IFR_DEFAULT, Value));
}
VOID SetDefaultId (IN UINT16 DefaultId) {
@@ -941,7 +950,7 @@ public:
}
VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {
- mDefault->Value = Value;
+ memcpy (&mDefault->Value, &Value, mDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));
}
};
@@ -1299,7 +1308,7 @@ private:
EFI_IFR_NUMERIC *mNumeric;
public:
- CIfrNumeric () : CIfrObj (EFI_IFR_NUMERIC_OP, (CHAR8 **)&mNumeric),
+ CIfrNumeric () : CIfrObj (EFI_IFR_NUMERIC_OP, (CHAR8 **)&mNumeric, sizeof (EFI_IFR_NUMERIC), TRUE),
CIfrOpHeader (EFI_IFR_NUMERIC_OP, &mNumeric->Header),
CIfrQuestionHeader (&mNumeric->Question),
CIfrMinMaxStepData (&mNumeric->data, TRUE) {
@@ -1313,6 +1322,27 @@ public:
gCurrentMinMaxData = NULL;
}
+ VOID ShrinkBinSize (IN UINT16 Size) {
+ //
+ // Update the buffer size which is truly be used later.
+ //
+ ShrinkObjBin(Size);
+ DecLength(Size);
+
+ //
+ // Allocate buffer in gCFormPkg.
+ //
+ _EMIT_PENDING_OBJ();
+
+ //
+ // Update the buffer pointer used by other class.
+ //
+ mNumeric = (EFI_IFR_NUMERIC *) GetObjBinAddr();
+ UpdateHeader (&mNumeric->Header);
+ UpdateCIfrQuestionHeader(&mNumeric->Question);
+ UpdateCIfrMinMaxStepData(&mNumeric->data);
+ }
+
EFI_VFR_RETURN_CODE SetFlags (IN UINT8 HFlags, IN UINT8 LFlags) {
EFI_VFR_RETURN_CODE Ret;
@@ -1335,7 +1365,7 @@ private:
EFI_IFR_ONE_OF *mOneOf;
public:
- CIfrOneOf () : CIfrObj (EFI_IFR_ONE_OF_OP, (CHAR8 **)&mOneOf),
+ CIfrOneOf () : CIfrObj (EFI_IFR_ONE_OF_OP, (CHAR8 **)&mOneOf, sizeof (EFI_IFR_ONE_OF), TRUE),
CIfrOpHeader (EFI_IFR_ONE_OF_OP, &mOneOf->Header),
CIfrQuestionHeader (&mOneOf->Question),
CIfrMinMaxStepData (&mOneOf->data) {
@@ -1364,6 +1394,27 @@ public:
}
return VFR_RETURN_SUCCESS;
}
+
+ VOID ShrinkBinSize (IN UINT16 Size) {
+ //
+ // Update the buffer size which is truly be used later.
+ //
+ ShrinkObjBin(Size);
+ DecLength(Size);
+
+ //
+ // Allocate buffer in gCFormPkg.
+ //
+ _EMIT_PENDING_OBJ();
+
+ //
+ // Update the buffer pointer used by other class.
+ //
+ mOneOf = (EFI_IFR_ONE_OF *) GetObjBinAddr();
+ UpdateHeader (&mOneOf->Header);
+ UpdateCIfrQuestionHeader(&mOneOf->Question);
+ UpdateCIfrMinMaxStepData(&mOneOf->data);
+ }
};
class CIfrString : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
@@ -1626,12 +1677,12 @@ private:
EFI_IFR_ONE_OF_OPTION *mOneOfOption;
public:
- CIfrOneOfOption () : CIfrObj (EFI_IFR_ONE_OF_OPTION_OP, (CHAR8 **)&mOneOfOption),
- CIfrOpHeader (EFI_IFR_ONE_OF_OPTION_OP, &mOneOfOption->Header) {
+ CIfrOneOfOption (UINT8 Size) : CIfrObj (EFI_IFR_ONE_OF_OPTION_OP, (CHAR8 **)&mOneOfOption, Size),
+ CIfrOpHeader (EFI_IFR_ONE_OF_OPTION_OP, &mOneOfOption->Header, Size) {
mOneOfOption->Flags = 0;
mOneOfOption->Option = EFI_STRING_ID_INVALID;
mOneOfOption->Type = EFI_IFR_TYPE_OTHER;
- memset (&mOneOfOption->Value, 0, sizeof (mOneOfOption->Value));
+ memset (&mOneOfOption->Value, 0, Size - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
}
VOID SetOption (IN EFI_STRING_ID Option) {
@@ -1684,7 +1735,7 @@ public:
}
VOID SetValue (IN EFI_IFR_TYPE_VALUE Value) {
- mOneOfOption->Value = Value;
+ memcpy (&mOneOfOption->Value, &Value, mOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
}
UINT8 GetFlags (VOID) {
diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 3c7f0274d1..76d15790c3 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -1,5 +1,5 @@
/*++
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, 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
@@ -591,7 +591,7 @@ vfrFormSetDefinition :
// Declare undefined Question so that they can be used in expression.
//
if (gCFormPkg.HavePendingUnassigned()) {
- gCFormPkg.DeclarePendingQuestion (
+ mParserStatus += gCFormPkg.DeclarePendingQuestion (
gCVfrVarDataTypeDB,
mCVfrDataStorage,
mCVfrQuestionDB,
@@ -1472,6 +1472,8 @@ vfrStatementDefault :
EFI_DEFAULT_ID DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
CHAR8 *VarStoreName = NULL;
EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;
+ UINT8 Size = 0;
+ BOOLEAN TypeError = FALSE;
>>
D:Default
(
@@ -1484,7 +1486,53 @@ vfrStatementDefault :
_PCATCH (VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be between MinValue and MaxValue.");
}
}
- DObj = new CIfrDefault;
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Size = 1;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Size = 2;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Size = 4;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Size = 8;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ Size = 4;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ Size = 3;
+ break;
+
+ case EFI_IFR_TYPE_REF:
+ Size = 22;
+ break;
+
+ case EFI_IFR_TYPE_STRING:
+ Size = 2;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ Size = 1;
+ break;
+
+ default:
+ TypeError = TRUE;
+ Size = sizeof (EFI_IFR_TYPE_VALUE);
+ break;
+ }
+ if (TypeError) {
+ _PCATCH (VFR_RETURN_FATAL_ERROR, D->getLine(), "Default data type error.");
+ }
+ Size += OFFSET_OF (EFI_IFR_DEFAULT, Value);
+ DObj = new CIfrDefault (Size);
DObj->SetLineNo(D->getLine());
DObj->SetType (_GET_CURRQEST_DATATYPE());
DObj->SetValue(Val);
@@ -1991,6 +2039,7 @@ vfrStatementDate :
CHAR8 *VarIdStr[3] = {NULL, };
CIfrDate DObj;
EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
+ UINT8 Size = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (EFI_HII_DATE);
>>
L:Date << DObj.SetLineNo(L->getLine()); >>
(
@@ -2027,7 +2076,7 @@ vfrStatementDate :
DObj.SetHelp (_STOSID(YH->getText()));
if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }
>>
- << {CIfrDefault DefaultObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_DATE, Val); DefaultObj.SetLineNo(L->getLine());} >>
+ << {CIfrDefault DefaultObj(Size, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_DATE, Val); DefaultObj.SetLineNo(L->getLine());} >>
)
( vfrStatementInconsistentIf )*
)
@@ -2155,8 +2204,9 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
vfrStatementNumeric :
<<
CIfrNumeric NObj;
- UINT32 DataTypeSize;
- BOOLEAN IsSupported;
+ UINT32 DataTypeSize;
+ BOOLEAN IsSupported = TRUE;
+ UINT8 ShrinkSize = 0;
>>
L:Numeric << NObj.SetLineNo(L->getLine()); >>
vfrQuestionHeader[NObj] "," << // check data type
@@ -2170,23 +2220,27 @@ vfrStatementNumeric :
{
Key "=" KN:Number "," << AssignQuestionKey (NObj, KN); >>
}
- vfrSetMinMaxStep[NObj]
- vfrStatementQuestionOptionList
- E:EndNumeric <<
- IsSupported = FALSE;
+ vfrSetMinMaxStep[NObj] <<
switch (_GET_CURRQEST_DATATYPE()) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- case EFI_IFR_TYPE_NUM_SIZE_16:
- case EFI_IFR_TYPE_NUM_SIZE_32:
- case EFI_IFR_TYPE_NUM_SIZE_64:
- IsSupported = TRUE;
- break;
- default:
+ //
+ // Base on the type to know the actual used size,shrink the buffer
+ // size allocate before.
+ //
+ case EFI_IFR_TYPE_NUM_SIZE_8: ShrinkSize = 21;break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:ShrinkSize = 18;break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:ShrinkSize = 12;break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:break;
+ default:
+ IsSupported = FALSE;
break;
}
+ NObj.ShrinkBinSize (ShrinkSize);
if (!IsSupported) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Numeric question only support UINT8, UINT16, UINT32 and UINT64 data type.");
}
+ >>
+ vfrStatementQuestionOptionList
+ E:EndNumeric <<
CRT_END_OP (E);
>>
";"
@@ -2233,7 +2287,8 @@ vfrStatementOneOf :
<<
CIfrOneOf OObj;
UINT32 DataTypeSize;
- BOOLEAN IsSupported;
+ BOOLEAN IsSupported = TRUE;
+ UINT8 ShrinkSize = 0;
>>
L:OneOf << OObj.SetLineNo(L->getLine()); >>
vfrQuestionHeader[OObj] "," << //check data type
@@ -2247,22 +2302,27 @@ vfrStatementOneOf :
{
vfrSetMinMaxStep[OObj]
}
- vfrStatementQuestionOptionList
- E:EndOneOf <<
- IsSupported = FALSE;
+ <<
switch (_GET_CURRQEST_DATATYPE()) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- case EFI_IFR_TYPE_NUM_SIZE_16:
- case EFI_IFR_TYPE_NUM_SIZE_32:
- case EFI_IFR_TYPE_NUM_SIZE_64:
- IsSupported = TRUE;
- break;
+ //
+ // Base on the type to know the actual used size,shrink the buffer
+ // size allocate before.
+ //
+ case EFI_IFR_TYPE_NUM_SIZE_8: ShrinkSize = 21;break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:ShrinkSize = 18;break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:ShrinkSize = 12;break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:break;
default:
+ IsSupported = FALSE;
break;
}
+ OObj.ShrinkBinSize (ShrinkSize);
if (!IsSupported) {
_PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "OneOf question only support UINT8, UINT16, UINT32 and UINT64 data type.");
}
+ >>
+ vfrStatementQuestionOptionList
+ E:EndOneOf <<
CRT_END_OP (E);
>>
";"
@@ -2452,6 +2512,7 @@ vfrStatementTime :
CHAR8 *VarIdStr[3] = {NULL, };
CIfrTime TObj;
EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
+ UINT8 Size = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (EFI_HII_TIME);
>>
L:Time << TObj.SetLineNo(L->getLine()); >>
(
@@ -2488,7 +2549,7 @@ vfrStatementTime :
TObj.SetHelp (_STOSID(HH->getText()));
if (VarIdStr[0] != NULL) { delete VarIdStr[0]; } if (VarIdStr[1] != NULL) { delete VarIdStr[1]; } if (VarIdStr[2] != NULL) { delete VarIdStr[2]; }
>>
- << {CIfrDefault DefaultObj(EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_TIME, Val); DefaultObj.SetLineNo(L->getLine());} >>
+ << {CIfrDefault DefaultObj(Size, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_TIME, Val); DefaultObj.SetLineNo(L->getLine());} >>
)
( vfrStatementInconsistentIf )*
)
@@ -2803,11 +2864,35 @@ vfrStatementOptions :
vfrStatementOneOfOption :
<<
- EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
- CIfrOneOfOption OOOObj;
+ EFI_IFR_TYPE_VALUE Val = gZeroEfiIfrTypeValue;
CHAR8 *VarStoreName = NULL;
+ BOOLEAN TypeError = FALSE;
+ UINT8 Size = 0;
+
+ switch (_GET_CURRQEST_DATATYPE()) {
+ case EFI_IFR_TYPE_NUM_SIZE_8: Size = 1; break;
+ case EFI_IFR_TYPE_NUM_SIZE_16: Size = 2; break;
+ case EFI_IFR_TYPE_NUM_SIZE_32: Size = 4; break;
+ case EFI_IFR_TYPE_NUM_SIZE_64: Size = 8; break;
+ case EFI_IFR_TYPE_DATE: Size = 4; break;
+ case EFI_IFR_TYPE_TIME: Size = 3; break;
+ case EFI_IFR_TYPE_REF: Size = 22;break;
+ case EFI_IFR_TYPE_STRING: Size = 2; break;
+ case EFI_IFR_TYPE_BOOLEAN: Size = 1; break;
+ default:
+ TypeError = TRUE;
+ Size = sizeof (EFI_IFR_TYPE_VALUE);
+ break;
+ }
+ Size += OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
+ CIfrOneOfOption OOOObj (Size);
>>
- L:Option << OOOObj.SetLineNo(L->getLine()); >>
+ L:Option <<
+ OOOObj.SetLineNo(L->getLine());
+ if (TypeError) {
+ _PCATCH (VFR_RETURN_FATAL_ERROR, L->getLine(), "Get data type error.");
+ }
+ >>
Text "=" "STRING_TOKEN" "\(" S:Number "\)" "," << OOOObj.SetOption (_STOSID(S->getText())); >>
Value "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] >[Val] ","
<<
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
index 745cf8729f..471fbbbe25 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
@@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include <openssl/pkcs7.h>
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
@@ -543,7 +544,6 @@ Pkcs7Verify (
)
{
PKCS7 *Pkcs7;
- BIO *CertBio;
BIO *DataBio;
BOOLEAN Status;
X509 *Cert;
@@ -562,7 +562,6 @@ Pkcs7Verify (
}
Pkcs7 = NULL;
- CertBio = NULL;
DataBio = NULL;
Cert = NULL;
CertStore = NULL;
@@ -614,12 +613,7 @@ Pkcs7Verify (
//
// Read DER-encoded root certificate and Construct X509 Certificate
//
- CertBio = BIO_new (BIO_s_mem ());
- BIO_write (CertBio, TrustedCert, (int)CertLength);
- if (CertBio == NULL) {
- goto _Exit;
- }
- Cert = d2i_X509_bio (CertBio, NULL);
+ Cert = d2i_X509 (NULL, &TrustedCert, (long) CertLength);
if (Cert == NULL) {
goto _Exit;
}
@@ -649,6 +643,13 @@ Pkcs7Verify (
BIO_write (DataBio, InData, (int)DataLength);
//
+ // OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and
+ // doesn't support the extended key usage for Authenticode Code Signing.
+ // Bypass the certificate purpose checking by enabling any purposes setting.
+ //
+ X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
+
+ //
// Verifies the PKCS#7 signedData structure
//
Status = (BOOLEAN) PKCS7_verify (Pkcs7, NULL, CertStore, DataBio, NULL, PKCS7_BINARY);
@@ -658,7 +659,6 @@ _Exit:
// Release Resources
//
BIO_free (DataBio);
- BIO_free (CertBio);
X509_free (Cert);
X509_STORE_free (CertStore);
PKCS7_free (Pkcs7);
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
index 5959dfe7d9..5abe970cce 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
@@ -38,9 +38,7 @@ X509ConstructCertificate (
OUT UINT8 **SingleX509Cert
)
{
- BIO *CertBio;
X509 *X509Cert;
- BOOLEAN Status;
//
// Check input parameters.
@@ -49,31 +47,17 @@ X509ConstructCertificate (
return FALSE;
}
- Status = FALSE;
-
//
// Read DER-encoded X509 Certificate and Construct X509 object.
//
- CertBio = BIO_new (BIO_s_mem ());
- BIO_write (CertBio, Cert, (int) CertSize);
- if (CertBio == NULL) {
- goto _Exit;
- }
- X509Cert = d2i_X509_bio (CertBio, NULL);
+ X509Cert = d2i_X509 (NULL, &Cert, (long) CertSize);
if (X509Cert == NULL) {
- goto _Exit;
+ return FALSE;
}
*SingleX509Cert = (UINT8 *) X509Cert;
- Status = TRUE;
-_Exit:
- //
- // Release Resources.
- //
- BIO_free (CertBio);
-
- return Status;
+ return TRUE;
}
/**
diff --git a/CryptoPkg/Library/OpensslLib/EDKII_openssl-0.9.8w.patch b/CryptoPkg/Library/OpensslLib/EDKII_openssl-0.9.8w.patch
index a2ba8aeb43..c5f646ee96 100644
--- a/CryptoPkg/Library/OpensslLib/EDKII_openssl-0.9.8w.patch
+++ b/CryptoPkg/Library/OpensslLib/EDKII_openssl-0.9.8w.patch
@@ -260,20 +260,7 @@ Index: crypto/x509/x509_vfy.c
===================================================================
--- crypto/x509/x509_vfy.c (revision 1)
+++ crypto/x509/x509_vfy.c (working copy)
-@@ -386,7 +386,11 @@
-
- static int check_chain_extensions(X509_STORE_CTX *ctx)
- {
--#ifdef OPENSSL_NO_CHAIN_VERIFY
-+#if defined(OPENSSL_NO_CHAIN_VERIFY) || defined(OPENSSL_SYS_UEFI)
-+ /*
-+ NOTE: Bypass KU Flags Checking for UEFI version. There are incorrect KU flag setting
-+ in Authenticode Signing Certificates.
-+ */
- return 1;
- #else
- int i, ok=0, must_be_ca, plen = 0;
-@@ -899,6 +903,10 @@
+@@ -899,6 +899,10 @@
static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
{
@@ -284,7 +271,7 @@ Index: crypto/x509/x509_vfy.c
time_t *ptime;
int i;
-@@ -942,6 +950,7 @@
+@@ -942,6 +946,7 @@
}
return 1;
diff --git a/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c b/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c
index 3d9e85bb36..2efb8400fa 100644
--- a/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c
+++ b/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c
@@ -17,6 +17,7 @@
#include <PiDxe.h>
#include <Library/SerialPortLib.h>
+#include <Library/SerialPortExtLib.h>
#include <Library/EmuThunkLib.h>
@@ -116,4 +117,57 @@ SerialPortPoll (
return gEmuThunk->PollStdIn ();
}
+/**
+ Set the serial device control bits.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+ IN UINT32 Control
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Get the serial device control bits.
+
+ @param Control Control signals read from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+ OUT UINT32 *Control
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Set the serial device attributes.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ )
+{
+ return RETURN_SUCCESS;
+}
diff --git a/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf b/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf
index 81276e6073..119028d465 100644
--- a/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf
+++ b/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf
@@ -30,6 +30,7 @@
[Packages]
MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
EmuThunkLib
diff --git a/EmulatorPkg/Library/EmuBdsLib/BdsPlatform.h b/EmulatorPkg/Library/EmuBdsLib/BdsPlatform.h
index cf2bb3e81c..a099fecda0 100644
--- a/EmulatorPkg/Library/EmuBdsLib/BdsPlatform.h
+++ b/EmulatorPkg/Library/EmuBdsLib/BdsPlatform.h
@@ -42,8 +42,10 @@ extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[];
{ \
END_DEVICE_PATH_TYPE,\
END_ENTIRE_DEVICE_PATH_SUBTYPE,\
- END_DEVICE_PATH_LENGTH,\
- 0\
+ { \
+ END_DEVICE_PATH_LENGTH,\
+ 0\
+ }\
}
diff --git a/EmulatorPkg/Library/EmuBdsLib/PlatformData.c b/EmulatorPkg/Library/EmuBdsLib/PlatformData.c
index 37e35f5e06..977da6a28d 100644
--- a/EmulatorPkg/Library/EmuBdsLib/PlatformData.c
+++ b/EmulatorPkg/Library/EmuBdsLib/PlatformData.c
@@ -32,6 +32,7 @@ EMU_PLATFORM_UGA_DEVICE_PATH gGopDevicePath = {
0
},
{
+ {
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
@@ -39,7 +40,8 @@ EMU_PLATFORM_UGA_DEVICE_PATH gGopDevicePath = {
(UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8)
},
EMU_GRAPHICS_WINDOW_PROTOCOL_GUID,
- 0
+ },
+ 0
},
gEndEntire
};
diff --git a/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c b/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c
index 4ff7144218..3b74a0c325 100644
--- a/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c
+++ b/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c
@@ -18,6 +18,7 @@
#include <PiPei.h>
#include <Library/SerialPortLib.h>
+#include <Library/SerialPortExtLib.h>
#include <Library/PeiServicesLib.h>
#include <Ppi/EmuThunk.h>
@@ -137,4 +138,58 @@ SerialPortPoll (
return FALSE;
}
+/**
+ Set the serial device control bits.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+ IN UINT32 Control
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Get the serial device control bits.
+
+ @param Control Control signals read from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+ OUT UINT32 *Control
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Set the serial device attributes.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ )
+{
+ return RETURN_SUCCESS;
+}
+
diff --git a/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf b/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
index 16450f6da3..d431acdb07 100644
--- a/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
+++ b/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
@@ -33,6 +33,7 @@
[Packages]
MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
PeiServicesLib
diff --git a/EmulatorPkg/Unix/Host/EmuThunk.c b/EmulatorPkg/Unix/Host/EmuThunk.c
index 52875c3bce..a7b12b14e5 100644
--- a/EmulatorPkg/Unix/Host/EmuThunk.c
+++ b/EmulatorPkg/Unix/Host/EmuThunk.c
@@ -259,18 +259,26 @@ QueryPerformanceCounter (
{
#if __APPLE__
UINT64 Start;
- Nanoseconds elapsedNano;
+ static mach_timebase_info_data_t sTimebaseInfo;
+
Start = mach_absolute_time ();
// Convert to nanoseconds.
- // Have to do some pointer fun because AbsoluteToNanoseconds
- // works in terms of UnsignedWide, which is a structure rather
- // than a proper 64-bit integer.
- elapsedNano = AbsoluteToNanoseconds (*(AbsoluteTime *) &Start);
+ // If this is the first time we've run, get the timebase.
+ // We can use denom == 0 to indicate that sTimebaseInfo is
+ // uninitialised because it makes no sense to have a zero
+ // denominator is a fraction.
+
+ if ( sTimebaseInfo.denom == 0 ) {
+ (void) mach_timebase_info(&sTimebaseInfo);
+ }
+
+ // Do the maths. We hope that the multiplication doesn't
+ // overflow; the price you pay for working in fixed point.
- return *(uint64_t *) &elapsedNano;
+ return (Start * sTimebaseInfo.numer) / sTimebaseInfo.denom;
#else
// Need to figure out what to do for Linux?
return 0;
diff --git a/FatPkg/EnhancedFatDxe/DiskCache.c b/FatPkg/EnhancedFatDxe/DiskCache.c
index d738e5ce29..7dbd5d1f5d 100644
--- a/FatPkg/EnhancedFatDxe/DiskCache.c
+++ b/FatPkg/EnhancedFatDxe/DiskCache.c
@@ -1,6 +1,6 @@
/*++
-Copyright (c) 2005 - 2007, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the Software
License Agreement which accompanies this distribution.
@@ -525,7 +525,7 @@ Returns:
//
// Allocate the Fat Cache buffer
//
- CacheBuffer = AllocatePool (FatCacheSize + DataCacheSize);
+ CacheBuffer = AllocateZeroPool (FatCacheSize + DataCacheSize);
if (CacheBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c
index 0381098c8a..99a76c9f21 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBios.c
@@ -682,6 +682,7 @@ LegacyBiosInstall (
LEGACY_BIOS_INSTANCE *Private;
EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable;
EFI_PHYSICAL_ADDRESS MemoryAddress;
+ EFI_PHYSICAL_ADDRESS EbdaReservedBaseAddress;
VOID *MemoryPtr;
EFI_PHYSICAL_ADDRESS MemoryAddressUnder1MB;
UINTN Index;
@@ -880,9 +881,21 @@ LegacyBiosInstall (
//
// Allocate all 32k chunks from 0x60000 ~ 0x88000 for Legacy OPROMs that
// don't use PMM but look for zeroed memory. Note that various non-BBS
- // SCSIs expect different areas to be free
+ // OpROMs expect different areas to be free
//
- for (MemStart = 0x60000; MemStart < 0x88000; MemStart += 0x1000) {
+ EbdaReservedBaseAddress = MemoryAddress;
+ MemoryAddress = PcdGet32 (PcdOpromReservedMemoryBase);
+ MemorySize = PcdGet32 (PcdOpromReservedMemorySize);
+ //
+ // Check if base address and size for reserved memory are 4KB aligned.
+ //
+ ASSERT ((MemoryAddress & 0xFFF) == 0);
+ ASSERT ((MemorySize & 0xFFF) == 0);
+ //
+ // Check if the reserved memory is below EBDA reserved range.
+ //
+ ASSERT ((MemoryAddress < EbdaReservedBaseAddress) && ((MemoryAddress + MemorySize - 1) < EbdaReservedBaseAddress));
+ for (MemStart = MemoryAddress; MemStart < MemoryAddress + MemorySize; MemStart += 0x1000) {
Status = AllocateLegacyMemory (
AllocateAddress,
MemStart,
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
index ea8cb6bd08..a5ad0dfd26 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
@@ -140,6 +140,8 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEndOpromShadowAddress
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLowPmmMemorySize
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize
[Depex]
gEfiLegacyRegion2ProtocolGuid AND gEfiLegacyInterruptProtocolGuid AND gEfiLegacyBiosPlatformProtocolGuid AND gEfiLegacy8259ProtocolGuid AND gEfiGenericMemTestProtocolGuid AND gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
index b4083bc5f4..025ebfb3e2 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
@@ -199,6 +199,19 @@
## The value should be a multiple of 4KB.
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize|0x8000|UINT32|0x30000005
+ ## The PCD is used to specify memory base address for OPROM to find free memory.
+ # Some OPROMs do not use EBDA or PMM to allocate memory for its usage,
+ # instead they find the memory filled with zero from 0x20000.
+ # The value should be a multiple of 4KB.
+ # The range should be below the EBDA reserved range from
+ # (CONVENTIONAL_MEMORY_TOP - PcdEbdaReservedMemorySize) to CONVENTIONAL_MEMORY_TOP.
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase|0x60000|UINT32|0x3000000c
+
+ ## The PCD is used to specify memory size with bytes for OPROM to find free memory.
+ ## The value should be a multiple of 4KB. And the range should be below the EBDA reserved range from
+ # (CONVENTIONAL_MEMORY_TOP - PcdEbdaReservedMemorySize) to CONVENTIONAL_MEMORY_TOP.
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize|0x28000|UINT32|0x3000000d
+
## The PCD is used to specify memory size with page number for a pre-allocated reserved memory to be used
# by PEI in S3 phase. The default size 32K. When changing the value of this PCD, the platform
# developer should make sure the memory size is large enough to meet PEI requiremnt in S3 phase.
diff --git a/IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoHighLevel.c b/IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoHighLevel.c
index c41eb12592..2ba291f415 100644
--- a/IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoHighLevel.c
+++ b/IntelFrameworkPkg/Library/DxeIoLibCpuIo/IoHighLevel.c
@@ -4,7 +4,7 @@
All assertions for bit field operations are handled bit field functions in the
Base Library.
- Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -156,6 +156,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -196,6 +197,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -236,6 +238,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -278,6 +281,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -436,6 +441,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -476,6 +482,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -516,6 +523,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -558,6 +566,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -716,6 +726,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -756,6 +767,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -796,6 +808,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -838,6 +851,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -996,6 +1011,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1036,6 +1052,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1076,6 +1093,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1118,6 +1136,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1276,6 +1296,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1317,6 +1338,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1358,6 +1380,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1400,6 +1423,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1558,6 +1583,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1599,6 +1625,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1640,6 +1667,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1682,6 +1710,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1840,6 +1870,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1881,6 +1912,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1922,6 +1954,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1964,6 +1997,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2122,6 +2157,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2163,6 +2199,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2204,6 +2241,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2246,6 +2284,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
index 190ab799f1..2001175fe7 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
@@ -548,7 +548,6 @@ AhciBuildCommand (
CommandList->AhciCmdA = 1;
CommandList->AhciCmdP = 1;
- CommandList->AhciCmdC = (DataLength == 0) ? 1 : 0;
AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
} else {
diff --git a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
index d44359cfcf..2c79f46ed9 100644
--- a/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
+++ b/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaPassThruExecute.c
@@ -524,7 +524,36 @@ TransferAtaDevice (
Packet->Protocol = mAtaPassThruCmdProtocols[AtaDevice->UdmaValid][IsWrite];
Packet->Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
- Packet->Timeout = ATA_TIMEOUT;
+ //
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | ATA PIO Transfer Mode | Transfer Rate | ATA DMA Transfer Mode | Transfer Rate |
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | PIO Mode 0 | 3.3Mbytes/sec | Single-word DMA Mode 0 | 2.1Mbytes/sec |
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | PIO Mode 1 | 5.2Mbytes/sec | Single-word DMA Mode 1 | 4.2Mbytes/sec |
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | PIO Mode 2 | 8.3Mbytes/sec | Single-word DMA Mode 2 | 8.4Mbytes/sec |
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | PIO Mode 3 | 11.1Mbytes/sec | Multi-word DMA Mode 0 | 4.2Mbytes/sec |
+ // |------------------------|-----------------|------------------------|-----------------|
+ // | PIO Mode 4 | 16.6Mbytes/sec | Multi-word DMA Mode 1 | 13.3Mbytes/sec |
+ // |------------------------|-----------------|------------------------|-----------------|
+ //
+ // As AtaBus is used to manage ATA devices, we have to use the lowest transfer rate to
+ // calculate the possible maximum timeout value for each read/write operation.
+ //
+ if (AtaDevice->UdmaValid) {
+ //
+ // Calculate the maximum timeout value for DMA read/write operation.
+ //
+ Packet->Timeout = EFI_TIMER_PERIOD_SECONDS ((TransferLength * AtaDevice->BlockMedia.BlockSize) / 2100000 + 1);
+ } else {
+ //
+ // Calculate the maximum timeout value for PIO read/write operation
+ //
+ Packet->Timeout = EFI_TIMER_PERIOD_SECONDS ((TransferLength * AtaDevice->BlockMedia.BlockSize) / 3300000 + 1);
+ }
+
return AtaDevicePassThru (AtaDevice, TaskPacket, Event);
}
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 787bdc13a0..59891b814a 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -6,9 +6,10 @@
Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device.
Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached
- to the EHCI controller before the UHCI driver attaches to the companion UHCI controller.
- This way avoids the control transfer on a shared port between EHCI and companion host
- controller when UHCI gets attached earlier than EHCI and a USB 2.0 device inserts.
+ to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or
+ OHCI controller. This way avoids the control transfer on a shared port between EHCI
+ and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a
+ USB 2.0 device inserts.
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -1403,7 +1404,7 @@ EhcDriverBindingSupported (
// Test whether the controller belongs to Ehci type
//
if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)
- || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface !=PCI_IF_UHCI))) {
+ || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI))) {
Status = EFI_UNSUPPORTED;
}
@@ -1690,10 +1691,10 @@ EhcDriverBindingStart (
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN Index;
- UINTN UhciSegmentNumber;
- UINTN UhciBusNumber;
- UINTN UhciDeviceNumber;
- UINTN UhciFunctionNumber;
+ UINTN CompanionSegmentNumber;
+ UINTN CompanionBusNumber;
+ UINTN CompanionDeviceNumber;
+ UINTN CompanionFunctionNumber;
UINTN EhciSegmentNumber;
UINTN EhciBusNumber;
UINTN EhciDeviceNumber;
@@ -1783,19 +1784,19 @@ EhcDriverBindingStart (
goto CLOSE_PCIIO;
}
//
- // determine if the device is UHCI host controller or not. If yes, then find out the
+ // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the
// companion usb ehci host controller and force EHCI driver get attached to it before
- // UHCI driver attaches to UHCI host controller.
+ // UHCI or OHCI driver attaches to UHCI or OHCI host controller.
//
- if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI) &&
+ if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI || UsbClassCReg.ProgInterface == PCI_IF_OHCI) &&
(UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
(UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
Status = PciIo->GetLocation (
PciIo,
- &UhciSegmentNumber,
- &UhciBusNumber,
- &UhciDeviceNumber,
- &UhciFunctionNumber
+ &CompanionSegmentNumber,
+ &CompanionBusNumber,
+ &CompanionDeviceNumber,
+ &CompanionFunctionNumber
);
if (EFI_ERROR (Status)) {
goto CLOSE_PCIIO;
@@ -1853,7 +1854,7 @@ EhcDriverBindingStart (
// Currently, the judgment on the companion usb host controller is through the
// same bus number, which may vary on different platform.
//
- if (EhciBusNumber == UhciBusNumber) {
+ if (EhciBusNumber == CompanionBusNumber) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
@@ -2081,7 +2082,7 @@ EhcDriverBindingStop (
//
// Disable routing of all ports to EHCI controller, so all ports are
- // routed back to the UHCI controller.
+ // routed back to the UHCI or OHCI controller.
//
EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index e03934fa09..b8a1d78a7e 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -140,27 +140,27 @@ XhcReset (
)
{
USB_XHCI_INSTANCE *Xhc;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- Xhc = XHC_FROM_THIS (This);
-
- if (Xhc->DevicePath != NULL) {
- //
- // Report Status Code to indicate reset happens
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
- Xhc->DevicePath
- );
- }
-
- OldTpl = gBS->RaiseTPL (XHC_TPL);
-
- switch (Attributes) {
- case EFI_USB_HC_RESET_GLOBAL:
- //
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Xhc = XHC_FROM_THIS (This);
+
+ if (Xhc->DevicePath != NULL) {
+ //
+ // Report Status Code to indicate reset happens
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
+ Xhc->DevicePath
+ );
+ }
+
+ OldTpl = gBS->RaiseTPL (XHC_TPL);
+
+ switch (Attributes) {
+ case EFI_USB_HC_RESET_GLOBAL:
+ //
// Flow through, same behavior as Host Controller Reset
//
case EFI_USB_HC_RESET_HOST_CONTROLLER:
@@ -932,9 +932,9 @@ XhcControlTransfer (
}
Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *));
if (Xhc->HcCParams.Data.Csz == 0) {
- Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
+ Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0);
} else {
- Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
+ Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0);
}
ASSERT_EFI_ERROR (Status);
} else if (DescriptorType == USB_DESC_TYPE_CONFIG) {
@@ -1007,17 +1007,15 @@ XhcControlTransfer (
if ((State & XHC_PORTSC_PS) >> 10 == 0) {
PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED;
}
- } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
+ } else {
//
- // For high speed hub, its bit9~10 presents the attached device speed.
+ // For high or full/low speed hub, its bit9~10 presents the attached device speed.
//
if (XHC_BIT_IS_SET (State, BIT9)) {
PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED;
} else if (XHC_BIT_IS_SET (State, BIT10)) {
PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED;
}
- } else {
- ASSERT (0);
}
//
@@ -1690,15 +1688,15 @@ ON_EXIT:
@return The allocated and initialized USB_XHCI_INSTANCE structure if created,
otherwise NULL.
-**/
-USB_XHCI_INSTANCE*
-XhcCreateUsbHc (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN UINT64 OriginalPciAttributes
- )
-{
- USB_XHCI_INSTANCE *Xhc;
+**/
+USB_XHCI_INSTANCE*
+XhcCreateUsbHc (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINT64 OriginalPciAttributes
+ )
+{
+ USB_XHCI_INSTANCE *Xhc;
EFI_STATUS Status;
UINT32 PageSize;
UINT16 ExtCapReg;
@@ -1711,13 +1709,13 @@ XhcCreateUsbHc (
//
// Initialize private data structure
- //
- Xhc->Signature = XHCI_INSTANCE_SIG;
- Xhc->PciIo = PciIo;
- Xhc->DevicePath = DevicePath;
- Xhc->OriginalPciAttributes = OriginalPciAttributes;
- CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));
-
+ //
+ Xhc->Signature = XHCI_INSTANCE_SIG;
+ Xhc->PciIo = PciIo;
+ Xhc->DevicePath = DevicePath;
+ Xhc->OriginalPciAttributes = OriginalPciAttributes;
+ CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL));
+
InitializeListHead (&Xhc->AsyncIntTransfers);
//
@@ -1841,13 +1839,13 @@ XhcDriverBindingStart (
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 Supports;
- UINT64 OriginalPciAttributes;
- BOOLEAN PciAttributesSaved;
- USB_XHCI_INSTANCE *Xhc;
- EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
-
- //
- // Open the PciIo Protocol, then enable the USB host controller
+ UINT64 OriginalPciAttributes;
+ BOOLEAN PciAttributesSaved;
+ USB_XHCI_INSTANCE *Xhc;
+ EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
+
+ //
+ // Open the PciIo Protocol, then enable the USB host controller
//
Status = gBS->OpenProtocol (
Controller,
@@ -1859,25 +1857,25 @@ XhcDriverBindingStart (
);
if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Open Device Path Protocol for on USB host controller
- //
- HcDevicePath = NULL;
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &HcDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- PciAttributesSaved = FALSE;
- //
- // Save original PCI attributes
+ return Status;
+ }
+
+ //
+ // Open Device Path Protocol for on USB host controller
+ //
+ HcDevicePath = NULL;
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &HcDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ PciAttributesSaved = FALSE;
+ //
+ // Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
@@ -1912,13 +1910,13 @@ XhcDriverBindingStart (
goto CLOSE_PCIIO;
}
- //
- // Create then install USB2_HC_PROTOCOL
- //
- Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes);
-
- if (Xhc == NULL) {
- DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n"));
+ //
+ // Create then install USB2_HC_PROTOCOL
+ //
+ Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes);
+
+ if (Xhc == NULL) {
+ DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n"));
return EFI_OUT_OF_RESOURCES;
}
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index 324964a81c..c6d96caeb8 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -1815,7 +1815,36 @@ ScsiDiskReadSectors (
}
ByteCount = SectorCount * BlockSize;
- Timeout = EFI_TIMER_PERIOD_SECONDS (2);
+ //
+ // |------------------------|-----------------|------------------|-----------------|
+ // | ATA Transfer Mode | Transfer Rate | SCSI Interface | Transfer Rate |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 0 | 3.3Mbytes/sec | SCSI-1 | 5Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 1 | 5.2Mbytes/sec | Fast SCSI | 10Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 2 | 8.3Mbytes/sec | Fast-Wide SCSI | 20Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 3 | 11.1Mbytes/sec | Ultra SCSI | 20Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 4 | 16.6Mbytes/sec | Ultra Wide SCSI | 40Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 0 | 2.1Mbytes/sec | Ultra2 SCSI | 40Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 1 | 4.2Mbytes/sec | Ultra2 Wide SCSI | 80Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 2 | 8.4Mbytes/sec | Ultra3 SCSI | 160Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Multi-word DMA Mode 0 | 4.2Mbytes/sec | Ultra-320 SCSI | 320Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Multi-word DMA Mode 1 | 13.3Mbytes/sec | Ultra-640 SCSI | 640Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ //
+ // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use
+ // the lowest transfer rate to calculate the possible maximum timeout value for each operation.
+ // From the above table, we could know 2.1Mbytes per second is lowest one.
+ //
+ Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 1);
MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
@@ -1937,7 +1966,36 @@ ScsiDiskWriteSectors (
}
ByteCount = SectorCount * BlockSize;
- Timeout = EFI_TIMER_PERIOD_SECONDS (2);
+ //
+ // |------------------------|-----------------|------------------|-----------------|
+ // | ATA Transfer Mode | Transfer Rate | SCSI Interface | Transfer Rate |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 0 | 3.3Mbytes/sec | SCSI-1 | 5Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 1 | 5.2Mbytes/sec | Fast SCSI | 10Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 2 | 8.3Mbytes/sec | Fast-Wide SCSI | 20Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 3 | 11.1Mbytes/sec | Ultra SCSI | 20Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | PIO Mode 4 | 16.6Mbytes/sec | Ultra Wide SCSI | 40Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 0 | 2.1Mbytes/sec | Ultra2 SCSI | 40Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 1 | 4.2Mbytes/sec | Ultra2 Wide SCSI | 80Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Single-word DMA Mode 2 | 8.4Mbytes/sec | Ultra3 SCSI | 160Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Multi-word DMA Mode 0 | 4.2Mbytes/sec | Ultra-320 SCSI | 320Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ // | Multi-word DMA Mode 1 | 13.3Mbytes/sec | Ultra-640 SCSI | 640Mbytes/sec |
+ // |------------------------|-----------------|------------------|-----------------|
+ //
+ // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use
+ // the lowest transfer rate to calculate the possible maximum timeout value for each operation.
+ // From the above table, we could know 2.1Mbytes per second is lowest one.
+ //
+ Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 1);
MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
if (!ScsiDiskDevice->Cdb16Byte) {
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index 3bcc4b4e32..aa0507686b 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -241,20 +241,25 @@ DxeLoadCore (
NULL,
(VOID **) &PeiRecovery
);
- //
- // Report Status code the failure of locating Recovery PPI
- //
- REPORT_STATUS_CODE (
- EFI_ERROR_CODE | EFI_ERROR_MAJOR,
- (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
- );
- ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));
+ //
+ // Report Status code the failure of locating Recovery PPI
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
+ );
+ CpuDeadLoop ();
+ }
+
REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD));
Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status));
//
- // Report Status code that S3Resume PPI can not be found
+ // Report Status code that recovery image can not be found
//
REPORT_STATUS_CODE (
EFI_ERROR_CODE | EFI_ERROR_MAJOR,
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
index c1b3563d01..a7220e4235 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
@@ -78,6 +78,7 @@ SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = {
{ SmmDriverDispatchHandler, &gEfiEventDxeDispatchGuid, NULL, TRUE },
{ SmmReadyToLockHandler, &gEfiDxeSmmReadyToLockProtocolGuid, NULL, TRUE },
{ SmmLegacyBootHandler, &gEfiEventLegacyBootGuid, NULL, FALSE },
+ { SmmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },
{ NULL, NULL, NULL, FALSE }
};
@@ -229,6 +230,46 @@ SmmReadyToLockHandler (
}
/**
+ Software SMI handler that is called when the EndOfDxe event is signalled.
+ This function installs the SMM EndOfDxe Protocol so SMM Drivers are informed that
+ platform code will invoke 3rd part code.
+
+ @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param Context Points to an optional handler context which was specified when the handler was registered.
+ @param CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param CommBufferSize The size of the CommBuffer.
+
+ @return Status Code
+
+**/
+EFI_STATUS
+EFIAPI
+SmmEndOfDxeHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context, OPTIONAL
+ IN OUT VOID *CommBuffer, OPTIONAL
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE SmmHandle;
+
+ DEBUG ((EFI_D_INFO, "SmmEndOfDxeHandler\n"));
+ //
+ // Install SMM EndOfDxe protocol
+ //
+ SmmHandle = NULL;
+ Status = SmmInstallProtocolInterface (
+ &SmmHandle,
+ &gEfiSmmEndOfDxeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ return EFI_SUCCESS;
+}
+
+/**
The main entry point to SMM Foundation.
Note: This function is only used by SMRAM invocation. It is never used by DXE invocation.
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
index 055363e1ad..5392fb2315 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
@@ -20,6 +20,7 @@
#include <Protocol/DxeSmmReadyToLock.h>
#include <Protocol/SmmReadyToLock.h>
+#include <Protocol/SmmEndOfDxe.h>
#include <Protocol/CpuIo2.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/SmmAccess2.h>
@@ -587,6 +588,28 @@ SmmReadyToLockHandler (
);
/**
+ This function is the main entry point for an SMM handler dispatch
+ or communicate-based callback.
+
+ @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param Context Points to an optional handler context which was specified when the handler was registered.
+ @param CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param CommBufferSize The size of the CommBuffer.
+
+ @return Status Code
+
+**/
+EFI_STATUS
+EFIAPI
+SmmEndOfDxeHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context, OPTIONAL
+ IN OUT VOID *CommBuffer, OPTIONAL
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ );
+
+/**
Place holder function until all the SMM System Table Service are available.
@param Arg1 Undefined
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 1c15c7ec0d..e2ef13e3c1 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -63,6 +63,7 @@
gEfiSmmReadyToLockProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiFirmwareVolume2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmmEndOfDxeProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSecurityArchProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
gEfiSecurity2ArchProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
@@ -76,3 +77,4 @@
gAprioriGuid # ALWAYS_CONSUMED
gEfiEventDxeDispatchGuid # ALWAYS_CONSUMED
gEfiEventLegacyBootGuid # ALWAYS_CONSUMED
+ gEfiEndOfDxeEventGroupGuid # ALWAYS_CONSUMED
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
index bda9996dc8..4686470423 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
@@ -263,6 +263,12 @@ SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = {
//
{ TRUE, TRUE, &gEfiDxeSmmReadyToLockProtocolGuid, SmmIplReadyToLockEventNotify, &gEfiDxeSmmReadyToLockProtocolGuid, TPL_CALLBACK, NULL },
//
+ // Declare event notification on EndOfDxe event. When this notification is etablished,
+ // the associated event is immediately signalled, so the notification function will be executed and the
+ // SMM End Of Dxe Protocol will be found if it is already in the handle database.
+ //
+ { FALSE, TRUE, &gEfiEndOfDxeEventGroupGuid, SmmIplGuidedEventNotify, &gEfiEndOfDxeEventGroupGuid, TPL_CALLBACK, NULL },
+ //
// Declare event notification on the DXE Dispatch Event Group. This event is signaled by the DXE Core
// each time the DXE Core dispatcher has completed its work. When this event is signalled, the SMM Core
// if notified, so the SMM Core can dispatch SMM drivers.
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
index 125a021148..6af4f65b46 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
@@ -64,6 +64,7 @@
gEfiEventReadyToBootGuid # ALWAYS_CONSUMED
gEfiEventLegacyBootGuid # ALWAYS_CONSUMED
gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED
+ gEfiEndOfDxeEventGroupGuid # ALWAYS_CONSUMED
gLoadFixedAddressConfigurationTableGuid # SIMETIMES_CONSUMED
[Pcd]
diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index fa59254a25..7ad8dac446 100644
--- a/MdeModulePkg/Include/Library/NetLib.h
+++ b/MdeModulePkg/Include/Library/NetLib.h
@@ -662,6 +662,73 @@ NetListInsertBefore (
IN OUT LIST_ENTRY *NewEntry
);
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *NET_DESTROY_LINK_LIST_CALLBACK) (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context OPTIONAL
+ );
+
+/**
+ Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.
+
+ Destroy network children list by list traversals is not safe due to graph dependencies between nodes.
+ This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed
+ has been removed from the list or not.
+ If it has been removed, then restart the traversal from the head.
+ If it hasn't been removed, then continue with the next node directly.
+ This function will end the iterate and return the CallBack's last return value if error happens,
+ or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.
+
+ @param[in] List The head of the list.
+ @param[in] CallBack Pointer to the callback function to destroy one node in the list.
+ @param[in] Context Pointer to the callback function's context: corresponds to the
+ parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.
+ @param[out] ListLength The length of the link list if the function returns successfully.
+
+ @retval EFI_SUCCESS Two complete passes are made with no changes in the number of children.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval Others Return the CallBack's last return value.
+
+**/
+EFI_STATUS
+EFIAPI
+NetDestroyLinkList (
+ IN LIST_ENTRY *List,
+ IN NET_DESTROY_LINK_LIST_CALLBACK CallBack,
+ IN VOID *Context, OPTIONAL
+ OUT UINTN *ListLength OPTIONAL
+ );
+
+/**
+ This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.
+
+ @param[in] Handle Handle to be checked.
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval TURE Found the input Handle in ChildHandleBuffer.
+ @retval FALSE Can't find the input Handle in ChildHandleBuffer.
+
+**/
+BOOLEAN
+EFIAPI
+NetIsInHandleBuffer (
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ );
//
// Object container: EFI network stack spec defines various kinds of
@@ -1337,6 +1404,28 @@ NetLibStrToIp6andPrefix (
OUT UINT8 *PrefixLength
);
+/**
+
+ Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.
+ The text representation of address is defined in RFC 4291.
+
+ @param[in] Ip6Address The pointer to the IPv6 address.
+ @param[out] String The buffer to return the converted string.
+ @param[in] StringSize The length in bytes of the input String.
+
+ @retval EFI_SUCCESS Convert to string successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been
+ updated with the size needed to complete the request.
+**/
+EFI_STATUS
+EFIAPI
+NetLibIp6ToStr (
+ IN EFI_IPv6_ADDRESS *Ip6Address,
+ OUT CHAR16 *String,
+ IN UINTN StringSize
+ );
+
//
// Various signatures
//
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index 956f733400..61e4c8c9d1 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -40,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiLib.h>
#define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE
+#define DEFAULT_ZERO_START ((UINTN) ~0)
//
// All the supported IP4 maskes in host byte order.
@@ -1065,6 +1066,116 @@ NetListInsertBefore (
PostEntry->BackLink = NewEntry;
}
+/**
+ Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.
+
+ Destroy network child instance list by list traversals is not safe due to graph dependencies between nodes.
+ This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed
+ has been removed from the list or not.
+ If it has been removed, then restart the traversal from the head.
+ If it hasn't been removed, then continue with the next node directly.
+ This function will end the iterate and return the CallBack's last return value if error happens,
+ or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.
+
+ @param[in] List The head of the list.
+ @param[in] CallBack Pointer to the callback function to destroy one node in the list.
+ @param[in] Context Pointer to the callback function's context: corresponds to the
+ parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.
+ @param[out] ListLength The length of the link list if the function returns successfully.
+
+ @retval EFI_SUCCESS Two complete passes are made with no changes in the number of children.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval Others Return the CallBack's last return value.
+
+**/
+EFI_STATUS
+EFIAPI
+NetDestroyLinkList (
+ IN LIST_ENTRY *List,
+ IN NET_DESTROY_LINK_LIST_CALLBACK CallBack,
+ IN VOID *Context, OPTIONAL
+ OUT UINTN *ListLength OPTIONAL
+ )
+{
+ UINTN PreviousLength;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *Ptr;
+ UINTN Length;
+ EFI_STATUS Status;
+
+ if (List == NULL || CallBack == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Length = 0;
+ do {
+ PreviousLength = Length;
+ Entry = GetFirstNode (List);
+ while (!IsNull (List, Entry)) {
+ Status = CallBack (Entry, Context);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Walk through the list to see whether the Entry has been removed or not.
+ // If the Entry still exists, just try to destroy the next one.
+ // If not, go back to the start point to iterate the list again.
+ //
+ for (Ptr = List->ForwardLink; Ptr != List; Ptr = Ptr->ForwardLink) {
+ if (Ptr == Entry) {
+ break;
+ }
+ }
+ if (Ptr == Entry) {
+ Entry = GetNextNode (List, Entry);
+ } else {
+ Entry = GetFirstNode (List);
+ }
+ }
+ for (Length = 0, Ptr = List->ForwardLink; Ptr != List; Length++, Ptr = Ptr->ForwardLink);
+ } while (Length != PreviousLength);
+
+ if (ListLength != NULL) {
+ *ListLength = Length;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.
+
+ @param[in] Handle Handle to be checked.
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval TURE Found the input Handle in ChildHandleBuffer.
+ @retval FALSE Can't find the input Handle in ChildHandleBuffer.
+
+**/
+BOOLEAN
+EFIAPI
+NetIsInHandleBuffer (
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ )
+{
+ UINTN Index;
+
+ if (NumberOfChildren == 0 || ChildHandleBuffer == NULL) {
+ return FALSE;
+ }
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ if (Handle == ChildHandleBuffer[Index]) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/**
Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
@@ -3175,7 +3286,110 @@ Exit:
return Status;
}
+/**
+
+ Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.
+ The text representation of address is defined in RFC 4291.
+
+ @param[in] Ip6Address The pointer to the IPv6 address.
+ @param[out] String The buffer to return the converted string.
+ @param[in] StringSize The length in bytes of the input String.
+
+ @retval EFI_SUCCESS Convert to string successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been
+ updated with the size needed to complete the request.
+**/
+EFI_STATUS
+EFIAPI
+NetLibIp6ToStr (
+ IN EFI_IPv6_ADDRESS *Ip6Address,
+ OUT CHAR16 *String,
+ IN UINTN StringSize
+ )
+{
+ UINT16 Ip6Addr[8];
+ UINTN Index;
+ UINTN LongestZerosStart;
+ UINTN LongestZerosLength;
+ UINTN CurrentZerosStart;
+ UINTN CurrentZerosLength;
+ CHAR16 Buffer[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+ CHAR16 *Ptr;
+
+ if (Ip6Address == NULL || String == NULL || StringSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert the UINT8 array to an UINT16 array for easy handling.
+ //
+ ZeroMem (Ip6Addr, sizeof (Ip6Addr));
+ for (Index = 0; Index < 16; Index++) {
+ Ip6Addr[Index / 2] |= (Ip6Address->Addr[Index] << ((1 - (Index % 2)) << 3));
+ }
+ //
+ // Find the longest zeros and mark it.
+ //
+ CurrentZerosStart = DEFAULT_ZERO_START;
+ CurrentZerosLength = 0;
+ LongestZerosStart = DEFAULT_ZERO_START;
+ LongestZerosLength = 0;
+ for (Index = 0; Index < 8; Index++) {
+ if (Ip6Addr[Index] == 0) {
+ if (CurrentZerosStart == DEFAULT_ZERO_START) {
+ CurrentZerosStart = Index;
+ CurrentZerosLength = 1;
+ } else {
+ CurrentZerosLength++;
+ }
+ } else {
+ if (CurrentZerosStart != DEFAULT_ZERO_START) {
+ if (CurrentZerosLength > 2 && (LongestZerosStart == (DEFAULT_ZERO_START) || CurrentZerosLength > LongestZerosLength)) {
+ LongestZerosStart = CurrentZerosStart;
+ LongestZerosLength = CurrentZerosLength;
+ }
+ CurrentZerosStart = DEFAULT_ZERO_START;
+ CurrentZerosLength = 0;
+ }
+ }
+ }
+
+ if (CurrentZerosStart != DEFAULT_ZERO_START && CurrentZerosLength > 2) {
+ if (LongestZerosStart == DEFAULT_ZERO_START || LongestZerosLength < CurrentZerosLength) {
+ LongestZerosStart = CurrentZerosStart;
+ LongestZerosLength = CurrentZerosLength;
+ }
+ }
+
+ Ptr = Buffer;
+ for (Index = 0; Index < 8; Index++) {
+ if (LongestZerosStart != DEFAULT_ZERO_START && Index >= LongestZerosStart && Index < LongestZerosStart + LongestZerosLength) {
+ if (Index == LongestZerosStart) {
+ *Ptr++ = L':';
+ }
+ continue;
+ }
+ if (Index != 0) {
+ *Ptr++ = L':';
+ }
+ Ptr += UnicodeSPrint(Ptr, 10, L"%x", Ip6Addr[Index]);
+ }
+
+ if (LongestZerosStart != DEFAULT_ZERO_START && LongestZerosStart + LongestZerosLength == 8) {
+ *Ptr++ = L':';
+ }
+ *Ptr = L'\0';
+
+ if ((UINTN)Ptr - (UINTN)Buffer > StringSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ StrCpy (String, Buffer);
+
+ return EFI_SUCCESS;
+}
/**
This function obtains the system guid from the smbios table.
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
index 01ca7df7ce..afb4c10776 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
@@ -16,107 +16,6 @@
#include "InternalBootScriptLib.h"
/**
- Checks the parameter of SmbusExecute().
-
- This function checks the input parameters of SmbusExecute(). If the input parameters are valid
- for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
- error code based on the input SMBus bus protocol.
-
- @param SmBusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,
- and PEC.
- @param Operation Signifies which particular SMBus hardware protocol instance that
- it will use to execute the SMBus transactions. This SMBus
- hardware protocol is defined by the SMBus Specification and is
- not related to EFI.
- @param Length Signifies the number of bytes that this operation will do. The
- maximum number of bytes can be revision specific and operation
- specific. This field will contain the actual number of bytes that
- are executed for this operation. Not all operations require this
- argument.
- @param Buffer Contains the value of data to execute to the SMBus slave device.
- Not all operations require this argument. The length of this
- buffer is identified by Length.
-
- @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus
- protocol.
- @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
- @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
- and EfiSmbusQuickWrite. Length is outside the range of valid
- values.
- @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
- @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
-
-**/
-EFI_STATUS
-CheckParameters (
- IN UINTN SmBusAddress,
- IN EFI_SMBUS_OPERATION Operation,
- IN OUT UINTN *Length,
- IN OUT VOID *Buffer
- )
-{
- EFI_STATUS Status;
- UINTN RequiredLen;
- EFI_SMBUS_DEVICE_COMMAND Command;
- BOOLEAN PecCheck;
-
- Command = SMBUS_LIB_COMMAND (SmBusAddress);
- PecCheck = SMBUS_LIB_PEC (SmBusAddress);
- //
- // Set default value to be 2:
- // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
- //
- RequiredLen = 2;
- Status = EFI_SUCCESS;
- switch (Operation) {
- case EfiSmbusQuickRead:
- case EfiSmbusQuickWrite:
- if (PecCheck || Command != 0) {
- return EFI_UNSUPPORTED;
- }
- break;
- case EfiSmbusReceiveByte:
- case EfiSmbusSendByte:
- if (Command != 0) {
- return EFI_UNSUPPORTED;
- }
- //
- // Cascade to check length parameter.
- //
- case EfiSmbusReadByte:
- case EfiSmbusWriteByte:
- RequiredLen = 1;
- //
- // Cascade to check length parameter.
- //
- case EfiSmbusReadWord:
- case EfiSmbusWriteWord:
- case EfiSmbusProcessCall:
- if (Buffer == NULL || Length == NULL) {
- return EFI_INVALID_PARAMETER;
- } else if (*Length < RequiredLen) {
- Status = EFI_BUFFER_TOO_SMALL;
- }
- *Length = RequiredLen;
- break;
- case EfiSmbusReadBlock:
- case EfiSmbusWriteBlock:
- if ((Buffer == NULL) ||
- (Length == NULL) ||
- (*Length < MIN_SMBUS_BLOCK_LEN) ||
- (*Length > MAX_SMBUS_BLOCK_LEN)) {
- return EFI_INVALID_PARAMETER;
- }
- break;
- case EfiSmbusBWBRProcessCall:
- return EFI_UNSUPPORTED;
- default:
- return EFI_INVALID_PARAMETER;
- }
- return Status;
-}
-
-/**
Executes an SMBus operation to an SMBus controller. Returns when either the command has been
executed or an error is encountered in doing the operation.
@@ -166,14 +65,8 @@ SmbusExecute (
)
{
EFI_STATUS Status;
- UINTN WorkBufferLen;
UINT8 WorkBuffer[MAX_SMBUS_BLOCK_LEN];
- Status = CheckParameters (SmbusAddress, Operation, Length, Buffer);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
switch (Operation) {
case EfiSmbusQuickRead:
DEBUG ((EFI_D_INFO, "EfiSmbusQuickRead - 0x%08x\n", SmbusAddress));
@@ -185,15 +78,15 @@ SmbusExecute (
break;
case EfiSmbusReceiveByte:
DEBUG ((EFI_D_INFO, "EfiSmbusReceiveByte - 0x%08x\n", SmbusAddress));
- *(UINT8 *) Buffer = SmBusReceiveByte (SmbusAddress, &Status);
+ SmBusReceiveByte (SmbusAddress, &Status);
break;
case EfiSmbusSendByte:
- DEBUG ((EFI_D_INFO, "EfiSmbusReceiveByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));
+ DEBUG ((EFI_D_INFO, "EfiSmbusSendByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));
SmBusSendByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
break;
case EfiSmbusReadByte:
DEBUG ((EFI_D_INFO, "EfiSmbusReadByte - 0x%08x\n", SmbusAddress));
- *(UINT8 *) Buffer = SmBusReadDataByte (SmbusAddress, &Status);
+ SmBusReadDataByte (SmbusAddress, &Status);
break;
case EfiSmbusWriteByte:
DEBUG ((EFI_D_INFO, "EfiSmbusWriteByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));
@@ -201,41 +94,30 @@ SmbusExecute (
break;
case EfiSmbusReadWord:
DEBUG ((EFI_D_INFO, "EfiSmbusReadWord - 0x%08x\n", SmbusAddress));
- *(UINT16 *) Buffer = SmBusReadDataWord (SmbusAddress, &Status);
+ SmBusReadDataWord (SmbusAddress, &Status);
break;
case EfiSmbusWriteWord:
- DEBUG ((EFI_D_INFO, "EfiSmbusWriteByte - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
+ DEBUG ((EFI_D_INFO, "EfiSmbusWriteWord - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
SmBusWriteDataWord (SmbusAddress, *(UINT16 *) Buffer, &Status);
break;
case EfiSmbusProcessCall:
DEBUG ((EFI_D_INFO, "EfiSmbusProcessCall - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
- *(UINT16 *) Buffer = SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);
+ SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);
break;
case EfiSmbusReadBlock:
DEBUG ((EFI_D_INFO, "EfiSmbusReadBlock - 0x%08x\n", SmbusAddress));
- WorkBufferLen = SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
- if (!EFI_ERROR (Status)) {
- //
- // Read block transaction is complete successfully, and then
- // check whether the output buffer is large enough.
- //
- if (*Length >= WorkBufferLen) {
- CopyMem (Buffer, WorkBuffer, WorkBufferLen);
- } else {
- Status = EFI_BUFFER_TOO_SMALL;
- }
- *Length = WorkBufferLen;
- }
+ SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
break;
case EfiSmbusWriteBlock:
- DEBUG ((EFI_D_INFO, "EfiSmbusWriteBlock - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
- SmBusWriteBlock ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)) , Buffer, &Status);
+ DEBUG ((EFI_D_INFO, "EfiSmbusWriteBlock - 0x%08x\n", SmbusAddress));
+ SmBusWriteBlock ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)), Buffer, &Status);
break;
case EfiSmbusBWBRProcessCall:
- //
- // BUGBUG: Should this case be handled?
- //
+ DEBUG ((EFI_D_INFO, "EfiSmbusBWBRProcessCall - 0x%08x\n", SmbusAddress));
+ SmBusBlockProcessCall ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)), Buffer, WorkBuffer, &Status);
break;
+ default:
+ return EFI_INVALID_PARAMETER;
}
return Status;
@@ -287,7 +169,7 @@ BuildLoopData (
}
/**
- Translates boot script to MDE library interface.
+ Perform IO read operation
@param[in] Width Width of the operation.
@param[in] Address Address of the operation.
@@ -331,26 +213,57 @@ ScriptIoRead (
switch (Width) {
case S3BootScriptWidthUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint8 = IoRead8 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint8 = IoRead8 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint8:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8Read - 0x%08x\n", Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN) Address));
*Out.Uint8 = IoRead8 ((UINTN) Address);
break;
case S3BootScriptWidthUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint16 = IoRead16 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint16 = IoRead16 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint16:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16Read - 0x%08x\n", Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN) Address));
*Out.Uint16 = IoRead16 ((UINTN) Address);
break;
case S3BootScriptWidthUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint32 = IoRead32 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint32 = IoRead32 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint32:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32Read - 0x%08x\n", Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN) Address));
*Out.Uint32 = IoRead32 ((UINTN) Address);
break;
+ case S3BootScriptWidthUint64:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint64 = IoRead64 ((UINTN) Address);
+ break;
+ case S3BootScriptWidthFifoUint64:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint64 = IoRead64 ((UINTN) Address);
+ break;
+ case S3BootScriptWidthFillUint64:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN) Address));
+ *Out.Uint64 = IoRead64 ((UINTN) Address);
+ break;
+
default:
return EFI_INVALID_PARAMETER;
}
@@ -360,7 +273,7 @@ ScriptIoRead (
}
/**
- Perform a write operation
+ Perform IO write operation
@param[in] Width Width of the operation.
@param[in] Address Address of the operation.
@@ -463,7 +376,7 @@ ScriptIoWrite (
return EFI_SUCCESS;
}
/**
- Interprete the IO write entry in S3 boot script and perform the write operation
+ Interprete the boot script node with EFI_BOOT_SCRIPT_IO_WRITE OP code.
@param Script Pointer to the node which is to be interpreted.
@@ -490,7 +403,8 @@ BootScriptExecuteIoWrite (
Address = IoWrite.Address;
Count = IoWrite.Count;
Buffer = Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE);
-
+
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteIoWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));
return ScriptIoWrite(Width, Address, Count, Buffer);
}
/**
@@ -534,30 +448,54 @@ ScriptMemoryRead (
for (; Count > 0; Count--, Address += AddressStride, Out.Buf += BufferStride) {
switch (Width) {
case S3BootScriptWidthUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint8 = MmioRead8 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint8 = MmioRead8 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint8:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN)Address));
*Out.Uint8 = MmioRead8 ((UINTN) Address);
break;
case S3BootScriptWidthUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint16 = MmioRead16 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint16 = MmioRead16 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint16:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN)Address));
*Out.Uint16 = MmioRead16 ((UINTN) Address);
break;
case S3BootScriptWidthUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint32 = MmioRead32 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint32 = MmioRead32 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint32:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN)Address));
*Out.Uint32 = MmioRead32 ((UINTN) Address);
break;
case S3BootScriptWidthUint64:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint64 = MmioRead64 ((UINTN) Address);
+ break;
case S3BootScriptWidthFifoUint64:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN)Address));
+ *Out.Uint64 = MmioRead64 ((UINTN) Address);
+ break;
case S3BootScriptWidthFillUint64:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN)Address));
*Out.Uint64 = MmioRead64 ((UINTN) Address);
break;
@@ -569,7 +507,7 @@ ScriptMemoryRead (
return EFI_SUCCESS;
}
/**
- Translates boot script to MDE library interface.
+ Perform memory write operation
@param Width Width of the operation.
@param Address Address of the operation.
@@ -696,99 +634,190 @@ BootScriptExecuteMemoryWrite (
Count = MemWrite.Count;
Buffer = Script + sizeof(EFI_BOOT_SCRIPT_MEM_WRITE);
- DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, (UINTN)Count, (UINTN)Width));
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));
return ScriptMemoryWrite (Width,Address, Count, Buffer);
}
/**
- Translates boot script to MDE library interface for PCI configuration read operation
+ Performance PCI configuration read operation
@param Width Width of the operation.
@param Address Address of the operation.
- @param Buffer Pointer to the buffer reaf from PCI config space
+ @param Count Count of the number of accesses to perform.
+ @param Buffer Pointer to the buffer read from PCI config space
@retval EFI_SUCCESS The read succeed.
@retval EFI_INVALID_PARAMETER if Width is not defined
-
+ @note A known Limitations in the implementation which is 64bits operations are not supported.
+
**/
EFI_STATUS
ScriptPciCfgRead (
IN S3_BOOT_SCRIPT_LIB_WIDTH Width,
IN UINT64 Address,
+ IN UINTN Count,
OUT VOID *Buffer
)
{
+ EFI_STATUS Status;
+ UINTN AddressStride;
+ UINTN BufferStride;
+ PTR Out;
+ UINTN PciAddress;
+
+ Out.Buf = (UINT8 *) Buffer;
+
+ PciAddress = PCI_ADDRESS_ENCODE (Address);
+
+ Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Loop for each iteration and move the data
+ //
+ for (; Count > 0; Count--, PciAddress += AddressStride, Out.Buf += BufferStride) {
switch (Width) {
case S3BootScriptWidthUint8:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx\n", Address));
- * (UINT8 *) Buffer = PciRead8 (PCI_ADDRESS_ENCODE(Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", PciAddress));
+ *Out.Uint8 = PciRead8 (PciAddress);
+ break;
+ case S3BootScriptWidthFifoUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", PciAddress));
+ *Out.Uint8 = PciRead8 (PciAddress);
+ break;
+ case S3BootScriptWidthFillUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", PciAddress));
+ *Out.Uint8 = PciRead8 (PciAddress);
break;
case S3BootScriptWidthUint16:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx\n", Address));
- * (UINT16 *) Buffer = PciRead16 (PCI_ADDRESS_ENCODE(Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", PciAddress));
+ *Out.Uint16 = PciRead16 (PciAddress);
+ break;
+ case S3BootScriptWidthFifoUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", PciAddress));
+ *Out.Uint16 = PciRead16 (PciAddress);
+ break;
+ case S3BootScriptWidthFillUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", PciAddress));
+ *Out.Uint16 = PciRead16 (PciAddress);
break;
case S3BootScriptWidthUint32:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx\n", Address));
- * (UINT32 *) Buffer = PciRead32 (PCI_ADDRESS_ENCODE(Address));
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", PciAddress));
+ *Out.Uint32 = PciRead32 (PciAddress);
+ break;
+ case S3BootScriptWidthFifoUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", PciAddress));
+ *Out.Uint32 = PciRead32 (PciAddress);
+ break;
+ case S3BootScriptWidthFillUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", PciAddress));
+ *Out.Uint32 = PciRead32 (PciAddress);
break;
default:
return EFI_INVALID_PARAMETER;
+ }
}
- return EFI_SUCCESS;
+ return EFI_SUCCESS;
}
/**
- Translates boot script to MDE library interface for PCI configuration write operation
+ Performance PCI configuration write operation
@param Width Width of the operation.
@param Address Address of the operation.
- @param Buffer Pointer to the buffer reaf from PCI config space
+ @param Count Count of the number of accesses to perform.
+ @param Buffer Pointer to the buffer write to PCI config space
@retval EFI_SUCCESS The write succeed.
@retval EFI_INVALID_PARAMETER if Width is not defined
-
+ @note A known Limitations in the implementation which is 64bits operations are not supported.
+
**/
EFI_STATUS
ScriptPciCfgWrite (
IN S3_BOOT_SCRIPT_LIB_WIDTH Width,
IN UINT64 Address,
- OUT VOID *Buffer
+ IN UINTN Count,
+ IN VOID *Buffer
)
{
- switch (Width) {
- case S3BootScriptWidthUint8:
- case S3BootScriptWidthFifoUint8:
- case S3BootScriptWidthFillUint8:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx (0x%02x)\n", Address, (UINTN)*(UINT8 *) Buffer));
- PciWrite8 (PCI_ADDRESS_ENCODE(Address), *(UINT8 *) Buffer);
- break;
- case S3BootScriptWidthUint16:
- case S3BootScriptWidthFifoUint16:
- case S3BootScriptWidthFillUint16:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx (0x%04x)\n", Address, (UINTN)*(UINT16 *) Buffer));
- PciWrite16 (PCI_ADDRESS_ENCODE(Address), *(UINT16 *) Buffer);
- break;
- case S3BootScriptWidthUint32:
- case S3BootScriptWidthFifoUint32:
- case S3BootScriptWidthFillUint32:
- DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx (0x%08x)\n", Address, (UINTN)*(UINT32 *) Buffer));
- PciWrite32 (PCI_ADDRESS_ENCODE(Address), *(UINT32 *) Buffer);
- break;
- default:
- return EFI_INVALID_PARAMETER;
+ EFI_STATUS Status;
+ UINTN AddressStride;
+ UINTN BufferStride;
+ UINTN OriginalPciAddress;
+ PTR In;
+ PTR OriginalIn;
+ UINTN PciAddress;
+
+ In.Buf = (UINT8 *) Buffer;
+
+ PciAddress = PCI_ADDRESS_ENCODE (Address);
+
+ Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
- return EFI_SUCCESS;
+ //
+ // Loop for each iteration and move the data
+ //
+ OriginalPciAddress = PciAddress;
+ OriginalIn.Buf = In.Buf;
+ for (; Count > 0; Count--, PciAddress += AddressStride, In.Buf += BufferStride) {
+ switch (Width) {
+ case S3BootScriptWidthUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));
+ PciWrite8 (PciAddress, *In.Uint8);
+ break;
+ case S3BootScriptWidthFifoUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));
+ PciWrite8 (OriginalPciAddress, *In.Uint8);
+ break;
+ case S3BootScriptWidthFillUint8:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));
+ PciWrite8 (PciAddress, *OriginalIn.Uint8);
+ break;
+ case S3BootScriptWidthUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));
+ PciWrite16 (PciAddress, *In.Uint16);
+ break;
+ case S3BootScriptWidthFifoUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));
+ PciWrite16 (OriginalPciAddress, *In.Uint16);
+ break;
+ case S3BootScriptWidthFillUint16:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));
+ PciWrite16 (PciAddress, *OriginalIn.Uint16);
+ break;
+ case S3BootScriptWidthUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));
+ PciWrite32 (PciAddress, *In.Uint32);
+ break;
+ case S3BootScriptWidthFifoUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));
+ PciWrite32 (OriginalPciAddress, *In.Uint32);
+ break;
+ case S3BootScriptWidthFillUint32:
+ DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)PciAddress, (UINTN)*OriginalIn.Uint32));
+ PciWrite32 (PciAddress, *OriginalIn.Uint32);
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ return EFI_SUCCESS;
}
/**
- Perform pci configure 2 read operation.
+ Performance PCI configuration 2 read operation
@param Width Width of the operation.
@param Segment Pci segment number
@param Address Address of the operation.
- @param Buffer Pointer to the buffer to write to I/O space.
+ @param Count Count of the number of accesses to perform.
+ @param Buffer Pointer to the buffer to read from PCI config space.
@retval EFI_SUCCESS The data was written to the EFI System.
@retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
@@ -803,20 +832,22 @@ ScriptPciCfg2Read (
IN S3_BOOT_SCRIPT_LIB_WIDTH Width,
IN UINT16 Segment,
IN UINT64 Address,
+ IN UINTN Count,
OUT VOID *Buffer
)
{
ASSERT (Segment==0);
- return ScriptPciCfgRead (Width, Address, Buffer);
+ return ScriptPciCfgRead (Width, Address, Count, Buffer);
}
/**
- Perform pci configure write operation.
+ Performance PCI configuration 2 write operation
@param Width Width of the operation.
@param Segment Pci segment number
@param Address Address of the operation.
- @param Buffer Pointer to the buffer to write to I/O space.
+ @param Count Count of the number of accesses to perform.
+ @param Buffer Pointer to the buffer to write to PCI config space.
@retval EFI_SUCCESS The data was written to the EFI System.
@retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
@@ -833,14 +864,15 @@ ScriptPciCfg2Write (
IN S3_BOOT_SCRIPT_LIB_WIDTH Width,
IN UINT16 Segment,
IN UINT64 Address,
- OUT VOID *Buffer
+ IN UINTN Count,
+ IN VOID *Buffer
)
{
ASSERT (Segment==0);
- return ScriptPciCfgWrite (Width, Address, Buffer);
+ return ScriptPciCfgWrite (Width, Address, Count, Buffer);
}
/**
- Perform Pci configuration Write operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE OP code.
@param Script The pointer of typed node in boot script table
@@ -851,50 +883,24 @@ BootScriptExecutePciCfgWrite (
IN UINT8 *Script
)
{
- EFI_STATUS Status;
- UINT8 *Buffer;
- UINTN DataWidth;
- UINTN Index;
- UINT64 PciAddress;
- UINT8 Reg;
- EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE PciConfigWrite;
-
- CopyMem ((VOID*)&PciConfigWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));
- Status = EFI_SUCCESS;
-
- PciAddress = PciConfigWrite.Address;
- DataWidth = (UINT32)(0x01 << (PciConfigWrite.Width));
- Buffer = Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE);
-
- DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)PciAddress, (UINTN)PciConfigWrite.Count, (UINTN)DataWidth));
-
- for (Index = 0; Index < PciConfigWrite.Count; Index++) {
- Status = ScriptPciCfgWrite (
- (S3_BOOT_SCRIPT_LIB_WIDTH) PciConfigWrite.Width,
- PciAddress,
- Buffer
- );
+ VOID *Buffer;
+ S3_BOOT_SCRIPT_LIB_WIDTH Width;
+ UINT64 Address;
+ UINTN Count;
+ EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE PciCfgWrite;
- if ( S3BootScriptWidthFillUint8 != PciConfigWrite.Width ||
- S3BootScriptWidthFillUint16 != PciConfigWrite.Width ||
- S3BootScriptWidthFillUint32 != PciConfigWrite.Width ||
- S3BootScriptWidthFillUint64 != PciConfigWrite.Width){
- Reg = (UINT8) ((UINT8) PciAddress + DataWidth);
- PciAddress = (PciAddress & 0xFFFFFFFFFFFFFF00ULL) + Reg;
- }
+ CopyMem ((VOID*)&PciCfgWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));
- if (S3BootScriptWidthFifoUint8 != PciConfigWrite.Width ||
- S3BootScriptWidthFifoUint16 != PciConfigWrite.Width ||
- S3BootScriptWidthFifoUint32 != PciConfigWrite.Width ||
- S3BootScriptWidthFifoUint64 != PciConfigWrite.Width) {
- Buffer += DataWidth;
- }
- }
+ Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgWrite.Width;
+ Address = PciCfgWrite.Address;
+ Count = PciCfgWrite.Count;
+ Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE);
- return Status;
+ DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgWrite - 0x%08x, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (Address), Count, (UINTN)Width));
+ return ScriptPciCfgWrite (Width, Address, Count, Buffer);
}
/**
- Excute the script to perform IO modification operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_IO_READ_WRITE OP code.
@param Script The pointer of typed node in boot script table
@param AndMask Mask value for 'and' operation
@@ -918,7 +924,7 @@ BootScriptExecuteIoReadWrite (
CopyMem((VOID*)&IoReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_READ_WRITE));
- DEBUG ((EFI_D_INFO, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoReadWrite.Address, (UINT64)AndMask, (UINT64)OrMask));
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoReadWrite.Address, AndMask, OrMask));
Status = ScriptIoRead (
(S3_BOOT_SCRIPT_LIB_WIDTH) IoReadWrite.Width,
@@ -938,7 +944,7 @@ BootScriptExecuteIoReadWrite (
return Status;
}
/**
- Excute the script to perform memory modification operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_READ_WRITE OP code.
@param Script The pointer of typed node in boot script table
@param AndMask Mask value for 'and' operation
@@ -962,7 +968,7 @@ BootScriptExecuteMemoryReadWrite (
CopyMem((VOID*)&MemReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_READ_WRITE));
- DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemReadWrite.Address, (UINT64)AndMask, (UINT64)OrMask));
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemReadWrite.Address, AndMask, OrMask));
Status = ScriptMemoryRead (
(S3_BOOT_SCRIPT_LIB_WIDTH) MemReadWrite.Width,
@@ -982,7 +988,7 @@ BootScriptExecuteMemoryReadWrite (
return Status;
}
/**
- Excute the script to perform PCI IO modification operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CFG_READ_WRITE OP code.
@param Script The pointer of typed node in boot script table
@param AndMask Mask value for 'and' operation
@@ -1001,14 +1007,17 @@ BootScriptExecutePciCfgReadWrite (
EFI_STATUS Status;
UINT64 Data;
EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE PciCfgReadWrite;
-
+
+ Data = 0;
+
CopyMem((VOID*)&PciCfgReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));
- DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)PciCfgReadWrite.Address, (UINT64)AndMask, (UINT64)OrMask));
+ DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgReadWrite.Address), AndMask, OrMask));
Status = ScriptPciCfgRead (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,
PciCfgReadWrite.Address,
+ 1,
&Data
);
if (EFI_ERROR (Status)) {
@@ -1020,13 +1029,14 @@ BootScriptExecutePciCfgReadWrite (
Status = ScriptPciCfgWrite (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,
PciCfgReadWrite.Address,
+ 1,
&Data
);
return Status;
}
/**
- To Execute SMBUS command.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_SMBUS_EXECUTE OP code.
@param Script The pointer of typed node in boot script table
@@ -1057,7 +1067,7 @@ BootScriptExecuteSmbusExecute (
);
}
/**
- Execute stall operation in boot script table.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_STALL OP code.
@param Script The pointer of typed node in boot script table
@@ -1078,10 +1088,10 @@ BootScriptExecuteStall (
return EFI_SUCCESS;
}
/**
- To execute assigned function.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH OP code.
- @param Script The pointer of typed node in boot script table
- @retval EFI_SUCCESS The operation was executed successfully
+ @param Script The pointer of typed node in boot script table
+ @retval EFI_SUCCESS The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteDispatch (
@@ -1102,7 +1112,7 @@ BootScriptExecuteDispatch (
return Status;
}
/**
- Execute dispach2 opertion code which is to invoke a spcified function with one parameter.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH_2 OP code.
@param Script The pointer of typed node in boot script table
@retval EFI_SUCCESS The operation was executed successfully
@@ -1127,7 +1137,7 @@ BootScriptExecuteDispatch2 (
return Status;
}
/**
- Excute the script to poll memory.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_POLL OP code.
@param Script The pointer of typed node in boot script table
@param AndMask Mask value for 'and' operation
@@ -1152,7 +1162,7 @@ BootScriptExecuteMemPoll (
CopyMem ((VOID*)&MemPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_POLL));
- DEBUG ((EFI_D_INFO, "BootScriptExecuteMemPoll - 0x%08x\n", (UINTN)MemPoll.Address));
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteMemPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemPoll.Address, AndMask, OrMask));
Data = 0;
Status = ScriptMemoryRead (
@@ -1187,7 +1197,7 @@ BootScriptExecuteMemPoll (
}
}
/**
- Execute the boot script to interpret the Store arbitrary information.
+ Execute the boot script to interpret the Store arbitrary information.
This opcode is a no-op on dispatch and is only used for debugging script issues.
@param Script The pointer of node in boot script table
@@ -1328,7 +1338,7 @@ CheckAndOrMask (
return;
}
/**
- Excute the script to poll Io port for some time
+ Interprete the boot script node with EFI_BOOT_SCRIPT_IO_POLL OP code.
@param Script The pointer of typed node in boot script table
@param AndMask Mask value for 'and' operation
@@ -1352,7 +1362,7 @@ BootScriptExecuteIoPoll (
CopyMem ((VOID*)&IoPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_POLL));
- DEBUG ((EFI_D_INFO, "BootScriptExecuteIoPoll - 0x%08x\n", (UINTN)IoPoll.Address));
+ DEBUG ((EFI_D_INFO, "BootScriptExecuteIoPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoPoll.Address, AndMask, OrMask));
Data = 0;
Status = ScriptIoRead (
@@ -1385,7 +1395,7 @@ BootScriptExecuteIoPoll (
}
}
/**
- Perform Pci configuration Write operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE OP code.
@param Script The pointer of S3 boot script
@@ -1397,52 +1407,28 @@ BootScriptExecutePciCfg2Write (
IN UINT8 *Script
)
{
- UINT8 Reg;
- UINT8 *Buffer;
- UINTN DataWidth;
- UINTN Index;
- UINT16 Segment;
- UINT64 PciAddress;
- EFI_STATUS Status;
- EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write;
+ VOID *Buffer;
+ S3_BOOT_SCRIPT_LIB_WIDTH Width;
+ UINT16 Segment;
+ UINT64 Address;
+ UINTN Count;
+ EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write;
CopyMem ((VOID*)&PciCfg2Write, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));
- Status = EFI_SUCCESS;
- Segment = PciCfg2Write.Segment;
- PciAddress = PciCfg2Write.Address;
- DataWidth = (UINT32)(0x01 << (PciCfg2Write.Width));
- Buffer = Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);
-
- DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%08x\n", (UINTN)PciAddress));
-
- for (Index = 0; Index < PciCfg2Write.Count; Index++) {
- Status = ScriptPciCfg2Write (
- (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Write.Width,
- Segment,
- PciAddress,
- Buffer
- );
- if (S3BootScriptWidthFillUint8 != PciCfg2Write.Width ||
- S3BootScriptWidthFillUint16 != PciCfg2Write.Width ||
- S3BootScriptWidthFillUint32 != PciCfg2Write.Width ||
- S3BootScriptWidthFillUint64 != PciCfg2Write.Width){
- Reg = (UINT8) ((UINT8) PciAddress + DataWidth);
- PciAddress = (PciAddress & 0xFFFFFFFFFFFFFF00ULL) + Reg;
- }
- if (S3BootScriptWidthFifoUint8 != PciCfg2Write.Width ||
- S3BootScriptWidthFifoUint16 != PciCfg2Write.Width ||
- S3BootScriptWidthFifoUint32 != PciCfg2Write.Width ||
- S3BootScriptWidthFifoUint64 != PciCfg2Write.Width) {
- Buffer += DataWidth;
- }
- }
- return Status;
+ Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Write.Width;
+ Segment = PciCfg2Write.Segment;
+ Address = PciCfg2Write.Address;
+ Count = PciCfg2Write.Count;
+ Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);
+
+ DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%04x, 0x%08x, 0x%08x, 0x%08x\n", Segment, PCI_ADDRESS_ENCODE (Address), Count, (UINTN)Width));
+ return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);
}
/**
- Perform pci configuration read & Write operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE OP code.
@param Script The pointer of S3 boot script
@param AndMask Mask value for 'and' operation
@@ -1461,14 +1447,18 @@ BootScriptExecutePciCfg2ReadWrite (
UINT64 Data;
EFI_STATUS Status;
EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE PciCfg2ReadWrite;
+
+ Data = 0;
+
CopyMem ((VOID*)&PciCfg2ReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));
- DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2ReadWrite - 0x%08x\n", (UINTN)PciCfg2ReadWrite.Address));
+ DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2ReadWrite - 0x%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2ReadWrite.Segment, PCI_ADDRESS_ENCODE (PciCfg2ReadWrite.Address), AndMask, OrMask));
Status = ScriptPciCfg2Read (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,
PciCfg2ReadWrite.Segment,
PciCfg2ReadWrite.Address,
+ 1,
&Data
);
if (EFI_ERROR (Status)) {
@@ -1480,12 +1470,13 @@ BootScriptExecutePciCfg2ReadWrite (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,
PciCfg2ReadWrite.Segment,
PciCfg2ReadWrite.Address,
+ 1,
&Data
);
return Status;
}
/**
- To perform poll pci configure operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_POLL OP code.
@param Script The pointer of S3 boot script
@param AndMask Mask value for 'and' operation
@@ -1508,12 +1499,13 @@ BootScriptPciCfgPoll (
EFI_BOOT_SCRIPT_PCI_CONFIG_POLL PciCfgPoll;
CopyMem ((VOID*)&PciCfgPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));
- DEBUG ((EFI_D_INFO, "BootScriptPciCfgPoll - 0x%08x\n", (UINTN)PciCfgPoll.Address));
+ DEBUG ((EFI_D_INFO, "BootScriptPciCfgPoll - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgPoll.Address), AndMask, OrMask));
Data = 0;
Status = ScriptPciCfgRead (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,
PciCfgPoll.Address,
+ 1,
&Data
);
if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {
@@ -1526,6 +1518,7 @@ BootScriptPciCfgPoll (
Status = ScriptPciCfgRead (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,
PciCfgPoll.Address,
+ 1,
&Data
);
if ((!EFI_ERROR (Status)) &&
@@ -1542,7 +1535,7 @@ BootScriptPciCfgPoll (
}
/**
- To perform poll pci configure operation.
+ Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL OP code.
@param Script The pointer of S3 Boot Script
@param AndMask Mask value for 'and' operation
@@ -1568,12 +1561,13 @@ BootScriptPciCfg2Poll (
Data = 0;
CopyMem ((VOID*)&PciCfg2Poll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));
- DEBUG ((EFI_D_INFO, "BootScriptPciCfg2Poll - 0x%08x\n", (UINTN)PciCfg2Poll.Address));
+ DEBUG ((EFI_D_INFO, "BootScriptPciCfg2Poll - 0x%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2Poll.Segment, PCI_ADDRESS_ENCODE (PciCfg2Poll.Address), AndMask, OrMask));
Status = ScriptPciCfg2Read (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,
PciCfg2Poll.Segment,
PciCfg2Poll.Address,
+ 1,
&Data
);
if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {
@@ -1588,6 +1582,7 @@ BootScriptPciCfg2Poll (
(S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,
PciCfg2Poll.Segment,
PciCfg2Poll.Address,
+ 1,
&Data
);
if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
index 09dc2c4ec3..c087dd9401 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
@@ -41,15 +41,19 @@
SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTablePtr;
EFI_EVENT mEnterRuntimeEvent;
//
-// Allocate local copy in SMM because we can not use mS3BootScriptTablePtr when we AtRuntime in InSmm.
+// Allocate SMM copy because we can not use mS3BootScriptTablePtr when we AtRuntime in InSmm.
//
-SCRIPT_TABLE_PRIVATE_DATA mS3BootScriptTable;
+SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTableSmmPtr;
UINTN mLockBoxLength;
EFI_GUID mBootScriptDataGuid = {
0xaea6b965, 0xdcf5, 0x4311, { 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2 }
};
+EFI_GUID mBootScriptDataOrgGuid = {
+ 0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d }
+};
+
EFI_GUID mBootScriptHeaderDataGuid = {
0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }
};
@@ -128,6 +132,18 @@ SaveBootScriptDataToLockBox (
ASSERT_EFI_ERROR (Status);
//
+ // We need duplicate the original copy, because it may have INSERT boot script at runtime in SMM.
+ // If so, we should use original copy to restore data after OS rewrites the ACPINvs region.
+ // Or the data inserted may cause some original boot script data lost.
+ //
+ Status = SaveLockBox (
+ &mBootScriptDataOrgGuid,
+ (VOID *)mS3BootScriptTablePtr->TableBase,
+ mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
// Just need save TableBase.
// Do not update other field because they will NOT be used in S3.
//
@@ -212,7 +228,7 @@ S3BootScriptSmmEventCallBack (
//
// Check if it is already done
//
- if (mS3BootScriptTablePtr == &mS3BootScriptTable) {
+ if (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr) {
return EFI_SUCCESS;
}
@@ -222,13 +238,15 @@ S3BootScriptSmmEventCallBack (
S3BootScriptEventCallBack (NULL, NULL);
//
- // Save a local copy
+ // Save a SMM copy. If TableBase is NOT null, it means SMM copy has been ready, skip copy mem.
//
- CopyMem (&mS3BootScriptTable, mS3BootScriptTablePtr, sizeof(*mS3BootScriptTablePtr));
+ if (mS3BootScriptTableSmmPtr->TableBase == NULL) {
+ CopyMem (mS3BootScriptTableSmmPtr, mS3BootScriptTablePtr, sizeof(*mS3BootScriptTablePtr));
+ }
//
// We should not use ACPINvs copy, because it is not safe.
//
- mS3BootScriptTablePtr = &mS3BootScriptTable;
+ mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr;
//
// Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM.
@@ -239,7 +257,7 @@ S3BootScriptSmmEventCallBack (
//
// Record LockBoxLength
//
- mLockBoxLength = mS3BootScriptTable.TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
+ mLockBoxLength = mS3BootScriptTableSmmPtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
return EFI_SUCCESS;
}
@@ -264,6 +282,7 @@ S3BootScriptLibInitialize (
{
EFI_STATUS Status;
SCRIPT_TABLE_PRIVATE_DATA *S3TablePtr;
+ SCRIPT_TABLE_PRIVATE_DATA *S3TableSmmPtr;
VOID *Registration;
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
BOOLEAN InSmm;
@@ -325,6 +344,25 @@ S3BootScriptLibInitialize (
return RETURN_SUCCESS;
}
+ S3TableSmmPtr = (SCRIPT_TABLE_PRIVATE_DATA*)(UINTN)PcdGet64(PcdS3BootScriptTablePrivateSmmDataPtr);
+ //
+ // The Boot script private data in SMM is not be initialized. create it
+ //
+ if (S3TableSmmPtr == 0) {
+ Status = Smst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof(SCRIPT_TABLE_PRIVATE_DATA),
+ (VOID **) &S3TableSmmPtr
+ );
+ if (EFI_ERROR (Status)) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ PcdSet64 (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr);
+ ZeroMem (S3TableSmmPtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));
+ }
+ mS3BootScriptTableSmmPtr = S3TableSmmPtr;
+
//
// Then register event after lock
//
@@ -480,6 +518,7 @@ S3BootScriptGetEntryAddAddress (
UINT8* NewEntryPtr;
EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;
EFI_STATUS Status;
+ UINTN OrgLockBoxLength;
if (mS3BootScriptTablePtr->AtRuntime) {
//
@@ -495,38 +534,59 @@ S3BootScriptGetEntryAddAddress (
}
//
- // NOTE: OS will restore ACPINvs data. After S3, the table length in mS3BootScriptTable (SMM) is different with
+ // NOTE: OS will restore ACPINvs data. After S3, the table length in mS3BootScriptTableSmmPtr (SMM) is different with
// table length in BootScriptTable header (ACPINvs).
// So here we need sync them. We choose ACPINvs table length, because we want to override the boot script saved
// in SMM every time.
//
- ASSERT (mS3BootScriptTablePtr == &mS3BootScriptTable);
+ ASSERT (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr);
CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
if (mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE) != TableHeader.TableLength) {
//
// Restore it to use original value
//
- RestoreLockBox (&mBootScriptDataGuid, NULL, NULL);
+ OrgLockBoxLength = mLockBoxLength;
+ Status = RestoreLockBox (
+ &mBootScriptDataOrgGuid,
+ (VOID *)mS3BootScriptTablePtr->TableBase,
+ &OrgLockBoxLength
+ );
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (OrgLockBoxLength == mLockBoxLength);
+
+ //
+ // Update the current BootScriptData into LockBox as well
+ //
+ Status = UpdateLockBox (
+ &mBootScriptDataGuid,
+ 0,
+ (VOID *)mS3BootScriptTablePtr->TableBase,
+ OrgLockBoxLength
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
- // Copy it again to get original value
// NOTE: We should NOT use TableHeader.TableLength, because it is already updated to be whole length.
//
mS3BootScriptTablePtr->TableLength = (UINT32)(mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE));
}
NewEntryPtr = S3BootScriptGetRuntimeEntryAddAddress (EntryLength);
- //
- // Now the length field is updated, need sync to lockbox.
- // So in S3 resume, the data can be restored correctly.
- //
- CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
- Status = UpdateLockBox (
- &mBootScriptDataGuid,
- OFFSET_OF(EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),
- &TableHeader.TableLength,
- sizeof(TableHeader.TableLength)
- );
- ASSERT_EFI_ERROR (Status);
+
+ if (EntryLength != 0) {
+ //
+ // Now the length field is updated, need sync to lockbox.
+ // So in S3 resume, the data can be restored correctly.
+ //
+ CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
+ Status = UpdateLockBox (
+ &mBootScriptDataGuid,
+ OFFSET_OF(EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),
+ &TableHeader.TableLength,
+ sizeof(TableHeader.TableLength)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
} else {
NewEntryPtr = S3BootScriptGetBootTimeEntryAddAddress (EntryLength);
}
@@ -536,26 +596,36 @@ S3BootScriptGetEntryAddAddress (
/**
Sync BootScript LockBox data.
+
+ @param Script The address from where the boot script has been added or updated.
+
**/
VOID
SyncBootScript (
- VOID
+ IN UINT8 *Script
)
{
EFI_STATUS Status;
+ UINTN ScriptOffset;
+
+ ScriptOffset = (UINTN) (Script - mS3BootScriptTablePtr->TableBase);
- if (!mS3BootScriptTablePtr->AtRuntime || !mS3BootScriptTablePtr->InSmm) {
+ if (!mS3BootScriptTablePtr->AtRuntime || !mS3BootScriptTablePtr->InSmm || ScriptOffset >= mLockBoxLength) {
+ //
+ // If it is not at runtime in SMM or in the range that needs to be synced in LockBox, just return.
+ //
return ;
}
+
//
- // Update Terminate
+ // Update BootScriptData
// So in S3 resume, the data can be restored correctly.
//
Status = UpdateLockBox (
&mBootScriptDataGuid,
- mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE),
- (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE)),
- sizeof(EFI_BOOT_SCRIPT_TERMINATE)
+ ScriptOffset,
+ (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + ScriptOffset),
+ mLockBoxLength - ScriptOffset
);
ASSERT_EFI_ERROR (Status);
}
@@ -676,7 +746,7 @@ S3BootScriptSaveIoWrite (
CopyMem ((VOID*)Script, (VOID*)&ScriptIoWrite, sizeof(EFI_BOOT_SCRIPT_IO_WRITE));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)), Buffer, WidthInByte * Count);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -725,7 +795,7 @@ S3BootScriptSaveIoReadWrite (
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE)), Data, WidthInByte);
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + WidthInByte), DataMask, WidthInByte);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -773,7 +843,7 @@ S3BootScriptSaveMemWrite (
CopyMem ((VOID*)Script, (VOID*)&ScriptMemWrite, sizeof(EFI_BOOT_SCRIPT_MEM_WRITE));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)), Buffer, WidthInByte * Count);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -821,7 +891,7 @@ S3BootScriptSaveMemReadWrite (
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE)), Data, WidthInByte);
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + WidthInByte), DataMask, WidthInByte);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -835,6 +905,8 @@ S3BootScriptSaveMemReadWrite (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN_SUCCESS Opcode is added.
+ @note A known Limitations in the implementation which is 64bits operations are not supported.
+
**/
RETURN_STATUS
EFIAPI
@@ -850,6 +922,12 @@ S3BootScriptSavePciCfgWrite (
UINT8 WidthInByte;
EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE ScriptPciWrite;
+ if (Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count));
@@ -869,7 +947,7 @@ S3BootScriptSavePciCfgWrite (
CopyMem ((VOID*)Script, (VOID*)&ScriptPciWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)), Buffer, WidthInByte * Count);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -883,6 +961,8 @@ S3BootScriptSavePciCfgWrite (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN__SUCCESS Opcode is added.
+ @note A known Limitations in the implementation which is 64bits operations are not supported.
+
**/
RETURN_STATUS
EFIAPI
@@ -898,6 +978,12 @@ S3BootScriptSavePciCfgReadWrite (
UINT8 WidthInByte;
EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE ScriptPciReadWrite;
+ if (Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + (WidthInByte * 2));
@@ -921,12 +1007,12 @@ S3BootScriptSavePciCfgReadWrite (
WidthInByte
);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
/**
- Adds a record for a PCI configuration space modify operation into a specified boot script table.
+ Adds a record for a PCI configuration 2 space write operation into a specified boot script table.
@param Width The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
@param Segment The PCI segment number for Address.
@@ -936,6 +1022,8 @@ S3BootScriptSavePciCfgReadWrite (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN_SUCCESS Opcode is added.
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
+
**/
RETURN_STATUS
EFIAPI
@@ -951,7 +1039,14 @@ S3BootScriptSavePciCfg2Write (
UINT8 *Script;
UINT8 WidthInByte;
EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE ScriptPciWrite2;
-
+
+ if (Segment != 0 ||
+ Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE) + (WidthInByte * Count));
@@ -972,12 +1067,12 @@ S3BootScriptSavePciCfg2Write (
CopyMem ((VOID*)Script, (VOID*)&ScriptPciWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)), Buffer, WidthInByte * Count);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
/**
- Adds a record for a PCI configuration space modify operation into a specified boot script table.
+ Adds a record for a PCI configuration 2 space modify operation into a specified boot script table.
@param Width The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
@param Segment The PCI segment number for Address.
@@ -987,6 +1082,8 @@ S3BootScriptSavePciCfg2Write (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN_SUCCESS Opcode is added.
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
+
**/
RETURN_STATUS
EFIAPI
@@ -1002,6 +1099,13 @@ S3BootScriptSavePciCfg2ReadWrite (
UINT8 *Script;
UINT8 WidthInByte;
EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE ScriptPciReadWrite2;
+
+ if (Segment != 0 ||
+ Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + (WidthInByte * 2));
@@ -1027,10 +1131,111 @@ S3BootScriptSavePciCfg2ReadWrite (
WidthInByte
);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
+
+/**
+ Checks the parameter of S3BootScriptSaveSmbusExecute().
+
+ This function checks the input parameters of SmbusExecute(). If the input parameters are valid
+ for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
+ error code based on the input SMBus bus protocol.
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,
+ and PEC.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus
+ protocol.
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+CheckParameters (
+ IN UINTN SmBusAddress,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN OUT UINTN *Length,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN RequiredLen;
+ EFI_SMBUS_DEVICE_COMMAND Command;
+ BOOLEAN PecCheck;
+
+ Command = SMBUS_LIB_COMMAND (SmBusAddress);
+ PecCheck = SMBUS_LIB_PEC (SmBusAddress);
+ //
+ // Set default value to be 2:
+ // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
+ //
+ RequiredLen = 2;
+ Status = EFI_SUCCESS;
+ switch (Operation) {
+ case EfiSmbusQuickRead:
+ case EfiSmbusQuickWrite:
+ if (PecCheck || Command != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ break;
+ case EfiSmbusReceiveByte:
+ case EfiSmbusSendByte:
+ if (Command != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Cascade to check length parameter.
+ //
+ case EfiSmbusReadByte:
+ case EfiSmbusWriteByte:
+ RequiredLen = 1;
+ //
+ // Cascade to check length parameter.
+ //
+ case EfiSmbusReadWord:
+ case EfiSmbusWriteWord:
+ case EfiSmbusProcessCall:
+ if (Buffer == NULL || Length == NULL) {
+ return EFI_INVALID_PARAMETER;
+ } else if (*Length < RequiredLen) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ *Length = RequiredLen;
+ break;
+ case EfiSmbusReadBlock:
+ case EfiSmbusWriteBlock:
+ case EfiSmbusBWBRProcessCall:
+ if ((Buffer == NULL) ||
+ (Length == NULL) ||
+ (*Length < MIN_SMBUS_BLOCK_LEN) ||
+ (*Length > MAX_SMBUS_BLOCK_LEN)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ return Status;
+}
+
/**
Adds a record for an SMBus command execution into a specified boot script table.
@@ -1052,11 +1257,24 @@ S3BootScriptSaveSmbusExecute (
IN VOID *Buffer
)
{
+ EFI_STATUS Status;
+ UINTN BufferLength;
UINT8 DataSize;
UINT8 *Script;
EFI_BOOT_SCRIPT_SMBUS_EXECUTE ScriptSmbusExecute;
- DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + (*Length));
+ if (Length == NULL) {
+ BufferLength = 0;
+ } else {
+ BufferLength = *Length;
+ }
+
+ Status = CheckParameters (SmBusAddress, Operation, &BufferLength, Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + BufferLength);
Script = S3BootScriptGetEntryAddAddress (DataSize);
if (Script == NULL) {
@@ -1069,16 +1287,16 @@ S3BootScriptSaveSmbusExecute (
ScriptSmbusExecute.Length = DataSize;
ScriptSmbusExecute.SmBusAddress = (UINT64) SmBusAddress;
ScriptSmbusExecute.Operation = Operation;
- ScriptSmbusExecute.DataSize = (UINT32) *Length;
+ ScriptSmbusExecute.DataSize = (UINT32) BufferLength;
CopyMem ((VOID*)Script, (VOID*)&ScriptSmbusExecute, sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE));
CopyMem (
(VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)),
Buffer,
- (*Length)
+ BufferLength
);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -1115,12 +1333,12 @@ S3BootScriptSaveStall (
CopyMem ((VOID*)Script, (VOID*)&ScriptStall, sizeof (EFI_BOOT_SCRIPT_STALL));
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
/**
- Adds a record for an execution stall on the processor into a specified boot script table.
+ Adds a record for dispatching specified arbitrary code into a specified boot script table.
@param EntryPoint Entry point of the code to be dispatched.
@param Context Argument to be passed into the EntryPoint of the code to be dispatched.
@@ -1154,7 +1372,7 @@ S3BootScriptSaveDispatch2 (
CopyMem ((VOID*)Script, (VOID*)&ScriptDispatch2, sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
@@ -1212,7 +1430,7 @@ S3BootScriptSaveMemPoll (
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + WidthInByte), BitMask, WidthInByte);
CopyMem ((VOID*)Script, (VOID*)&ScriptMemPoll, sizeof (EFI_BOOT_SCRIPT_MEM_POLL));
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -1256,7 +1474,7 @@ S3BootScriptSaveInformation (
CopyMem ((VOID*)Script, (VOID*)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *) Information, (UINTN) InformationLength);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
@@ -1315,7 +1533,7 @@ S3BootScriptSaveDispatch (
CopyMem ((VOID*)Script, (VOID*)&ScriptDispatch, sizeof (EFI_BOOT_SCRIPT_DISPATCH));
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
@@ -1372,7 +1590,7 @@ S3BootScriptSaveIoPoll (
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL)), Data, WidthInByte);
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL) + WidthInByte), DataMask, WidthInByte);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -1391,6 +1609,7 @@ S3BootScriptSaveIoPoll (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN_SUCCESS Opcode is added.
+ @note A known Limitations in the implementation which is 64bits operations are not supported.
**/
RETURN_STATUS
@@ -1408,6 +1627,12 @@ S3BootScriptSavePciPoll (
UINT8 Length;
EFI_BOOT_SCRIPT_PCI_CONFIG_POLL ScriptPciPoll;
+ if (Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));
@@ -1428,7 +1653,7 @@ S3BootScriptSavePciPoll (
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL)), Data, WidthInByte);
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + WidthInByte), DataMask, WidthInByte);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -1447,9 +1672,8 @@ S3BootScriptSavePciPoll (
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.
@retval RETURN_SUCCESS Opcode is added.
- @note A known Limitations in the implementation: When interpreting the opcode EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE
- EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as
- Zero, or else, assert.
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.
+
**/
RETURN_STATUS
EFIAPI
@@ -1466,7 +1690,14 @@ S3BootScriptSavePci2Poll (
UINT8 *Script;
UINT8 Length;
EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL ScriptPci2Poll;
-
+
+ if (Segment != 0 ||
+ Width == S3BootScriptWidthUint64 ||
+ Width == S3BootScriptWidthFifoUint64 ||
+ Width == S3BootScriptWidthFillUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
WidthInByte = (UINT8) (0x01 << (Width & 0x03));
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));
@@ -1488,7 +1719,7 @@ S3BootScriptSavePci2Poll (
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL)), Data, WidthInByte);
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + WidthInByte), DataMask, WidthInByte);
- SyncBootScript ();
+ SyncBootScript (Script);
return RETURN_SUCCESS;
}
@@ -1590,10 +1821,16 @@ S3BootScriptMoveLastOpcode (
ValidatePosition = FALSE;
TempPosition = (Position == NULL) ? NULL:(*Position);
- Script = mS3BootScriptTablePtr->TableBase;
- if (Script == 0) {
- return EFI_OUT_OF_RESOURCES;
+
+ //
+ // Check that the script is initialized and synced without adding an entry to the script.
+ //
+ Script = S3BootScriptGetEntryAddAddress (0);
+ if (Script == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
}
+ Script = mS3BootScriptTablePtr->TableBase;
+
StartAddress = (UINTN) Script;
TableLength = mS3BootScriptTablePtr->TableLength;
Script = Script + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
@@ -1636,7 +1873,10 @@ S3BootScriptMoveLastOpcode (
//
// Copy the node to Boot script table
//
- CopyMem((VOID*)Script, (VOID*)TempBootScriptEntry, ScriptHeader.Length);
+ CopyMem((VOID*)Script, (VOID*)TempBootScriptEntry, ScriptHeader.Length);
+
+ SyncBootScript (Script);
+
//
// return out the Position
//
@@ -1694,6 +1934,8 @@ S3BootScriptLabelInternal (
CopyMem ((VOID*)Script, (VOID*)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *) Information, (UINTN) InformationLength);
+ SyncBootScript (Script);
+
return S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);
}
@@ -1748,8 +1990,8 @@ S3BootScriptLabel (
}
//
- // Check that the script is initialized without adding an entry to the script.
- // The code must search for the label first befor it knows if a new entry needs
+ // Check that the script is initialized and synced without adding an entry to the script.
+ // The code must search for the label first before it knows if a new entry needs
// to be added.
//
Script = S3BootScriptGetEntryAddAddress (0);
@@ -1812,13 +2054,19 @@ S3BootScriptCompare (
UINT8* Script;
UINT32 TableLength;
- Script = mS3BootScriptTablePtr->TableBase;
- if (Script == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
if (RelativePosition == NULL) {
return EFI_INVALID_PARAMETER;
}
+
+ //
+ // Check that the script is initialized and synced without adding an entry to the script.
+ //
+ Script = S3BootScriptGetEntryAddAddress (0);
+ if (Script == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+ Script = mS3BootScriptTablePtr->TableBase;
+
//
// mS3BootScriptTablePtr->TableLength does not include the termination node, so add it up
//
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
index 26eecaf412..e84aabac95 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
@@ -61,4 +61,5 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptRuntimeTableReservePageNumber ## CONSUMES
diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c
index 63c85dea2f..ba74d0f88f 100644
--- a/MdeModulePkg/Library/UefiHiiLib/HiiLib.c
+++ b/MdeModulePkg/Library/UefiHiiLib/HiiLib.c
@@ -1,7 +1,7 @@
/** @file
HII Library implementation that uses DXE protocols and services.
- Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2013, 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
@@ -946,6 +946,7 @@ InternalHiiValidateCurrentSetting (
UINT16 Offset;
UINT16 Width;
UINT64 VarValue;
+ UINT64 TmpValue;
LIST_ENTRY *Link;
UINT8 *VarBuffer;
UINTN MaxBufferSize;
@@ -1510,7 +1511,9 @@ InternalHiiValidateCurrentSetting (
//
// Check current value is the value of one of option.
//
- if (VarValue == IfrOneOfOption->Value.u64) {
+ TmpValue = 0;
+ CopyMem (&TmpValue, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
+ if (VarValue == TmpValue) {
//
// The value is one of option value.
// Set OpCode to Zero, don't need check again.
@@ -2628,7 +2631,7 @@ HiiCreateOneOfOptionOpCode (
OpCode.Type = Type;
CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, sizeof (OpCode));
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, OFFSET_OF(EFI_IFR_ONE_OF_OPTION, Value) + mHiiDefaultTypeToWidth[Type]);
}
/**
@@ -2664,7 +2667,7 @@ HiiCreateDefaultOpCode (
OpCode.DefaultId = DefaultId;
CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, sizeof (OpCode));
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, OFFSET_OF(EFI_IFR_DEFAULT, Value) + mHiiDefaultTypeToWidth[Type]);
}
/**
@@ -2959,9 +2962,11 @@ HiiCreateNumericOpCode (
{
EFI_IFR_NUMERIC OpCode;
UINTN Position;
+ UINTN Length;
ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED))) == 0);
+ Length = 0;
ZeroMem (&OpCode, sizeof (OpCode));
OpCode.Question.QuestionId = QuestionId;
OpCode.Question.VarStoreId = VarStoreId;
@@ -2976,33 +2981,39 @@ HiiCreateNumericOpCode (
OpCode.data.u8.MinValue = (UINT8)Minimum;
OpCode.data.u8.MaxValue = (UINT8)Maximum;
OpCode.data.u8.Step = (UINT8)Step;
+ Length = 3;
break;
case EFI_IFR_NUMERIC_SIZE_2:
OpCode.data.u16.MinValue = (UINT16)Minimum;
OpCode.data.u16.MaxValue = (UINT16)Maximum;
OpCode.data.u16.Step = (UINT16)Step;
+ Length = 6;
break;
case EFI_IFR_NUMERIC_SIZE_4:
OpCode.data.u32.MinValue = (UINT32)Minimum;
OpCode.data.u32.MaxValue = (UINT32)Maximum;
OpCode.data.u32.Step = (UINT32)Step;
+ Length = 12;
break;
case EFI_IFR_NUMERIC_SIZE_8:
OpCode.data.u64.MinValue = Minimum;
OpCode.data.u64.MaxValue = Maximum;
OpCode.data.u64.Step = Step;
+ Length = 24;
break;
}
+ Length += OFFSET_OF (EFI_IFR_NUMERIC, data);
+
if (DefaultsOpCodeHandle == NULL) {
- return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode));
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length);
}
Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode), 0, 1);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, Length, 0, 1);
InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
HiiCreateEndOpCode (OpCodeHandle);
return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
@@ -3115,6 +3126,7 @@ HiiCreateOneOfOpCode (
{
EFI_IFR_ONE_OF OpCode;
UINTN Position;
+ UINTN Length;
ASSERT (OptionsOpCodeHandle != NULL);
ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
@@ -3128,8 +3140,11 @@ HiiCreateOneOfOpCode (
OpCode.Question.Flags = QuestionFlags;
OpCode.Flags = OneOfFlags;
+ Length = OFFSET_OF (EFI_IFR_ONE_OF, data);
+ Length += (1 << (OneOfFlags & EFI_IFR_NUMERIC_SIZE)) * 3;
+
Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
- InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, sizeof (OpCode), 0, 1);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, Length, 0, 1);
InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle);
if (DefaultsOpCodeHandle != NULL) {
InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d3d1a299b4..710e3e6a04 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -852,3 +852,9 @@
# default value is set to Zero. And the PCD is assumed ONLY to be accessed in DxeS3BootScriptLib Library.
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0|UINT64|0x00030000
+ ## This dynamic PCD hold an address to point to private data structure SMM copy used in DxeS3BootScriptLib library
+ # instance which records the S3 boot script table start address, length, etc. To introduce this PCD is
+ # only for DxeS3BootScriptLib instance implementation purpose. The platform developer should make sure the
+ # default value is set to Zero. And the PCD is assumed ONLY to be accessed in DxeS3BootScriptLib Library.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0x0|UINT64|0x00030001
+
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index dfd1669ab1..56a83125e6 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -720,7 +720,7 @@ AddTableToList (
// Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
// vice-versa.
//
- if ((UINT64)(UINTN)AcpiSupportInstance->Facs3 < BASE_4GB) {
+ if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;
} else {
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
@@ -849,7 +849,7 @@ AddTableToList (
// Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
// vice-versa.
//
- if ((UINT64)(UINTN)AcpiSupportInstance->Facs3 < BASE_4GB) {
+ if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;
} else {
Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
diff --git a/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c b/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
index 52b0ec651c..212564a5c8 100644
--- a/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
+++ b/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
@@ -497,6 +497,19 @@ GraphicsConsoleControllerDriverStart (
}
}
}
+ if (ModeNumber != Private->GraphicsOutput->Mode->Mode) {
+ //
+ // Current graphics mode is not set or is not set to the mode which we has found,
+ // set the new graphic mode.
+ //
+ Status = Private->GraphicsOutput->SetMode (Private->GraphicsOutput, ModeNumber);
+ if (EFI_ERROR (Status)) {
+ //
+ // The mode set operation failed
+ //
+ goto Error;
+ }
+ }
} else if (FeaturePcdGet (PcdUgaConsumeSupport)) {
//
// At first try to set user-defined resolution
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h
index 39bc743e24..8deae8851a 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWrite.h
@@ -3,7 +3,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by FtwLite module.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiDxe.h>
#include <Guid/SystemNvDataGuid.h>
+#include <Guid/ZeroGuid.h>
#include <Protocol/FaultTolerantWrite.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/SwapAddressRange.h>
@@ -736,5 +737,16 @@ EFI_STATUS
InitFtwProtocol (
IN OUT EFI_FTW_DEVICE *FtwDevice
);
+
+/**
+ Initialize a local work space header.
+
+ Since Signature and WriteQueueSize have been known, Crc can be calculated out,
+ then the work space header will be fixed.
+**/
+VOID
+InitializeLocalWorkSpaceHeader (
+ VOID
+ );
#endif
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
index f1d64942b4..c5f41d7378 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
@@ -1174,6 +1174,8 @@ InitFtwProtocol (
FtwDevice->FtwLastWriteHeader = NULL;
FtwDevice->FtwLastWriteRecord = NULL;
+ InitializeLocalWorkSpaceHeader ();
+
//
// Refresh the working space data from working block
//
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
index bbe5fb63b5..bd8285d00e 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/UpdateWorkingBlock.c
@@ -16,77 +16,90 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "FaultTolerantWrite.h"
-/**
- Check to see if it is a valid work space.
-
+EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER mWorkingBlockHeader = {ZERO_GUID, 0, 0, 0, 0, {0, 0, 0}, 0};
- @param WorkingHeader Pointer of working block header
-
- @retval TRUE The work space is valid.
- @retval FALSE The work space is invalid.
+/**
+ Initialize a local work space header.
+ Since Signature and WriteQueueSize have been known, Crc can be calculated out,
+ then the work space header will be fixed.
**/
-BOOLEAN
-IsValidWorkSpace (
- IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
+VOID
+InitializeLocalWorkSpaceHeader (
+ VOID
)
{
EFI_STATUS Status;
- EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER WorkingBlockHeader;
- if (WorkingHeader == NULL) {
- return FALSE;
- }
-
- if (WorkingHeader->WorkingBlockValid != FTW_VALID_STATE) {
- DEBUG ((EFI_D_ERROR, "Ftw: Work block header valid bit check error\n"));
- return FALSE;
- }
//
- // Check signature with gEfiSystemNvDataFvGuid
+ // Check signature with gEfiSystemNvDataFvGuid.
//
- if (!CompareGuid (&gEfiSystemNvDataFvGuid, &WorkingHeader->Signature)) {
- DEBUG ((EFI_D_ERROR, "Ftw: Work block header signature check error\n"));
- return FALSE;
+ if (CompareGuid (&gEfiSystemNvDataFvGuid, &mWorkingBlockHeader.Signature)) {
+ //
+ // The local work space header has been initialized.
+ //
+ return;
}
+
+ SetMem (
+ &mWorkingBlockHeader,
+ sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
+ FTW_ERASED_BYTE
+ );
+
//
- // Check the CRC of header
+ // Here using gEfiSystemNvDataFvGuid as the signature.
//
CopyMem (
- &WorkingBlockHeader,
- WorkingHeader,
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)
+ &mWorkingBlockHeader.Signature,
+ &gEfiSystemNvDataFvGuid,
+ sizeof (EFI_GUID)
);
+ mWorkingBlockHeader.WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));
//
- // Filter out the Crc and State fields
+ // Crc is calculated with all the fields except Crc and STATE, so leave them as FTW_ERASED_BYTE.
//
- SetMem (
- &WorkingBlockHeader.Crc,
- sizeof (UINT32),
- FTW_ERASED_BYTE
- );
- WorkingBlockHeader.WorkingBlockValid = FTW_ERASE_POLARITY;
- WorkingBlockHeader.WorkingBlockInvalid = FTW_ERASE_POLARITY;
//
// Calculate the Crc of woking block header
//
Status = gBS->CalculateCrc32 (
- (UINT8 *) &WorkingBlockHeader,
+ &mWorkingBlockHeader,
sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
- &WorkingBlockHeader.Crc
+ &mWorkingBlockHeader.Crc
);
- if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+
+ mWorkingBlockHeader.WorkingBlockValid = FTW_VALID_STATE;
+ mWorkingBlockHeader.WorkingBlockInvalid = FTW_INVALID_STATE;
+}
+
+/**
+ Check to see if it is a valid work space.
+
+
+ @param WorkingHeader Pointer of working block header
+
+ @retval TRUE The work space is valid.
+ @retval FALSE The work space is invalid.
+
+**/
+BOOLEAN
+IsValidWorkSpace (
+ IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
+ )
+{
+ if (WorkingHeader == NULL) {
return FALSE;
}
- if (WorkingBlockHeader.Crc != WorkingHeader->Crc) {
- DEBUG ((EFI_D_ERROR, "Ftw: Work block header CRC check error\n"));
- return FALSE;
+ if (CompareMem (WorkingHeader, &mWorkingBlockHeader, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)) == 0) {
+ return TRUE;
}
- return TRUE;
+ DEBUG ((EFI_D_ERROR, "Ftw: Work block header check error\n"));
+ return FALSE;
}
/**
@@ -103,49 +116,11 @@ InitWorkSpaceHeader (
IN EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingHeader
)
{
- EFI_STATUS Status;
-
if (WorkingHeader == NULL) {
return EFI_INVALID_PARAMETER;
}
- //
- // Here using gEfiSystemNvDataFvGuid as the signature.
- //
- CopyMem (
- &WorkingHeader->Signature,
- &gEfiSystemNvDataFvGuid,
- sizeof (EFI_GUID)
- );
- WorkingHeader->WriteQueueSize = (UINT64) (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) - sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));
- //
- // Crc is calculated with all the fields except Crc and STATE
- //
- WorkingHeader->WorkingBlockValid = FTW_ERASE_POLARITY;
- WorkingHeader->WorkingBlockInvalid = FTW_ERASE_POLARITY;
-
- SetMem (
- &WorkingHeader->Crc,
- sizeof (UINT32),
- FTW_ERASED_BYTE
- );
-
- //
- // Calculate the CRC value
- //
- Status = gBS->CalculateCrc32 (
- (UINT8 *) WorkingHeader,
- sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
- &WorkingHeader->Crc
- );
- if (EFI_ERROR (Status)) {
- return EFI_ABORTED;
- }
- //
- // Restore the WorkingBlockValid flag to VALID state
- //
- WorkingHeader->WorkingBlockValid = FTW_VALID_STATE;
- WorkingHeader->WorkingBlockInvalid = FTW_INVALID_STATE;
+ CopyMem (WorkingHeader, &mWorkingBlockHeader, sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER));
return EFI_SUCCESS;
}
@@ -166,6 +141,7 @@ WorkSpaceRefresh (
{
EFI_STATUS Status;
UINTN Length;
+ UINTN RemainingSpaceSize;
//
// Initialize WorkSpace as FTW_ERASED_BYTE
@@ -198,7 +174,15 @@ WorkSpaceRefresh (
FtwDevice->FtwWorkSpaceSize,
&FtwDevice->FtwLastWriteHeader
);
- if (EFI_ERROR (Status)) {
+ RemainingSpaceSize = FtwDevice->FtwWorkSpaceSize - ((UINTN) FtwDevice->FtwLastWriteHeader - (UINTN) FtwDevice->FtwWorkSpace);
+ DEBUG ((EFI_D_INFO, "Ftw: Remaining work space size - %x\n", RemainingSpaceSize));
+ //
+ // If FtwGetLastWriteHeader() returns error, or the remaining space size is even not enough to contain
+ // one EFI_FAULT_TOLERANT_WRITE_HEADER + one EFI_FAULT_TOLERANT_WRITE_RECORD(It will cause that the header
+ // pointed by FtwDevice->FtwLastWriteHeader or record pointed by FtwDevice->FtwLastWriteRecord may contain invalid data),
+ // it needs to reclaim work space.
+ //
+ if (EFI_ERROR (Status) || RemainingSpaceSize < sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER) + sizeof (EFI_FAULT_TOLERANT_WRITE_RECORD)) {
//
// reclaim work space in working block.
//
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
index c79a4c9ab8..81cebdabcd 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
@@ -1,7 +1,7 @@
/** @file
Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.
-Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2013, 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
@@ -1861,7 +1861,7 @@ ParseIfrData (
// Prepare new DefaultValue
//
DefaultData.Type = DefaultValueFromFlag;
- CopyMem (&DefaultData.Value.u64, &IfrOneOfOption->Value.u64, sizeof (UINT64));
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {
DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
InsertDefaultValue (BlockData, &DefaultData);
@@ -1886,7 +1886,7 @@ ParseIfrData (
// Prepare new DefaultValue
//
DefaultData.Type = DefaultValueFromDefault;
- CopyMem (&DefaultData.Value.u64, &IfrOneOfOption->Value.u64, sizeof (UINT64));
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
DefaultData.DefaultId = DefaultDataPtr->DefaultId;
@@ -1922,7 +1922,7 @@ ParseIfrData (
//
DefaultData.Type = DefaultValueFromOpcode;
DefaultData.DefaultId = VarDefaultId;
- CopyMem (&DefaultData.Value, &IfrDefault->Value, sizeof (EFI_IFR_TYPE_VALUE));
+ CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));
// If the value field is expression, set the cleaned flag.
if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {
@@ -3919,18 +3919,14 @@ HiiConfigToBlock (
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
- //
- // Skip '&'
- //
- StringPtr++;
//
// Parse each <ConfigElement> if exists
- // Only <BlockConfig> format is supported by this help function.
+ // Only '&'<BlockConfig> format is supported by this help function.
// <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE='<Number>
//
- while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
- StringPtr += StrLen (L"OFFSET=");
+ while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
+ StringPtr += StrLen (L"&OFFSET=");
//
// Get Offset
//
@@ -3949,7 +3945,7 @@ HiiConfigToBlock (
StringPtr += Length;
if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
- *Progress = StringPtr - Length - StrLen (L"OFFSET=") - 1;
+ *Progress = StringPtr - Length - StrLen (L"&OFFSET=");
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
@@ -3990,7 +3986,7 @@ HiiConfigToBlock (
StringPtr += Length;
if (*StringPtr != 0 && *StringPtr != L'&') {
- *Progress = StringPtr - Length - 7;
+ *Progress = StringPtr - Length - StrLen (L"&VALUE=");
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
@@ -4009,20 +4005,18 @@ HiiConfigToBlock (
Value = NULL;
//
- // If '\0', parsing is finished. Otherwise skip '&' to continue
+ // If '\0', parsing is finished.
//
if (*StringPtr == 0) {
break;
}
-
- StringPtr++;
}
//
- // The input string is ConfigAltResp format.
+ // The input string is not ConfigResp format, return error.
//
- if ((*StringPtr != 0) && (StrnCmp (StringPtr, L"&GUID=", StrLen (L"&GUID=")) != 0)) {
- *Progress = StringPtr - 1;
+ if (*StringPtr != 0) {
+ *Progress = StringPtr;
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
index 37042d11cd..81ddd62634 100644
--- a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
+++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
@@ -1,7 +1,7 @@
/** @file
ARP driver functions.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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<BR>
@@ -242,6 +242,36 @@ ArpCleanService (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+ArpDestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ ARP_INSTANCE_DATA *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
+ ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
+/**
Tests to see if this driver supports a given controller.
If a child device is provided, it further tests to see if this driver supports
@@ -446,14 +476,14 @@ ArpDriverBindingStop (
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
ARP_SERVICE_DATA *ArpService;
- ARP_INSTANCE_DATA *Instance;
+ LIST_ENTRY *List;
//
// Get the NicHandle which the arp servicebinding is installed on.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
//
@@ -474,7 +504,21 @@ ArpDriverBindingStop (
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy all the ARP children instances.
+ //
+ List = &ArpService->ChildrenList;
+ Status = NetDestroyLinkList (
+ List,
+ ArpDestroyChildEntryInHandleBuffer,
+ ServiceBinding,
+ NULL
+ );
+ ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
+ ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
+ ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
+ } else if (IsListEmpty (&ArpService->ChildrenList)) {
//
// Uninstall the ARP ServiceBinding protocol.
//
@@ -491,17 +535,6 @@ ArpDriverBindingStop (
ArpCleanService (ArpService);
FreePool (ArpService);
- } else {
-
- while (!IsListEmpty (&ArpService->ChildrenList)) {
- Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
-
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- }
-
- ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
- ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
- ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
}
return EFI_SUCCESS;
@@ -690,14 +723,14 @@ ArpServiceBindingDestroyChild (
Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
- if (Instance->Destroyed) {
+ if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
- // Use the Destroyed as a flag to avoid re-entrance.
+ // Use the InDestroy as a flag to avoid re-entrance.
//
- Instance->Destroyed = TRUE;
+ Instance->InDestroy = TRUE;
//
// Close the Managed Network protocol.
@@ -722,7 +755,7 @@ ArpServiceBindingDestroyChild (
DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
Status));
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
return Status;
}
diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
index c754177a1f..633c3e7d38 100644
--- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
+++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
@@ -1,7 +1,7 @@
/** @file
The implementation of the ARP protocol.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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<BR>
@@ -52,7 +52,7 @@ ArpInitInstance (
CopyMem (&Instance->ArpProto, &mEfiArpProtocolTemplate, sizeof (Instance->ArpProto));
Instance->Configured = FALSE;
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
InitializeListHead (&Instance->List);
}
diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h
index 418b4c81c7..a5dce7d9a5 100644
--- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h
+++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h
@@ -1,7 +1,7 @@
/** @file
EFI Address Resolution Protocol (ARP) Protocol interface header file.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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<BR>
@@ -123,7 +123,7 @@ typedef struct {
LIST_ENTRY List;
EFI_ARP_CONFIG_DATA ConfigData;
BOOLEAN Configured;
- BOOLEAN Destroyed;
+ BOOLEAN InDestroy;
} ARP_INSTANCE_DATA;
#define ARP_SERVICE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'S')
diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c
index 136b1df88e..ee47fb1ef7 100644
--- a/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for ArpDxe driver.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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<BR>
@@ -39,6 +39,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpDriverNameTable[] = {
{ NULL, NULL }
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpControllerNameTable[] = {
+ { "eng;en", L"ARP Controller" },
+ { NULL, NULL }
+};
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -173,6 +178,48 @@ ArpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_STATUS Status;
+ EFI_ARP_PROTOCOL *Arp;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiArpProtocolGuid,
+ (VOID **)&Arp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mArpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gArpComponentName)
+ );
+}
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
index e9d86fb56e..2ea07608f1 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -174,6 +174,20 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcpDriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable = NULL;
+
+CHAR16 *mDhcp4ControllerName[] = {
+ L"DHCPv4 (State=0, Stopped)",
+ L"DHCPv4 (State=1, Init)",
+ L"DHCPv4 (State=2, Selecting)",
+ L"DHCPv4 (State=3, Requesting)",
+ L"DHCPv4 (State=4, Bound)",
+ L"DHCPv4 (State=5, Renewing)",
+ L"DHCPv4 (State=6, Rebinding)",
+ L"DHCPv4 (State=7, InitReboot)",
+ L"DHCPv4 (State=8, Rebooting)"
+};
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -231,6 +245,66 @@ DhcpComponentNameGetDriverName (
}
/**
+ Update the component name for the Dhcp4 child handle.
+
+ @param Dhcp4[in] A pointer to the EFI_DHCP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval EFI_DEVICE_ERROR DHCP is in unknown state.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_DHCP4_PROTOCOL *Dhcp4
+ )
+{
+ EFI_STATUS Status;
+ EFI_DHCP4_MODE_DATA Dhcp4ModeData;
+
+ if (Dhcp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (gDhcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gDhcpControllerNameTable);
+ gDhcpControllerNameTable = NULL;
+ }
+
+ if (Dhcp4ModeData.State > Dhcp4Rebooting) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gDhcp4ComponentName.SupportedLanguages,
+ &gDhcpControllerNameTable,
+ mDhcp4ControllerName[Dhcp4ModeData.State],
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gDhcp4ComponentName2.SupportedLanguages,
+ &gDhcpControllerNameTable,
+ mDhcp4ControllerName[Dhcp4ModeData.State],
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -308,5 +382,56 @@ DhcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp4ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiDhcp4ProtocolGuid,
+ (VOID **)&Dhcp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Dhcp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gDhcpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gDhcp4ComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
index 8a773d9461..d1bba3022a 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
@@ -212,7 +212,6 @@ Dhcp4CreateService (
DhcpSb->Signature = DHCP_SERVICE_SIGNATURE;
DhcpSb->ServiceState = DHCP_UNCONFIGED;
- DhcpSb->InDestroy = FALSE;
DhcpSb->Controller = Controller;
DhcpSb->Image = ImageHandle;
InitializeListHead (&DhcpSb->Children);
@@ -354,6 +353,36 @@ ON_ERROR:
return Status;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Dhcp4DestroyChildEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ DHCP_PROTOCOL *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);
+ ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
/**
Stop this driver on ControllerHandle. This service is called by the
@@ -384,10 +413,10 @@ Dhcp4DriverBindingStop (
{
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
DHCP_SERVICE *DhcpSb;
- DHCP_PROTOCOL *Instance;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
- EFI_TPL OldTpl;
+ LIST_ENTRY *List;
+ UINTN ListLength;
//
// DHCP driver opens UDP child, So, the ControllerHandle is the
@@ -396,7 +425,7 @@ Dhcp4DriverBindingStop (
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -413,16 +442,30 @@ Dhcp4DriverBindingStop (
}
DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);
-
- if (DhcpSb->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&DhcpSb->Children)) {
+ //
+ // Destroy all the children instances before destory the service.
+ //
+ List = &DhcpSb->Children;
+ Status = NetDestroyLinkList (
+ List,
+ Dhcp4DestroyChildEntry,
+ ServiceBinding,
+ &ListLength
+ );
+ if (EFI_ERROR (Status) || ListLength != 0) {
+ Status = EFI_DEVICE_ERROR;
+ }
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren == 0 && !IsListEmpty (&DhcpSb->Children)) {
+ Status = EFI_DEVICE_ERROR;
+ }
- DhcpSb->InDestroy = TRUE;
+ if (NumberOfChildren == 0 && IsListEmpty (&DhcpSb->Children)) {
+ //
+ // Destroy the service itself if no child instance left.
+ //
DhcpSb->ServiceState = DHCP_DESTROY;
gBS->UninstallProtocolInterface (
@@ -433,24 +476,15 @@ Dhcp4DriverBindingStop (
Dhcp4CloseService (DhcpSb);
- FreePool (DhcpSb);
- } else {
- //
- // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestroyChild
- // may cause other child to be deleted.
- //
- while (!IsListEmpty (&DhcpSb->Children)) {
- Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- }
-
- if (DhcpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
+ if (gDhcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gDhcpControllerNameTable);
+ gDhcpControllerNameTable = NULL;
}
+ FreePool (DhcpSb);
+
+ Status = EFI_SUCCESS;
}
- gBS->RestoreTPL (OldTpl);
-
return Status;
}
@@ -663,12 +697,13 @@ Dhcp4ServiceBindingDestroyChild (
//
// Uninstall the DHCP4 protocol first to enable a top down destruction.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiDhcp4ProtocolGuid,
Dhcp
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
index b59b74135b..b4a63ef173 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
@@ -1,7 +1,7 @@
/** @file
Header for the DHCP4 driver.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp4ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable;
/**
Test to see if this driver supports ControllerHandle. This service
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
index b9a85f2333..41b5e95997 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
@@ -1,7 +1,7 @@
/** @file
This file implement the EFI_DHCP4_PROTOCOL interface.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -1234,6 +1234,8 @@ Dhcp4InstanceCreateUdpIo (
)
{
DHCP_SERVICE *DhcpSb;
+ EFI_STATUS Status;
+ VOID *Udp4;
ASSERT (Instance->Token != NULL);
@@ -1248,7 +1250,19 @@ Dhcp4InstanceCreateUdpIo (
if (Instance->UdpIo == NULL) {
return EFI_OUT_OF_RESOURCES;
} else {
- return EFI_SUCCESS;
+ Status = gBS->OpenProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ (VOID **) &Udp4,
+ Instance->Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ UdpIoFreeIo (Instance->UdpIo);
+ Instance->UdpIo = NULL;
+ }
+ return Status;
}
}
@@ -1416,6 +1430,12 @@ SIGNAL_USER:
//
NetbufQueFlush (&Instance->ResponseQueue);
UdpIoCleanIo (Instance->UdpIo);
+ gBS->CloseProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ Instance->Service->Image,
+ Instance->Handle
+ );
UdpIoFreeIo (Instance->UdpIo);
Instance->UdpIo = NULL;
Instance->Token = NULL;
@@ -1581,6 +1601,12 @@ ON_ERROR:
if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) {
UdpIoCleanIo (Instance->UdpIo);
+ gBS->CloseProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ Instance->Service->Image,
+ Instance->Handle
+ );
UdpIoFreeIo (Instance->UdpIo);
Instance->UdpIo = NULL;
Instance->Token = NULL;
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
index 08faff0206..44213cf40a 100644
--- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
+++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
@@ -84,7 +84,6 @@ struct _DHCP_SERVICE {
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN ServiceState; // CONFIGED, UNCONFIGED, and DESTROY
- BOOLEAN InDestroy;
EFI_HANDLE Controller;
EFI_HANDLE Image;
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c b/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c
index acb9c0758d..e88587a4bb 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for iSCSI.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -37,6 +37,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable[] =
{NULL, NULL}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiControllerNameTable[] = {
+ {"eng;en", L"iSCSI (IPv4)"},
+ {NULL, NULL}
+};
+
/**
Retrieves a Unicode string that is the user readable name of the EFI Driver.
@@ -131,5 +136,36 @@ IScsiComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_HANDLE IScsiController;
+ ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
+ EFI_STATUS Status;
+
+ //
+ // Get the handle of the controller we are controling.
+ //
+ IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
+ if (IScsiController == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->OpenProtocol (
+ IScsiController,
+ &gEfiCallerIdGuid,
+ (VOID **)&IScsiIdentifier,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mIScsiControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIScsiComponentName)
+ );
}
+
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
index d3fcf048fc..2ccfb3cc1c 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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<BR>
@@ -173,6 +173,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp4DriverNameTable[] = {
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -231,6 +233,74 @@ Ip4ComponentNameGetDriverName (
}
/**
+ Update the component name for the IP4 child handle.
+
+ @param Ip4[in] A pointer to the EFI_IP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_IP4_PROTOCOL *Ip4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_IP4_MODE_DATA Ip4ModeData;
+
+ if (Ip4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)
+ //
+ Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"IPv4 (SrcIP=%d.%d.%d.%d)",
+ Ip4ModeData.ConfigData.StationAddress.Addr[0],
+ Ip4ModeData.ConfigData.StationAddress.Addr[1],
+ Ip4ModeData.ConfigData.StationAddress.Addr[2],
+ Ip4ModeData.ConfigData.StationAddress.Addr[3]
+ );
+ }
+
+ if (gIp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp4ControllerNameTable);
+ gIp4ControllerNameTable = NULL;
+ }
+ Status = AddUnicodeString2 (
+ "eng",
+ gIp4ComponentName.SupportedLanguages,
+ &gIp4ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIp4ComponentName2.SupportedLanguages,
+ &gIp4ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -308,5 +378,57 @@ Ip4ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_IP4_PROTOCOL *Ip4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ (VOID **)&Ip4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Ip4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIp4ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIp4ComponentName)
+ );
}
+
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
index 295f822979..64049303e4 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
@@ -1,7 +1,7 @@
/** @file
Common definition for IP4.
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -63,6 +63,9 @@ typedef struct _IP4_SERVICE IP4_SERVICE;
#define IP4_FIRST_FRAGMENT(FragmentField) \
((BOOLEAN)(((FragmentField) & IP4_HEAD_OFFSET_MASK) == 0))
+#define IP4_DO_NOT_FRAGMENT(FragmentField) \
+ ((BOOLEAN)(((FragmentField) & IP4_HEAD_DF_MASK) == IP4_HEAD_DF_MASK))
+
#define IP4_IS_BROADCAST(CastType) ((CastType) >= IP4_LOCAL_BROADCAST)
///
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
index 4ce85a3f51..4a3d342711 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
@@ -176,7 +176,6 @@ Ip4CreateService (
IpSb->ServiceBinding.CreateChild = Ip4ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild;
IpSb->State = IP4_SERVICE_UNSTARTED;
- IpSb->InDestroy = FALSE;
IpSb->NumChildren = 0;
InitializeListHead (&IpSb->Children);
@@ -396,6 +395,43 @@ Ip4CleanService (
return EFI_SUCCESS;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Ip4DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ IP4_PROTOCOL *IpInstance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, Link, IP4_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
+}
/**
Start this driver on ControllerHandle. This service is called by the
@@ -529,14 +565,13 @@ Ip4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- IP4_SERVICE *IpSb;
- IP4_PROTOCOL *IpInstance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- INTN State;
- BOOLEAN IsArp;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ IP4_SERVICE *IpSb;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ INTN State;
+ LIST_ENTRY *List;
+ IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol
@@ -557,7 +592,6 @@ Ip4DriverBindingStop (
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
-
if (Status == EFI_SUCCESS) {
//
// Retrieve the IP4 service binding protocol. If failed, it is
@@ -572,15 +606,11 @@ Ip4DriverBindingStop (
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
-
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
if (IpSb->Ip4Config != NULL && (IpSb->State != IP4_SERVICE_DESTROY)) {
IpSb->Ip4Config->Stop (IpSb->Ip4Config);
@@ -591,9 +621,7 @@ Ip4DriverBindingStop (
IpSb->Image,
ControllerHandle
);
-
if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -609,7 +637,6 @@ Ip4DriverBindingStop (
gBS->CloseEvent (IpSb->ReconfigEvent);
}
- gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
@@ -619,16 +646,12 @@ Ip4DriverBindingStop (
// service binding is installed on the NIC handle. So, need to open
// the protocol info to find the NIC handle.
//
- IsArp = FALSE;
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
-
if (NicHandle == NULL) {
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
- IsArp = TRUE;
- }
-
- if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ if (NicHandle == NULL) {
+ return EFI_SUCCESS;
+ }
}
//
@@ -642,34 +665,23 @@ Ip4DriverBindingStop (
NicHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
-
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (IpSb->InDestroy) {
- gBS->RestoreTPL (OldTpl);
- return EFI_SUCCESS;
- }
-
- if (IsArp) {
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
-
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- goto ON_ERROR;
- }
-
- IpSb->InDestroy = TRUE;
-
+ if (NumberOfChildren != 0) {
+ List = &IpSb->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Ip4DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&IpSb->Children)) {
State = IpSb->State;
IpSb->State = IP4_SERVICE_DESTROY;
@@ -682,7 +694,6 @@ Ip4DriverBindingStop (
// OK, clean other resources then uninstall the service binding protocol.
//
Status = Ip4CleanService (IpSb);
-
if (EFI_ERROR (Status)) {
IpSb->State = State;
goto ON_ERROR;
@@ -693,52 +704,15 @@ Ip4DriverBindingStop (
&gEfiIp4ServiceBindingProtocolGuid,
ServiceBinding
);
-
- FreePool (IpSb);
- } else if (NumberOfChildren == 0) {
- IpSb->InDestroy = TRUE;
-
- State = IpSb->State;
- IpSb->State = IP4_SERVICE_DESTROY;
-
- //
- // Clear the variable data.
- //
- Ip4ClearVariableData (IpSb);
-
- //
- // OK, clean other resources then uninstall the service binding protocol.
- //
- Status = Ip4CleanService (IpSb);
-
- if (EFI_ERROR (Status)) {
- IpSb->State = State;
- goto ON_ERROR;
+
+ if (gIp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp4ControllerNameTable);
+ gIp4ControllerNameTable = NULL;
}
-
- gBS->UninstallProtocolInterface (
- NicHandle,
- &gEfiIp4ServiceBindingProtocolGuid,
- ServiceBinding
- );
-
FreePool (IpSb);
- } else {
-
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
-
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- }
}
ON_ERROR:
-
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -935,6 +909,15 @@ Ip4ServiceBindingDestroyChild (
ChildHandle
);
+ if (IpInstance->Interface != NULL && IpInstance->Interface->Arp != NULL) {
+ gBS->CloseProtocol (
+ IpInstance->Interface->ArpHandle,
+ &gEfiArpProtocolGuid,
+ gIp4DriverBinding.DriverBindingHandle,
+ ChildHandle
+ );
+ }
+
//
// Uninstall the IP4 protocol first. Many thing happens during
// this:
@@ -949,12 +932,13 @@ Ip4ServiceBindingDestroyChild (
// will be called back before preceeding. If any packets not recycled,
// that means there is a resource leak.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiIp4ProtocolGuid,
&IpInstance->Ip4Proto
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
index 96044fd0ce..32984bad66 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -19,6 +19,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gIp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gIp4ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable;
+
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
//
// Function prototype for the driver's entry point
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
index 18cb9ff360..e5e2b984ee 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -193,7 +193,7 @@ Ip4ProcessIcmpError (
}
IP4_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR;
- return Ip4Demultiplex (IpSb, Head, Packet);
+ return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);
}
@@ -308,7 +308,7 @@ Ip4ProcessIcmpQuery (
return Ip4IcmpReplyEcho (IpSb, Head, Packet);
}
- return Ip4Demultiplex (IpSb, Head, Packet);
+ return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
index f4ce3ea025..74bf7f76eb 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
@@ -868,6 +868,7 @@ Ip4ConfigProtocol (
EFI_STATUS Status;
IP4_ADDR Ip;
IP4_ADDR Netmask;
+ EFI_ARP_PROTOCOL *Arp;
IpSb = IpInstance->Service;
@@ -972,6 +973,20 @@ Ip4ConfigProtocol (
}
IpInstance->Interface = IpIf;
+ if (IpIf->Arp != NULL) {
+ Arp = NULL;
+ Status = gBS->OpenProtocol (
+ IpIf->ArpHandle,
+ &gEfiArpProtocolGuid,
+ (VOID **) &Arp,
+ gIp4DriverBinding.DriverBindingHandle,
+ IpInstance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+ }
InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
@@ -1028,6 +1043,14 @@ Ip4CleanProtocol (
if (IpInstance->Interface != NULL) {
RemoveEntryList (&IpInstance->AddrLink);
+ if (IpInstance->Interface->Arp != NULL) {
+ gBS->CloseProtocol (
+ IpInstance->Interface->ArpHandle,
+ &gEfiArpProtocolGuid,
+ gIp4DriverBinding.DriverBindingHandle,
+ IpInstance->Handle
+ );
+ }
Ip4FreeInterface (IpInstance->Interface, IpInstance);
IpInstance->Interface = NULL;
}
@@ -1193,14 +1216,6 @@ EfiIp4Configure (
// Validate the configuration first.
//
if (IpConfigData != NULL) {
- //
- // This implementation doesn't support RawData
- //
- if (IpConfigData->RawData) {
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- }
-
CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));
CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));
@@ -1620,22 +1635,23 @@ Ip4TokenExist (
return EFI_SUCCESS;
}
-
/**
Validate the user's token against current station address.
- @param[in] Token User's token to validate
- @param[in] IpIf The IP4 child's interface.
+ @param[in] Token User's token to validate.
+ @param[in] IpIf The IP4 child's interface.
+ @param[in] RawData Set to TRUE to send unformatted packets.
- @retval EFI_INVALID_PARAMETER Some parameters are invalid
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_BAD_BUFFER_SIZE The user's option/data is too long.
- @retval EFI_SUCCESS The token is OK
+ @retval EFI_SUCCESS The token is valid.
**/
EFI_STATUS
Ip4TxTokenValid (
IN EFI_IP4_COMPLETION_TOKEN *Token,
- IN IP4_INTERFACE *IpIf
+ IN IP4_INTERFACE *IpIf,
+ IN BOOLEAN RawData
)
{
EFI_IP4_TRANSMIT_DATA *TxData;
@@ -1653,20 +1669,7 @@ Ip4TxTokenValid (
TxData = Token->Packet.TxData;
//
- // Check the IP options: no more than 40 bytes and format is OK
- //
- if (TxData->OptionsLength != 0) {
- if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- //
- // Check the fragment table: no empty fragment, and length isn't bogus
+ // Check the fragment table: no empty fragment, and length isn't bogus.
//
if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {
return EFI_INVALID_PARAMETER;
@@ -1674,6 +1677,10 @@ Ip4TxTokenValid (
Offset = TxData->TotalDataLength;
+ if (Offset > IP4_MAX_PACKET_SIZE) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
for (Index = 0; Index < TxData->FragmentCount; Index++) {
if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
(TxData->FragmentTable[Index].FragmentLength == 0)) {
@@ -1689,6 +1696,27 @@ Ip4TxTokenValid (
}
//
+ // NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData
+ // is TRUE.
+ //
+ if (RawData) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check the IP options: no more than 40 bytes and format is OK
+ //
+ if (TxData->OptionsLength != 0) {
+ if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
// Check the source and gateway: they must be a valid unicast.
// Gateway must also be on the connected network.
//
@@ -1888,6 +1916,10 @@ EfiIp4Transmit (
EFI_TPL OldTpl;
BOOLEAN DontFragment;
UINT32 HeadLen;
+ UINT8 RawHdrLen;
+ UINT32 OptionsLength;
+ UINT8 *OptionsBuffer;
+ VOID *FirstFragment;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
@@ -1913,7 +1945,7 @@ EfiIp4Transmit (
//
// make sure that token is properly formated
//
- Status = Ip4TxTokenValid (Token, IpIf);
+ Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
@@ -1933,32 +1965,82 @@ EfiIp4Transmit (
//
TxData = Token->Packet.TxData;
- CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
- Head.Dst = NTOHL (Head.Dst);
+ FirstFragment = NULL;
- if (TxData->OverrideData != NULL) {
- Override = TxData->OverrideData;
- Head.Protocol = Override->Protocol;
- Head.Tos = Override->TypeOfService;
- Head.Ttl = Override->TimeToLive;
- DontFragment = Override->DoNotFragment;
+ if (Config->RawData) {
+ //
+ // When RawData is TRUE, first buffer in FragmentTable points to a raw
+ // IPv4 fragment including IPv4 header and options.
+ //
+ FirstFragment = TxData->FragmentTable[0].FragmentBuffer;
+ CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));
- CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
- CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
+ RawHdrLen = (UINT8) (RawHdrLen & 0x0f);
+ if (RawHdrLen < 5) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RawHdrLen = (UINT8) (RawHdrLen << 2);
+
+ CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
+
+ Ip4NtohHead (&Head);
+ HeadLen = 0;
+ DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
- Head.Src = NTOHL (Head.Src);
- GateWay = NTOHL (GateWay);
+ if (!DontFragment) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GateWay = IP4_ALLZERO_ADDRESS;
+
+ //
+ // Get IPv4 options from first fragment.
+ //
+ if (RawHdrLen == IP4_MIN_HEADLEN) {
+ OptionsLength = 0;
+ OptionsBuffer = NULL;
+ } else {
+ OptionsLength = RawHdrLen - IP4_MIN_HEADLEN;
+ OptionsBuffer = (UINT8 *) FirstFragment + IP4_MIN_HEADLEN;
+ }
+
+ //
+ // Trim off IPv4 header and options from first fragment.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment + RawHdrLen;
+ TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen;
} else {
- Head.Src = IpIf->Ip;
- GateWay = IP4_ALLZERO_ADDRESS;
- Head.Protocol = Config->DefaultProtocol;
- Head.Tos = Config->TypeOfService;
- Head.Ttl = Config->TimeToLive;
- DontFragment = Config->DoNotFragment;
- }
+ CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
+ Head.Dst = NTOHL (Head.Dst);
- Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
- HeadLen = (TxData->OptionsLength + 3) & (~0x03);
+ if (TxData->OverrideData != NULL) {
+ Override = TxData->OverrideData;
+ Head.Protocol = Override->Protocol;
+ Head.Tos = Override->TypeOfService;
+ Head.Ttl = Override->TimeToLive;
+ DontFragment = Override->DoNotFragment;
+
+ CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
+ CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
+
+ Head.Src = NTOHL (Head.Src);
+ GateWay = NTOHL (GateWay);
+ } else {
+ Head.Src = IpIf->Ip;
+ GateWay = IP4_ALLZERO_ADDRESS;
+ Head.Protocol = Config->DefaultProtocol;
+ Head.Tos = Config->TypeOfService;
+ Head.Ttl = Config->TimeToLive;
+ DontFragment = Config->DoNotFragment;
+ }
+
+ Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);
+ HeadLen = (TxData->OptionsLength + 3) & (~0x03);
+
+ OptionsLength = TxData->OptionsLength;
+ OptionsBuffer = (UINT8 *) (TxData->OptionsBuffer);
+ }
//
// If don't fragment and fragment needed, return error
@@ -2004,6 +2086,13 @@ EfiIp4Transmit (
// free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been
// enqueued.
//
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
NetbufFree (Wrap->Packet);
goto ON_EXIT;
}
@@ -2019,8 +2108,8 @@ EfiIp4Transmit (
IpInstance,
Wrap->Packet,
&Head,
- TxData->OptionsBuffer,
- TxData->OptionsLength,
+ OptionsBuffer,
+ OptionsLength,
GateWay,
Ip4OnPacketSent,
Wrap
@@ -2028,9 +2117,24 @@ EfiIp4Transmit (
if (EFI_ERROR (Status)) {
Wrap->Sent = FALSE;
+
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
NetbufFree (Wrap->Packet);
}
+ if (Config->RawData) {
+ //
+ // Restore pointer of first fragment in RawData mode.
+ //
+ TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;
+ }
+
ON_EXIT:
gBS->RestoreTPL (OldTpl);
return Status;
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
index 563cf7f91f..ad8a9276bd 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
@@ -33,6 +33,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#include "Ip4Common.h"
#include "Ip4Driver.h"
@@ -160,7 +161,6 @@ struct _IP4_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN State;
- BOOLEAN InDestroy;
//
// List of all the IP instances and interfaces, and default
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
index d985b1aeb6..62163f4c57 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
@@ -714,7 +714,7 @@ Ip4PreProcessPacket (
UINT16 Checksum;
//
- // Check that the IP4 header is correctly formatted
+ // Check if the IP4 header is correctly formatted.
//
if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {
return EFI_INVALID_PARAMETER;
@@ -774,7 +774,7 @@ Ip4PreProcessPacket (
}
//
- // Trim the head off, after this point, the packet is headless.
+ // Trim the head off, after this point, the packet is headless,
// and Packet->TotalLen == Info->Length.
//
NetbufTrim (*Packet, HeadLen, TRUE);
@@ -928,7 +928,7 @@ Ip4AccpetFrame (
break;
default:
- Ip4Demultiplex (IpSb, Head, Packet);
+ Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);
}
Packet = NULL;
@@ -1151,8 +1151,8 @@ Ip4OnRecyclePacket (
to the upper layer. Upper layer will signal the recycle event in
it when it is done with the packet.
- @param[in] IpInstance The IP4 child to receive the packet
- @param[in] Packet The packet to deliver up.
+ @param[in] IpInstance The IP4 child to receive the packet.
+ @param[in] Packet The packet to deliver up.
@retval Wrap if warp the packet succeed.
@retval NULL failed to wrap the packet .
@@ -1167,6 +1167,7 @@ Ip4WrapRxData (
IP4_RXDATA_WRAP *Wrap;
EFI_IP4_RECEIVE_DATA *RxData;
EFI_STATUS Status;
+ BOOLEAN RawData;
Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));
@@ -1180,7 +1181,7 @@ Ip4WrapRxData (
Wrap->Packet = Packet;
RxData = &Wrap->RxData;
- ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME));
+ ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
@@ -1197,17 +1198,21 @@ Ip4WrapRxData (
ASSERT (Packet->Ip.Ip4 != NULL);
+ ASSERT (IpInstance != NULL);
+ RawData = IpInstance->ConfigData.RawData;
+
//
// The application expects a network byte order header.
//
- RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2);
- RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);
-
- RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;
- RxData->Options = NULL;
+ if (!RawData) {
+ RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2);
+ RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);
+ RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;
+ RxData->Options = NULL;
- if (RxData->OptionsLength != 0) {
- RxData->Options = (VOID *) (RxData->Header + 1);
+ if (RxData->OptionsLength != 0) {
+ RxData->Options = (VOID *) (RxData->Header + 1);
+ }
}
RxData->DataLength = Packet->TotalSize;
@@ -1246,6 +1251,7 @@ Ip4InstanceDeliverPacket (
NET_BUF *Packet;
NET_BUF *Dup;
UINT8 *Head;
+ UINT32 HeadLen;
//
// Deliver a packet if there are both a packet and a receive token.
@@ -1271,24 +1277,32 @@ Ip4InstanceDeliverPacket (
//
// Create a duplicated packet if this packet is shared
//
- Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN);
+ if (IpInstance->ConfigData.RawData) {
+ HeadLen = 0;
+ } else {
+ HeadLen = IP4_MAX_HEADLEN;
+ }
+
+ Dup = NetbufDuplicate (Packet, NULL, HeadLen);
if (Dup == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- //
- // Copy the IP head over. The packet to deliver up is
- // headless. Trim the head off after copy. The IP head
- // may be not continuous before the data.
- //
- Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);
- ASSERT (Head != NULL);
-
- Dup->Ip.Ip4 = (IP4_HEAD *) Head;
-
- CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);
- NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);
+ if (!IpInstance->ConfigData.RawData) {
+ //
+ // Copy the IP head over. The packet to deliver up is
+ // headless. Trim the head off after copy. The IP head
+ // may be not continuous before the data.
+ //
+ Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);
+ ASSERT (Head != NULL);
+
+ Dup->Ip.Ip4 = (IP4_HEAD *) Head;
+
+ CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);
+ NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);
+ }
Wrap = Ip4WrapRxData (IpInstance, Dup);
@@ -1326,10 +1340,12 @@ Ip4InstanceDeliverPacket (
Enqueue a received packet to all the IP children that share
the same interface.
- @param[in] IpSb The IP4 service instance that receive the packet
- @param[in] Head The header of the received packet
- @param[in] Packet The data of the received packet
- @param[in] IpIf The interface to enqueue the packet to
+ @param[in] IpSb The IP4 service instance that receive the packet.
+ @param[in] Head The header of the received packet.
+ @param[in] Packet The data of the received packet.
+ @param[in] Option Point to the IP4 packet header options.
+ @param[in] OptionLen Length of the IP4 packet header options.
+ @param[in] IpIf The interface to enqueue the packet to.
@return The number of the IP4 children that accepts the packet
@@ -1339,6 +1355,8 @@ Ip4InterfaceEnquePacket (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen,
IN IP4_INTERFACE *IpIf
)
{
@@ -1404,6 +1422,13 @@ Ip4InterfaceEnquePacket (
IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);
NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE);
+ //
+ // In RawData mode, add IPv4 headers and options back to packet.
+ //
+ if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)){
+ Ip4PrependHead (Packet, Head, Option, OptionLen);
+ }
+
if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {
Enqueued++;
}
@@ -1450,11 +1475,13 @@ Ip4InterfaceDeliverPacket (
child wants to consume the packet because each IP child needs
its own copy of the packet to make changes.
- @param[in] IpSb The IP4 service instance that received the packet
- @param[in] Head The header of the received packet
- @param[in] Packet The data of the received packet
+ @param[in] IpSb The IP4 service instance that received the packet.
+ @param[in] Head The header of the received packet.
+ @param[in] Packet The data of the received packet.
+ @param[in] Option Point to the IP4 packet header options.
+ @param[in] OptionLen Length of the IP4 packet header options.
- @retval EFI_NOT_FOUND No IP child accepts the packet
+ @retval EFI_NOT_FOUND No IP child accepts the packet.
@retval EFI_SUCCESS The packet is enqueued or delivered to some IP
children.
@@ -1463,7 +1490,9 @@ EFI_STATUS
Ip4Demultiplex (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
- IN NET_BUF *Packet
+ IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen
)
{
LIST_ENTRY *Entry;
@@ -1480,7 +1509,14 @@ Ip4Demultiplex (
IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
if (IpIf->Configured) {
- Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf);
+ Enqueued += Ip4InterfaceEnquePacket (
+ IpSb,
+ Head,
+ Packet,
+ Option,
+ OptionLen,
+ IpIf
+ );
}
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
index fda4d18c9c..1c8e8b2a15 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -141,11 +141,13 @@ Ip4AccpetFrame (
child wants to consume the packet because each IP child needs
its own copy of the packet to make changes.
- @param[in] IpSb The IP4 service instance that received the packet
- @param[in] Head The header of the received packet
- @param[in] Packet The data of the received packet
+ @param[in] IpSb The IP4 service instance that received the packet.
+ @param[in] Head The header of the received packet.
+ @param[in] Packet The data of the received packet.
+ @param[in] Option Point to the IP4 packet header options.
+ @param[in] OptionLen Length of the IP4 packet header options.
- @retval EFI_NOT_FOUND No IP child accepts the packet
+ @retval EFI_NOT_FOUND No IP child accepts the packet.
@retval EFI_SUCCESS The packet is enqueued or delivered to some IP
children.
@@ -154,17 +156,21 @@ EFI_STATUS
Ip4Demultiplex (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
- IN NET_BUF *Packet
+ IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen
);
/**
Enqueue a received packet to all the IP children that share
the same interface.
- @param[in] IpSb The IP4 service instance that receive the packet
- @param[in] Head The header of the received packet
- @param[in] Packet The data of the received packet
- @param[in] IpIf The interface to enqueue the packet to
+ @param[in] IpSb The IP4 service instance that receive the packet.
+ @param[in] Head The header of the received packet.
+ @param[in] Packet The data of the received packet.
+ @param[in] Option Point to the IP4 packet header options.
+ @param[in] OptionLen Length of the IP4 packet header options.
+ @param[in] IpIf The interface to enqueue the packet to.
@return The number of the IP4 children that accepts the packet
@@ -174,6 +180,8 @@ Ip4InterfaceEnquePacket (
IN IP4_SERVICE *IpSb,
IN IP4_HEAD *Head,
IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen,
IN IP4_INTERFACE *IpIf
);
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
index 85dffe0643..7ff17b6637 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
@@ -1,7 +1,7 @@
/** @file
Transmit the IP4 packet.
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -204,6 +204,10 @@ Ip4SysPacketSent (
@retval EFI_NO_MAPPING There is no interface to the destination.
@retval EFI_NOT_FOUND There is no route to the destination
@retval EFI_SUCCESS The packet is successfully transmitted.
+ @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length +
+ total data length is greater than MTU (or greater
+ than the maximum packet size if Token.Packet.TxData.
+ OverrideData.DoNotFragment is TRUE.)
@retval Others Failed to transmit the packet.
**/
@@ -231,6 +235,7 @@ Ip4Output (
UINT32 Offset;
UINT32 Mtu;
UINT32 Num;
+ BOOLEAN RawData;
//
// Select an interface/source for system packet, application
@@ -252,11 +257,18 @@ Ip4Output (
//
// Before IPsec process, prepared the IP head.
+ // If Ip4Output is transmitting RawData, don't update IPv4 header.
//
- HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
- Head->HeadLen = (UINT8) (HeadLen >> 2);
- Head->Id = mIp4Id++;
- Head->Ver = 4;
+ HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
+
+ if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) {
+ RawData = TRUE;
+ } else {
+ Head->HeadLen = (UINT8) (HeadLen >> 2);
+ Head->Id = mIp4Id++;
+ Head->Ver = 4;
+ RawData = FALSE;
+ }
//
// Call IPsec process.
@@ -324,6 +336,13 @@ Ip4Output (
if (Packet->TotalSize + HeadLen > Mtu) {
//
+ // Fragmentation is diabled for RawData mode.
+ //
+ if (RawData) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
// Packet is fragmented from the tail to the head, that is, the
// first frame sent is the last fragment of the packet. The first
// fragment is NOT sent in this loop. First compute how many
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c
index c56ad061e1..25a7f88482 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for MnpDxe driver.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include "MnpDriver.h"
+#include "MnpImpl.h"
//
// EFI Component Name Protocol
@@ -44,6 +44,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMnpDriverNameTable[
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -101,6 +103,106 @@ MnpComponentNameGetDriverName (
}
/**
+ Update the component name for the MNP child handle.
+
+ @param Mnp[in] A pointer to the EFI_MANAGED_NETWORK_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ CHAR16 HandleName[80];
+ EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
+ EFI_SIMPLE_NETWORK_MODE SnpModeData;
+ UINTN OffSet;
+ UINTN Index;
+
+ if (Mnp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp);
+ //
+ // Format the child name into the string buffer as:
+ // MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0)
+ //
+ Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData);
+ if (!EFI_ERROR (Status)) {
+ OffSet = 0;
+ //
+ // Print the MAC address.
+ //
+ OffSet += UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"MNP (MAC="
+ );
+ for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) {
+ OffSet += UnicodeSPrint (
+ HandleName + OffSet,
+ sizeof (HandleName) - OffSet * sizeof (CHAR16),
+ L"%02X-",
+ SnpModeData.CurrentAddress.Addr[Index]
+ );
+ }
+ //
+ // Remove the last '-'
+ //
+ OffSet--;
+ //
+ // Print the ProtocolType and VLAN ID for this instance.
+ //
+ OffSet += UnicodeSPrint (
+ HandleName + OffSet,
+ sizeof (HandleName) - OffSet * sizeof (CHAR16),
+ L", ProtocolType=0x%X, VlanId=%d)",
+ MnpConfigData.ProtocolTypeFilter,
+ Instance->MnpServiceData->VlanId
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"MNP (Not started)"
+ );
+ } else {
+ return Status;
+ }
+
+ if (gMnpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMnpControllerNameTable);
+ gMnpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gMnpComponentName.SupportedLanguages,
+ &gMnpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gMnpComponentName2.SupportedLanguages,
+ &gMnpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -178,5 +280,68 @@ MnpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
+
+ //
+ // Only provide names for MNP child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gMnpDriverBinding.DriverBindingHandle,
+ &gEfiSimpleNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkServiceBindingProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid,
+ (VOID **)&Mnp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Mnp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gMnpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gMnpComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h
index 6f60ef7e69..6232c3e1ed 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h
+++ b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h
@@ -1,7 +1,7 @@
/** @file
The header file of UEFI Component Name(2) protocol.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_COMPONENT_NAME2_PROTOCOL gMnpComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName;
+extern EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable;
/**
Retrieves a Unicode string that is the user readable name of the driver.
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
index c19c71b411..046d4dfddc 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
@@ -1,7 +1,7 @@
/** @file
Implementation of Managed Network Protocol private services.
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -45,7 +45,6 @@ EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = {
FALSE
};
-
/**
Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net
buffer is specified by MnpDeviceData->BufferLength.
@@ -687,6 +686,31 @@ MnpDestroyServiceData (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpDestoryChildEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ MNP_INSTANCE_DATA *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+
+ ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
+ Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
+/**
Destroy all child of the MNP service data.
@param[in, out] MnpServiceData Pointer to the mnp service context data.
@@ -700,26 +724,20 @@ MnpDestroyServiceChild (
IN OUT MNP_SERVICE_DATA *MnpServiceData
)
{
- EFI_STATUS Status;
- MNP_INSTANCE_DATA *Instance;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
-
- ServiceBinding = &MnpServiceData->ServiceBinding;
- while (!IsListEmpty (&MnpServiceData->ChildrenList)) {
- //
- // Don't use NetListRemoveHead here, the remove opreration will be done
- // in ServiceBindingDestroyChild.
- //
- Instance = NET_LIST_HEAD (
- &MnpServiceData->ChildrenList,
- MNP_INSTANCE_DATA,
- InstEntry
- );
-
- Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ LIST_ENTRY *List;
+ EFI_STATUS Status;
+ UINTN ListLength;
+
+ List = &MnpServiceData->ChildrenList;
+
+ Status = NetDestroyLinkList (
+ List,
+ MnpDestoryChildEntry,
+ &MnpServiceData->ServiceBinding,
+ &ListLength
+ );
+ if (EFI_ERROR (Status) || ListLength != 0) {
+ return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
index 03ddfb7ccc..2ddcec8962 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
@@ -1,7 +1,7 @@
/** @file
Implementation of driver entry point and driver binding protocol.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -27,6 +27,52 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
};
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpDestroyServiceDataEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ MNP_SERVICE_DATA *MnpServiceData;
+
+ MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
+ return MnpDestroyServiceData (MnpServiceData);
+}
+
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpDestroyServiceChildEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ MNP_SERVICE_DATA *MnpServiceData;
+
+ MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
+ return MnpDestroyServiceChild (MnpServiceData);
+}
+
+/**
Test to see if this driver supports ControllerHandle. This service
is called by the EFI boot service ConnectController(). In
order to make drivers as small as possible, there are a few calling
@@ -276,8 +322,8 @@ MnpDriverBindingStop (
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
- BOOLEAN AllChildrenStopped;
- LIST_ENTRY *Entry;
+ LIST_ENTRY *List;
+ UINTN ListLength;
//
// Try to retrieve MNP service binding protocol from the ControllerHandle
@@ -317,10 +363,15 @@ MnpDriverBindingStop (
//
// Destroy all MNP service data
//
- while (!IsListEmpty (&MnpDeviceData->ServiceList)) {
- Entry = GetFirstNode (&MnpDeviceData->ServiceList);
- MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
- MnpDestroyServiceData (MnpServiceData);
+ List = &MnpDeviceData->ServiceList;
+ Status = NetDestroyLinkList (
+ List,
+ MnpDestroyServiceDataEntry,
+ NULL,
+ &ListLength
+ );
+ if (EFI_ERROR (Status) || ListLength !=0) {
+ return EFI_DEVICE_ERROR;
}
//
@@ -341,23 +392,24 @@ MnpDriverBindingStop (
MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
FreePool (MnpDeviceData);
+ if (gMnpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMnpControllerNameTable);
+ gMnpControllerNameTable = NULL;
+ }
return EFI_SUCCESS;
}
//
// Stop all MNP child
//
- AllChildrenStopped = TRUE;
- NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
- MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
-
- Status = MnpDestroyServiceChild (MnpServiceData);
- if (EFI_ERROR (Status)) {
- AllChildrenStopped = FALSE;
- }
- }
-
- if (!AllChildrenStopped) {
+ List = &MnpDeviceData->ServiceList;
+ Status = NetDestroyLinkList (
+ List,
+ MnpDestroyServiceChildEntry,
+ NULL,
+ &ListLength
+ );
+ if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h
index f096862485..35a9b710db 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h
@@ -1,7 +1,7 @@
/** @file
Declaration of strctures and functions for MnpDxe driver.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -33,11 +33,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/DpcLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
#include "ComponentName.h"
#define MNP_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('M', 'n', 'p', 'D')
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding;
+
typedef struct {
UINT32 Signature;
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c
index 71f49f6039..901c2df064 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Mtftp4Dxe driver.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include "Mtftp4Driver.h"
+#include "Mtftp4Impl.h"
//
// EFI Component Name Functions
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp4DriverNameTable[]
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp4ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -231,6 +233,72 @@ Mtftp4ComponentNameGetDriverName (
}
/**
+ Update the component name for the Mtftp4 child handle.
+
+ @param Mtftp4[in] A pointer to the EFI_MTFTP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_MTFTP4_PROTOCOL *Mtftp4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_MTFTP4_MODE_DATA ModeData;
+
+ if (Mtftp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69)
+ //
+ Status = Mtftp4->GetModeData (Mtftp4, &ModeData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)",
+ ModeData.ConfigData.ServerIp.Addr[0],
+ ModeData.ConfigData.ServerIp.Addr[1],
+ ModeData.ConfigData.ServerIp.Addr[2],
+ ModeData.ConfigData.ServerIp.Addr[3],
+ ModeData.ConfigData.InitialServerPort
+ );
+
+ if (gMtftp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMtftp4ControllerNameTable);
+ gMtftp4ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gMtftp4ComponentName.SupportedLanguages,
+ &gMtftp4ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gMtftp4ComponentName2.SupportedLanguages,
+ &gMtftp4ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -308,5 +376,56 @@ Mtftp4ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_MTFTP4_PROTOCOL *Mtftp4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp4ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiMtftp4ProtocolGuid,
+ (VOID **)&Mtftp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Mtftp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gMtftp4ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gMtftp4ComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
index 2a12b1d5e7..a23d405baa 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
@@ -159,7 +159,6 @@ Mtftp4CreateService (
MtftpSb->Signature = MTFTP4_SERVICE_SIGNATURE;
MtftpSb->ServiceBinding = gMtftp4ServiceBindingTemplete;
- MtftpSb->InDestroy = FALSE;
MtftpSb->ChildrenNum = 0;
InitializeListHead (&MtftpSb->Children);
@@ -318,6 +317,43 @@ ON_ERROR:
return Status;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Mtftp4DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ MTFTP4_PROTOCOL *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP4_PROTOCOL, Link, MTFTP4_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
/**
Stop the MTFTP driver on controller. The controller is a UDP
@@ -341,12 +377,12 @@ Mtftp4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- MTFTP4_SERVICE *MtftpSb;
- MTFTP4_PROTOCOL *Instance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ MTFTP4_SERVICE *MtftpSb;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ LIST_ENTRY *List;
+ MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// MTFTP driver opens UDP child, So, Controller is a UDP
@@ -356,7 +392,7 @@ Mtftp4DriverBindingStop (
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -374,16 +410,23 @@ Mtftp4DriverBindingStop (
MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);
- if (MtftpSb->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&MtftpSb->Children)) {
+ //
+ // Destroy the Mtftp4 child instance in ChildHandleBuffer.
+ //
+ List = &MtftpSb->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Mtftp4DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (NumberOfChildren == 0) {
-
- MtftpSb->InDestroy = TRUE;
-
+ if (NumberOfChildren == 0 && IsListEmpty (&MtftpSb->Children)) {
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp4ServiceBindingProtocolGuid,
@@ -391,21 +434,15 @@ Mtftp4DriverBindingStop (
);
Mtftp4CleanService (MtftpSb);
-
- FreePool (MtftpSb);
- } else {
-
- while (!IsListEmpty (&MtftpSb->Children)) {
- Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
- Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
+ if (gMtftp4ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMtftp4ControllerNameTable);
+ gMtftp4ControllerNameTable = NULL;
}
+ FreePool (MtftpSb);
- if (MtftpSb->ChildrenNum != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -429,7 +466,6 @@ Mtftp4InitProtocol (
InitializeListHead (&Instance->Link);
CopyMem (&Instance->Mtftp4, &gMtftp4ProtocolTemplate, sizeof (Instance->Mtftp4));
Instance->State = MTFTP4_STATE_UNCONFIGED;
- Instance->InDestroy = FALSE;
Instance->Service = MtftpSb;
InitializeListHead (&Instance->Blocks);
@@ -499,7 +535,9 @@ Mtftp4ServiceBindingCreateChild (
);
if (EFI_ERROR (Status)) {
- goto ON_ERROR;
+ UdpIoFreeIo (Instance->UnicastPort);
+ FreePool (Instance);
+ return Status;
}
Instance->Handle = *ChildHandle;
@@ -516,13 +554,30 @@ Mtftp4ServiceBindingCreateChild (
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
- gBS->UninstallMultipleProtocolInterfaces (
- Instance->Handle,
- &gEfiMtftp4ProtocolGuid,
- &Instance->Mtftp4,
- NULL
- );
+ goto ON_ERROR;
+ }
+ //
+ // Open the Udp4 protocol by child.
+ //
+ Status = gBS->OpenProtocol (
+ Instance->UnicastPort->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ (VOID **) &Udp4,
+ gMtftp4DriverBinding.DriverBindingHandle,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Close the Udp4 protocol.
+ //
+ gBS->CloseProtocol (
+ MtftpSb->ConnectUdp->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ gMtftp4DriverBinding.DriverBindingHandle,
+ ChildHandle
+ );
goto ON_ERROR;
}
@@ -536,13 +591,21 @@ Mtftp4ServiceBindingCreateChild (
gBS->RestoreTPL (OldTpl);
-ON_ERROR:
+ return EFI_SUCCESS;
- if (EFI_ERROR (Status)) {
- UdpIoFreeIo (Instance->UnicastPort);
- FreePool (Instance);
+ON_ERROR:
+ if (Instance->Handle != NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Instance->Handle,
+ &gEfiMtftp4ProtocolGuid,
+ &Instance->Mtftp4,
+ NULL
+ );
}
+ UdpIoFreeIo (Instance->UnicastPort);
+ FreePool (Instance);
+
return Status;
}
@@ -615,6 +678,22 @@ Mtftp4ServiceBindingDestroyChild (
ChildHandle
);
+ gBS->CloseProtocol (
+ Instance->UnicastPort->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ gMtftp4DriverBinding.DriverBindingHandle,
+ ChildHandle
+ );
+
+ if (Instance->McastUdpPort != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpPort->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ gMtftp4DriverBinding.DriverBindingHandle,
+ ChildHandle
+ );
+ }
+
//
// Uninstall the MTFTP4 protocol first to enable a top down destruction.
//
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h
index 63828bd433..936eab1ba1 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h
@@ -26,6 +26,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_COMPONENT_NAME_PROTOCOL gMtftp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp4ComponentName2;
extern EFI_DRIVER_BINDING_PROTOCOL gMtftp4DriverBinding;
+extern EFI_UNICODE_STRING_TABLE *gMtftp4ControllerNameTable;
/**
Test whether MTFTP driver support this controller.
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
index 5183e1a5b3..f3a4952360 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
@@ -58,6 +58,12 @@ Mtftp4CleanOperation (
}
if (Instance->McastUdpPort != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpPort->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ gMtftp4DriverBinding.DriverBindingHandle,
+ Instance->Handle
+ );
UdpIoFreeIo (Instance->McastUdpPort);
Instance->McastUdpPort = NULL;
}
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
index 41f524abb0..527fd1db10 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
@@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UdpIoLib.h>
+#include <Library/PrintLib.h>
extern EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate;
@@ -68,8 +69,6 @@ struct _MTFTP4_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
- BOOLEAN InDestroy;
-
UINT16 ChildrenNum;
LIST_ENTRY Children;
@@ -149,6 +148,12 @@ struct _MTFTP4_PROTOCOL {
UDP_IO *McastUdpPort;
};
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Clean up the MTFTP session to get ready for new operation.
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
index 264598f49a..ae157c5e0a 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
@@ -1,7 +1,7 @@
/** @file
Routines to process Rrq (download).
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -486,6 +486,7 @@ Mtftp4RrqHandleOack (
MTFTP4_OPTION Reply;
EFI_STATUS Status;
INTN Expected;
+ EFI_UDP4_PROTOCOL *Udp4;
*Completed = FALSE;
@@ -548,13 +549,31 @@ Mtftp4RrqHandleOack (
//
Instance->McastIp = Reply.McastIp;
Instance->McastPort = Reply.McastPort;
- Instance->McastUdpPort = UdpIoCreateIo (
- Instance->Service->Controller,
- Instance->Service->Image,
- Mtftp4RrqConfigMcastPort,
- UDP_IO_UDP4_VERSION,
- Instance
- );
+ if (Instance->McastUdpPort == NULL) {
+ Instance->McastUdpPort = UdpIoCreateIo (
+ Instance->Service->Controller,
+ Instance->Service->Image,
+ Mtftp4RrqConfigMcastPort,
+ UDP_IO_UDP4_VERSION,
+ Instance
+ );
+ if (Instance->McastUdpPort != NULL) {
+ Status = gBS->OpenProtocol (
+ Instance->McastUdpPort->UdpHandle,
+ &gEfiUdp4ProtocolGuid,
+ (VOID **) &Udp4,
+ Instance->Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ UdpIoFreeIo (Instance->McastUdpPort);
+ Instance->McastUdpPort = NULL;
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
if (Instance->McastUdpPort == NULL) {
return EFI_DEVICE_ERROR;
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c
index e8f7ec18bc..0b12359f14 100644
--- a/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for SnpDxe driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -175,6 +175,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameT
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gSimpleNetworkControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -232,6 +234,78 @@ SimpleNetworkComponentNameGetDriverName (
}
/**
+ Update the component name for the Snp child handle.
+
+ @param Snp[in] A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ UINTN OffSet;
+ UINTN Index;
+
+ if (Snp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OffSet = 0;
+ OffSet += UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"SNP (MAC="
+ );
+ for (Index = 0; Index < Snp->Mode->HwAddressSize; Index++) {
+ OffSet += UnicodeSPrint (
+ HandleName + OffSet,
+ sizeof (HandleName) - OffSet * sizeof (CHAR16),
+ L"%02X-",
+ Snp->Mode->CurrentAddress.Addr[Index]
+ );
+ }
+ //
+ // Remove the last '-'
+ //
+ OffSet--;
+ OffSet += UnicodeSPrint (
+ HandleName + OffSet,
+ sizeof (HandleName) - OffSet * sizeof (CHAR16),
+ L")"
+ );
+ if (gSimpleNetworkControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gSimpleNetworkControllerNameTable);
+ gSimpleNetworkControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gSimpleNetworkComponentName.SupportedLanguages,
+ &gSimpleNetworkControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gSimpleNetworkComponentName2.SupportedLanguages,
+ &gSimpleNetworkControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -310,5 +384,52 @@ SimpleNetworkComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gSimpleNetworkDriverBinding.DriverBindingHandle,
+ &gEfiSimpleNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ControllerHandle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleNetworkProtocolGuid,
+ (VOID **)&Snp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Snp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gSimpleNetworkControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gSimpleNetworkComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
index 72693e9ec4..f1fea0cff4 100644
--- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
+++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
@@ -1,7 +1,7 @@
/** @file
Implementation of driver entry point and driver binding protocol.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -828,7 +828,7 @@ SimpleNetworkDriverStop (
//
// Simple Network Protocol Driver Global Variables
//
-EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {
+EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
SimpleNetworkDriverSupported,
SimpleNetworkDriverStart,
SimpleNetworkDriverStop,
@@ -1014,7 +1014,7 @@ InitializeSnpNiiDriver (
return EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
- &mSimpleNetworkDriverBinding,
+ &gSimpleNetworkDriverBinding,
ImageHandle,
&gSimpleNetworkComponentName,
&gSimpleNetworkComponentName2
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h
index dc63845334..4211b4dfc7 100644
--- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h
+++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h
@@ -1,7 +1,7 @@
/** @file
Declaration of strctures and functions for SnpDxe driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
#include <IndustryStandard/Pci.h>
@@ -135,6 +136,7 @@ typedef struct {
//
// Global Variables
//
+extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gSimpleNetworkComponentName2;
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c
index 587f7c665b..dd0af8d7b4 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Tcp4Dxe driver.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -171,6 +171,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTable[] = {
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -228,6 +230,76 @@ TcpComponentNameGetDriverName (
}
/**
+ Update the component name for the Tcp4 child handle.
+
+ @param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_TCP4_PROTOCOL *Tcp4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
+
+ if (Tcp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
+ //
+ Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",
+ Tcp4ConfigData.AccessPoint.StationPort,
+ Tcp4ConfigData.AccessPoint.RemotePort,
+ (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
+ );
+ } if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"TCPv4 (Not started)"
+ );
+ } else {
+ return Status;
+ }
+
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gTcp4ComponentName.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gTcp4ComponentName2.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -305,5 +377,56 @@ TcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_TCP4_PROTOCOL *Tcp4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp4ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTcp4ProtocolGuid,
+ (VOID **)&Tcp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Tcp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gTcpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gTcp4ComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c
index ac36460da8..feed86c590 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c
@@ -1,7 +1,7 @@
/** @file
Interface function of the Socket.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -148,11 +148,11 @@ SockDestroyChild (
ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));
- if (Sock->IsDestroyed) {
+ if (Sock->InDestroy) {
return EFI_SUCCESS;
}
- Sock->IsDestroyed = TRUE;
+ Sock->InDestroy = TRUE;
Status = EfiAcquireLockOrFail (&(Sock->Lock));
if (EFI_ERROR (Status)) {
@@ -173,7 +173,7 @@ SockDestroyChild (
DEBUG ((EFI_D_ERROR, "SockDestroyChild: Protocol detach socket"
" failed with %r\n", Status));
- Sock->IsDestroyed = FALSE;
+ Sock->InDestroy = FALSE;
} else if (SOCK_IS_CONFIGURED (Sock)) {
SockConnFlush (Sock);
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h
index b8ace790ca..8c25c63b11 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h
@@ -30,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#define SOCK_SND_BUF 0
#define SOCK_RCV_BUF 1
@@ -645,7 +646,7 @@ struct _SOCKET {
SOCK_BUFFER SndBuffer; ///< Send buffer of application's data
SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data
EFI_STATUS SockError; ///< The error returned by low layer protocol
- BOOLEAN IsDestroyed;
+ BOOLEAN InDestroy;
//
// Fields used to manage the connection request
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
index 688f9a7e99..93d10c9eb2 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
@@ -1,7 +1,7 @@
/** @file
Tcp request dispatcher implementation.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -263,6 +263,8 @@ Tcp4AttachPcb (
TCP_CB *Tcb;
TCP4_PROTO_DATA *ProtoData;
IP_IO *IpIo;
+ EFI_STATUS Status;
+ VOID *Ip;
Tcb = AllocateZeroPool (sizeof (TCP_CB));
@@ -286,6 +288,22 @@ Tcp4AttachPcb (
return EFI_OUT_OF_RESOURCES;
}
+ //
+ // Open the new created IP instance BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Tcb->IpInfo->ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ &Ip,
+ IpIo->Image,
+ Sk->SockHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ IpIoRemoveIp (IpIo, Tcb->IpInfo);
+ return Status;
+ }
+
InitializeListHead (&Tcb->List);
InitializeListHead (&Tcb->SndQue);
InitializeListHead (&Tcb->RcvQue);
@@ -318,6 +336,16 @@ Tcp4DetachPcb (
Tcp4FlushPcb (Tcb);
+ //
+ // Close the IP protocol.
+ //
+ gBS->CloseProtocol (
+ Tcb->IpInfo->ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ ProtoData->TcpService->IpIo->Image,
+ Sk->SockHandle
+ );
+
IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
FreePool (Tcb);
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
index a29b6bc434..76eac722cb 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
@@ -1,7 +1,7 @@
/** @file
Tcp driver function.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT16 mTcp4RandomPort;
extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
TCP4_HEARTBEAT_TIMER mTcp4Timer = {
NULL,
@@ -136,6 +137,44 @@ Tcp4DestroyTimer (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Tcp4DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ SOCKET *Sock;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
+ ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
+}
+
+/**
The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
@param ImageHandle The firmware allocated handle for this
@@ -387,6 +426,7 @@ ON_ERROR:
if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
}
FreePool (TcpServiceData);
@@ -431,17 +471,18 @@ Tcp4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_STATUS Status;
- EFI_HANDLE NicHandle;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- TCP4_SERVICE_DATA *TcpServiceData;
- SOCKET *Sock;
+ EFI_STATUS Status;
+ EFI_HANDLE NicHandle;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ TCP4_SERVICE_DATA *TcpServiceData;
+ LIST_ENTRY *List;
+ TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
//
@@ -465,7 +506,18 @@ Tcp4DriverBindingStop (
TcpServiceData = TCP4_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren != 0) {
+ List = &TcpServiceData->SocketList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Tcp4DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&TcpServiceData->SocketList)) {
//
// Uninstall TCP servicebinding protocol
//
@@ -480,6 +532,7 @@ Tcp4DriverBindingStop (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
@@ -491,17 +544,17 @@ Tcp4DriverBindingStop (
//
TcpClearVariableData (TcpServiceData);
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
//
// Release the TCP service data
//
FreePool (TcpServiceData);
- } else {
-
- while (!IsListEmpty (&TcpServiceData->SocketList)) {
- Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
- }
+ Status = EFI_SUCCESS;
}
return Status;
@@ -713,14 +766,11 @@ Tcp4ServiceBindingDestroyChild (
EFI_STATUS Status;
EFI_TCP4_PROTOCOL *Tcp4;
SOCKET *Sock;
- EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
return EFI_INVALID_PARAMETER;
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
//
// retrieve the Tcp4 protocol from ChildHandle
//
@@ -744,7 +794,6 @@ Tcp4ServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
- gBS->RestoreTPL (OldTpl);
return Status;
}
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h
index c59075780f..cd904584bf 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h
@@ -1,7 +1,7 @@
/** @file
TCP4 protocol services header file.
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2012, 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
@@ -75,6 +75,12 @@ typedef struct _TCP4_ROUTE_INFO {
EFI_IPv4_ADDRESS *GatewayAddress;
} TCP4_ROUTE_INFO;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Get the current operational status of a TCP instance.
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c
index acb8f167e1..cf311055e2 100644
--- a/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdpDriverNameTable[] = {
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdpControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -231,6 +233,75 @@ UdpComponentNameGetDriverName (
}
/**
+ Update the component name for the Udp4 child handle.
+
+ @param Udp4[in] A pointer to the EFI_UDP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ EFI_UDP4_PROTOCOL *Udp4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[64];
+ EFI_UDP4_CONFIG_DATA Udp4ConfigData;
+
+ if (Udp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // UDPv4 (SrcPort=59, DestPort=60)
+ //
+ Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"UDPv4 (SrcPort=%d, DestPort=%d)",
+ Udp4ConfigData.StationPort,
+ Udp4ConfigData.RemotePort
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"UDPv4 (Not started)"
+ );
+ } else {
+ return Status;
+ }
+
+ if (gUdpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gUdpControllerNameTable);
+ gUdpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gUdp4ComponentName.SupportedLanguages,
+ &gUdpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gUdp4ComponentName2.SupportedLanguages,
+ &gUdpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -308,6 +379,57 @@ UdpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_UDP4_PROTOCOL *Udp4;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp4ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiUdp4ProtocolGuid,
+ (VOID **)&Udp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Udp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gUdpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUdp4ComponentName)
+ );
}
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
index 5afb3aa58e..34e15da432 100644
--- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
+++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -28,6 +28,44 @@ EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {
Udp4ServiceBindingDestroyChild
};
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Udp4DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ UDP4_INSTANCE_DATA *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE);
+ ServiceBinding = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
+}
+
/**
Test to see if this driver supports ControllerHandle. This service
@@ -178,18 +216,19 @@ Udp4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_STATUS Status;
- EFI_HANDLE NicHandle;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- UDP4_SERVICE_DATA *Udp4Service;
- UDP4_INSTANCE_DATA *Instance;
+ EFI_STATUS Status;
+ EFI_HANDLE NicHandle;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UDP4_SERVICE_DATA *Udp4Service;
+ UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
+ LIST_ENTRY *List;
//
// Find the NicHandle where UDP4 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
//
@@ -208,9 +247,21 @@ Udp4DriverBindingStop (
}
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);
-
- if (NumberOfChildren == 0) {
-
+ if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
+ //
+ List = &Udp4Service->ChildrenList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Udp4DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else {
gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiUdp4ServiceBindingProtocolGuid,
@@ -222,14 +273,11 @@ Udp4DriverBindingStop (
Udp4CleanService (Udp4Service);
- FreePool (Udp4Service);
- } else {
-
- while (!IsListEmpty (&Udp4Service->ChildrenList)) {
- Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
-
- ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
+ if (gUdpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gUdpControllerNameTable);
+ gUdpControllerNameTable = NULL;
}
+ FreePool (Udp4Service);
}
return Status;
@@ -323,6 +371,21 @@ Udp4ServiceBindingCreateChild (
goto ON_ERROR;
}
+ //
+ // Open this instance's Ip4 protocol in the IpInfo BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ (VOID **) &Ip4,
+ gUdp4DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
@@ -412,14 +475,14 @@ Udp4ServiceBindingDestroyChild (
Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);
- if (Instance->Destroyed) {
+ if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
// Use the Destroyed flag to avoid the re-entering of the following code.
//
- Instance->Destroyed = TRUE;
+ Instance->InDestroy = TRUE;
//
// Close the Ip4 protocol.
@@ -430,6 +493,15 @@ Udp4ServiceBindingDestroyChild (
gUdp4DriverBinding.DriverBindingHandle,
Instance->ChildHandle
);
+ //
+ // Close the Ip4 protocol on this instance's IpInfo.
+ //
+ gBS->CloseProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp4ProtocolGuid,
+ gUdp4DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle
+ );
//
// Uninstall the Udp4Protocol previously installed on the ChildHandle.
@@ -441,7 +513,7 @@ Udp4ServiceBindingDestroyChild (
NULL
);
if (EFI_ERROR (Status)) {
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
return Status;
}
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
index 9326f3d344..8bba3572a2 100644
--- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
@@ -1,7 +1,7 @@
/** @file
The implementation of the Udp4 protocol.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -484,7 +484,7 @@ Udp4InitInstance (
Instance->IcmpError = EFI_SUCCESS;
Instance->Configured = FALSE;
Instance->IsNoMapping = FALSE;
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
}
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h
index f8a39ebcf7..8142a4640f 100644
--- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h
+++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h
@@ -1,7 +1,7 @@
/** @file
EFI UDPv4 protocol implementation.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -31,12 +31,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/MemoryAllocationLib.h>
#include <Library/TimerLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#include "Udp4Driver.h"
extern EFI_COMPONENT_NAME_PROTOCOL gUdp4ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gUdp4ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gUdpControllerNameTable;
extern EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding;
extern EFI_UDP4_PROTOCOL mUdp4Protocol;
extern UINT16 mUdp4RandomPort;
@@ -109,7 +111,7 @@ typedef struct _UDP4_INSTANCE_DATA_ {
IP_IO_IP_INFO *IpInfo;
- BOOLEAN Destroyed;
+ BOOLEAN InDestroy;
} UDP4_INSTANCE_DATA;
typedef struct _UDP4_RXDATA_WRAP_ {
@@ -119,6 +121,12 @@ typedef struct _UDP4_RXDATA_WRAP_ {
EFI_UDP4_RECEIVE_DATA RxData;
} UDP4_RXDATA_WRAP;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Reads the current operational settings.
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c
index 0d0378311d..f4ef59ce5e 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2012, 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
@@ -168,6 +168,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = {
+ {
+ "eng;en",
+ L"PXE Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -302,6 +313,53 @@ PxeBcComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+
+ if (ControllerHandle == NULL || ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
+
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
+
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
+
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
+
+ if (NicHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+ }
+ }
+
+ Status = gBS->OpenProtocol (
+ NicHandle,
+ &gEfiPxeBaseCodeProtocolGuid,
+ (VOID **) &PxeBc,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mPxeBcControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gPxeBcComponentName)
+ );
+}
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
index 0efcda58e5..2287863e3e 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
@@ -1,7 +1,7 @@
/** @file
The driver binding for UEFI PXEBC protocol.
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2012, 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
@@ -526,7 +526,7 @@ PxeBcDriverBindingStop (
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
}
}
diff --git a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
index f992cea07b..10fb7fa670 100644
--- a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
+++ b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
@@ -1,7 +1,7 @@
/** @file
HII Config Access protocol implementation of VLAN configuration module.
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2012, 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
@@ -489,6 +489,7 @@ InstallVlanConfigForm (
CHAR16 *MacString;
EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
//
// Create child handle and install HII Config Access Protocol
@@ -518,6 +519,22 @@ InstallVlanConfigForm (
PrivateData->DriverHandle = DriverHandle;
//
+ // Establish the parent-child relationship between the new created
+ // child handle and the ControllerHandle.
+ //
+ Status = gBS->OpenProtocol (
+ PrivateData->ControllerHandle,
+ &gEfiVlanConfigProtocolGuid,
+ (VOID **)&VlanConfig,
+ PrivateData->ImageHandle,
+ PrivateData->DriverHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
// Publish the HII package list
//
HiiHandle = HiiAddPackages (
@@ -594,6 +611,16 @@ UninstallVlanConfigForm (
}
//
+ // End the parent-child relationship.
+ //
+ gBS->CloseProtocol (
+ PrivateData->ControllerHandle,
+ &gEfiVlanConfigProtocolGuid,
+ PrivateData->ImageHandle,
+ PrivateData->DriverHandle
+ );
+
+ //
// Uninstall HII Config Access Protocol
//
if (PrivateData->DriverHandle != NULL) {
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index 7221c42fa3..cc3823f0ef 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -1,7 +1,7 @@
/** @file
Parser for IFR binary encoding.
-Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2013, 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
@@ -1779,8 +1779,8 @@ ParseOpCodes (
CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
- if (OpCodeLength == sizeof (EFI_IFR_DEFAULT)) {
- CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
+ if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {
+ CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
ExtendValueToU64 (&CurrentDefault->Value);
}
@@ -1809,7 +1809,7 @@ ParseOpCodes (
CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
- CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
+ CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
ExtendValueToU64 (&CurrentOption->Value);
ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 381cefeae5..bcc8e020fd 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -3513,7 +3513,7 @@ LoadStorage (
//
// Convert Result from <ConfigAltResp> to <ConfigResp>
//
- StrPtr = StrStr (Result, L"ALTCFG");
+ StrPtr = StrStr (Result, L"&GUID=");
if (StrPtr != NULL) {
*StrPtr = L'\0';
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 3aa45c2dd2..fad1cb323e 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -505,6 +505,7 @@ GetEndPointer (
@param IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param UpdatingVariable Pointer to updating variable.
+ @param ReclaimAnyway If TRUE, do reclaim anyway.
@return EFI_OUT_OF_RESOURCES
@return EFI_SUCCESS
@@ -516,7 +517,8 @@ Reclaim (
IN EFI_PHYSICAL_ADDRESS VariableBase,
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
- IN VARIABLE_HEADER *UpdatingVariable
+ IN VARIABLE_HEADER *UpdatingVariable,
+ IN BOOLEAN ReclaimAnyway
)
{
VARIABLE_HEADER *Variable;
@@ -539,7 +541,9 @@ Reclaim (
CHAR16 *UpdatingVariableNamePtr;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
+ BOOLEAN NeedDoReclaim;
+ NeedDoReclaim = FALSE;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
CommonVariableTotalSize = 0;
@@ -558,11 +562,18 @@ Reclaim (
) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
MaximumBufferSize += VariableSize;
+ } else {
+ NeedDoReclaim = TRUE;
}
Variable = NextVariable;
}
+ if (!ReclaimAnyway && !NeedDoReclaim) {
+ DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
+ return EFI_SUCCESS;
+ }
+
//
// Reserve the 1 Bytes with Oxff to identify the
// end of the variable buffer.
@@ -1468,6 +1479,7 @@ UpdateVariable (
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
if (!Variable->Volatile) {
CacheVariable->CurrPtr->State = State;
+ FlushHobVariableToFlash (VariableName, VendorGuid);
}
}
goto Done;
@@ -1595,7 +1607,7 @@ UpdateVariable (
// Perform garbage collection & reclaim operation.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
- &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1710,7 +1722,7 @@ UpdateVariable (
// Perform garbage collection & reclaim operation.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
- &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);
+ &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1767,6 +1779,9 @@ UpdateVariable (
if (!EFI_ERROR (Status)) {
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
+ if (!Volatile) {
+ FlushHobVariableToFlash (VariableName, VendorGuid);
+ }
}
Done:
@@ -2383,12 +2398,102 @@ ReclaimForOS(
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
- NULL
+ NULL,
+ FALSE
);
ASSERT_EFI_ERROR (Status);
}
}
+/**
+ Flush the HOB variable to flash.
+
+ @param[in] VariableName Name of variable has been updated or deleted.
+ @param[in] VendorGuid Guid of variable has been updated or deleted.
+
+**/
+VOID
+FlushHobVariableToFlash (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_HEADER *Variable;
+ VOID *VariableData;
+ BOOLEAN ErrorFlag;
+
+ ErrorFlag = FALSE;
+
+ //
+ // Flush the HOB variable to flash.
+ //
+ if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
+ //
+ // Set HobVariableBase to 0, it can avoid SetVariable to call back.
+ //
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
+ for ( Variable = GetStartPointer (VariableStoreHeader)
+ ; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
+ ; Variable = GetNextVariablePtr (Variable)
+ ) {
+ if (Variable->State != VAR_ADDED) {
+ //
+ // The HOB variable has been set to DELETED state in local.
+ //
+ continue;
+ }
+ ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
+ if (VendorGuid == NULL || VariableName == NULL ||
+ !CompareGuid (VendorGuid, &Variable->VendorGuid) ||
+ StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
+ VariableData = GetVariableDataPtr (Variable);
+ Status = VariableServiceSetVariable (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ Variable->Attributes,
+ Variable->DataSize,
+ VariableData
+ );
+ DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", &Variable->VendorGuid, GetVariableNamePtr (Variable), Status));
+ } else {
+ //
+ // The updated or deleted variable is matched with the HOB variable.
+ // Don't break here because we will try to set other HOB variables
+ // since this variable could be set successfully.
+ //
+ Status = EFI_SUCCESS;
+ }
+ if (!EFI_ERROR (Status)) {
+ //
+ // If set variable successful, or the updated or deleted variable is matched with the HOB variable,
+ // set the HOB variable to DELETED state in local.
+ //
+ DEBUG ((EFI_D_INFO, "Variable driver set the HOB variable to DELETED state in local: %g %s\n", &Variable->VendorGuid, GetVariableNamePtr (Variable)));
+ Variable->State &= VAR_DELETED;
+ } else {
+ ErrorFlag = TRUE;
+ }
+ }
+ if (ErrorFlag) {
+ //
+ // We still have HOB variable(s) not flushed in flash.
+ //
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
+ } else {
+ //
+ // All HOB variables have been flushed in flash.
+ //
+ DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));
+ if (!AtRuntime ()) {
+ FreePool ((VOID *) VariableStoreHeader);
+ }
+ }
+ }
+
+}
/**
Initializes variable write service after FVB was ready.
@@ -2407,8 +2512,6 @@ VariableWriteServiceInitialize (
UINTN Index;
UINT8 Data;
EFI_PHYSICAL_ADDRESS VariableStoreBase;
- VARIABLE_HEADER *Variable;
- VOID *VariableData;
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
@@ -2426,7 +2529,8 @@ VariableWriteServiceInitialize (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
- NULL
+ NULL,
+ TRUE
);
if (EFI_ERROR (Status)) {
return Status;
@@ -2435,33 +2539,8 @@ VariableWriteServiceInitialize (
}
}
- //
- // Flush the HOB variable to flash and invalidate HOB variable.
- //
- if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
- //
- // Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB
- //
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
- mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
+ FlushHobVariableToFlash (NULL, NULL);
- for ( Variable = GetStartPointer (VariableStoreHeader)
- ; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
- ; Variable = GetNextVariablePtr (Variable)
- ) {
- ASSERT (Variable->State == VAR_ADDED);
- ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
- VariableData = GetVariableDataPtr (Variable);
- Status = VariableServiceSetVariable (
- GetVariableNamePtr (Variable),
- &Variable->VendorGuid,
- Variable->Attributes,
- Variable->DataSize,
- VariableData
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
return EFI_SUCCESS;
}
@@ -2513,8 +2592,12 @@ VariableCommonInitialize (
GuidHob = GetFirstGuidHob (&gEfiVariableGuid);
if (GuidHob != NULL) {
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
+ VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
- mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);
+ if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
} else {
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index c4a16e6f63..cd88177dba 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -91,6 +91,19 @@ typedef struct {
} VARIABLE_CACHE_ENTRY;
/**
+ Flush the HOB variable to flash.
+
+ @param[in] VariableName Name of variable has been updated or deleted.
+ @param[in] VendorGuid Guid of variable has been updated or deleted.
+
+**/
+VOID
+FlushHobVariableToFlash (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ );
+
+/**
Writes a buffer to variable storage space, in the working block.
This function writes a buffer to variable storage space into a firmware
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
index 3b6efac1bc..ba4d29ab30 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
@@ -3,7 +3,7 @@
Implement all four UEFI Runtime Variable services for the nonvolatile
and volatile storage space and install variable architecture protocol.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -231,6 +231,7 @@ VariableClassAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
index 15e55d417e..550f01a525 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
@@ -445,7 +445,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -467,7 +467,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -498,7 +498,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -528,7 +528,7 @@ SmmVariableHandler (
case SMM_VARIABLE_FUNCTION_GET_STATISTICS:
VariableInfo = (VARIABLE_INFO_ENTRY *) SmmVariableFunctionHeader->Data;
- InfoSize = *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
+ InfoSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
//
// Do not need to check SmmVariableFunctionHeader->Data in SMRAM here.
@@ -542,7 +542,7 @@ SmmVariableHandler (
}
Status = SmmVariableGetStatistics (VariableInfo, &InfoSize);
- *CommBufferSize = InfoSize + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
+ *CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
break;
default:
diff --git a/MdePkg/Include/Guid/EventGroup.h b/MdePkg/Include/Guid/EventGroup.h
index dba9fc27e4..831465d0aa 100644
--- a/MdePkg/Include/Guid/EventGroup.h
+++ b/MdePkg/Include/Guid/EventGroup.h
@@ -1,7 +1,7 @@
/** @file
- GUIDs for gBS->CreateEventEx Event Groups. Defined in UEFI spec 2.0 and PI 1.2.
+ GUIDs for gBS->CreateEventEx Event Groups. Defined in UEFI spec 2.0 and PI 1.2.1.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -44,4 +44,9 @@ extern EFI_GUID gEfiEventReadyToBootGuid;
extern EFI_GUID gEfiEventDxeDispatchGuid;
+#define EFI_END_OF_DXE_EVENT_GROUP_GUID \
+ { 0x2ce967a, 0xdd7e, 0x4ffc, { 0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80 } }
+
+extern EFI_GUID gEfiEndOfDxeEventGroupGuid;
+
#endif
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 33d55c5de7..992c5387f9 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -2343,6 +2343,7 @@ BitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2376,6 +2377,7 @@ BitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2409,6 +2411,7 @@ BitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2443,6 +2446,8 @@ BitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2505,6 +2510,7 @@ BitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2538,6 +2544,7 @@ BitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2571,6 +2578,7 @@ BitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2605,6 +2613,8 @@ BitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2667,6 +2677,7 @@ BitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2700,6 +2711,7 @@ BitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2733,6 +2745,7 @@ BitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2767,6 +2780,8 @@ BitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2829,6 +2844,7 @@ BitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2862,6 +2878,7 @@ BitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2895,6 +2912,7 @@ BitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2929,6 +2947,8 @@ BitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5380,6 +5400,7 @@ AsmMsrBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5416,6 +5437,7 @@ AsmMsrBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5452,6 +5474,7 @@ AsmMsrBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5490,6 +5513,8 @@ AsmMsrBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5684,6 +5709,7 @@ AsmMsrBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5720,6 +5746,7 @@ AsmMsrBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5756,6 +5783,7 @@ AsmMsrBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -5793,6 +5821,8 @@ AsmMsrBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/IoLib.h b/MdePkg/Include/Library/IoLib.h
index 9de0fc5d55..a0dd16bcd5 100644
--- a/MdePkg/Include/Library/IoLib.h
+++ b/MdePkg/Include/Library/IoLib.h
@@ -1,7 +1,7 @@
/** @file
Provide services to access I/O Ports and MMIO registers.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -192,6 +192,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -226,6 +227,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -260,6 +262,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -296,6 +299,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -485,6 +490,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -520,6 +526,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -555,6 +562,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -592,6 +600,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -781,6 +791,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -816,6 +827,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -851,6 +863,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -888,6 +901,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1077,6 +1092,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1112,6 +1128,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1147,6 +1164,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1184,6 +1202,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1366,6 +1386,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1401,6 +1422,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1436,6 +1458,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1472,6 +1495,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1660,6 +1685,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1696,6 +1722,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1732,6 +1759,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1769,6 +1797,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1957,6 +1987,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1993,6 +2024,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2029,6 +2061,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2066,6 +2099,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2252,6 +2287,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2288,6 +2324,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2324,6 +2361,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2361,6 +2399,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/PciCf8Lib.h b/MdePkg/Include/Library/PciCf8Lib.h
index fc98457b3b..52fb142a9c 100644
--- a/MdePkg/Include/Library/PciCf8Lib.h
+++ b/MdePkg/Include/Library/PciCf8Lib.h
@@ -5,7 +5,7 @@
configuration cycles must be through I/O ports 0xCF8 and 0xCFC. This library only allows
access to PCI Segment #0.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -243,6 +243,7 @@ PciCf8BitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -279,6 +280,7 @@ PciCf8BitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -315,6 +317,7 @@ PciCf8BitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -353,6 +356,8 @@ PciCf8BitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -558,6 +563,7 @@ PciCf8BitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -595,6 +601,7 @@ PciCf8BitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -632,6 +639,7 @@ PciCf8BitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -671,6 +679,8 @@ PciCf8BitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -876,6 +886,7 @@ PciCf8BitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -913,6 +924,7 @@ PciCf8BitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -950,6 +962,7 @@ PciCf8BitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -989,6 +1002,8 @@ PciCf8BitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/PciExpressLib.h b/MdePkg/Include/Library/PciExpressLib.h
index bba6810544..e312d57528 100644
--- a/MdePkg/Include/Library/PciExpressLib.h
+++ b/MdePkg/Include/Library/PciExpressLib.h
@@ -5,7 +5,7 @@
configuration cycles must be through the 256 MB PCI Express MMIO window whose base address
is defined by PcdPciExpressBaseAddress.
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -235,6 +235,7 @@ PciExpressBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -270,6 +271,7 @@ PciExpressBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -305,6 +307,7 @@ PciExpressBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -342,6 +345,8 @@ PciExpressBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -540,6 +545,7 @@ PciExpressBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -576,6 +582,7 @@ PciExpressBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -612,6 +619,7 @@ PciExpressBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -650,6 +658,8 @@ PciExpressBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -848,6 +858,7 @@ PciExpressBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -884,6 +895,7 @@ PciExpressBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -920,6 +932,7 @@ PciExpressBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -958,6 +971,8 @@ PciExpressBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/PciLib.h b/MdePkg/Include/Library/PciLib.h
index a6f6de6a73..b113ddf487 100644
--- a/MdePkg/Include/Library/PciLib.h
+++ b/MdePkg/Include/Library/PciLib.h
@@ -10,7 +10,7 @@
these three libraries is identical. The PCI CF8 Library and PCI Express Library simply use
explicit access methods.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -236,6 +236,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -271,6 +272,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -306,6 +308,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -343,6 +346,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -541,6 +546,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -577,6 +583,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -613,6 +620,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -651,6 +659,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -849,6 +859,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -885,6 +896,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -921,6 +933,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -959,6 +972,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/PciSegmentLib.h b/MdePkg/Include/Library/PciSegmentLib.h
index 94192bf633..113501034e 100644
--- a/MdePkg/Include/Library/PciSegmentLib.h
+++ b/MdePkg/Include/Library/PciSegmentLib.h
@@ -23,7 +23,7 @@
access method. Modules will typically use the PCI Segment Library for its PCI configuration
accesses when PCI Segments other than Segment #0 must be accessed.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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
@@ -243,6 +243,7 @@ PciSegmentBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -278,6 +279,7 @@ PciSegmentBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -313,6 +315,7 @@ PciSegmentBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -350,6 +353,8 @@ PciSegmentBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -539,6 +544,7 @@ PciSegmentBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -569,6 +575,7 @@ PciSegmentBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -605,6 +612,7 @@ PciSegmentBitFieldOr16 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -642,6 +650,8 @@ PciSegmentBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -828,6 +838,7 @@ PciSegmentBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -863,6 +874,7 @@ PciSegmentBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -898,7 +910,7 @@ PciSegmentBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
-
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -936,6 +948,8 @@ PciSegmentBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/S3IoLib.h b/MdePkg/Include/Library/S3IoLib.h
index ab6e126ced..47c4ff96b5 100644
--- a/MdePkg/Include/Library/S3IoLib.h
+++ b/MdePkg/Include/Library/S3IoLib.h
@@ -3,7 +3,7 @@
to be replayed during an S3 resume. This library class maps directly on top
of the IoLib class.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -186,6 +186,7 @@ S3IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -221,6 +222,7 @@ S3IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -256,6 +258,7 @@ S3IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -292,6 +295,8 @@ S3IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -481,6 +486,7 @@ S3IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -516,6 +522,7 @@ S3IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -551,6 +558,7 @@ S3IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -588,6 +596,8 @@ S3IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -777,6 +787,7 @@ S3IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -812,6 +823,7 @@ S3IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -847,6 +859,7 @@ S3IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -884,6 +897,8 @@ S3IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1073,6 +1088,7 @@ S3IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1108,6 +1124,7 @@ S3IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1143,6 +1160,7 @@ S3IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1180,6 +1198,8 @@ S3IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Port The I/O port to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1368,6 +1388,7 @@ S3MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1404,6 +1425,7 @@ S3MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1440,6 +1462,7 @@ S3MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1477,6 +1500,8 @@ S3MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1666,6 +1691,7 @@ S3MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1702,6 +1728,7 @@ S3MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1738,6 +1765,7 @@ S3MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1775,6 +1803,8 @@ S3MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1963,6 +1993,7 @@ S3MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -1999,6 +2030,7 @@ S3MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2035,6 +2067,7 @@ S3MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2072,6 +2105,8 @@ S3MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2260,6 +2295,7 @@ S3MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2296,6 +2332,7 @@ S3MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2332,6 +2369,7 @@ S3MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -2369,6 +2407,8 @@ S3MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The MMIO register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Library/S3PciLib.h b/MdePkg/Include/Library/S3PciLib.h
index 72b6e26e38..bae12aba1e 100644
--- a/MdePkg/Include/Library/S3PciLib.h
+++ b/MdePkg/Include/Library/S3PciLib.h
@@ -3,7 +3,7 @@
the PCI operations to be replayed during an S3 resume. This library class
maps directly on top of the PciLib class.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -208,6 +208,7 @@ S3PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -244,6 +245,7 @@ S3PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -280,6 +282,7 @@ S3PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -317,6 +320,8 @@ S3PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -520,6 +525,7 @@ S3PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -557,6 +563,7 @@ S3PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -594,6 +601,7 @@ S3PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -632,6 +640,8 @@ S3PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -803,7 +813,7 @@ S3PciAndThenOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
-
+
@param[in] Address The PCI configuration register to read.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
Range 0..31.
@@ -835,6 +845,7 @@ S3PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -872,6 +883,7 @@ S3PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -909,6 +921,7 @@ S3PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
@@ -947,6 +960,8 @@ S3PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param[in] Address The PCI configuration register to write.
@param[in] StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Include/Pi/PiBootMode.h b/MdePkg/Include/Pi/PiBootMode.h
index 932507cbed..53986861b9 100644
--- a/MdePkg/Include/Pi/PiBootMode.h
+++ b/MdePkg/Include/Pi/PiBootMode.h
@@ -1,7 +1,7 @@
/** @file
Present the boot mode values in PI.
- Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -11,7 +11,7 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
- PI Version 1.0
+ PI Version 1.2.1A
**/
@@ -33,6 +33,7 @@ typedef UINT32 EFI_BOOT_MODE;
#define BOOT_WITH_DEFAULT_SETTINGS 0x04
#define BOOT_ON_S4_RESUME 0x05
#define BOOT_ON_S5_RESUME 0x06
+#define BOOT_WITH_MFG_MODE_SETTINGS 0x07
#define BOOT_ON_S2_RESUME 0x10
#define BOOT_ON_S3_RESUME 0x11
#define BOOT_ON_FLASH_UPDATE 0x12
diff --git a/MdePkg/Include/Protocol/SmmEndOfDxe.h b/MdePkg/Include/Protocol/SmmEndOfDxe.h
new file mode 100644
index 0000000000..702d742f61
--- /dev/null
+++ b/MdePkg/Include/Protocol/SmmEndOfDxe.h
@@ -0,0 +1,28 @@
+/** @file
+ SMM End Of Dxe protocol as defined in the PI 1.2.1 specification.
+
+ This protocol is a mandatory protocol published by the PI platform code prior to invoking any
+ 3rd party content, including options ROM's and UEFI executables that are not from the platform manufacturer.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SMM_END_OF_DXE_H_
+#define _SMM_END_OF_DXE_H_
+
+#define EFI_SMM_END_OF_DXE_PROTOCOL_GUID \
+ { \
+ 0x24e70042, 0xd5c5, 0x4260, { 0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d } \
+ }
+
+extern EFI_GUID gEfiSmmEndOfDxeProtocolGuid;
+
+#endif
diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c b/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
index d35485b6d7..ab1ddf4c42 100644
--- a/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
@@ -4,7 +4,7 @@
All assertions for bit field operations are handled bit field functions in the
Base Library.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -152,6 +152,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -192,6 +193,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -232,6 +234,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -274,6 +277,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -437,6 +442,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -478,6 +484,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -519,6 +526,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -562,6 +570,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -725,6 +735,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -766,6 +777,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -807,6 +819,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -850,6 +863,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1013,6 +1028,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1054,6 +1070,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1095,6 +1112,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1138,6 +1156,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1296,6 +1316,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1337,6 +1358,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1378,6 +1400,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1420,6 +1443,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1582,6 +1607,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1624,6 +1650,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1666,6 +1693,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1709,6 +1737,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1871,6 +1901,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1913,6 +1944,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1955,6 +1987,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1998,6 +2031,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2160,6 +2195,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2202,6 +2238,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2244,6 +2281,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2287,6 +2325,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BaseLib/BitField.c b/MdePkg/Library/BaseLib/BitField.c
index d17e562407..eb5fcd938c 100644
--- a/MdePkg/Library/BaseLib/BitField.c
+++ b/MdePkg/Library/BaseLib/BitField.c
@@ -1,7 +1,7 @@
/** @file
Bit field functions of BaseLib.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -49,6 +49,8 @@ InternalBaseLibBitFieldReadUint (
in Operand and the value specified by AndData. All other bits in Operand are
preserved. The new value is returned.
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@param EndBit The ordinal of the most significant bit in the bit field.
@@ -67,6 +69,11 @@ InternalBaseLibBitFieldOrUint (
)
{
//
+ // Higher bits in OrData those are not used must be zero.
+ //
+ ASSERT ((OrData >> (EndBit - StartBit + 1)) == 0);
+
+ //
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
// are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
//
@@ -81,6 +88,8 @@ InternalBaseLibBitFieldOrUint (
in Operand and the value specified by AndData. All other bits in Operand are
preserved. The new value is returned.
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@param EndBit The ordinal of the most significant bit in the bit field.
@@ -99,6 +108,11 @@ InternalBaseLibBitFieldAndUint (
)
{
//
+ // Higher bits in AndData those are not used must be zero.
+ //
+ ASSERT ((AndData >> (EndBit - StartBit + 1)) == 0);
+
+ //
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
// are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
//
@@ -148,6 +162,7 @@ BitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -185,6 +200,7 @@ BitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -222,6 +238,7 @@ BitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -260,6 +277,8 @@ BitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -335,6 +354,7 @@ BitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -372,6 +392,7 @@ BitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -409,6 +430,7 @@ BitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -447,6 +469,8 @@ BitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -522,6 +546,7 @@ BitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -559,6 +584,7 @@ BitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -596,6 +622,7 @@ BitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -634,6 +661,8 @@ BitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -709,6 +738,7 @@ BitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -746,6 +776,7 @@ BitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -771,6 +802,7 @@ BitFieldOr64 (
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
+ ASSERT (RShiftU64 (OrData, EndBit - StartBit + 1) == 0);
Value1 = LShiftU64 (OrData, StartBit);
Value2 = LShiftU64 ((UINT64) - 2, EndBit);
@@ -790,6 +822,7 @@ BitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -815,6 +848,7 @@ BitFieldAnd64 (
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
+ ASSERT (RShiftU64 (AndData, EndBit - StartBit + 1) == 0);
Value1 = LShiftU64 (~AndData, StartBit);
Value2 = LShiftU64 ((UINT64)-2, EndBit);
@@ -835,6 +869,8 @@ BitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Operand Operand on which to perform the bitfield operation.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BaseLib/X86Msr.c b/MdePkg/Library/BaseLib/X86Msr.c
index 6a6bd9e766..9430980401 100644
--- a/MdePkg/Library/BaseLib/X86Msr.c
+++ b/MdePkg/Library/BaseLib/X86Msr.c
@@ -1,7 +1,7 @@
/** @file
IA-32/x64 MSR functions.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -203,6 +203,7 @@ AsmMsrBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -243,6 +244,7 @@ AsmMsrBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -283,6 +285,7 @@ AsmMsrBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -325,6 +328,8 @@ AsmMsrBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -491,6 +496,7 @@ AsmMsrBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -532,6 +538,7 @@ AsmMsrBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -573,6 +580,7 @@ AsmMsrBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -615,6 +623,8 @@ AsmMsrBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Index The 32-bit MSR index to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c b/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
index 2cc77f1aaa..828508b2eb 100644
--- a/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
+++ b/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
@@ -2,7 +2,7 @@
PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
Layers on top of an I/O Library instance.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -369,6 +369,7 @@ PciCf8BitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -424,6 +425,7 @@ PciCf8BitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -479,6 +481,7 @@ PciCf8BitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -536,6 +539,8 @@ PciCf8BitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -862,6 +867,7 @@ PciCf8BitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -918,6 +924,7 @@ PciCf8BitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -974,6 +981,7 @@ PciCf8BitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1032,6 +1040,8 @@ PciCf8BitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1358,6 +1368,7 @@ PciCf8BitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1414,6 +1425,7 @@ PciCf8BitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1470,6 +1482,7 @@ PciCf8BitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1528,6 +1541,8 @@ PciCf8BitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BasePciExpressLib/PciExpressLib.c b/MdePkg/Library/BasePciExpressLib/PciExpressLib.c
index a5cfc3996d..61be0098a6 100644
--- a/MdePkg/Library/BasePciExpressLib/PciExpressLib.c
+++ b/MdePkg/Library/BasePciExpressLib/PciExpressLib.c
@@ -5,7 +5,7 @@
All assertions for I/O operations are handled in MMIO functions in the IoLib
Library.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -286,6 +286,7 @@ PciExpressBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -330,6 +331,7 @@ PciExpressBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -374,6 +376,7 @@ PciExpressBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -420,6 +423,8 @@ PciExpressBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -660,6 +665,7 @@ PciExpressBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -705,6 +711,7 @@ PciExpressBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -750,6 +757,7 @@ PciExpressBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -797,6 +805,8 @@ PciExpressBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1037,6 +1047,7 @@ PciExpressBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1082,6 +1093,7 @@ PciExpressBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1127,6 +1139,7 @@ PciExpressBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1174,6 +1187,8 @@ PciExpressBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BasePciLibCf8/PciLib.c b/MdePkg/Library/BasePciLibCf8/PciLib.c
index f64f73a370..f5f21475d8 100644
--- a/MdePkg/Library/BasePciLibCf8/PciLib.c
+++ b/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -2,7 +2,7 @@
PCI Library functions that use I/O ports 0xCF8 and 0xCFC to perform
PCI Configuration cycles. Layers on top of one PCI CF8 Library instance.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -236,6 +236,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -274,6 +275,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -312,6 +314,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -352,6 +355,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -571,6 +576,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -610,6 +616,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -649,6 +656,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -690,6 +698,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -909,6 +919,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -948,6 +959,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -987,6 +999,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1028,6 +1041,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BasePciLibPciExpress/PciLib.c b/MdePkg/Library/BasePciLibPciExpress/PciLib.c
index e93818c6d2..487a0389b9 100644
--- a/MdePkg/Library/BasePciLibPciExpress/PciLib.c
+++ b/MdePkg/Library/BasePciLibPciExpress/PciLib.c
@@ -2,7 +2,7 @@
PCI Library functions that use the 256 MB PCI Express MMIO window to perform PCI
Configuration cycles. Layers on PCI Express Library.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -236,6 +236,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -274,6 +275,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -312,6 +314,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -352,6 +355,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -571,6 +576,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -610,6 +616,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -649,6 +656,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -690,6 +698,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -909,6 +919,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -948,6 +959,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -987,6 +999,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1028,6 +1041,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index ffff0c14aa..b7ecc31715 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -30,6 +30,23 @@
#include "BasePeCoffLibInternals.h"
/**
+ Adjust some fields in section header for TE image.
+
+ @param SectionHeader Pointer to the section header.
+ @param TeStrippedOffset Size adjust for the TE image.
+
+**/
+VOID
+PeCoffLoaderAdjustOffsetForTeImage (
+ EFI_IMAGE_SECTION_HEADER *SectionHeader,
+ UINT32 TeStrippedOffset
+ )
+{
+ SectionHeader->VirtualAddress -= TeStrippedOffset;
+ SectionHeader->PointerToRawData -= TeStrippedOffset;
+}
+
+/**
Retrieves the magic value from the PE/COFF header.
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
@@ -157,6 +174,50 @@ PeCoffLoaderGetPeHeader (
ImageContext->SectionAlignment = 0;
ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
+ //
+ // Check the StrippedSize.
+ //
+ if (sizeof (EFI_TE_IMAGE_HEADER) >= (UINT32)Hdr.Te->StrippedSize) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Check the SizeOfHeaders field.
+ //
+ if (Hdr.Te->BaseOfCode <= Hdr.Te->StrippedSize) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // Read last byte of Hdr.Te->SizeOfHeaders from the file.
+ //
+ Size = 1;
+ ReadSize = Size;
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ ImageContext->SizeOfHeaders - 1,
+ &Size,
+ &BufferData
+ );
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {
+ ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
+ if (Size != ReadSize) {
+ Status = RETURN_UNSUPPORTED;
+ }
+ return Status;
+ }
+
+ //
+ // TE Image Data Directory Entry size is non-zero, but the Data Directory Virtual Address is zero.
+ // This case is not a valid TE image.
+ //
+ if ((Hdr.Te->DataDirectory[0].Size != 0 && Hdr.Te->DataDirectory[0].VirtualAddress == 0) ||
+ (Hdr.Te->DataDirectory[1].Size != 0 && Hdr.Te->DataDirectory[1].VirtualAddress == 0)) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
+ }
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
ImageContext->IsTeImage = FALSE;
ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;
@@ -417,6 +478,13 @@ PeCoffLoaderGetPeHeader (
return Status;
}
+ //
+ // Adjust some field in Section Header for TE image.
+ //
+ if (ImageContext->IsTeImage) {
+ PeCoffLoaderAdjustOffsetForTeImage (&SectionHeader, (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
+ }
+
if (SectionHeader.SizeOfRawData > 0) {
//
// Section data should bigger than the Pe header.
@@ -514,6 +582,7 @@ PeCoffLoaderGetImageInfo (
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;
UINT32 NumberOfRvaAndSizes;
UINT16 Magic;
+ UINT32 TeStrippedOffset;
if (ImageContext == NULL) {
return RETURN_INVALID_PARAMETER;
@@ -535,6 +604,7 @@ PeCoffLoaderGetImageInfo (
// Retrieve the base address of the image
//
if (!(ImageContext->IsTeImage)) {
+ TeStrippedOffset = 0;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset
@@ -547,7 +617,8 @@ PeCoffLoaderGetImageInfo (
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;
}
} else {
- ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
+ TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + TeStrippedOffset);
}
//
@@ -581,15 +652,6 @@ PeCoffLoaderGetImageInfo (
} else {
ImageContext->RelocationsStripped = FALSE;
}
-
- //
- // TE Image Relocation Data Directory Entry size is non-zero, but the Relocation Data Directory Virtual Address is zero.
- // This case is not a valid TE image.
- //
- if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {
- ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
- return RETURN_UNSUPPORTED;
- }
if (!(ImageContext->IsTeImage)) {
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
@@ -723,9 +785,8 @@ PeCoffLoaderGetImageInfo (
DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -
SectionHeader.VirtualAddress +
- SectionHeader.PointerToRawData +
- sizeof (EFI_TE_IMAGE_HEADER) -
- Hdr.Te->StrippedSize;
+ SectionHeader.PointerToRawData -
+ TeStrippedOffset;
//
// File offset of the debug directory was found, if this is not the last
@@ -749,7 +810,7 @@ PeCoffLoaderGetImageInfo (
// Section Table.
//
if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) {
- ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize);
+ ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) - TeStrippedOffset;
}
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
@@ -791,8 +852,9 @@ PeCoffLoaderGetImageInfo (
/**
Converts an image address to the loaded address.
- @param ImageContext The context of the image being loaded.
- @param Address The relative virtual address to be converted to the loaded address.
+ @param ImageContext The context of the image being loaded.
+ @param Address The address to be converted to the loaded address.
+ @param TeStrippedOffset Stripped offset for TE image.
@return The converted address or NULL if the address can not be converted.
@@ -800,18 +862,19 @@ PeCoffLoaderGetImageInfo (
VOID *
PeCoffLoaderImageAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
- IN UINTN Address
+ IN UINTN Address,
+ IN UINTN TeStrippedOffset
)
{
//
// Make sure that Address and ImageSize is correct for the loaded image.
//
- if (Address >= ImageContext->ImageSize) {
+ if (Address >= ImageContext->ImageSize + TeStrippedOffset) {
ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
return NULL;
}
- return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address);
+ return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address - TeStrippedOffset);
}
/**
@@ -867,6 +930,7 @@ PeCoffLoaderRelocateImage (
PHYSICAL_ADDRESS BaseAddress;
UINT32 NumberOfRvaAndSizes;
UINT16 Magic;
+ UINT32 TeStrippedOffset;
ASSERT (ImageContext != NULL);
@@ -897,7 +961,7 @@ PeCoffLoaderRelocateImage (
if (!(ImageContext->IsTeImage)) {
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
-
+ TeStrippedOffset = 0;
Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
@@ -930,47 +994,37 @@ PeCoffLoaderRelocateImage (
// is present in the image. You have to check the NumberOfRvaAndSizes in
// the optional header to verify a desired directory entry is there.
//
-
- if ((NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) && (RelocDir->Size > 0)) {
- RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
- RelocBaseEnd = PeCoffLoaderImageAddress (
- ImageContext,
- RelocDir->VirtualAddress + RelocDir->Size - 1
- );
- if (RelocBase == NULL || RelocBaseEnd == NULL) {
- return RETURN_LOAD_ERROR;
- }
- } else {
- //
- // Set base and end to bypass processing below.
- //
- RelocBase = RelocBaseEnd = NULL;
+ if ((NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)) {
+ RelocDir = NULL;
}
} else {
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
- Adjust = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase);
+ TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
+ Adjust = (UINT64) (BaseAddress - (Hdr.Te->ImageBase + TeStrippedOffset));
if (Adjust != 0) {
- Hdr.Te->ImageBase = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
+ Hdr.Te->ImageBase = (UINT64) (BaseAddress - TeStrippedOffset);
}
//
// Find the relocation block
//
RelocDir = &Hdr.Te->DataDirectory[0];
- if (RelocDir->Size > 0) {
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(
- ImageContext->ImageAddress +
- RelocDir->VirtualAddress +
- sizeof(EFI_TE_IMAGE_HEADER) -
- Hdr.Te->StrippedSize
- );
- RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);
- } else {
- //
- // Set base and end to bypass processing below.
- //
- RelocBase = RelocBaseEnd = NULL;
+ }
+
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext,
+ RelocDir->VirtualAddress + RelocDir->Size - 1,
+ TeStrippedOffset
+ );
+ if (RelocBase == NULL || RelocBaseEnd == NULL) {
+ return RETURN_LOAD_ERROR;
}
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = NULL;
}
//
@@ -993,19 +1047,10 @@ PeCoffLoaderRelocateImage (
}
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
-
- if (!(ImageContext->IsTeImage)) {
- FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
- if (FixupBase == NULL) {
- return RETURN_LOAD_ERROR;
- }
- } else {
- FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
- RelocBase->VirtualAddress +
- sizeof(EFI_TE_IMAGE_HEADER) -
- Hdr.Te->StrippedSize
- );
- }
+ FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);
+ if (FixupBase == NULL) {
+ return RETURN_LOAD_ERROR;
+ }
//
// Run this relocation record
@@ -1154,7 +1199,7 @@ PeCoffLoaderLoadImage (
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
CHAR16 *String;
UINT32 Offset;
-
+ UINT32 TeStrippedOffset;
ASSERT (ImageContext != NULL);
@@ -1241,6 +1286,7 @@ PeCoffLoaderLoadImage (
Hdr.Pe32->FileHeader.SizeOfOptionalHeader
);
NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);
+ TeStrippedOffset = 0;
} else {
Status = ImageContext->ImageRead (
ImageContext->Handle,
@@ -1250,13 +1296,12 @@ PeCoffLoaderLoadImage (
);
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
-
FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
(UINTN)ImageContext->ImageAddress +
sizeof(EFI_TE_IMAGE_HEADER)
);
NumberOfSections = (UINTN) (Hdr.Te->NumberOfSections);
-
+ TeStrippedOffset = (UINT32) Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
}
if (RETURN_ERROR (Status)) {
@@ -1280,11 +1325,8 @@ PeCoffLoaderLoadImage (
//
// Compute sections address
//
- Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);
- End = PeCoffLoaderImageAddress (
- ImageContext,
- Section->VirtualAddress + Section->Misc.VirtualSize - 1
- );
+ Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress, TeStrippedOffset);
+ End = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress + Section->Misc.VirtualSize - 1, TeStrippedOffset);
//
// If the size of the section is non-zero and the base address or end address resolved to 0, then fail.
@@ -1294,28 +1336,13 @@ PeCoffLoaderLoadImage (
return RETURN_LOAD_ERROR;
}
- if (ImageContext->IsTeImage) {
- Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
- End = (CHAR8 *)((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
- }
-
if (Section->SizeOfRawData > 0) {
- if (!(ImageContext->IsTeImage)) {
- Status = ImageContext->ImageRead (
- ImageContext->Handle,
- Section->PointerToRawData,
- &Size,
- Base
- );
- } else {
- Status = ImageContext->ImageRead (
- ImageContext->Handle,
- Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize,
- &Size,
- Base
- );
- }
-
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ Section->PointerToRawData - TeStrippedOffset,
+ &Size,
+ Base
+ );
if (RETURN_ERROR (Status)) {
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
return Status;
@@ -1350,7 +1377,8 @@ PeCoffLoaderLoadImage (
//
ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
ImageContext,
- (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint
+ (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint,
+ 0
);
} else {
//
@@ -1358,16 +1386,16 @@ PeCoffLoaderLoadImage (
//
ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
ImageContext,
- (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint
+ (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint,
+ 0
);
}
} else {
- ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (
- (UINTN)ImageContext->ImageAddress +
- (UINTN)Hdr.Te->AddressOfEntryPoint +
- (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
- (UINTN)Hdr.Te->StrippedSize
- );
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
+ ImageContext,
+ (UINTN)Hdr.Te->AddressOfEntryPoint,
+ TeStrippedOffset
+ );
}
//
@@ -1411,107 +1439,82 @@ PeCoffLoaderLoadImage (
// Load the Codeview information if present
//
if (ImageContext->DebugDirectoryEntryRva != 0) {
- if (!(ImageContext->IsTeImage)) {
- DebugEntry = PeCoffLoaderImageAddress (
- ImageContext,
- ImageContext->DebugDirectoryEntryRva
- );
- } else {
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
- ImageContext->ImageAddress +
- ImageContext->DebugDirectoryEntryRva +
- sizeof(EFI_TE_IMAGE_HEADER) -
- Hdr.Te->StrippedSize
- );
+ DebugEntry = PeCoffLoaderImageAddress (
+ ImageContext,
+ ImageContext->DebugDirectoryEntryRva,
+ TeStrippedOffset
+ );
+ if (DebugEntry == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
}
- if (DebugEntry != NULL) {
- TempDebugEntryRva = DebugEntry->RVA;
- if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
- Section--;
- if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {
- TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
- } else {
- TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
- }
+ TempDebugEntryRva = DebugEntry->RVA;
+ if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
+ Section--;
+ if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {
+ TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
+ } else {
+ TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
}
+ }
- if (TempDebugEntryRva != 0) {
- if (!(ImageContext->IsTeImage)) {
- ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);
- } else {
- ImageContext->CodeView = (VOID *)(
- (UINTN)ImageContext->ImageAddress +
- (UINTN)TempDebugEntryRva +
- (UINTN)sizeof (EFI_TE_IMAGE_HEADER) -
- (UINTN) Hdr.Te->StrippedSize
- );
- }
+ if (TempDebugEntryRva != 0) {
+ ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva, TeStrippedOffset);
+ if (ImageContext->CodeView == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+
+ if (DebugEntry->RVA == 0) {
+ Size = DebugEntry->SizeOfData;
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugEntry->FileOffset - TeStrippedOffset,
+ &Size,
+ ImageContext->CodeView
+ );
+ //
+ // Should we apply fix up to this field according to the size difference between PE and TE?
+ // Because now we maintain TE header fields unfixed, this field will also remain as they are
+ // in original PE image.
+ //
- if (ImageContext->CodeView == NULL) {
+ if (RETURN_ERROR (Status)) {
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
return RETURN_LOAD_ERROR;
}
- if (DebugEntry->RVA == 0) {
- Size = DebugEntry->SizeOfData;
- if (!(ImageContext->IsTeImage)) {
- Status = ImageContext->ImageRead (
- ImageContext->Handle,
- DebugEntry->FileOffset,
- &Size,
- ImageContext->CodeView
- );
- } else {
- Status = ImageContext->ImageRead (
- ImageContext->Handle,
- DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize,
- &Size,
- ImageContext->CodeView
- );
- //
- // Should we apply fix up to this field according to the size difference between PE and TE?
- // Because now we maintain TE header fields unfixed, this field will also remain as they are
- // in original PE image.
- //
- }
-
- if (RETURN_ERROR (Status)) {
- ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
- return RETURN_LOAD_ERROR;
- }
+ DebugEntry->RVA = TempDebugEntryRva;
+ }
- DebugEntry->RVA = TempDebugEntryRva;
+ switch (*(UINT32 *) ImageContext->CodeView) {
+ case CODEVIEW_SIGNATURE_NB10:
+ if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
}
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
- switch (*(UINT32 *) ImageContext->CodeView) {
- case CODEVIEW_SIGNATURE_NB10:
- if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {
- ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
- return RETURN_UNSUPPORTED;
- }
- ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
- break;
-
- case CODEVIEW_SIGNATURE_RSDS:
- if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {
- ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
- return RETURN_UNSUPPORTED;
- }
- ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
- break;
-
- case CODEVIEW_SIGNATURE_MTOC:
- if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {
- ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
- return RETURN_UNSUPPORTED;
- }
- ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
- break;
+ case CODEVIEW_SIGNATURE_RSDS:
+ if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
+ }
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
- default:
- break;
+ case CODEVIEW_SIGNATURE_MTOC:
+ if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {
+ ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;
+ return RETURN_UNSUPPORTED;
}
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
+ break;
+
+ default:
+ break;
}
}
}
@@ -1536,7 +1539,7 @@ PeCoffLoaderLoadImage (
}
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && DirectoryEntry->Size != 0) {
- Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress);
+ Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress, 0);
if (Base != NULL) {
ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;
Offset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) *
@@ -1611,7 +1614,7 @@ PeCoffLoaderLoadImage (
return RETURN_UNSUPPORTED;
}
ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);
- ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData);
+ ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData, 0);
break;
}
}
@@ -1818,13 +1821,6 @@ PeCoffLoaderRelocateImageForRuntime (
FixupData = FixupData + sizeof (UINT64);
break;
- case EFI_IMAGE_REL_BASED_HIGHADJ:
- //
- // Not valid Relocation type for UEFI image, ASSERT
- //
- ASSERT (FALSE);
- break;
-
default:
//
// Only Itanium requires ConvertPeImage_Ex
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
index 358ec27fd0..0851acc18c 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
@@ -116,8 +116,9 @@ PeCoffLoaderGetPeHeader (
/**
Converts an image address to the loaded address.
- @param ImageContext The context of the image being loaded.
- @param Address The address to be converted to the loaded address.
+ @param ImageContext The context of the image being loaded.
+ @param Address The address to be converted to the loaded address.
+ @param TeStrippedOffset Stripped offset for TE image.
@return The converted address or NULL if the address can not be converted.
@@ -125,7 +126,8 @@ PeCoffLoaderGetPeHeader (
VOID *
PeCoffLoaderImageAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
- IN UINTN Address
+ IN UINTN Address,
+ IN UINTN TeStrippedOffset
);
#endif
diff --git a/MdePkg/Library/BaseS3IoLib/S3IoLib.c b/MdePkg/Library/BaseS3IoLib/S3IoLib.c
index 2ff3fff21a..017bcbb9cd 100644
--- a/MdePkg/Library/BaseS3IoLib/S3IoLib.c
+++ b/MdePkg/Library/BaseS3IoLib/S3IoLib.c
@@ -2,7 +2,7 @@
I/O and MMIO Library Services that do I/O and also enable the I/O operatation
to be replayed during an S3 resume.
- Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 -2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -264,6 +264,7 @@ S3IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -302,6 +303,7 @@ S3IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -340,6 +342,7 @@ S3IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -379,6 +382,8 @@ S3IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -614,6 +619,7 @@ S3IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -652,6 +658,7 @@ S3IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -690,6 +697,7 @@ S3IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -730,6 +738,8 @@ S3IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -965,6 +975,7 @@ S3IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1003,6 +1014,7 @@ S3IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1041,6 +1053,7 @@ S3IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1081,6 +1094,8 @@ S3IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1316,6 +1331,7 @@ S3IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1354,6 +1370,7 @@ S3IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1392,6 +1409,7 @@ S3IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1432,6 +1450,8 @@ S3IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1697,6 +1717,7 @@ S3MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1736,6 +1757,7 @@ S3MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1775,6 +1797,7 @@ S3MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1815,6 +1838,8 @@ S3MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2050,6 +2075,7 @@ S3MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2089,6 +2115,7 @@ S3MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2128,6 +2155,7 @@ S3MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2168,6 +2196,8 @@ S3MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2402,6 +2432,7 @@ S3MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2441,6 +2472,7 @@ S3MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2480,6 +2512,7 @@ S3MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2520,6 +2553,8 @@ S3MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2754,6 +2789,7 @@ S3MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2793,6 +2829,7 @@ S3MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2832,6 +2869,7 @@ S3MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2872,6 +2910,8 @@ S3MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/BaseS3PciLib/S3PciLib.c b/MdePkg/Library/BaseS3PciLib/S3PciLib.c
index bbaf99c1c8..e29f7fe63e 100644
--- a/MdePkg/Library/BaseS3PciLib/S3PciLib.c
+++ b/MdePkg/Library/BaseS3PciLib/S3PciLib.c
@@ -3,7 +3,7 @@
the PCI operations to be replayed during an S3 resume. This library class
maps directly on top of the PciLib class.
- Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -277,6 +277,7 @@ S3PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -316,6 +317,7 @@ S3PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -355,6 +357,7 @@ S3PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -395,6 +398,8 @@ S3PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -645,6 +650,7 @@ S3PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -685,6 +691,7 @@ S3PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -725,6 +732,7 @@ S3PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -766,6 +774,8 @@ S3PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1016,6 +1026,7 @@ S3PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1056,6 +1067,7 @@ S3PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1096,6 +1108,7 @@ S3PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1137,6 +1150,8 @@ S3PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c b/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c
index 29d4af58d6..c872ebf554 100644
--- a/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c
+++ b/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c
@@ -4,7 +4,7 @@
All assertions for bit field operations are handled bit field functions in the
Base Library.
- Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 2012, 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
@@ -148,6 +148,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -188,6 +189,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -228,6 +230,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -270,6 +273,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -428,6 +433,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -468,6 +474,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -508,6 +515,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -550,6 +558,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -708,6 +718,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -748,6 +759,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -788,6 +800,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -830,6 +843,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -988,6 +1003,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1028,6 +1044,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1068,6 +1085,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1110,6 +1128,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1268,6 +1288,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1309,6 +1330,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1350,6 +1372,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1392,6 +1415,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1550,6 +1575,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1591,6 +1617,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1632,6 +1659,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1674,6 +1702,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1832,6 +1862,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1873,6 +1904,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1914,6 +1946,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1956,6 +1989,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2114,6 +2149,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2155,6 +2191,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2196,6 +2233,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2238,6 +2276,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c b/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
index c84a8b789f..7b602192a4 100644
--- a/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
+++ b/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
@@ -1,7 +1,7 @@
/** @file
High-level Io/Mmio functions.
- Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -144,6 +144,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -184,6 +185,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -224,6 +226,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -266,6 +269,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -424,6 +429,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -464,6 +470,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -504,6 +511,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -546,6 +554,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -704,6 +714,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -744,6 +755,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -784,6 +796,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -826,6 +839,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -984,6 +999,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1024,6 +1040,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1064,6 +1081,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1106,6 +1124,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1264,6 +1284,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1305,6 +1326,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1346,6 +1368,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1388,6 +1411,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1546,6 +1571,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1587,6 +1613,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1628,6 +1655,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1670,6 +1698,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1828,6 +1858,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1869,6 +1900,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1910,6 +1942,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1952,6 +1985,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2110,6 +2145,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2151,6 +2187,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2192,6 +2229,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2234,6 +2272,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/DxePciLibEsal/PciLib.c b/MdePkg/Library/DxePciLibEsal/PciLib.c
index 8cc1a506f8..43fcef1bae 100644
--- a/MdePkg/Library/DxePciLibEsal/PciLib.c
+++ b/MdePkg/Library/DxePciLibEsal/PciLib.c
@@ -1,7 +1,7 @@
/** @file
DXE PCI Library instance layered on top of ESAL services.
- Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -392,6 +392,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -433,6 +434,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -474,6 +476,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -517,6 +520,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -743,6 +748,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -785,6 +791,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -827,6 +834,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -871,6 +879,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1097,6 +1107,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1139,6 +1150,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1181,6 +1193,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1225,6 +1238,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c b/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
index a7572a093f..07ddd8fd0a 100644
--- a/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
+++ b/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
@@ -1,7 +1,7 @@
/** @file
DXE PCI Segment Library instance layered on top of ESAL services.
- Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -364,6 +364,7 @@ PciSegmentBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -405,6 +406,7 @@ PciSegmentBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -446,6 +448,7 @@ PciSegmentBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -489,6 +492,8 @@ PciSegmentBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -708,6 +713,7 @@ PciSegmentBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -749,6 +755,7 @@ PciSegmentBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -790,6 +797,7 @@ PciSegmentBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -833,6 +841,8 @@ PciSegmentBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1052,6 +1062,7 @@ PciSegmentBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1093,6 +1104,7 @@ PciSegmentBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1134,6 +1146,7 @@ PciSegmentBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1177,6 +1190,8 @@ PciSegmentBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c b/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
index fc276d583e..01bd96166e 100644
--- a/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
+++ b/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
@@ -5,7 +5,7 @@
All assertions for I/O operations are handled in MMIO functions in the IoLib
Library.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -545,6 +545,7 @@ PciExpressBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -588,6 +589,7 @@ PciExpressBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -631,6 +633,7 @@ PciExpressBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -676,6 +679,8 @@ PciExpressBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -909,6 +914,7 @@ PciExpressBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -953,6 +959,7 @@ PciExpressBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -997,6 +1004,7 @@ PciExpressBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1043,6 +1051,8 @@ PciExpressBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1276,6 +1286,7 @@ PciExpressBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1320,6 +1331,7 @@ PciExpressBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1364,6 +1376,7 @@ PciExpressBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1410,6 +1423,8 @@ PciExpressBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c b/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
index f5e554f9e8..ce73658e84 100644
--- a/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
+++ b/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
@@ -4,7 +4,7 @@
All assertions for bit field operations are handled bit field functions in the
Base Library.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, 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
@@ -152,6 +152,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -192,6 +193,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -232,6 +234,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -274,6 +277,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -437,6 +442,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -478,6 +484,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -519,6 +526,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -562,6 +570,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -725,6 +735,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -766,6 +777,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -807,6 +819,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -850,6 +863,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1013,6 +1028,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1054,6 +1070,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1095,6 +1112,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1138,6 +1156,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1296,6 +1316,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1337,6 +1358,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1378,6 +1400,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1420,6 +1443,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1582,6 +1607,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1624,6 +1650,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1666,6 +1693,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1709,6 +1737,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1871,6 +1901,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1913,6 +1944,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1955,6 +1987,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1998,6 +2031,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2160,6 +2195,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2202,6 +2238,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2244,6 +2281,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2287,6 +2325,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c b/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
index 0eef525261..689a2299a3 100644
--- a/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
+++ b/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
@@ -1,7 +1,7 @@
/** @file
PCI Library using PCI CFG2 PPI.
- Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 2012, 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
@@ -350,6 +350,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -391,6 +392,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -432,6 +434,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -475,6 +478,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -701,6 +706,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -743,6 +749,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -785,6 +792,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -829,6 +837,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1055,6 +1065,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1097,6 +1108,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1139,6 +1151,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1183,6 +1196,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c b/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c
index 8330243b1e..93f63df389 100644
--- a/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c
+++ b/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c
@@ -1,7 +1,7 @@
/** @file
PCI Segment Library implementation using PCI CFG2 PPI.
- Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 2012, 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
@@ -369,6 +369,7 @@ PciSegmentBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -410,6 +411,7 @@ PciSegmentBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -451,6 +453,7 @@ PciSegmentBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -494,6 +497,8 @@ PciSegmentBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -711,6 +716,7 @@ PciSegmentBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -747,6 +753,7 @@ PciSegmentBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -789,6 +796,7 @@ PciSegmentBitFieldOr16 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -832,6 +840,8 @@ PciSegmentBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1050,6 +1060,7 @@ PciSegmentBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1091,6 +1102,7 @@ PciSegmentBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1132,7 +1144,7 @@ PciSegmentBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
-
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1176,6 +1188,8 @@ PciSegmentBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c b/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c
index 5d2697e270..31be13cb6d 100644
--- a/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c
+++ b/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c
@@ -4,7 +4,7 @@
All assertions for bit field operations are handled bit field functions in the
Base Library.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -153,6 +153,7 @@ IoBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -193,6 +194,7 @@ IoBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -233,6 +235,7 @@ IoBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -275,6 +278,8 @@ IoBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -433,6 +438,7 @@ IoBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -473,6 +479,7 @@ IoBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -513,6 +520,7 @@ IoBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -555,6 +563,8 @@ IoBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -713,6 +723,7 @@ IoBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -753,6 +764,7 @@ IoBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -793,6 +805,7 @@ IoBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -835,6 +848,8 @@ IoBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -993,6 +1008,7 @@ IoBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1033,6 +1049,7 @@ IoBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1073,6 +1090,7 @@ IoBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1115,6 +1133,8 @@ IoBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Port The I/O port to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1273,6 +1293,7 @@ MmioBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1314,6 +1335,7 @@ MmioBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1355,6 +1377,7 @@ MmioBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1397,6 +1420,8 @@ MmioBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1555,6 +1580,7 @@ MmioBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1596,6 +1622,7 @@ MmioBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1637,6 +1664,7 @@ MmioBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1679,6 +1707,8 @@ MmioBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1837,6 +1867,7 @@ MmioBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1878,6 +1909,7 @@ MmioBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1919,6 +1951,7 @@ MmioBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1961,6 +1994,8 @@ MmioBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2119,6 +2154,7 @@ MmioBitFieldRead64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2160,6 +2196,7 @@ MmioBitFieldWrite64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2201,6 +2238,7 @@ MmioBitFieldOr64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -2243,6 +2281,8 @@ MmioBitFieldAnd64 (
If StartBit is greater than 63, then ASSERT().
If EndBit is greater than 63, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The MMIO register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c b/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
index d8b7e72dbd..0b94aeb62a 100644
--- a/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
+++ b/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
@@ -1,7 +1,7 @@
/** @file
PCI Library using SMM PCI Root Bridge I/O Protocol.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -362,6 +362,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -403,6 +404,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -444,6 +446,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -487,6 +490,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -713,6 +718,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -755,6 +761,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -797,6 +804,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -841,6 +849,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1067,6 +1077,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1109,6 +1120,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1151,6 +1163,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1195,6 +1208,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c b/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c
index 4d4c7f2d58..148e12c190 100644
--- a/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c
+++ b/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c
@@ -1,7 +1,7 @@
/** @file
PCI Library using PCI Root Bridge I/O Protocol.
- Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 2012, 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
@@ -364,6 +364,7 @@ PciBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -405,6 +406,7 @@ PciBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -446,6 +448,7 @@ PciBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -489,6 +492,8 @@ PciBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -715,6 +720,7 @@ PciBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -757,6 +763,7 @@ PciBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -799,6 +806,7 @@ PciBitFieldOr16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -843,6 +851,8 @@ PciBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1069,6 +1079,7 @@ PciBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1111,6 +1122,7 @@ PciBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1153,6 +1165,7 @@ PciBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1197,6 +1210,8 @@ PciBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c b/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
index ccd9df34d0..5b286b057f 100644
--- a/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
+++ b/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
@@ -1,7 +1,7 @@
/** @file
PCI Segment Library implementation using PCI Root Bridge I/O Protocol.
- Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 2012, 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
@@ -446,6 +446,7 @@ PciSegmentBitFieldRead8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -487,6 +488,7 @@ PciSegmentBitFieldWrite8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -528,6 +530,7 @@ PciSegmentBitFieldOr8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -571,6 +574,8 @@ PciSegmentBitFieldAnd8 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -788,6 +793,7 @@ PciSegmentBitFieldRead16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -824,6 +830,7 @@ PciSegmentBitFieldWrite16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -866,6 +873,7 @@ PciSegmentBitFieldOr16 (
If StartBit is greater than 7, then ASSERT().
If EndBit is greater than 7, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -909,6 +917,8 @@ PciSegmentBitFieldAnd16 (
If StartBit is greater than 15, then ASSERT().
If EndBit is greater than 15, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1123,6 +1133,7 @@ PciSegmentBitFieldRead32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1164,6 +1175,7 @@ PciSegmentBitFieldWrite32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1205,7 +1217,7 @@ PciSegmentBitFieldOr32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
-
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
@@ -1249,6 +1261,8 @@ PciSegmentBitFieldAnd32 (
If StartBit is greater than 31, then ASSERT().
If EndBit is greater than 31, then ASSERT().
If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
@param Address The PCI configuration register to write.
@param StartBit The ordinal of the least significant bit in the bit field.
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index aefba3ffb1..3de6ff5aea 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -581,6 +581,12 @@
## Include/Guid/FirmwareFileSystem3.h
gEfiFirmwareFileSystem3Guid = { 0x5473c07a, 0x3dcb, 0x4dca, { 0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a }}
+ #
+ # GUID defined in PI1.2.1
+ #
+ ## Include/Guid/EventGroup.h
+ gEfiEndOfDxeEventGroupGuid = { 0x2ce967a, 0xdd7e, 0x4ffc, { 0x9e, 0xe7, 0x81, 0xc, 0xf0, 0x47, 0x8, 0x80 }}
+
[Guids.IA32, Guids.X64]
## Include/Guid/Cper.h
gEfiIa32X64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, { 0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }}
@@ -893,6 +899,13 @@
gEfiSecurity2ArchProtocolGuid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
#
+ # Protocols defined in PI 1.2.1
+ #
+
+ ## Include/Protocol/SmmEndOfDxe.h
+ gEfiSmmEndOfDxeProtocolGuid = { 0x24e70042, 0xd5c5, 0x4260, { 0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d }}
+
+ #
# Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
#
diff --git a/NetworkPkg/Dhcp6Dxe/ComponentName.c b/NetworkPkg/Dhcp6Dxe/ComponentName.c
index 178c8bca45..352df087f9 100644
--- a/NetworkPkg/Dhcp6Dxe/ComponentName.c
+++ b/NetworkPkg/Dhcp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Dhcp6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -172,6 +172,19 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcp6DriverNameTab
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable = NULL;
+
+CHAR16 *mDhcp6ControllerName[] = {
+ L"DHCPv6 (State=0, Init)",
+ L"DHCPv6 (State=1, Selecting)",
+ L"DHCPv6 (State=2, Requesting)",
+ L"DHCPv6 (State=3, Declining)",
+ L"DHCPv6 (State=4, Confirming)",
+ L"DHCPv6 (State=5, Releasing)",
+ L"DHCPv6 (State=6, Bound)",
+ L"DHCPv6 (State=7, Renewing)",
+ L"DHCPv6 (State=8, Rebinding)"
+};
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -229,6 +242,67 @@ Dhcp6ComponentNameGetDriverName (
);
}
+/**
+ Update the component name for the Dhcp6 child handle.
+
+ @param Dhcp6[in] A pointer to the EFI_DHCP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_DHCP6_PROTOCOL *Dhcp6
+ )
+{
+ EFI_STATUS Status;
+ EFI_DHCP6_MODE_DATA Dhcp6ModeData;
+ CHAR16 HandleName[64];
+
+ if (Dhcp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (gDhcp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gDhcp6ControllerNameTable);
+ gDhcp6ControllerNameTable = NULL;
+ }
+
+ if (Dhcp6ModeData.Ia == NULL) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"DHCPv6 (No configured IA)");
+ } else {
+ StrCpy (HandleName, mDhcp6ControllerName[Dhcp6ModeData.Ia->State]);
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gDhcp6ComponentName.SupportedLanguages,
+ &gDhcp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gDhcp6ComponentName2.SupportedLanguages,
+ &gDhcp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
/**
Retrieves a Unicode string that is the user-readable name of the controller
@@ -308,5 +382,57 @@ Dhcp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_DHCP6_PROTOCOL *Dhcp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiDhcp6ProtocolGuid,
+ (VOID **)&Dhcp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Dhcp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gDhcp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gDhcp6ComponentName)
+ );
}
+
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
index 346986bd15..de53a1a9b4 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
@@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
Dhcp6ServiceBindingDestroyChild
};
-
/**
Configure the default Udp6Io to receive all the DHCP6 traffic
on this network interface.
@@ -155,7 +154,6 @@ Dhcp6CreateService (
// Initialize the fields of the new Dhcp6 service.
//
Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;
- Dhcp6Srv->InDestroy = FALSE;
Dhcp6Srv->Controller = Controller;
Dhcp6Srv->Image = ImageHandle;
Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));
@@ -328,6 +326,36 @@ Dhcp6CreateInstance (
return EFI_SUCCESS;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Dhcp6DestroyChildEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ DHCP6_INSTANCE *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE);
+ ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
/**
Entry point of the DHCP6 driver to install various protocols.
@@ -498,11 +526,11 @@ Dhcp6DriverBindingStop (
)
{
EFI_STATUS Status;
- EFI_TPL OldTpl;
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
DHCP6_SERVICE *Service;
- DHCP6_INSTANCE *Instance;
+ LIST_ENTRY *List;
+ UINTN ListLength;
//
// Find and check the Nic handle by the controller handle.
@@ -510,7 +538,7 @@ Dhcp6DriverBindingStop (
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -527,50 +555,44 @@ Dhcp6DriverBindingStop (
}
Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);
-
- if (Service->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&Service->Child)) {
+ //
+ // Destroy all the children instances before destory the service.
+ //
+ List = &Service->Child;
+ Status = NetDestroyLinkList (
+ List,
+ Dhcp6DestroyChildEntry,
+ ServiceBinding,
+ &ListLength
+ );
+ if (EFI_ERROR (Status) || ListLength != 0) {
+ Status = EFI_DEVICE_ERROR;
+ }
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {
+ Status = EFI_DEVICE_ERROR;
+ }
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {
//
// Destroy the service itself if no child instance left.
//
- Service->InDestroy = TRUE;
-
Status = gBS->UninstallProtocolInterface (
NicHandle,
&gEfiDhcp6ServiceBindingProtocolGuid,
ServiceBinding
);
-
if (EFI_ERROR (Status)) {
- Service->InDestroy = FALSE;
goto ON_EXIT;
}
Dhcp6DestroyService (Service);
-
- } else {
- //
- // Destroy all the children instances before destroy the service.
- //
- while (!IsListEmpty (&Service->Child)) {
- Instance = NET_LIST_HEAD (&Service->Child, DHCP6_INSTANCE, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- }
- //
- // Any of child failed to be destroyed.
- //
- if (Service->NumOfChild != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
-
+
ON_EXIT:
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -771,12 +793,13 @@ Dhcp6ServiceBindingDestroyChild (
//
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiDhcp6ProtocolGuid,
Dhcp6
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
gBS->RestoreTPL (OldTpl);
@@ -789,9 +812,8 @@ Dhcp6ServiceBindingDestroyChild (
RemoveEntryList (&Instance->Link);
Service->NumOfChild--;
- Dhcp6DestroyInstance (Instance);
-
gBS->RestoreTPL (OldTpl);
+ Dhcp6DestroyInstance (Instance);
return EFI_SUCCESS;
}
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
index 4ef7f17963..bec47a0679 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
@@ -2,7 +2,7 @@
Driver Binding functions and Service Binding functions
declaration for Dhcp6 Driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -21,6 +21,7 @@
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable;
/**
Test to see if this driver supports ControllerHandle. This service
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
index 2c2b9f9f0e..934c03ed85 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
@@ -216,12 +216,11 @@ EfiDhcp6Stop (
Instance->UdpSts = EFI_ALREADY_STARTED;
Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);
+ gBS->RestoreTPL (OldTpl);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
- gBS->RestoreTPL (OldTpl);
-
//
// Poll udp out of the net tpl if synchoronus call.
//
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
index d4e9746be8..71b16b1919 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
@@ -34,6 +34,7 @@
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/NetLib.h>
+#include <Library/PrintLib.h>
typedef struct _DHCP6_IA_CB DHCP6_IA_CB;
@@ -245,7 +246,7 @@ struct _DHCP6_INSTANCE {
EFI_DHCP6_PACKET *AdSelect;
UINT8 AdPref;
EFI_IPv6_ADDRESS *Unicast;
- EFI_STATUS UdpSts;
+ volatile EFI_STATUS UdpSts;
BOOLEAN InDestroy;
BOOLEAN MediaPresent;
UINT64 StartTime;
@@ -266,7 +267,6 @@ struct _DHCP6_SERVICE {
UINT32 Xid;
LIST_ENTRY Child;
UINTN NumOfChild;
- BOOLEAN InDestroy;
};
/**
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index f2e33f335f..0e83d07853 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -2510,7 +2510,7 @@ Dhcp6HandleStateful (
ClientId = Service->ClientId;
Status = EFI_SUCCESS;
- if (Instance->InDestroy || Instance->Config == NULL) {
+ if (Instance->Config == NULL) {
goto ON_CONTINUE;
}
@@ -2624,10 +2624,6 @@ Dhcp6HandleStateless (
IsMatched = FALSE;
InfCb = NULL;
- if (Instance->InDestroy) {
- goto ON_EXIT;
- }
-
if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {
goto ON_EXIT;
}
diff --git a/NetworkPkg/IScsiDxe/ComponentName.c b/NetworkPkg/IScsiDxe/ComponentName.c
index e4e28e8961..1ee21f5d5d 100644
--- a/NetworkPkg/IScsiDxe/ComponentName.c
+++ b/NetworkPkg/IScsiDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for iSCSI.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -43,6 +43,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -100,6 +102,99 @@ IScsiComponentNameGetDriverName (
}
/**
+ Update the component name for the iSCSI NIC handle.
+
+ @param[in] Controller The handle of the NIC controller.
+ @param[in] Ipv6Flag TRUE if IP6 network stack is used.
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval EFI_UNSUPPORTED Can't get the corresponding NIC info from the Controller handle.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_HANDLE Controller,
+ IN BOOLEAN Ipv6Flag
+ )
+{
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddr;
+ UINTN HwAddressSize;
+ UINT16 VlanId;
+ ISCSI_NIC_INFO *ThisNic;
+ ISCSI_NIC_INFO *NicInfo;
+ LIST_ENTRY *Entry;
+ CHAR16 HandleName[80];
+
+ //
+ // Get MAC address of this network device.
+ //
+ Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get VLAN ID of this network device.
+ //
+ VlanId = NetLibGetVlanId (Controller);
+
+ //
+ // Check whether the NIC information exists.
+ //
+ ThisNic = NULL;
+
+ NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
+ NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
+ if (NicInfo->HwAddressSize == HwAddressSize &&
+ CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
+ NicInfo->VlanId == VlanId) {
+
+ ThisNic = NicInfo;
+ break;
+ }
+ }
+
+ if (ThisNic == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"iSCSI (%s, NicIndex=%d)",
+ Ipv6Flag ? L"IPv6" : L"IPv4",
+ ThisNic->NicIndex
+ );
+
+ if (gIScsiControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIScsiControllerNameTable);
+ gIScsiControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gIScsiComponentName.SupportedLanguages,
+ &gIScsiControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIScsiComponentName2.SupportedLanguages,
+ &gIScsiControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -177,5 +272,54 @@ IScsiComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_HANDLE IScsiController;
+ BOOLEAN Ipv6Flag;
+ EFI_STATUS Status;
+ EFI_GUID *IScsiPrivateGuid;
+ ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
+
+ //
+ // Get the handle of the controller we are controling.
+ //
+ IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
+ if (IScsiController != NULL) {
+ IScsiPrivateGuid = &gIScsiV4PrivateGuid;
+ Ipv6Flag = FALSE;
+ } else {
+ IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
+ if (IScsiController != NULL) {
+ IScsiPrivateGuid = &gIScsiV6PrivateGuid;
+ Ipv6Flag = TRUE;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from IScsiController
+ //
+ Status = gBS->OpenProtocol (
+ IScsiController,
+ IScsiPrivateGuid,
+ (VOID **) &IScsiIdentifier,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = UpdateName(IScsiController, Ipv6Flag);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIScsiControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIScsiComponentName)
+ );
}
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.c b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
index 2bf102ba8b..2627a59dd6 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp6.c
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
@@ -1,7 +1,7 @@
/** @file
iSCSI DHCP6 related configuration routines.
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2012, 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
@@ -250,6 +250,7 @@ IScsiDhcp6ParseReply (
EFI_DHCP6_PACKET_OPTION *BootFileOpt;
EFI_DHCP6_PACKET_OPTION **OptionList;
ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;
+ UINT16 ParaLen;
OptionCount = 0;
BootFileOpt = NULL;
@@ -282,7 +283,7 @@ IScsiDhcp6ParseReply (
if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {
if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
- Status = EFI_INVALID_PARAMETER;
+ Status = EFI_UNSUPPORTED;
goto Exit;
}
//
@@ -302,6 +303,24 @@ IScsiDhcp6ParseReply (
// The server sends this option to inform the client about an URL to a boot file.
//
BootFileOpt = OptionList[Index];
+ } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARA) {
+ //
+ // The server sends this option to inform the client about DHCP6 server address.
+ //
+ if (OptionList[Index]->OpLen < 18) {
+ Status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+ //
+ // Check param-len 1, should be 16 bytes.
+ //
+ CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16));
+ if (NTOHS (ParaLen) != 16) {
+ Status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+
+ CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS));
}
}
@@ -405,7 +424,7 @@ IScsiDoDhcp6 (
goto ON_EXIT;
}
- Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);
+ Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5);
if (Oro == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
@@ -416,9 +435,10 @@ IScsiDoDhcp6 (
// All members in EFI_DHCP6_PACKET_OPTION are in network order.
//
Oro->OpCode = HTONS (DHCP6_OPT_REQUEST_OPTION);
- Oro->OpLen = HTONS (2 * 2);
+ Oro->OpLen = HTONS (2 * 3);
Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;
Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;
+ Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARA;
InfoReqReXmit.Irt = 4;
InfoReqReXmit.Mrc = 1;
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.h b/NetworkPkg/IScsiDxe/IScsiDhcp6.h
index fe3dfb7e4d..4ca25bd494 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp6.h
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.h
@@ -1,7 +1,7 @@
/** @file
The header file of iSCSI DHCP6 related configuration routines.
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/// Assigned by IANA, RFC 5970
///
#define DHCP6_OPT_BOOT_FILE_URL 59
+#define DHCP6_OPT_BOOT_FILE_PARA 60
#define ISCSI_ROOT_PATH_ID "iscsi:"
#define ISCSI_ROOT_PATH_FIELD_DELIMITER ':'
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c
index 7d8b18455c..2fd4c95a08 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.c
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.c
@@ -1,7 +1,7 @@
/** @file
The entry point of IScsi driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -23,8 +23,8 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
NULL
};
-EFI_GUID mIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
-EFI_GUID mIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
+EFI_GUID gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
+EFI_GUID gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
ISCSI_PRIVATE_DATA *mPrivate = NULL;
/**
@@ -121,7 +121,7 @@ IScsiDriverBindingSupported (
Status = gBS->OpenProtocol (
ControllerHandle,
- &mIScsiV4PrivateGuid,
+ &gIScsiV4PrivateGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
@@ -150,7 +150,7 @@ IScsiDriverBindingSupported (
Status = gBS->OpenProtocol (
ControllerHandle,
- &mIScsiV6PrivateGuid,
+ &gIScsiV6PrivateGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
@@ -231,11 +231,11 @@ IScsiStart (
//
if (IpVersion == IP_VERSION_4) {
- IScsiPrivateGuid = &mIScsiV4PrivateGuid;
+ IScsiPrivateGuid = &gIScsiV4PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
ProtocolGuid = &gEfiTcp4ProtocolGuid;
} else if (IpVersion == IP_VERSION_6) {
- IScsiPrivateGuid = &mIScsiV6PrivateGuid;
+ IScsiPrivateGuid = &gIScsiV6PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
ProtocolGuid = &gEfiTcp6ProtocolGuid;
} else {
@@ -931,13 +931,13 @@ IScsiDriverBindingStop (
//
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
if (IScsiController != NULL) {
- ProtocolGuid = &mIScsiV4PrivateGuid;
+ ProtocolGuid = &gIScsiV4PrivateGuid;
TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
} else {
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
ASSERT (IScsiController != NULL);
- ProtocolGuid = &mIScsiV6PrivateGuid;
+ ProtocolGuid = &gIScsiV6PrivateGuid;
TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
}
@@ -1060,6 +1060,11 @@ IScsiUnload (
&gIScsiAuthenticationInfo,
NULL
);
+
+ if (gIScsiControllerNameTable!= NULL) {
+ FreeUnicodeStringTable (gIScsiControllerNameTable);
+ gIScsiControllerNameTable = NULL;
+ }
return gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.h b/NetworkPkg/IScsiDxe/IScsiDriver.h
index 04866f0ed4..8c266fe763 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.h
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.h
@@ -1,7 +1,7 @@
/** @file
The header file of IScsiDriver.c.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2012, 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
@@ -33,9 +33,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName;
+extern EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable;
extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName;
extern EFI_AUTHENTICATION_INFO_PROTOCOL gIScsiAuthenticationInfo;
extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate;
+extern EFI_GUID gIScsiV4PrivateGuid;
+extern EFI_GUID gIScsiV6PrivateGuid;
typedef struct {
CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE];
diff --git a/NetworkPkg/IScsiDxe/IScsiIbft.c b/NetworkPkg/IScsiDxe/IScsiIbft.c
index 879d310cc9..9dba4e6f36 100644
--- a/NetworkPkg/IScsiDxe/IScsiIbft.c
+++ b/NetworkPkg/IScsiDxe/IScsiIbft.c
@@ -321,14 +321,10 @@ IScsiFillNICAndTargetSections (
Nic->SubnetMaskPrefixLength = NvData->PrefixLength;
CopyMem (&Nic->Ip, &NvData->LocalIp, sizeof (EFI_IPv6_ADDRESS));
CopyMem (&Nic->Gateway, &NvData->Gateway, sizeof (EFI_IPv6_ADDRESS));
-
CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS));
CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS));
- //
- // TODO: DHCP server address cannot be retrieved by DHCPv6 process since
- // DHCP server option is removed.
- //CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
- //
+ CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
+
} else {
ASSERT (FALSE);
}
diff --git a/NetworkPkg/Ip6Dxe/ComponentName.c b/NetworkPkg/Ip6Dxe/ComponentName.c
index bcdf4b1e42..75a1562ca0 100644
--- a/NetworkPkg/Ip6Dxe/ComponentName.c
+++ b/NetworkPkg/Ip6Dxe/ComponentName.c
@@ -2,7 +2,7 @@
Implementation of EFI_COMPONENT_NAME_PROTOCOL and
EFI_COMPONENT_NAME2_PROTOCOL protocol.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp6DriverNameTable[
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -232,6 +234,88 @@ Ip6ComponentNameGetDriverName (
}
/**
+ Update the component name for the IP6 child handle.
+
+ @param Ip6[in] A pointer to the EFI_IP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_IP6_PROTOCOL *Ip6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[128];
+ EFI_IP6_MODE_DATA Ip6ModeData;
+ UINTN Offset;
+ CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ if (Ip6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Offset = 0;
+ Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);
+ if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) {
+ Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Offset += UnicodeSPrint (
+ HandleName,
+ sizeof(HandleName),
+ L"IPv6(StationAddress=%s, ",
+ Address
+ );
+ Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ UnicodeSPrint (
+ HandleName + Offset,
+ sizeof(HandleName) - Offset * sizeof (CHAR16),
+ L"DestinationAddress=%s)",
+ Address
+ );
+ } else if (!Ip6ModeData.IsStarted) {
+ UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status);
+ }
+
+ if (gIp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp6ControllerNameTable);
+ gIp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gIp6ComponentName.SupportedLanguages,
+ &gIp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIp6ComponentName2.SupportedLanguages,
+ &gIp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -309,5 +393,56 @@ Ip6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_IP6_PROTOCOL *Ip6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ (VOID **)&Ip6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Ip6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIp6ComponentName)
+ );
}
diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.c b/NetworkPkg/Ip6Dxe/Ip6Common.c
index 2ae14a952c..18ec012a1e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Common.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Common.c
@@ -1,7 +1,7 @@
/** @file
The implementation of common functions shared by IP6 driver.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -329,6 +329,38 @@ Ip6AddAddr (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Ip6DestroyChildEntryByAddr (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ IP6_PROTOCOL *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ EFI_IPv6_ADDRESS *Address;
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;
+ Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;
+
+ if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Destroy the IP instance if its StationAddress is removed. It is the help function
for Ip6RemoveAddr().
@@ -342,35 +374,20 @@ Ip6DestroyInstanceByAddress (
IN EFI_IPv6_ADDRESS *Address
)
{
- BOOLEAN OneDestroyed;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- LIST_ENTRY *Entry;
- IP6_PROTOCOL *Instance;
+ LIST_ENTRY *List;
+ IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context;
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
- ServiceBinding = &IpSb->ServiceBinding;
-
- //
- // Upper layer IP protocol consumers may have tight relationship between several
- // IP protocol instances, in other words, calling ServiceBinding->DestroyChild to
- // destroy one IP child may cause other related IP children destroyed too. This
- // will probably leave hole in the children list when we iterate it. So everytime
- // we just destroy one child then back to the start point to iterate the list.
- //
- do {
- OneDestroyed = FALSE;
-
- NET_LIST_FOR_EACH (Entry, &IpSb->Children) {
- Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
-
- if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- OneDestroyed = TRUE;
- break;
- }
- }
- } while (OneDestroyed);
+ List = &IpSb->Children;
+ Context.ServiceBinding = &IpSb->ServiceBinding;
+ Context.Address = Address;
+ NetDestroyLinkList (
+ List,
+ Ip6DestroyChildEntryByAddr,
+ &Context,
+ NULL
+ );
}
/**
diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.h b/NetworkPkg/Ip6Dxe/Ip6Common.h
index c3755f4859..9c2ddf4d4e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Common.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Common.h
@@ -1,7 +1,7 @@
/** @file
Common definition and functions for IP6 driver.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -60,6 +60,11 @@ typedef enum {
Ip6AnyCast
} IP6_ADDRESS_TYPE;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ EFI_IPv6_ADDRESS *Address;
+} IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT;
+
typedef struct _IP6_INTERFACE IP6_INTERFACE;
typedef struct _IP6_PROTOCOL IP6_PROTOCOL;
typedef struct _IP6_SERVICE IP6_SERVICE;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.c b/NetworkPkg/Ip6Dxe/Ip6Driver.c
index 3fd1f73195..8095ed1ae2 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Driver.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Driver.c
@@ -114,14 +114,16 @@ Ip6CleanService (
Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance);
- //
- // Leave link-scope all-nodes multicast address (FF02::1)
- //
- Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
+ if (!IpSb->LinkLocalDadFail) {
+ //
+ // Leave link-scope all-nodes multicast address (FF02::1)
+ //
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
- Status = Ip6LeaveGroup (IpSb, &AllNodes);
- if (EFI_ERROR (Status)) {
- return Status;
+ Status = Ip6LeaveGroup (IpSb, &AllNodes);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
if (IpSb->DefaultInterface != NULL) {
@@ -244,7 +246,6 @@ Ip6CreateService (
IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild;
IpSb->State = IP6_SERVICE_UNSTARTED;
- IpSb->InDestroy = FALSE;
IpSb->NumChildren = 0;
InitializeListHead (&IpSb->Children);
@@ -573,6 +574,44 @@ Ip6DriverBindingStart (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Ip6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ IP6_PROTOCOL *IpInstance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
+}
+
+/**
Stop this driver on ControllerHandle.
@param[in] This Protocol instance pointer.
@@ -595,30 +634,23 @@ Ip6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- IP6_SERVICE *IpSb;
- IP6_PROTOCOL *IpInstance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- BOOLEAN IsDhcp6;
- EFI_TPL OldTpl;
- INTN State;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ IP6_SERVICE *IpSb;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ LIST_ENTRY *List;
+ INTN State;
+ BOOLEAN IsDhcp6;
+ IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
IsDhcp6 = FALSE;
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
-
- if (NicHandle != NULL) {
- //
- // DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6
- // Protocol used by Ip6Config.
- //
- IsDhcp6 = TRUE;
- } else {
-
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
-
- if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
+ if (NicHandle != NULL) {
+ IsDhcp6 = TRUE;
+ } else {
+ return EFI_SUCCESS;
}
}
@@ -636,21 +668,25 @@ Ip6DriverBindingStop (
IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (IpSb->InDestroy) {
- Status = EFI_SUCCESS;
- goto Exit;
- }
-
if (IsDhcp6) {
-
Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance);
gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event);
IpSb->Ip6ConfigInstance.Dhcp6Event = NULL;
- } else if (NumberOfChildren == 0) {
-
- IpSb->InDestroy = TRUE;
+ } else if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer.
+ //
+ List = &IpSb->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Ip6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&IpSb->Children)) {
State = IpSb->State;
IpSb->State = IP6_SERVICE_DESTROY;
@@ -675,24 +711,10 @@ Ip6DriverBindingStop (
);
ASSERT_EFI_ERROR (Status);
FreePool (IpSb);
- } else {
- //
- // NumberOfChildren is not zero, destroy all IP6 children instances.
- //
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link);
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
-
+
Exit:
-
- gBS->RestoreTPL (OldTpl);
-
return Status;
}
@@ -830,7 +852,6 @@ Ip6ServiceBindingDestroyChild (
IP6_PROTOCOL *IpInstance;
EFI_IP6_PROTOCOL *Ip6;
EFI_TPL OldTpl;
- INTN State;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -868,13 +889,12 @@ Ip6ServiceBindingDestroyChild (
// when UDP driver is being stopped, it will destroy all
// the IP child it opens.
//
- if (IpInstance->State == IP6_STATE_DESTROY) {
+ if (IpInstance->InDestroy) {
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
- State = IpInstance->State;
- IpInstance->State = IP6_STATE_DESTROY;
+ IpInstance->InDestroy = TRUE;
//
// Close the Managed Network protocol.
@@ -900,12 +920,13 @@ Ip6ServiceBindingDestroyChild (
// will be called back before preceeding. If any packets not recycled,
// that means there is a resource leak.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiIp6ProtocolGuid,
&IpInstance->Ip6Proto
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
@@ -935,7 +956,6 @@ Ip6ServiceBindingDestroyChild (
return EFI_SUCCESS;
ON_ERROR:
- IpInstance->State = State;
gBS->RestoreTPL (OldTpl);
return Status;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.h b/NetworkPkg/Ip6Dxe/Ip6Driver.h
index 4a23d836b8..d16ff48e2a 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Driver.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Driver.h
@@ -19,6 +19,13 @@
extern EFI_DRIVER_BINDING_PROTOCOL gIp6DriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gIp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable;
+
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+}IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
/**
Clean up an IP6 service binding instance. It releases all
diff --git a/NetworkPkg/Ip6Dxe/Ip6If.c b/NetworkPkg/Ip6Dxe/Ip6If.c
index a934188479..280cd764f1 100644
--- a/NetworkPkg/Ip6Dxe/Ip6If.c
+++ b/NetworkPkg/Ip6Dxe/Ip6If.c
@@ -565,11 +565,7 @@ Ip6ReceiveFrame (
{
EFI_STATUS Status;
IP6_LINK_RX_TOKEN *Token;
-
- if (IpSb->InDestroy) {
- return EFI_INVALID_PARAMETER;
- }
-
+
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
Token = &IpSb->RecvRequest;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.c b/NetworkPkg/Ip6Dxe/Ip6Impl.c
index 44e0392511..365495a5e4 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Impl.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Impl.c
@@ -635,7 +635,7 @@ EfiIp6Configure (
IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
IpSb = IpInstance->Service;
- if (IpSb->LinkLocalDadFail) {
+ if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) {
return EFI_DEVICE_ERROR;
}
@@ -1777,10 +1777,6 @@ EfiIp6Cancel (
IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
IpSb = IpInstance->Service;
- if (IpSb->LinkLocalDadFail) {
- return EFI_DEVICE_ERROR;
- }
-
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (IpInstance->State != IP6_STATE_CONFIGED) {
diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.h b/NetworkPkg/Ip6Dxe/Ip6Impl.h
index 1241e63669..8f114bbb10 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Impl.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Impl.h
@@ -1,7 +1,7 @@
/** @file
Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -68,7 +68,6 @@
//
#define IP6_STATE_UNCONFIGED 0
#define IP6_STATE_CONFIGED 1
-#define IP6_STATE_DESTROY 2
//
// The state of IP6 service. It starts from UNSTARTED. It transits
@@ -157,13 +156,13 @@ struct _IP6_PROTOCOL {
UINT32 GroupCount;
EFI_IP6_CONFIG_DATA ConfigData;
+ BOOLEAN InDestroy;
};
struct _IP6_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN State;
- BOOLEAN InDestroy;
//
// List of all the IP instances and interfaces, and default
diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c
index d510f330c1..9f30f9b20e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Nd.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c
@@ -821,7 +821,8 @@ Ip6OnDADFinished (
UINT16 OptBuf[4];
EFI_DHCP6_PACKET_OPTION *Oro;
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;
-
+ EFI_IPv6_ADDRESS AllNodes;
+
IpSb = IpIf->Service;
AddrInfo = DadEntry->AddressInfo;
@@ -922,6 +923,11 @@ Ip6OnDADFinished (
RemoveEntryList (&DadEntry->Link);
FreePool (DadEntry);
//
+ // Leave link-scope all-nodes multicast address (FF02::1)
+ //
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
+ Ip6LeaveGroup (IpSb, &AllNodes);
+ //
// Disable IP operation since link-local address is a duplicate address.
//
IpSb->LinkLocalDadFail = TRUE;
diff --git a/NetworkPkg/IpSecDxe/ComponentName.c b/NetworkPkg/IpSecDxe/ComponentName.c
index e164d8bbb3..d68b175cc1 100644
--- a/NetworkPkg/IpSecDxe/ComponentName.c
+++ b/NetworkPkg/IpSecDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for IPsec driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -172,6 +172,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecDriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecControllerNameTable[] = {
+ {
+ "eng;en",
+ L"IPsec Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -306,5 +317,35 @@ IpSecComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+
+ //
+ // ChildHandle must be NULL for a Device Driver
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiIpSec2ProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mIpSecControllerNameTable,
+ ControllerName,
+ (BOOLEAN) (This == &gIpSecComponentName)
+ );
}
diff --git a/NetworkPkg/Mtftp6Dxe/ComponentName.c b/NetworkPkg/Mtftp6Dxe/ComponentName.c
index 72a5eb0582..f4327abcf9 100644
--- a/NetworkPkg/Mtftp6Dxe/ComponentName.c
+++ b/NetworkPkg/Mtftp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Mtftp6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp6DriverNameT
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -227,6 +229,74 @@ Mtftp6ComponentNameGetDriverName (
}
/**
+ Update the component name for the Mtftp6 child handle.
+
+ @param Mtftp6[in] A pointer to the EFI_MTFTP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_MTFTP6_PROTOCOL *Mtftp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[128];
+ EFI_MTFTP6_MODE_DATA Mtftp6ModeData;
+ CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ if (Mtftp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Mtftp6->GetModeData (Mtftp6, &Mtftp6ModeData);
+ if (!EFI_ERROR (Status)) {
+ Status = NetLibIp6ToStr (&Mtftp6ModeData.ConfigData.ServerIp, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"MTFTPv6(ServerIp=%s, InitialServerPort=%d)",
+ Address,
+ Mtftp6ModeData.ConfigData.InitialServerPort
+ );
+ } else {
+ UnicodeSPrint (HandleName, 0x100, L"MTFTPv6(%r)", Status);
+ }
+
+ if (gMtftp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMtftp6ControllerNameTable);
+ gMtftp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gMtftp6ComponentName.SupportedLanguages,
+ &gMtftp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gMtftp6ComponentName2.SupportedLanguages,
+ &gMtftp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -304,5 +374,57 @@ Mtftp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_MTFTP6_PROTOCOL *Mtftp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiMtftp6ProtocolGuid,
+ (VOID **)&Mtftp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Mtftp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gMtftp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gMtftp6ComponentName)
+ );
}
+
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
index 432eea9cd4..5f47938c2d 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
@@ -98,7 +98,6 @@ Mtftp6CreateService (
Mtftp6Srv->Signature = MTFTP6_SERVICE_SIGNATURE;
Mtftp6Srv->Controller = Controller;
Mtftp6Srv->Image = Image;
- Mtftp6Srv->InDestroy = FALSE;
Mtftp6Srv->ChildrenNum = 0;
CopyMem (
@@ -238,6 +237,45 @@ Mtftp6CreateInstance (
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Mtftp6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ MTFTP6_INSTANCE *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
+ ServiceBinding = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
+
+/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
both device drivers and bus drivers.
@@ -429,20 +467,20 @@ Mtftp6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- MTFTP6_SERVICE *Service;
- MTFTP6_INSTANCE *Instance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ MTFTP6_SERVICE *Service;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ LIST_ENTRY *List;
+ MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
+
//
// Locate the Nic handle to retrieve the Mtftp6 private data.
//
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -460,18 +498,26 @@ Mtftp6DriverBindingStop (
Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);
- if (Service->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&Service->Children)) {
+ //
+ // Destroy the Mtftp6 child instance in ChildHandleBuffer.
+ //
+ List = &Service->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Mtftp6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) {
//
// Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
//
- Service->InDestroy = TRUE;
-
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp6ServiceBindingProtocolGuid,
@@ -479,22 +525,9 @@ Mtftp6DriverBindingStop (
);
Mtftp6DestroyService (Service);
-
- } else {
- //
- // Destroy the Mtftp6 child instance one by one.
- //
- while (!IsListEmpty (&Service->Children)) {
- Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link);
- Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
- }
-
- if (Service->ChildrenNum != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -674,15 +707,34 @@ Mtftp6ServiceBindingDestroyChild (
ChildHandle
);
+ if (Instance->UdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ gMtftp6DriverBinding.DriverBindingHandle,
+ Instance->Handle
+ );
+ }
+
+ if (Instance->McastUdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ gMtftp6DriverBinding.DriverBindingHandle,
+ Instance->Handle
+ );
+ }
+
//
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiMtftp6ProtocolGuid,
Mtftp6
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
gBS->RestoreTPL (OldTpl);
@@ -695,9 +747,9 @@ Mtftp6ServiceBindingDestroyChild (
RemoveEntryList (&Instance->Link);
Service->ChildrenNum --;
- Mtftp6DestroyInstance (Instance);
-
gBS->RestoreTPL (OldTpl);
+ Mtftp6DestroyInstance (Instance);
+
return EFI_SUCCESS;
}
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
index 3e3165b5e4..55ac1ddffb 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
@@ -2,7 +2,7 @@
Driver Binding functions and Service Binding functions
declaration for Mtftp6 Driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -21,6 +21,7 @@
extern EFI_COMPONENT_NAME_PROTOCOL gMtftp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable;
/**
Test to see if this driver supports Controller. This service
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
index 4a4e5b192c..9b08455ef3 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
@@ -197,6 +197,19 @@ EfiMtftp6Configure (
UDP_IO_UDP6_VERSION,
NULL
);
+ if (Instance->UdpIo != NULL) {
+ Status = gBS->OpenProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **) &Udp6,
+ Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ }
}
if (Instance->UdpIo == NULL) {
@@ -626,8 +639,6 @@ EfiMtftp6Poll (
//
if (Instance->Config == NULL) {
return EFI_NOT_STARTED;
- } else if (Instance->InDestroy) {
- return EFI_DEVICE_ERROR;
}
Udp6 = Instance->UdpIo->Protocol.Udp6;
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
index 68fa0da115..6b1ce7f853 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
@@ -29,6 +29,7 @@
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/NetLib.h>
+#include <Library/PrintLib.h>
typedef struct _MTFTP6_SERVICE MTFTP6_SERVICE;
typedef struct _MTFTP6_INSTANCE MTFTP6_INSTANCE;
@@ -117,9 +118,14 @@ struct _MTFTP6_SERVICE {
// mtftp driver and udp driver.
//
UDP_IO *DummyUdpIo;
- BOOLEAN InDestroy;
};
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Returns the current operating mode data for the MTFTP6 instance.
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
index 7fc613a665..4a481f4b46 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
@@ -453,6 +453,7 @@ Mtftp6RrqHandleOack (
MTFTP6_EXT_OPTION_INFO ExtInfo;
EFI_STATUS Status;
INTN Expected;
+ EFI_UDP6_PROTOCOL *Udp6;
*IsCompleted = FALSE;
@@ -555,6 +556,21 @@ Mtftp6RrqHandleOack (
UDP_IO_UDP6_VERSION,
Instance
);
+ if (Instance->McastUdpIo != NULL) {
+ Status = gBS->OpenProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **) &Udp6,
+ Instance->Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ UdpIoFreeIo (Instance->McastUdpIo);
+ Instance->McastUdpIo = NULL;
+ return EFI_DEVICE_ERROR;
+ }
+ }
}
if (Instance->McastUdpIo == NULL) {
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
index 24ce0e85ba..f5b22313ee 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
@@ -1,7 +1,7 @@
/** @file
Mtftp6 support functions implementation.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -903,6 +903,12 @@ Mtftp6OperationClean (
}
if (Instance->McastUdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ Instance->McastUdpIo->Image,
+ Instance->Handle
+ );
UdpIoFreeIo (Instance->McastUdpIo);
Instance->McastUdpIo = NULL;
}
diff --git a/NetworkPkg/TcpDxe/ComponentName.c b/NetworkPkg/TcpDxe/ComponentName.c
index f1e0e62f73..9b4dada6a0 100644
--- a/NetworkPkg/TcpDxe/ComponentName.c
+++ b/NetworkPkg/TcpDxe/ComponentName.c
@@ -2,7 +2,7 @@
Implementation of protocols EFI_COMPONENT_NAME_PROTOCOL and
EFI_COMPONENT_NAME2_PROTOCOL.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTabl
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -225,6 +227,142 @@ TcpComponentNameGetDriverName (
}
/**
+ Update the component name for the Tcp4 child handle.
+
+ @param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateTcp4Name (
+ IN EFI_TCP4_PROTOCOL *Tcp4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
+
+ if (Tcp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
+ //
+ Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",
+ Tcp4ConfigData.AccessPoint.StationPort,
+ Tcp4ConfigData.AccessPoint.RemotePort,
+ (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
+ );
+ } if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"TCPv4 (Not started)"
+ );
+ } else {
+ return Status;
+ }
+
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gTcpComponentName.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gTcpComponentName2.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
+ Update the component name for the Tcp6 child handle.
+
+ @param Tcp6[in] A pointer to the EFI_TCP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateTcp6Name (
+ IN EFI_TCP6_PROTOCOL *Tcp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_TCP6_CONFIG_DATA Tcp6ConfigData;
+
+ if (Tcp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Tcp6->GetModeData (Tcp6, NULL, &Tcp6ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"TCPv6(SrcPort=%d, DestPort=%d, ActiveFlag=%d)",
+ Tcp6ConfigData.AccessPoint.StationPort,
+ Tcp6ConfigData.AccessPoint.RemotePort,
+ Tcp6ConfigData.AccessPoint.ActiveFlag
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"TCPv6(Not started)");
+ } else {
+ return Status;
+ }
+
+
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gTcpComponentName.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gTcpComponentName2.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -300,5 +438,89 @@ TcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_TCP4_PROTOCOL *Tcp4;
+ EFI_TCP6_PROTOCOL *Tcp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp6ProtocolGuid
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTcp6ProtocolGuid,
+ (VOID **)&Tcp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateTcp6Name (Tcp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp4ProtocolGuid
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTcp4ProtocolGuid,
+ (VOID **)&Tcp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateTcp4Name (Tcp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gTcpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gTcpComponentName)
+ );
}
+
diff --git a/NetworkPkg/TcpDxe/SockInterface.c b/NetworkPkg/TcpDxe/SockInterface.c
index 075e9ada6a..4abda74220 100644
--- a/NetworkPkg/TcpDxe/SockInterface.c
+++ b/NetworkPkg/TcpDxe/SockInterface.c
@@ -146,11 +146,11 @@ SockDestroyChild (
ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));
- if (Sock->IsDestroyed) {
+ if (Sock->InDestroy) {
return EFI_SUCCESS;
}
- Sock->IsDestroyed = TRUE;
+ Sock->InDestroy = TRUE;
Status = EfiAcquireLockOrFail (&(Sock->Lock));
if (EFI_ERROR (Status)) {
@@ -177,7 +177,7 @@ SockDestroyChild (
Status)
);
- Sock->IsDestroyed = FALSE;
+ Sock->InDestroy = FALSE;
} else if (SOCK_IS_CONFIGURED (Sock)) {
SockConnFlush (Sock);
diff --git a/NetworkPkg/TcpDxe/Socket.h b/NetworkPkg/TcpDxe/Socket.h
index 9e2d907150..5a63047f90 100644
--- a/NetworkPkg/TcpDxe/Socket.h
+++ b/NetworkPkg/TcpDxe/Socket.h
@@ -477,7 +477,7 @@ struct _TCP_SOCKET {
SOCK_BUFFER SndBuffer; ///< Send buffer of application's data
SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data
EFI_STATUS SockError; ///< The error returned by low layer protocol
- BOOLEAN IsDestroyed;
+ BOOLEAN InDestroy;
//
// Fields used to manage the connection request
diff --git a/NetworkPkg/TcpDxe/TcpDispatcher.c b/NetworkPkg/TcpDxe/TcpDispatcher.c
index 3e6d34c63f..d3d2cb1c3a 100644
--- a/NetworkPkg/TcpDxe/TcpDispatcher.c
+++ b/NetworkPkg/TcpDxe/TcpDispatcher.c
@@ -354,7 +354,16 @@ TcpAttachPcb (
TCP_CB *Tcb;
TCP_PROTO_DATA *ProtoData;
IP_IO *IpIo;
+ EFI_STATUS Status;
+ VOID *Ip;
+ EFI_GUID *IpProtocolGuid;
+ if (Sk->IpVersion == IP_VERSION_4) {
+ IpProtocolGuid = &gEfiIp4ProtocolGuid;
+ } else {
+ IpProtocolGuid = &gEfiIp6ProtocolGuid;
+ }
+
Tcb = AllocateZeroPool (sizeof (TCP_CB));
if (Tcb == NULL) {
@@ -377,6 +386,22 @@ TcpAttachPcb (
return EFI_OUT_OF_RESOURCES;
}
+ //
+ // Open the new created IP instance BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Tcb->IpInfo->ChildHandle,
+ IpProtocolGuid,
+ &Ip,
+ IpIo->Image,
+ Sk->SockHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ IpIoRemoveIp (IpIo, Tcb->IpInfo);
+ return Status;
+ }
+
InitializeListHead (&Tcb->List);
InitializeListHead (&Tcb->SndQue);
InitializeListHead (&Tcb->RcvQue);
@@ -401,7 +426,14 @@ TcpDetachPcb (
{
TCP_PROTO_DATA *ProtoData;
TCP_CB *Tcb;
+ EFI_GUID *IpProtocolGuid;
+ if (Sk->IpVersion == IP_VERSION_4) {
+ IpProtocolGuid = &gEfiIp4ProtocolGuid;
+ } else {
+ IpProtocolGuid = &gEfiIp6ProtocolGuid;
+ }
+
ProtoData = (TCP_PROTO_DATA *) Sk->ProtoReserved;
Tcb = ProtoData->TcpPcb;
@@ -409,6 +441,16 @@ TcpDetachPcb (
TcpFlushPcb (Tcb);
+ //
+ // Close the IP protocol.
+ //
+ gBS->CloseProtocol (
+ Tcb->IpInfo->ChildHandle,
+ IpProtocolGuid,
+ ProtoData->TcpService->IpIo->Image,
+ Sk->SockHandle
+ );
+
IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
FreePool (Tcb);
diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
index c9ac10c758..74af7969f7 100644
--- a/NetworkPkg/TcpDxe/TcpDriver.c
+++ b/NetworkPkg/TcpDxe/TcpDriver.c
@@ -1,7 +1,7 @@
/** @file
The driver binding and service binding protocol for the TCP driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -323,6 +323,7 @@ ON_ERROR:
if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
}
FreePool (TcpServiceData);
@@ -331,13 +332,53 @@ ON_ERROR:
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+TcpDestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ SOCKET *Sock;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
+ ServiceBinding = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
+}
+
+/**
Destroy a TCP6 or TCP4 service binding instance. It will release all
the resources allocated by the instance.
@param[in] Controller Controller handle of device to bind driver to.
@param[in] ImageHandle The TCP driver's image handle.
- @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
of children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
@retval EFI_SUCCESS The resources used by the instance were cleaned up.
@@ -349,6 +390,7 @@ TcpDestroyService (
IN EFI_HANDLE Controller,
IN EFI_HANDLE ImageHandle,
IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL
IN UINT8 IpVersion
)
{
@@ -358,7 +400,8 @@ TcpDestroyService (
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
TCP_SERVICE_DATA *TcpServiceData;
EFI_STATUS Status;
- SOCKET *Sock;
+ LIST_ENTRY *List;
+ TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
@@ -372,7 +415,7 @@ TcpDestroyService (
NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);
if (NicHandle == NULL) {
- return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -389,7 +432,18 @@ TcpDestroyService (
TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren != 0) {
+ List = &TcpServiceData->SocketList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ TcpDestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&TcpServiceData->SocketList)) {
//
// Uninstall TCP servicebinding protocol
//
@@ -404,6 +458,7 @@ TcpDestroyService (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
@@ -419,16 +474,11 @@ TcpDestroyService (
// Release the TCP service data
//
FreePool (TcpServiceData);
- } else {
-
- while (!IsListEmpty (&TcpServiceData->SocketList)) {
- Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
- }
+ Status = EFI_SUCCESS;
}
- return EFI_SUCCESS;
+ return Status;
}
/**
@@ -595,6 +645,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
+ ChildHandleBuffer,
IP_VERSION_4
);
@@ -602,6 +653,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
+ ChildHandleBuffer,
IP_VERSION_6
);
@@ -839,14 +891,11 @@ TcpServiceBindingDestroyChild (
EFI_STATUS Status;
VOID *Tcp;
SOCKET *Sock;
- EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
return EFI_INVALID_PARAMETER;
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
//
// retrieve the Tcp4 protocol from ChildHandle
//
@@ -885,7 +934,5 @@ TcpServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
- gBS->RestoreTPL (OldTpl);
-
return Status;
}
diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h
index 69c764cde1..bd4434e26b 100644
--- a/NetworkPkg/TcpDxe/TcpMain.h
+++ b/NetworkPkg/TcpDxe/TcpMain.h
@@ -2,7 +2,7 @@
Declaration of protocol interfaces in EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.
It is the common head file for all Tcp*.c in TCP driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -21,6 +21,7 @@
#include <Protocol/DriverBinding.h>
#include <Library/IpIoLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
#include "Socket.h"
#include "TcpProto.h"
@@ -32,6 +33,7 @@ extern UINT16 mTcp6RandomPort;
extern CHAR16 *mTcpStateName[];
extern EFI_COMPONENT_NAME_PROTOCOL gTcpComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gTcpComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
extern LIST_ENTRY mTcpRunQue;
extern LIST_ENTRY mTcpListenQue;
@@ -90,6 +92,12 @@ typedef struct _TCP4_ROUTE_INFO {
EFI_IPv4_ADDRESS *GatewayAddress;
} TCP4_ROUTE_INFO;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
//
// EFI_TCP4_PROTOCOL definitions.
//
diff --git a/NetworkPkg/Udp6Dxe/ComponentName.c b/NetworkPkg/Udp6Dxe/ComponentName.c
index 2511465187..93c2003f34 100644
--- a/NetworkPkg/Udp6Dxe/ComponentName.c
+++ b/NetworkPkg/Udp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for UDP6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdp6DriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -231,6 +233,70 @@ Udp6ComponentNameGetDriverName (
}
/**
+ Update the component name for the Udp6 child handle.
+
+ @param Udp6[in] A pointer to the EFI_UDP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_UDP6_PROTOCOL *Udp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[64];
+ EFI_UDP6_CONFIG_DATA Udp6ConfigData;
+
+ if (Udp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Udp6->GetModeData (Udp6, &Udp6ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"UDPv6 (SrcPort=%d, DestPort=%d)",
+ Udp6ConfigData.StationPort,
+ Udp6ConfigData.RemotePort
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (%r)", Status);
+ }
+
+ if (gUdp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gUdp6ControllerNameTable);
+ gUdp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gUdp6ComponentName.SupportedLanguages,
+ &gUdp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gUdp6ComponentName2.SupportedLanguages,
+ &gUdp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -308,6 +374,56 @@ Udp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_STATUS Status;
+ EFI_UDP6_PROTOCOL *Udp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **)&Udp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Udp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gUdp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUdp6ComponentName)
+ );
+}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Driver.c b/NetworkPkg/Udp6Dxe/Udp6Driver.c
index 1726ebbde4..1c2c33336e 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Driver.c
+++ b/NetworkPkg/Udp6Dxe/Udp6Driver.c
@@ -1,7 +1,7 @@
/** @file
Driver Binding functions and Service Binding functions for the Network driver module.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -179,6 +179,44 @@ EXIT:
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+EFIAPI
+Udp6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+ )
+{
+ UDP6_INSTANCE_DATA *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
+ ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
+}
+
+/**
Stop this driver on ControllerHandle.
This service is called by the EFI boot service DisconnectController(). In order to
@@ -211,14 +249,15 @@ Udp6DriverBindingStop (
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UDP6_SERVICE_DATA *Udp6Service;
- UDP6_INSTANCE_DATA *Instance;
+ LIST_ENTRY *List;
+ UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
//
@@ -238,8 +277,21 @@ Udp6DriverBindingStop (
Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
-
+ if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
+ //
+ List = &Udp6Service->ChildrenList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Udp6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&Udp6Service->ChildrenList)) {
gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiUdp6ServiceBindingProtocolGuid,
@@ -252,13 +304,8 @@ Udp6DriverBindingStop (
Udp6CleanService (Udp6Service);
FreePool (Udp6Service);
- } else {
- while (!IsListEmpty (&Udp6Service->ChildrenList)) {
- Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link);
-
- Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
- }
+ Status = EFI_SUCCESS;
}
return Status;
@@ -351,6 +398,21 @@ Udp6ServiceBindingCreateChild (
goto ON_ERROR;
}
+ //
+ // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ (VOID **) &Ip6,
+ gUdp6DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
@@ -440,17 +502,17 @@ Udp6ServiceBindingDestroyChild (
Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
- if (Instance->Destroyed) {
+ if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
// Use the Destroyed flag to avoid the re-entering of the following code.
//
- Instance->Destroyed = TRUE;
+ Instance->InDestroy = TRUE;
//
- // Close the Ip6 protocol.
+ // Close the Ip6 protocol on the default IpIo.
//
gBS->CloseProtocol (
Udp6Service->IpIo->ChildHandle,
@@ -458,6 +520,15 @@ Udp6ServiceBindingDestroyChild (
gUdp6DriverBinding.DriverBindingHandle,
Instance->ChildHandle
);
+ //
+ // Close the Ip6 protocol on this instance's IpInfo.
+ //
+ gBS->CloseProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ gUdp6DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle
+ );
//
// Uninstall the Udp6Protocol previously installed on the ChildHandle.
@@ -469,7 +540,7 @@ Udp6ServiceBindingDestroyChild (
NULL
);
if (EFI_ERROR (Status)) {
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
return Status;
}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.c b/NetworkPkg/Udp6Dxe/Udp6Impl.c
index 8e259319b9..3830b14415 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Impl.c
+++ b/NetworkPkg/Udp6Dxe/Udp6Impl.c
@@ -1,7 +1,7 @@
/** @file
Udp6 driver's whole implementation.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -363,7 +363,8 @@ ON_ERROR:
}
IpIoDestroy (Udp6Service->IpIo);
-
+ Udp6Service->IpIo = NULL;
+
return Status;
}
@@ -388,6 +389,9 @@ Udp6CleanService (
// Destroy the IpIo.
//
IpIoDestroy (Udp6Service->IpIo);
+ Udp6Service->IpIo = NULL;
+
+ ZeroMem (Udp6Service, sizeof (UDP6_SERVICE_DATA));
}
@@ -491,7 +495,7 @@ Udp6InitInstance (
Instance->IcmpError = EFI_SUCCESS;
Instance->Configured = FALSE;
Instance->IsNoMapping = FALSE;
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.h b/NetworkPkg/Udp6Dxe/Udp6Impl.h
index 108e30b71c..9ca4f4a011 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Impl.h
+++ b/NetworkPkg/Udp6Dxe/Udp6Impl.h
@@ -1,7 +1,7 @@
/** @file
Udp6 driver's whole implementation and internal data structures.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -30,11 +30,13 @@
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#include "Udp6Driver.h"
extern EFI_COMPONENT_NAME2_PROTOCOL gUdp6ComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gUdp6ComponentName;
+extern EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable;
extern EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding;
extern EFI_UDP6_PROTOCOL mUdp6Protocol;
extern UINT16 mUdp6RandomPort;
@@ -97,7 +99,7 @@ typedef struct _UDP6_INSTANCE_DATA {
UINT16 HeadSum;
EFI_STATUS IcmpError;
IP_IO_IP_INFO *IpInfo;
- BOOLEAN Destroyed;
+ BOOLEAN InDestroy;
} UDP6_INSTANCE_DATA;
typedef struct _UDP6_RXDATA_WRAP {
@@ -107,6 +109,12 @@ typedef struct _UDP6_RXDATA_WRAP {
EFI_UDP6_RECEIVE_DATA RxData;
} UDP6_RXDATA_WRAP;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Clean the Udp service context data.
diff --git a/NetworkPkg/UefiPxeBcDxe/ComponentName.c b/NetworkPkg/UefiPxeBcDxe/ComponentName.c
index 05e338a7f9..6e48d4aa18 100644
--- a/NetworkPkg/UefiPxeBcDxe/ComponentName.c
+++ b/NetworkPkg/UefiPxeBcDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for UefiPxeBc driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, 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
@@ -171,6 +171,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTab
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = {
+ {
+ "eng;en",
+ L"PXE Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -307,6 +317,42 @@ PxeBcComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_STATUS Status;
+ EFI_HANDLE NicHandle;
+ PXEBC_PRIVATE_PROTOCOL *Id;
+ if (ControllerHandle == NULL || ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);
+ if (NicHandle == NULL) {
+ NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
+ if (NicHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Try to retrieve the private data by PxeBcPrivate protocol.
+ //
+ Status = gBS->OpenProtocol (
+ NicHandle,
+ &gEfiCallerIdGuid,
+ (VOID **) &Id,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mPxeBcControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gPxeBcComponentName)
+ );
+}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
index 080b751cb1..b29df68bbd 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
@@ -1398,7 +1398,7 @@ PxeBcDriverBindingStop (
if (NicHandle == NULL) {
NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
} else {
IsIpv6 = TRUE;
}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
index c82237be0e..80e56bc06f 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
@@ -1,7 +1,7 @@
/** @file
Support functions declaration for UefiPxeBc Driver.
- Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 2012, 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
@@ -485,4 +485,29 @@ CalcElapsedTime (
IN PXEBC_PRIVATE_DATA *Private
);
+/**
+ Get the Nic handle using any child handle in the IPv4 stack.
+
+ @param[in] ControllerHandle Pointer to child handle over IPv4.
+
+ @return NicHandle The pointer to the Nic handle.
+
+**/
+EFI_HANDLE
+PxeBcGetNicByIp4Children (
+ IN EFI_HANDLE ControllerHandle
+ );
+
+/**
+ Get the Nic handle using any child handle in the IPv6 stack.
+
+ @param[in] ControllerHandle Pointer to child handle over IPv6.
+
+ @return NicHandle The pointer to the Nic handle.
+
+**/
+EFI_HANDLE
+PxeBcGetNicByIp6Children (
+ IN EFI_HANDLE ControllerHandle
+ );
#endif
diff --git a/OptionRomPkg/UndiRuntimeDxe/ComponentName.c b/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
new file mode 100644
index 0000000000..405c6fb372
--- /dev/null
+++ b/OptionRomPkg/UndiRuntimeDxe/ComponentName.c
@@ -0,0 +1,365 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for EFI UNDI32 driver.
+
+Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed
+and made available under the terms and conditions of the BSD License which
+accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "Undi32.h"
+
+//
+// EFI Component Name Functions
+//
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUndiComponentName = {
+ UndiComponentNameGetDriverName,
+ UndiComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UndiComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UndiComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUndiDriverNameTable[] = {
+ {
+ "eng;en",
+ L"UNDI32 Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUndiControllerNameTable[] = {
+ {
+ "eng;en",
+ L"UNDI32 Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mUndiDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gUndiComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+ Currently not implemented.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UndiComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gUndiDriverBinding.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ControllerHandle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
+ (VOID **)&Nii,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mUndiControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUndiComponentName)
+ );
+}
diff --git a/OptionRomPkg/UndiRuntimeDxe/Init.c b/OptionRomPkg/UndiRuntimeDxe/Init.c
index 49ec0d5ded..3d0a3de5cb 100644
--- a/OptionRomPkg/UndiRuntimeDxe/Init.c
+++ b/OptionRomPkg/UndiRuntimeDxe/Init.c
@@ -1015,11 +1015,13 @@ InitializeUndi(
EFI_EVENT Event;
EFI_STATUS Status;
- Status = EfiLibInstallDriverBinding (
+ Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gUndiDriverBinding,
- ImageHandle
+ ImageHandle,
+ &gUndiComponentName,
+ &gUndiComponentName2
);
ASSERT_EFI_ERROR (Status);
diff --git a/OptionRomPkg/UndiRuntimeDxe/Undi32.h b/OptionRomPkg/UndiRuntimeDxe/Undi32.h
index c35f4f3eab..2bc019ef24 100644
--- a/OptionRomPkg/UndiRuntimeDxe/Undi32.h
+++ b/OptionRomPkg/UndiRuntimeDxe/Undi32.h
@@ -1,7 +1,7 @@
/** @file
EFI internal structures for the EFI UNDI driver.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2012, 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,6 +36,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "E100b.h"
+extern EFI_DRIVER_BINDING_PROTOCOL gUndiDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUndiComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gUndiComponentName2;
+
#define MAX_NIC_INTERFACES 16
#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31 0x00010001
diff --git a/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf b/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
index ed8e3be270..654c5fc6a8 100644
--- a/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
+++ b/OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
@@ -2,7 +2,7 @@
# Component description file for Undi module.
#
# This module provides support for Universal Network Driver Interface
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2012, 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
@@ -33,7 +33,7 @@
E100b.c
Decode.c
Init.c
-
+ ComponentName.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c
index 5ab89aa6c6..35d667fe3a 100644
--- a/OvmfPkg/AcpiPlatformDxe/Qemu.c
+++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c
@@ -2,6 +2,9 @@
OVMF ACPI QEMU support
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+
+ Copyright (C) 2012, Red Hat, Inc.
+
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
@@ -196,6 +199,19 @@ typedef struct {
PCI_WINDOW PciWindow64;
} FIRMWARE_DATA;
+typedef struct {
+ UINT8 NameOp;
+ UINT8 RootChar;
+ UINT8 NameChar[4];
+ UINT8 PackageOp;
+ UINT8 PkgLength;
+ UINT8 NumElements;
+ UINT8 DWordPrefix;
+ UINT8 Pm1aCntSlpTyp;
+ UINT8 Pm1bCntSlpTyp;
+ UINT8 Reserved[2];
+} SYSTEM_STATE_PACKAGE;
+
#pragma pack()
@@ -296,6 +312,80 @@ PopulateFwData(
STATIC
+VOID
+EFIAPI
+GetSuspendStates (
+ UINTN *SuspendToRamSize,
+ SYSTEM_STATE_PACKAGE *SuspendToRam,
+ UINTN *SuspendToDiskSize,
+ SYSTEM_STATE_PACKAGE *SuspendToDisk
+ )
+{
+ STATIC CONST SYSTEM_STATE_PACKAGE Template = {
+ 0x08, // NameOp
+ '\\', // RootChar
+ { '_', 'S', 'x', '_' }, // NameChar[4]
+ 0x12, // PackageOp
+ 0x07, // PkgLength
+ 0x01, // NumElements
+ 0x0c, // DWordPrefix
+ 0x00, // Pm1aCntSlpTyp
+ 0x00, // Pm1bCntSlpTyp -- we don't support it
+ { 0x00, 0x00 } // Reserved
+ };
+ RETURN_STATUS Status;
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
+ UINTN FwCfgSize;
+ UINT8 SystemStates[6];
+
+ //
+ // configure defaults
+ //
+ *SuspendToRamSize = sizeof Template;
+ CopyMem (SuspendToRam, &Template, sizeof Template);
+ SuspendToRam->NameChar[2] = '3'; // S3
+ SuspendToRam->Pm1aCntSlpTyp = 1; // PIIX4: STR
+
+ *SuspendToDiskSize = sizeof Template;
+ CopyMem (SuspendToDisk, &Template, sizeof Template);
+ SuspendToDisk->NameChar[2] = '4'; // S4
+ SuspendToDisk->Pm1aCntSlpTyp = 2; // PIIX4: POSCL
+
+ //
+ // check for overrides
+ //
+ Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
+ if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {
+ DEBUG ((DEBUG_INFO, "ACPI using S3/S4 defaults\n"));
+ return;
+ }
+ QemuFwCfgSelectItem (FwCfgItem);
+ QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);
+
+ //
+ // Each byte corresponds to a system state. In each byte, the MSB tells us
+ // whether the given state is enabled. If so, the three LSBs specify the
+ // value to be written to the PM control register's SUS_TYP bits.
+ //
+ if (SystemStates[3] & BIT7) {
+ SuspendToRam->Pm1aCntSlpTyp = SystemStates[3] & (BIT2 | BIT1 | BIT0);
+ DEBUG ((DEBUG_INFO, "ACPI S3 value: %d\n", SuspendToRam->Pm1aCntSlpTyp));
+ } else {
+ *SuspendToRamSize = 0;
+ DEBUG ((DEBUG_INFO, "ACPI S3 disabled\n"));
+ }
+
+ if (SystemStates[4] & BIT7) {
+ SuspendToDisk->Pm1aCntSlpTyp = SystemStates[4] & (BIT2 | BIT1 | BIT0);
+ DEBUG ((DEBUG_INFO, "ACPI S4 value: %d\n", SuspendToDisk->Pm1aCntSlpTyp));
+ } else {
+ *SuspendToDiskSize = 0;
+ DEBUG ((DEBUG_INFO, "ACPI S4 disabled\n"));
+ }
+}
+
+
+STATIC
EFI_STATUS
EFIAPI
QemuInstallAcpiSsdtTable (
@@ -312,10 +402,16 @@ QemuInstallAcpiSsdtTable (
FwData = AllocateReservedPool (sizeof (*FwData));
if (FwData != NULL) {
- UINTN SsdtSize;
- UINT8 *Ssdt;
-
- SsdtSize = AcpiTableBufferSize + 17;
+ UINTN SuspendToRamSize;
+ SYSTEM_STATE_PACKAGE SuspendToRam;
+ UINTN SuspendToDiskSize;
+ SYSTEM_STATE_PACKAGE SuspendToDisk;
+ UINTN SsdtSize;
+ UINT8 *Ssdt;
+
+ GetSuspendStates (&SuspendToRamSize, &SuspendToRam,
+ &SuspendToDiskSize, &SuspendToDisk);
+ SsdtSize = AcpiTableBufferSize + 17 + SuspendToRamSize + SuspendToDiskSize;
Ssdt = AllocatePool (SsdtSize);
if (Ssdt != NULL) {
@@ -352,6 +448,14 @@ QemuInstallAcpiSsdtTable (
*(UINT32*) SsdtPtr = sizeof (*FwData);
SsdtPtr += 4;
+ //
+ // add suspend system states
+ //
+ CopyMem (SsdtPtr, &SuspendToRam, SuspendToRamSize);
+ SsdtPtr += SuspendToRamSize;
+ CopyMem (SsdtPtr, &SuspendToDisk, SuspendToDiskSize);
+ SsdtPtr += SuspendToDiskSize;
+
ASSERT((UINTN) (SsdtPtr - Ssdt) == SsdtSize);
((EFI_ACPI_DESCRIPTION_HEADER *) Ssdt)->Length = (UINT32) SsdtSize;
Status = InstallAcpiTable (AcpiProtocol, Ssdt, SsdtSize, TableKey);
diff --git a/OvmfPkg/AcpiTables/Dsdt.asl b/OvmfPkg/AcpiTables/Dsdt.asl
index bd57a731e3..12a4f142af 100644
--- a/OvmfPkg/AcpiTables/Dsdt.asl
+++ b/OvmfPkg/AcpiTables/Dsdt.asl
@@ -16,9 +16,11 @@ DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {
//
// System Sleep States
//
- Name (\_S0, Package () {5, 0, 0, 0})
- Name (\_S4, Package () {1, 0, 0, 0})
- Name (\_S5, Package () {0, 0, 0, 0})
+ // We build S3 and S4 with GetSuspendStates() in
+ // "OvmfPkg/AcpiPlatformDxe/Qemu.c".
+ //
+ Name (\_S0, Package () {5, 0, 0, 0}) // Working
+ Name (\_S5, Package () {0, 0, 0, 0}) // Soft Off
//
// System Bus
diff --git a/OvmfPkg/README b/OvmfPkg/README
index 51041a0551..8db4cac0dc 100644
--- a/OvmfPkg/README
+++ b/OvmfPkg/README
@@ -13,11 +13,12 @@ Current status: Alpha
Current capabilities:
* IA32 and X64 architectures
-* QEMU (0.9.1 or later)
+* QEMU (0.10.0 or later)
- Video, keyboard, IDE, CD-ROM, serial
- Runs UEFI shell
- Optional NIC support. Requires QEMU (0.12.2 or later)
-* UEFI Linux has booted (but is not stable)
+* UEFI Linux boots
+* UEFI Windows 8 boots
=== FUTURE PLANS ===
diff --git a/PandaBoardPkg/build.sh b/PandaBoardPkg/build.sh
index 3c2c7a0c5c..8002eac264 100755
--- a/PandaBoardPkg/build.sh
+++ b/PandaBoardPkg/build.sh
@@ -53,6 +53,11 @@ fi
#
# Pick a default tool type for a given OS if no toolchain already defined
#
+if [ X"$TOOLCHAIN" != X"" ]
+then
+ TARGET_TOOLS="$TOOLCHAIN"
+fi
+
if [ -z "${TARGET_TOOLS:-}" ]
then
case `uname` in
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh
index 0cdf3eead9..dee12604aa 100755
--- a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh
@@ -1,15 +1,68 @@
#!/bin/bash
-
+# set the default image filename, this can be overwritten by a parameter
IMAGE=../../../../Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd
-if [ $# -ne 2 ]
+# set the default SoC, this can be overwritten by a parameter
+SOC=5250
+
+function usage
+{
+ echo "Usage: $0"
+ echo " --disk path to the SD card device to write to, eg /dev/sdd"
+ echo " This can be found by looking at dmesg output"
+ echo " --image The image to write to the SD card"
+ echo " This defaults to:"
+ echo " $IMAGE"
+ echo " --soc Which SoC we are using"
+ echo " This defaults to: 5250"
+}
+
+while [ "$1" != "" ]; do
+ case $1 in
+ -s | --soc )
+ shift
+ SOC=$1
+ ;;
+
+ -d | --disk )
+ shift
+ DISK=$1
+ ;;
+
+ -i | --image )
+ shift
+ IMAGE=$1
+ ;;
+
+ /h | /? | -? | -h | --help )
+ usage
+ exit
+ ;;
+ -* )
+ usage
+ echo "unknown arg $1"
+ exit 1
+ esac
+ shift
+done
+
+echo "Config:"
+echo "IMAGE $IMAGE"
+echo "SoC $SOC"
+echo "DISK $DISK"
+
+
+if [ ! -b "$DISK" ]
+then
+ echo "You must specify a valid --disk option"
+ exit 1
+fi
+
+if [ ! -f $IMAGE ]
then
echo ""
- echo "ERROR: Not input parameter for making image"
- echo ""
- echo "USAGE:"
- echo " sudo ./imgburn.sh 5250 /dev/sdb"
+ echo "ERROR: UEFI image $IMAGE does not exist.."
echo ""
exit
fi
@@ -21,25 +74,21 @@ then
fi
# make BL2
-if [ -f $IMAGE ]
+./mkbl2 $IMAGE
+
+if [ ! -f fwbl2.bin ]
then
- ./mkbl2 $IMAGE
- echo "BL2 image is created."
- echo ""
- echo ":::: You SHOULD check platform of ARNDALE_EFI.fd"
- echo ""
-else
echo ""
- echo "ERROR: UEFI is not built.."
+ echo "ERROR: Failed to create BL2 image."
echo ""
exit
fi
# select platform
-if [ "$1" = "5250" ]
+if [ "$SOC" = "5250" ]
then
# write BL1
- dd if=./5250/fwbl1_5250.bin of=$2 seek=1 count=16
+ dd if=./5250/fwbl1_5250.bin of=$DISK seek=1 count=16
else
echo ""
echo "ERROR: Please select platform.."
@@ -49,9 +98,9 @@ fi
# write BL2
-dd if=./fwbl2.bin of=$2 seek=17 count=32
+dd if=./fwbl2.bin of=$DISK seek=17 count=32
# write bootloader file e.g. u-boot or UEFI firmware image
-dd if=$IMAGE of=$2 seek=49
+dd if=$IMAGE of=$DISK seek=49
sync
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
index c41a379b8a..3b4fc57cb2 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
@@ -715,14 +715,15 @@ AddImageExeInfo (
if (Name != NULL) {
NameStringLen = StrSize (Name);
+ } else {
+ NameStringLen = sizeof (CHAR16);
}
- ImageExeInfoTable = NULL;
EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **) &ImageExeInfoTable);
if (ImageExeInfoTable != NULL) {
//
// The table has been found!
- // We must enlarge the table to accmodate the new exe info entry.
+ // We must enlarge the table to accomodate the new exe info entry.
//
ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);
} else {
@@ -755,6 +756,8 @@ AddImageExeInfo (
if (Name != NULL) {
CopyMem ((UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32), Name, NameStringLen);
+ } else {
+ ZeroMem ((UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32), sizeof (CHAR16));
}
CopyMem (
(UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32) + NameStringLen,
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
index e683783fa5..5f023dfdee 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
@@ -521,6 +521,7 @@ GetEndPointer (
@param IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param UpdatingVariable Pointer to updating variable.
+ @param ReclaimAnyway If TRUE, do reclaim anyway.
@return EFI_OUT_OF_RESOURCES
@return EFI_SUCCESS
@@ -532,7 +533,8 @@ Reclaim (
IN EFI_PHYSICAL_ADDRESS VariableBase,
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
- IN VARIABLE_HEADER *UpdatingVariable
+ IN VARIABLE_HEADER *UpdatingVariable,
+ IN BOOLEAN ReclaimAnyway
)
{
VARIABLE_HEADER *Variable;
@@ -555,7 +557,9 @@ Reclaim (
CHAR16 *UpdatingVariableNamePtr;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
+ BOOLEAN NeedDoReclaim;
+ NeedDoReclaim = FALSE;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
CommonVariableTotalSize = 0;
@@ -574,11 +578,18 @@ Reclaim (
) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
MaximumBufferSize += VariableSize;
+ } else {
+ NeedDoReclaim = TRUE;
}
Variable = NextVariable;
}
+ if (!ReclaimAnyway && !NeedDoReclaim) {
+ DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
+ return EFI_SUCCESS;
+ }
+
//
// Reserve the 1 Bytes with Oxff to identify the
// end of the variable buffer.
@@ -1524,6 +1535,7 @@ UpdateVariable (
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
if (!Variable->Volatile) {
CacheVariable->CurrPtr->State = State;
+ FlushHobVariableToFlash (VariableName, VendorGuid);
}
}
goto Done;
@@ -1733,7 +1745,7 @@ UpdateVariable (
// Perform garbage collection & reclaim operation.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
- &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1848,7 +1860,7 @@ UpdateVariable (
// Perform garbage collection & reclaim operation.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
- &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);
+ &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1905,6 +1917,9 @@ UpdateVariable (
if (!EFI_ERROR (Status)) {
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
+ if (!Volatile) {
+ FlushHobVariableToFlash (VariableName, VendorGuid);
+ }
}
Done:
@@ -2613,12 +2628,102 @@ ReclaimForOS(
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
- NULL
+ NULL,
+ FALSE
);
ASSERT_EFI_ERROR (Status);
}
}
+/**
+ Flush the HOB variable to flash.
+
+ @param[in] VariableName Name of variable has been updated or deleted.
+ @param[in] VendorGuid Guid of variable has been updated or deleted.
+
+**/
+VOID
+FlushHobVariableToFlash (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_HEADER *Variable;
+ VOID *VariableData;
+ BOOLEAN ErrorFlag;
+
+ ErrorFlag = FALSE;
+
+ //
+ // Flush the HOB variable to flash.
+ //
+ if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
+ //
+ // Set HobVariableBase to 0, it can avoid SetVariable to call back.
+ //
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
+ for ( Variable = GetStartPointer (VariableStoreHeader)
+ ; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
+ ; Variable = GetNextVariablePtr (Variable)
+ ) {
+ if (Variable->State != VAR_ADDED) {
+ //
+ // The HOB variable has been set to DELETED state in local.
+ //
+ continue;
+ }
+ ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
+ if (VendorGuid == NULL || VariableName == NULL ||
+ !CompareGuid (VendorGuid, &Variable->VendorGuid) ||
+ StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
+ VariableData = GetVariableDataPtr (Variable);
+ Status = VariableServiceSetVariable (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ Variable->Attributes,
+ Variable->DataSize,
+ VariableData
+ );
+ DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", &Variable->VendorGuid, GetVariableNamePtr (Variable), Status));
+ } else {
+ //
+ // The updated or deleted variable is matched with the HOB variable.
+ // Don't break here because we will try to set other HOB variables
+ // since this variable could be set successfully.
+ //
+ Status = EFI_SUCCESS;
+ }
+ if (!EFI_ERROR (Status)) {
+ //
+ // If set variable successful, or the updated or deleted variable is matched with the HOB variable,
+ // set the HOB variable to DELETED state in local.
+ //
+ DEBUG ((EFI_D_INFO, "Variable driver set the HOB variable to DELETED state in local: %g %s\n", &Variable->VendorGuid, GetVariableNamePtr (Variable)));
+ Variable->State &= VAR_DELETED;
+ } else {
+ ErrorFlag = TRUE;
+ }
+ }
+ if (ErrorFlag) {
+ //
+ // We still have HOB variable(s) not flushed in flash.
+ //
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
+ } else {
+ //
+ // All HOB variables have been flushed in flash.
+ //
+ DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));
+ if (!AtRuntime ()) {
+ FreePool ((VOID *) VariableStoreHeader);
+ }
+ }
+ }
+
+}
/**
Initializes variable write service after FVB was ready.
@@ -2637,8 +2742,6 @@ VariableWriteServiceInitialize (
UINTN Index;
UINT8 Data;
EFI_PHYSICAL_ADDRESS VariableStoreBase;
- VARIABLE_HEADER *Variable;
- VOID *VariableData;
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
@@ -2656,7 +2759,8 @@ VariableWriteServiceInitialize (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
- NULL
+ NULL,
+ TRUE
);
if (EFI_ERROR (Status)) {
return Status;
@@ -2665,34 +2769,7 @@ VariableWriteServiceInitialize (
}
}
-
- //
- // Flush the HOB variable to flash and invalidate HOB variable.
- //
- if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
- //
- // Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB
- //
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
- mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
-
- for ( Variable = GetStartPointer (VariableStoreHeader)
- ; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
- ; Variable = GetNextVariablePtr (Variable)
- ) {
- ASSERT (Variable->State == VAR_ADDED);
- ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
- VariableData = GetVariableDataPtr (Variable);
- Status = VariableServiceSetVariable (
- GetVariableNamePtr (Variable),
- &Variable->VendorGuid,
- Variable->Attributes,
- Variable->DataSize,
- VariableData
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
+ FlushHobVariableToFlash (NULL, NULL);
//
// Authenticated variable initialize.
@@ -2750,8 +2827,12 @@ VariableCommonInitialize (
GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
if (GuidHob != NULL) {
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
+ VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
- mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
+ mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);
+ if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
} else {
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
}
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
index 563485f929..6a51bcce2a 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
@@ -100,6 +100,19 @@ typedef struct {
} VARIABLE_CACHE_ENTRY;
/**
+ Flush the HOB variable to flash.
+
+ @param[in] VariableName Name of variable has been updated or deleted.
+ @param[in] VendorGuid Guid of variable has been updated or deleted.
+
+**/
+VOID
+FlushHobVariableToFlash (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ );
+
+/**
Writes a buffer to variable storage space, in the working block.
This function writes a buffer to variable storage space into a firmware
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
index c8ee79a1ec..316845f045 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
@@ -451,7 +451,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -473,7 +473,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -504,7 +504,7 @@ SmmVariableHandler (
//
// SMRAM range check already covered before
//
- if (InfoSize > *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data)) {
+ if (InfoSize > *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
@@ -534,7 +534,7 @@ SmmVariableHandler (
case SMM_VARIABLE_FUNCTION_GET_STATISTICS:
VariableInfo = (VARIABLE_INFO_ENTRY *) SmmVariableFunctionHeader->Data;
- InfoSize = *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
+ InfoSize = *CommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
//
// Do not need to check SmmVariableFunctionHeader->Data in SMRAM here.
@@ -548,7 +548,7 @@ SmmVariableHandler (
}
Status = SmmVariableGetStatistics (VariableInfo, &InfoSize);
- *CommBufferSize = InfoSize + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);
+ *CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
break;
default:
diff --git a/ShellPkg/Application/Shell/Shell.uni b/ShellPkg/Application/Shell/Shell.uni
index 71484b441e..b9ddcaed61 100644
--- a/ShellPkg/Application/Shell/Shell.uni
+++ b/ShellPkg/Application/Shell/Shell.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
index fb44768c0b..66a242f66f 100644
--- a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
+++ b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
@@ -334,6 +334,16 @@ ShellCommandRegisterCommandName (
)
{
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
+ SHELL_COMMAND_INTERNAL_LIST_ENTRY *Command;
+ SHELL_COMMAND_INTERNAL_LIST_ENTRY *PrevCommand;
+ INTN LexicalMatchValue;
+
+ //
+ // Initialize local variables.
+ //
+ Command = NULL;
+ PrevCommand = NULL;
+ LexicalMatchValue = 0;
//
// ASSERTs for NULL parameters
@@ -392,9 +402,40 @@ ShellCommandRegisterCommandName (
}
//
- // add the new struct to the list
+ // Insert a new entry on top of the list
//
- InsertTailList (&mCommandList.Link, &Node->Link);
+ InsertHeadList (&mCommandList.Link, &Node->Link);
+
+ //
+ // Move a new registered command to its sorted ordered location in the list
+ //
+ for (Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode (&mCommandList.Link),
+ PrevCommand = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetFirstNode (&mCommandList.Link)
+ ; !IsNull (&mCommandList.Link, &Command->Link)
+ ; Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *)GetNextNode (&mCommandList.Link, &Command->Link)) {
+
+ //
+ // Get Lexical Comparison Value between PrevCommand and Command list entry
+ //
+ LexicalMatchValue = gUnicodeCollation->StriColl (
+ gUnicodeCollation,
+ PrevCommand->CommandString,
+ Command->CommandString
+ );
+
+ //
+ // Swap PrevCommand and Command list entry if PrevCommand list entry
+ // is alphabetically greater than Command list entry
+ //
+ if (LexicalMatchValue > 0){
+ Command = (SHELL_COMMAND_INTERNAL_LIST_ENTRY *) SwapListEntries (&PrevCommand->Link, &Command->Link);
+ } else if (LexicalMatchValue < 0) {
+ //
+ // PrevCommand entry is lexically lower than Command entry
+ //
+ break;
+ }
+ }
return (RETURN_SUCCESS);
}
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
index dfee96bb29..ff628b782a 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
@@ -74,7 +74,7 @@ DisplayMmioMemory(
ShellStatus = SHELL_NOT_FOUND;
} else {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_MMIO_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size);
- DumpHex(2,0,Size,Buffer);
+ DumpHex(2, (UINTN)Address, Size, Buffer);
}
FreePool(Buffer);
@@ -168,7 +168,7 @@ ShellCommandRunDmem (
if (ShellStatus == SHELL_SUCCESS) {
if (!ShellCommandLineGetFlag(Package, L"-mmio")) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMEM_HEADER_ROW), gShellDebug1HiiHandle, (UINT64)(UINTN)Address, Size);
- DumpHex(2,0,(UINTN)Size,Address);
+ DumpHex(2, (UINTN)Address, (UINTN)Size, Address);
if (Address == (VOID*)gST) {
Acpi20TableAddress = 0;
AcpiTableAddress = 0;
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
index b6f3847992..be8b7c6c53 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
@@ -3953,7 +3953,7 @@ DisplayPMAUse (
IN UINT8 Option
)
{
- ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_LOCATION), gShellDebug1HiiHandle);
+ ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_QUERYTABLE_PHYS_MEM_ARRAY_USE), gShellDebug1HiiHandle);
PRINT_INFO_OPTION (Use, Option);
PRINT_TABLE_ITEM (PMAUseTable, Use);
}
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c
index 95627a545c..1f0d0be710 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosView.c
@@ -325,6 +325,12 @@ SMBiosView (
if (!RandomView) {
break;
}
+ //
+ // Support Execution Interrupt.
+ //
+ if (ShellGetExecutionBreakFlag ()) {
+ return EFI_ABORTED;
+ }
}
ShellPrintEx(-1,-1,L"\n=========================================================\n");
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
index e50995c58f..ea5df85c05 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
index 75e0de2fa2..1d72ea6c3a 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
@@ -180,7 +180,7 @@ DumpHex (
Val[Index * 3] = 0;
Str[Index] = 0;
- ShellPrintEx(-1, -1, L"%*a%02X: %-.48a *%a*\r\n", Indent, "", Offset, Val, Str);
+ ShellPrintEx(-1, -1, L"%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str);
Data += Size;
Offset += Size;
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
index caf852ee4f..2dfb808c0d 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
index 9ffad7ec04..4354b140f6 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.uni b/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.uni
index 1c6a04108d..81ef1b2ce2 100644
--- a/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni
index e9dec01bf2..c2020ca7f7 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c b/ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c
index 1c643b0e57..7e9d039f15 100644
--- a/ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c
+++ b/ShellPkg/Library/UefiShellLevel3CommandsLib/Help.c
@@ -48,7 +48,9 @@ ShellCommandRunHelp (
CHAR16 *SectionToGetHelpOn;
CHAR16 *HiiString;
BOOLEAN Found;
+ BOOLEAN HelpPage;
+ HelpPage = FALSE;
ProblemParam = NULL;
ShellStatus = SHELL_SUCCESS;
OutText = NULL;
@@ -109,6 +111,7 @@ ShellCommandRunHelp (
ASSERT(SectionToGetHelpOn == NULL);
StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME", 0);
} else {
+ HelpPage = TRUE;
ASSERT(SectionToGetHelpOn == NULL);
//
// Get the section name for the given command name
@@ -119,7 +122,10 @@ ShellCommandRunHelp (
StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS", 0);
} else if (ShellCommandLineGetFlag(Package, L"-verbose") || ShellCommandLineGetFlag(Package, L"-v")) {
} else {
- StrnCatGrow(&SectionToGetHelpOn, NULL, L"NAME", 0);
+ //
+ // The output of help <command> will display NAME, SYNOPSIS, OPTIONS, DESCRIPTION, and EXAMPLES sections.
+ //
+ StrnCatGrow (&SectionToGetHelpOn, NULL, L"NAME,SYNOPSIS,OPTIONS,DESCRIPTION,EXAMPLES", 0);
}
}
@@ -139,6 +145,12 @@ ShellCommandRunHelp (
; CommandList != NULL && !IsListEmpty(&CommandList->Link) && !IsNull(&CommandList->Link, &Node->Link)
; Node = (COMMAND_LIST*)GetNextNode(&CommandList->Link, &Node->Link)
){
+ //
+ // Checking execution break flag when print multiple command help information.
+ //
+ if (ShellGetExecutionBreakFlag ()) {
+ break;
+ }
if ((gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, CommandToGetHelpOn)) ||
(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL) != NULL && (gUnicodeCollation->MetaiMatch(gUnicodeCollation, Node->CommandString, (CHAR16*)(gEfiShellProtocol->GetAlias(CommandToGetHelpOn, NULL)))))) {
//
@@ -153,16 +165,44 @@ ShellCommandRunHelp (
}
ShellStatus = SHELL_NOT_FOUND;
} else {
- while (OutText[StrLen(OutText)-1] == L'\r' || OutText[StrLen(OutText)-1] == L'\n' || OutText[StrLen(OutText)-1] == L' ') {
- OutText[StrLen(OutText)-1] = CHAR_NULL;
+ if (HelpPage) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_PAGE_COMMAND), gShellLevel3HiiHandle, OutText);
+ } else {
+ while (OutText[StrLen(OutText)-1] == L'\r' || OutText[StrLen(OutText)-1] == L'\n' || OutText[StrLen(OutText)-1] == L' ') {
+ OutText[StrLen(OutText)-1] = CHAR_NULL;
+ }
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_COMMAND), gShellLevel3HiiHandle, Node->CommandString, OutText);
}
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HELP_COMMAND), gShellLevel3HiiHandle, Node->CommandString, OutText);
FreePool(OutText);
OutText = NULL;
Found = TRUE;
}
}
}
+ //
+ // Search the .man file for Shell applications (Shell external commands).
+ //
+ if (!Found) {
+ Status = gEfiShellProtocol->GetHelpText (CommandToGetHelpOn, SectionToGetHelpOn, &OutText);
+ if (EFI_ERROR(Status) || OutText == NULL) {
+ if (Status == EFI_DEVICE_ERROR) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_INV), gShellLevel3HiiHandle, CommandToGetHelpOn);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_NF), gShellLevel3HiiHandle, CommandToGetHelpOn);
+ }
+ ShellStatus = SHELL_NOT_FOUND;
+ } else {
+ while (OutText[StrLen (OutText) - 1] == L'\r' || OutText[StrLen (OutText) - 1] == L'\n' || OutText[StrLen (OutText) - 1] == L' ') {
+ OutText[StrLen (OutText)-1] = CHAR_NULL;
+ }
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HELP_COMMAND), gShellLevel3HiiHandle, CommandToGetHelpOn, OutText);
+ if (OutText != NULL) {
+ FreePool (OutText);
+ OutText = NULL;
+ }
+ Found = TRUE;
+ }
+ }
}
if (!Found && ShellStatus == SHELL_SUCCESS) {
diff --git a/ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.uni b/ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.uni
index db91f5b8cc..bf5714c9a0 100644
--- a/ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.uni
Binary files differ
diff --git a/StdLib/Include/Containers/Fifo.h b/StdLib/Include/Containers/Fifo.h
new file mode 100644
index 0000000000..3b232fec23
--- /dev/null
+++ b/StdLib/Include/Containers/Fifo.h
@@ -0,0 +1,206 @@
+/** @file
+ Class for arbitrary sized FIFO queues.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _FIFO_CLASS_H
+#define _FIFO_CLASS_H
+#include <Uefi.h>
+#include <wchar.h>
+#include <Containers/ModuloUtil.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+typedef struct _FIFO_CLASS cFIFO;
+
+/// Constants to select what is counted by the FIFO_NumInQueue function.
+typedef enum {
+ AsElements, ///< Count the number of readable elements in the queue.
+ AsBytes ///< Count the number of readable bytes in the queue.
+} FIFO_ElemBytes;
+
+/** Construct a new instance of a FIFO Queue.
+
+ @param[in] NumElements Number of elements to be contained in the new FIFO.
+ @param[in] ElementSize Size, in bytes, of an element
+
+ @retval NULL Unable to create the instance.
+ @retval NonNULL Pointer to the new FIFO instance.
+**/
+cFIFO * EFIAPI New_cFIFO(UINT32 NumElements, size_t ElementSize);
+
+/** Add one or more elements to the FIFO.
+
+ This function allows one to add one or more elements, as specified by Count,
+ to the FIFO. Each element is of the size specified when the FIFO object
+ was instantiated (FIFO.ElementSize).
+
+ pElement points to the first byte of the first element to be added.
+ If multiple elements are to be added, the elements are expected to be
+ organized as a packed array.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] pElement Pointer to the element(s) to enqueue (add).
+ @param[in] Count Number of elements to add.
+
+ @retval 0 The FIFO is full.
+ @retval >=0 The number of elements added to the FIFO.
+**/
+typedef size_t (EFIAPI *cFIFO_Enqueue) (cFIFO *Self, const void *ElementPointer, size_t Count);
+
+/** Read or copy elements from the FIFO.
+
+ This function allows one to read one or more elements, as specified by Count,
+ from the FIFO. Each element is of the size specified when the FIFO object
+ was instantiated (FIFO.ElementSize).
+
+ pElement points to the destination of the first byte of the first element
+ to be read. If multiple elements are to be read, the elements are expected
+ to be organized as a packed array.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[out] pElement Pointer to where to store the element(s) read from the FIFO.
+ @param[in] Count Number of elements to dequeue.
+ @param[in] Consume If TRUE, consume read elements. Otherwise, preserve.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of elements read from the FIFO.
+**/
+typedef size_t (EFIAPI *cFIFO_Dequeue) (cFIFO *Self, void *ElementPointer, size_t Count);
+
+/** Make a copy of the FIFO's data.
+ The contents of the FIFO is copied out and linearized without affecting the
+ FIFO contents.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[out] ElementPointer Pointer to where to store the elements copied from the FIFO.
+ @param[in] Count Number of elements to copy.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of elements copied from the FIFO.
+**/
+typedef size_t (EFIAPI *cFIFO_Copy) (cFIFO *Self, void *ElementPointer, size_t Count);
+
+/** Test whether the FIFO is empty.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @retval TRUE The FIFO is empty.
+ @retval FALSE The FIFO is NOT empty.
+**/
+typedef BOOLEAN (EFIAPI *cFIFO_IsEmpty) (cFIFO *Self);
+
+/** Test whether the FIFO is full.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @retval TRUE The FIFO is full.
+ @retval FALSE The FIFO is NOT full.
+**/
+typedef BOOLEAN (EFIAPI *cFIFO_IsFull) (cFIFO *Self);
+
+/** Determine number of items available to read from the FIFO.
+
+ The number of items are either the number of bytes, or the number of elements
+ depending upon the value of the As enumerator.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] As An enumeration variable whose value determines whether the
+ returned value is the number of bytes or the number of elements
+ currently contained by the FIFO.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of items contained in the FIFO.
+**/
+typedef size_t (EFIAPI *cFIFO_NumInQueue) (cFIFO *Self, FIFO_ElemBytes As);
+
+/** Determine amount of free space in the FIFO that can be written into.
+
+ The number of items are either the number of bytes, or the number of elements
+ depending upon the value of the As enumerator.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] As An enumeration variable whose value determines whether the
+ returned value is the number of bytes or the number of elements
+ currently available in the FIFO.
+
+ @retval 0 The FIFO is full.
+ @retval >=0 The number of items which can be accepted by the FIFO.
+**/
+typedef size_t (EFIAPI *cFIFO_FreeSpace) (cFIFO *Self, FIFO_ElemBytes As);
+
+/** Empty the FIFO, discarding up to NumToFlush elements.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] NumToFlush Number of elements to flush from the FIFO.
+ If larger than the number of elements in the
+ FIFO, the FIFO is emptied.
+
+ @return Returns the number of elements remaining in the FIFO after the flush.
+**/
+typedef size_t (EFIAPI *cFIFO_Flush) (cFIFO *Self, size_t NumToFlush);
+
+/** Remove the most recent element from the FIFO.
+
+ @param[in] Self Pointer to the FIFO instance.
+**/
+typedef void (EFIAPI *cFIFO_Truncate) (cFIFO *Self);
+
+/** Cleanly delete a FIFO instance.
+
+ @param[in] Self Pointer to the FIFO instance.
+**/
+typedef void (EFIAPI *cFIFO_Delete) (cFIFO *Self);
+
+/** Get the FIFO's current Read Index.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @return The current value of the FIFO's ReadIndex member is returned.
+**/
+typedef UINT32 (EFIAPI *cFIFO_GetRDex) (cFIFO *Self);
+
+/** Get the FIFO's current Write Index.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @return The current value of the FIFO's WriteIndex member is returned.
+**/
+typedef UINT32 (EFIAPI *cFIFO_GetWDex) (cFIFO *Self);
+
+/// Structure declaration for FIFO objects.
+struct _FIFO_CLASS {
+ /* ######## Public Functions ######## */
+ cFIFO_Enqueue Write; ///< Write an element into the FIFO.
+ cFIFO_Dequeue Read; ///< Read an element from the FIFO.
+ cFIFO_Copy Copy; ///< Non-destructive copy from FIFO.
+ cFIFO_IsEmpty IsEmpty; ///< Test whether the FIFO is empty.
+ cFIFO_IsFull IsFull; ///< Test whether the FIFO is full.
+ cFIFO_NumInQueue Count; ///< Return the number of elements contained in the FIFO.
+ cFIFO_FreeSpace FreeSpace; ///< Return the number of available elements in the FIFO.
+ cFIFO_Flush Flush; ///< Remove the N earliest elements from the FIFO.
+ cFIFO_Truncate Truncate; ///< Remove the most recent element from the FIFO.
+ cFIFO_Delete Delete; ///< Delete the FIFO object.
+
+ /* ######## Protected Functions ######## */
+ cFIFO_GetRDex GetRDex; ///< Get a copy of the current Read Index.
+ cFIFO_GetWDex GetWDex; ///< Get a copy of the current Write Index.
+
+ /* ######## PRIVATE Data ######## */
+ void *Queue; ///< The FIFO's data storage.
+ UINT32 ElementSize; ///< Number of bytes in an element.
+ UINT32 NumElements; ///< Number of elements the FIFO can store.
+ UINT32 ReadIndex; ///< Index of next element to Read.
+ UINT32 WriteIndex; ///< Index of where next element will be Written.
+};
+
+__END_DECLS
+#endif /* _FIFO_CLASS_H */
diff --git a/StdLib/Include/Containers/ModuloUtil.h b/StdLib/Include/Containers/ModuloUtil.h
new file mode 100644
index 0000000000..f98ab0aea9
--- /dev/null
+++ b/StdLib/Include/Containers/ModuloUtil.h
@@ -0,0 +1,105 @@
+/** @file
+ Utility functions for performing basic math operations constrained within a
+ modulus.
+
+ These functions are intended to simplify small changes to a value which much
+ remain within a specified modulus. Changes must be less than or equal to
+ the modulus specified by MaxVal.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _MODULO_UTIL_H
+#define _MODULO_UTIL_H
+#include <Uefi.h>
+#include <sys/EfiCdefs.h>
+
+__BEGIN_DECLS
+
+/** Counter = (Counter + 1) % MaxVal;
+
+ Counter is always expected to be LESS THAN MaxVal.
+ 0 <= Counter < MaxVal
+
+ @param[in] Counter The value to be incremented.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of incrementing Counter, modulus MaxVal.
+ If Counter >= MaxVal, returns -1.
+**/
+INT32
+EFIAPI
+ModuloIncrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ );
+
+/** Counter = (Counter - 1) % MaxVal;
+
+ Counter is always expected to be LESS THAN MaxVal.
+ 0 <= Counter < MaxVal
+
+ @param[in] Counter The value to be decremented.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of decrementing Counter, modulus MaxVal.
+ If Counter >= MaxVal, returns -1.
+**/
+INT32
+EFIAPI
+ModuloDecrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ );
+
+/** Counter = (Counter + Increment) % MaxVal;
+
+ @param[in] Counter The value to be incremented.
+ @param[in] Increment The value to add to Counter.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of adding Increment to Counter, modulus MaxVal,
+ or -1 if Increment is larger than MaxVal.
+**/
+INT32
+EFIAPI
+ModuloAdd (
+ UINT32 Counter,
+ UINT32 Increment,
+ UINT32 MaxVal
+ );
+
+/** Increment Counter but don't increment past MaxVal.
+
+ @param[in] Counter The value to be decremented.
+ @param[in] MaxVal The upper bound for Counter. Counter < MaxVal.
+
+ @return Returns the result of incrementing Counter.
+**/
+UINT32
+EFIAPI
+BoundIncrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ );
+
+/** Decrement Counter but don't decrement past zero.
+
+ @param[in] Counter The value to be decremented.
+
+ @return Returns the result of decrementing Counter.
+**/
+UINT32
+EFIAPI
+BoundDecrement(
+ UINT32 Counter
+ );
+
+__END_DECLS
+#endif /* _MODULO_UTIL_H */
diff --git a/StdLib/Include/sys/termios.h b/StdLib/Include/sys/termios.h
index 13e15d2fad..e144d521f5 100644
--- a/StdLib/Include/sys/termios.h
+++ b/StdLib/Include/sys/termios.h
@@ -215,19 +215,171 @@ struct termios {
#include <sys/EfiCdefs.h>
__BEGIN_DECLS
+
+/** Get input baud rate.
+
+ Extracts the input baud rate from the termios structure pointed to by the
+ pTermios argument.
+
+ @param[in] pTermios A pointer to the termios structure from which to extract
+ the input baud rate.
+
+ @return The value of the input speed is returned exactly as it is contained
+ in the termios structure, without interpretation.
+**/
speed_t cfgetispeed (const struct termios *);
+
+/** Get output baud rate.
+
+ Extracts the output baud rate from the termios structure pointed to by the
+ pTermios argument.
+
+ @param[in] pTermios A pointer to the termios structure from which to extract
+ the output baud rate.
+
+ @return The value of the output speed is returned exactly as it is contained
+ in the termios structure, without interpretation.
+**/
speed_t cfgetospeed (const struct termios *);
+
+/** Set input baud rate.
+
+ Replaces the input baud rate, in the termios structure pointed to by the
+ pTermios argument, with the value of NewSpeed.
+
+ @param[out] pTermios A pointer to the termios structure into which to set
+ the input baud rate.
+ @param[in] NewSpeed The new input baud rate.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EINVAL - The value of NewSpeed is outside the range of
+ possible speed values as specified in <sys/termios.h>.
+**/
int cfsetispeed (struct termios *, speed_t);
+
+/** Set output baud rate.
+
+ Replaces the output baud rate, in the termios structure pointed to by the
+ pTermios argument, with the value of NewSpeed.
+
+ @param[out] pTermios A pointer to the termios structure into which to set
+ the output baud rate.
+ @param[in] NewSpeed The new output baud rate.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EINVAL - The value of NewSpeed is outside the range of
+ possible speed values as specified in <sys/termios.h>.
+**/
int cfsetospeed (struct termios *, speed_t);
+
+/** Get the parameters associated with an interactive IO device.
+
+ Get the parameters associated with the device referred to by
+ fd and store them into the termios structure referenced by pTermios.
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+ @param[out] pTermios A pointer to a termios structure into which to store
+ attributes of the interactive IO device.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+**/
int tcgetattr (int, struct termios *);
+
+/** Set the parameters associated with an interactive IO device.
+
+ Set the parameters associated with the device referred to by
+ fd to the values in the termios structure referenced by pTermios.
+
+ Behavior is modified by the value of the OptAct parameter:
+ * TCSANOW: The change shall occur immediately.
+ * TCSADRAIN: The change shall occur after all output written to fd is
+ transmitted. This action should be used when changing parameters which
+ affect output.
+ * TCSAFLUSH: The change shall occur after all output written to fd is
+ transmitted, and all input so far received but not read shall be
+ discarded before the change is made.
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+ @param[in] OptAct Currently has no effect.
+ @param[in] pTermios A pointer to a termios structure into which to retrieve
+ attributes to set in the interactive IO device.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+**/
int tcsetattr (int, int, const struct termios *);
+
+/** Transmit pending output.
+
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+ * EINTR - A signal interrupted tcdrain().
+ * ENOTSUP - This function is not supported.
+**/
int tcdrain (int);
+
+/** Suspend or restart the transmission or reception of data.
+
+ This function will suspend or resume transmission or reception of data on
+ the file referred to by fd, depending on the value of Action.
+
+ @param[in] fd The file descriptor of an open interactive IO device (terminal).
+ @param[in] Action The action to be performed:
+ * TCOOFF - Suspend output.
+ * TCOON - Resume suspended output.
+ * TCIOFF - If fd refers to an IIO device, transmit a
+ STOP character, which is intended to cause the
+ terminal device to stop transmitting data.
+ * TCION - If fd refers to an IIO device, transmit a
+ START character, which is intended to cause the
+ terminal device to start transmitting data.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+ * EINVAL - The Action argument is not a supported value.
+ * ENOTSUP - This function is not supported.
+**/
int tcflow (int, int);
+
+/** Discard non-transmitted output data, non-read input data, or both.
+
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+ @param[in] QueueSelector The IO queue to be affected:
+ * TCIFLUSH - If fd refers to a device open for input, flush
+ pending input. Otherwise error EINVAL.
+ * TCOFLUSH - If fd refers to a device open for output,
+ flush pending output. Otherwise error EINVAL.
+ * TCIOFLUSH - If fd refers to a device open for both
+ input and output, flush pending input and output.
+ Otherwise error EINVAL.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+ * EINVAL - The QueueSelector argument is not a supported value.
+ * ENOTSUP - This function is not supported.
+**/
int tcflush (int, int);
+
//int tcsendbreak (int, int);
//pid_t tcgetsid (int);
-
//void cfmakeraw (struct termios *);
//int cfsetspeed (struct termios *, speed_t);
__END_DECLS
diff --git a/StdLib/LibC/Containers/Common/ModuloUtil.c b/StdLib/LibC/Containers/Common/ModuloUtil.c
new file mode 100644
index 0000000000..5f75698bd6
--- /dev/null
+++ b/StdLib/LibC/Containers/Common/ModuloUtil.c
@@ -0,0 +1,149 @@
+/** @file
+ Utility functions for performing basic math operations constrained within a
+ modulus.
+
+ These functions are intended to simplify small changes to a value which much
+ remain within a specified modulus.
+
+ NOTE: Changes must be less than or equal to the modulus specified by MaxVal.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <LibConfig.h>
+#include <assert.h>
+
+/** Counter = (Counter + 1) % MaxVal;
+
+ Counter is always expected to be LESS THAN MaxVal.
+ 0 <= Counter < MaxVal
+
+ @param[in] Counter The value to be incremented.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of incrementing Counter, modulus MaxVal.
+ If Counter >= MaxVal, returns -1.
+**/
+INT32
+EFIAPI
+ModuloIncrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ )
+{
+ INT32 Temp;
+
+ if(Counter < MaxVal) {
+ Temp = (INT32)(Counter + 1);
+ if(Temp >= (INT32)MaxVal) {
+ Temp = 0;
+ }
+ }
+ else {
+ Temp = -1;
+ }
+ return Temp;
+}
+
+/** Counter = (Counter - 1) % MaxVal;
+
+ Counter is always expected to be LESS THAN MaxVal.
+ 0 <= Counter < MaxVal
+
+ @param[in] Counter The value to be decremented.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of decrementing Counter, modulus MaxVal.
+ If Counter >= MaxVal, returns -1.
+**/
+INT32
+EFIAPI
+ModuloDecrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ )
+{
+ INT32 Temp;
+
+ if(Counter < MaxVal) {
+ Temp = (INT32)Counter - 1;
+ // If Counter is zero, Temp will become -1.
+ if(Temp < 0) {
+ Temp = (INT32)MaxVal - 1;
+ }
+ }
+ else {
+ Temp = -1;
+ }
+
+ return Temp;
+}
+
+/** Decrement Counter but don't decrement past zero.
+
+ @param[in] Counter The value to be decremented.
+
+ @return Returns the result of decrementing Counter.
+**/
+UINT32
+EFIAPI
+BoundDecrement(
+ UINT32 Counter
+ )
+{
+ return ((Counter > 0) ? (Counter - 1) : 0);
+}
+
+/** Increment Counter but don't increment past MaxVal.
+ Counter should be maintained in the range (0 <= Counter < MaxVal).
+
+ @param[in] Counter The value to be decremented.
+ @param[in] MaxVal The upper bound for Counter.
+
+ @return Returns the result of incrementing Counter.
+**/
+UINT32
+EFIAPI
+BoundIncrement(
+ UINT32 Counter,
+ UINT32 MaxVal
+ )
+{
+ return ((Counter < (MaxVal - 1)) ? (Counter + 1) : (MaxVal - 1));
+}
+
+/** Counter = (Counter + Increment) % MaxVal;
+
+ @param[in] Counter The value to be incremented.
+ @param[in] Increment The value to add to Counter.
+ @param[in] MaxVal Modulus of the operation.
+
+ @return Returns the result of adding Increment to Counter, modulus MaxVal,
+ or -1 if Increment is larger than MaxVal.
+**/
+INT32
+EFIAPI
+ModuloAdd (
+ UINT32 Counter,
+ UINT32 Increment,
+ UINT32 MaxVal
+ )
+{
+ UINT32 Temp;
+
+ if(Increment > MaxVal) {
+ return -1;
+ }
+ Temp = (Counter + Increment);
+ while(Temp >= MaxVal) {
+ Temp -= MaxVal;
+ }
+ return Temp;
+}
diff --git a/StdLib/LibC/Containers/ContainerLib.inf b/StdLib/LibC/Containers/ContainerLib.inf
new file mode 100644
index 0000000000..4ca6690c4d
--- /dev/null
+++ b/StdLib/LibC/Containers/ContainerLib.inf
@@ -0,0 +1,46 @@
+## @file
+# INF file for building the Container library.
+#
+# Various types of containers are implemented within this library.
+# Types of containers may be Queues (FIFO, LIFO, etc.), hash tables, etc.
+#
+# Copyright (c) 2012, 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
+#
+# THIS 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 = LibContainer
+ FILE_GUID = 92f7436e-7395-4da1-a7be-f352f0bcd79c
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibContainer
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Queues/Fifo.c
+ Common/ModuloUtil.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ LibC
+ LibWchar
+
+[Packages]
+ MdePkg/MdePkg.dec
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
diff --git a/StdLib/LibC/Containers/Queues/Fifo.c b/StdLib/LibC/Containers/Queues/Fifo.c
new file mode 100644
index 0000000000..347ac02fd2
--- /dev/null
+++ b/StdLib/LibC/Containers/Queues/Fifo.c
@@ -0,0 +1,526 @@
+/** @file
+ Class for arbitrary sized FIFO queues.
+
+ The FIFO is empty if both the Read and Write indexes are equal.
+ The FIFO is full if the next write would make the Read and Write indexes equal.
+
+ Member variable NumElements is the maximum number of elements that can be
+ contained in the FIFO.
+ If NumElements is ZERO, there is an error.
+ NumElements should be in the range 1:N.
+
+ Members WriteIndex and ReadIndex are indexes into the array implementing the
+ FIFO. They should be in the range 0:(NumElements - 1).
+
+ One element of the FIFO is always reserved as the "terminator" element. Thus,
+ the capacity of a FIFO is actually NumElements-1.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <wchar.h>
+#include <Containers/Fifo.h>
+
+/** Determine number of items available to read from the FIFO.
+
+ The number of items are either the number of bytes, or the number of elements
+ depending upon the value of the As enumerator.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] As An enumeration variable whose value determines whether the
+ returned value is the number of bytes or the number of elements
+ currently contained by the FIFO.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of items contained by the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_NumInQueue (
+ cFIFO *Self,
+ FIFO_ElemBytes As
+)
+{
+ size_t Count;
+
+ if(Self->ReadIndex <= Self->WriteIndex) {
+ Count = Self->WriteIndex - Self->ReadIndex;
+ }
+ else {
+ Count = Self->NumElements - (Self->ReadIndex - Self->WriteIndex);
+ }
+ if(As == AsBytes) {
+ Count *= Self->ElementSize;
+ }
+ return Count;
+}
+
+/** Determine amount of free space in the FIFO that can be written into.
+
+ The number of items are either the number of bytes, or the number of elements
+ depending upon the value of the As enumerator.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] As An enumeration variable whose value determines whether the
+ returned value is the number of bytes or the number of elements
+ currently available in the FIFO.
+
+ @retval 0 The FIFO is full.
+ @retval >=0 The number of items which can be accepted by the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_FreeSpace (
+ cFIFO *Self,
+ FIFO_ElemBytes As
+)
+{
+ size_t Count;
+ UINT32 RDex;
+ UINT32 WDex;
+
+ RDex = Self->ReadIndex;
+ WDex = Self->WriteIndex;
+
+ if(RDex <= WDex) {
+ Count = Self->NumElements - ((WDex - RDex) - 1);
+ }
+ else {
+ Count = (RDex - WDex);
+ }
+ if(As == AsBytes) {
+ Count *= Self->ElementSize;
+ }
+ return Count;
+}
+
+/** Reduce the FIFO contents by NumElem elements.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] NumElem Number of elements to delete from the FIFO.
+
+ @retval 0 FIFO is now empty.
+ @retval N>0 There are still N elements in the FIFO.
+ @retval -1 There are fewer than NumElem elements in the FIFO.
+**/
+static
+ssize_t
+FIFO_Reduce (
+ cFIFO *Self,
+ size_t NumElem
+ )
+{
+ size_t QCount;
+ ssize_t RetVal;
+
+ assert(Self != NULL);
+
+ QCount = FIFO_NumInQueue(Self, AsElements);
+ if(NumElem > QCount) {
+ RetVal = -1;
+ errno = EINVAL;
+ }
+ else {
+ RetVal = (ssize_t)ModuloAdd(Self->ReadIndex, (UINT32)NumElem, Self->NumElements);
+ Self->ReadIndex = (UINT32)RetVal;
+
+ RetVal = (ssize_t)(QCount - NumElem);
+ }
+ return RetVal;
+}
+
+/** Test whether the FIFO is empty.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @retval TRUE The FIFO is empty.
+ @retval FALSE There is data in the FIFO.
+**/
+static
+BOOLEAN
+EFIAPI
+FIFO_IsEmpty (
+ cFIFO *Self
+ )
+{
+ assert(Self != NULL);
+
+ return (BOOLEAN)(Self->WriteIndex == Self->ReadIndex);
+}
+
+/** Test whether the FIFO is full.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @retval TRUE The FIFO is full.
+ @retval FALSE There is free space in the FIFO.
+**/
+static
+BOOLEAN
+EFIAPI
+FIFO_IsFull (
+ cFIFO *Self
+ )
+{
+ assert(Self != NULL);
+
+ return (BOOLEAN)(ModuloIncrement(Self->WriteIndex, Self->NumElements) == (INT32)Self->ReadIndex);
+}
+
+/** Add one or more elements to the FIFO.
+
+ This function allows one to add one or more elements, as specified by Count,
+ to the FIFO. Each element is of the size specified when the FIFO object
+ was instantiated (FIFO.ElementSize).
+
+ pElement points to the first byte of the first element to be added.
+ If multiple elements are to be added, the elements are expected to be
+ organized as a packed array.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] pElement Pointer to the element(s) to enqueue (add).
+ @param[in] Count Number of elements to add.
+
+ @retval 0 The FIFO is full.
+ @retval >=0 The number of elements added to the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_Enqueue (
+ cFIFO *Self,
+ const void *pElement,
+ size_t Count
+ )
+{
+ uintptr_t ElemPtr;
+ uintptr_t QPtr;
+ size_t i;
+ UINT32 SizeOfElement;
+ UINT32 Windex;
+
+ assert(Self != NULL);
+ assert(pElement != NULL);
+ assert(Count >= 0);
+
+ if(FIFO_IsFull(Self)) {
+ Count = 0;
+ }
+ else {
+ Count = MIN(Count, Self->FreeSpace(Self, AsElements));
+ SizeOfElement = Self->ElementSize;
+ Windex = Self->WriteIndex;
+
+ ElemPtr = (uintptr_t)pElement;
+
+ QPtr = (uintptr_t)Self->Queue + (SizeOfElement * Windex);
+ for(i = 0; i < Count; ++i) {
+ (void)CopyMem((void *)QPtr, (const void *)ElemPtr, SizeOfElement);
+ Windex = (UINT32)ModuloIncrement(Windex, Self->NumElements);
+ if(Windex == 0) { // If the index wrapped
+ QPtr = (uintptr_t)Self->Queue;
+ }
+ else {
+ QPtr += SizeOfElement;
+ }
+ ElemPtr += SizeOfElement;
+ }
+ (void)ZeroMem((void*)QPtr, SizeOfElement);
+ Self->WriteIndex = Windex;
+ }
+ return Count;
+}
+
+/** Read or copy elements from the FIFO.
+
+ This function allows one to read one or more elements, as specified by Count,
+ from the FIFO. Each element is of the size specified when the FIFO object
+ was instantiated (FIFO.ElementSize).
+
+ pElement points to the destination of the first byte of the first element
+ to be read. If multiple elements are to be read, the elements are expected
+ to be organized as a packed array.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[out] pElement Pointer to where to store the element(s) read from the FIFO.
+ @param[in] Count Number of elements to dequeue.
+ @param[in] Consume If TRUE, consume read elements. Otherwise, preserve.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of elements read from the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_Dequeue (
+ cFIFO *Self,
+ void *pElement,
+ size_t Count,
+ BOOLEAN Consume
+ )
+{
+ UINTN ElemPtr;
+ UINTN QPtr;
+ UINT32 RDex;
+ UINT32 SizeOfElement;
+ UINT32 i;
+
+ assert(Self != NULL);
+ assert(pElement != NULL);
+ assert(Count != 0);
+
+ if(FIFO_IsEmpty(Self)) {
+ Count = 0;
+ }
+ else {
+ RDex = Self->ReadIndex;
+ SizeOfElement = Self->ElementSize;
+ ElemPtr = (UINTN)pElement;
+ Count = MIN(Count, Self->Count(Self, AsElements));
+
+ QPtr = (UINTN)Self->Queue + (RDex * Self->ElementSize);
+ for(i = 0; i < Count; ++i) {
+ (void)CopyMem((void *)ElemPtr, (const void *)QPtr, Self->ElementSize);
+ RDex = (UINT32)ModuloIncrement(RDex, Self->NumElements);
+ if(RDex == 0) { // If the index wrapped
+ QPtr = (UINTN)Self->Queue;
+ }
+ else {
+ QPtr += Self->ElementSize;
+ }
+ ElemPtr += Self->ElementSize;
+ }
+ if(Consume) {
+ Self->ReadIndex = RDex;
+ }
+ }
+ return Count;
+}
+
+/** Read elements from the FIFO.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[out] pElement Pointer to where to store the element read from the FIFO.
+ @param[in] Count Number of elements to dequeue.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of elements read from the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_Read (
+ cFIFO *Self,
+ void *pElement,
+ size_t Count
+ )
+{
+ return FIFO_Dequeue(Self, pElement, Count, TRUE);
+}
+
+/** Make a copy of the FIFO's data.
+ The contents of the FIFO is copied out and linearized without affecting the
+ FIFO contents.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[out] pElement Pointer to where to store the elements copied from the FIFO.
+ @param[in] Count Number of elements to copy.
+
+ @retval 0 The FIFO is empty.
+ @retval >=0 The number of elements copied from the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_Copy (
+ cFIFO *Self,
+ void *pElement,
+ size_t Count
+ )
+{
+ return FIFO_Dequeue(Self, pElement, Count, FALSE);
+}
+
+/** Get the FIFO's current Read Index.
+
+ @param[in] Self Pointer to the FIFO instance.
+**/
+static
+UINT32
+EFIAPI
+FIFO_GetRDex (
+ cFIFO *Self
+)
+{
+ assert(Self != NULL);
+
+ return Self->ReadIndex;
+}
+
+/** Get the FIFO's current Write Index.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @return The current value of the FIFO's WriteIndex member is returned.
+**/
+static
+UINT32
+EFIAPI
+FIFO_GetWDex (
+ cFIFO *Self
+)
+{
+ assert(Self != NULL);
+
+ return Self->WriteIndex;
+}
+
+/** Cleanly delete a FIFO instance.
+
+ @param[in] Self Pointer to the FIFO instance.
+**/
+static
+void
+EFIAPI
+FIFO_Delete (
+ cFIFO *Self
+ )
+{
+ assert(Self != NULL);
+
+ if(Self->Queue != NULL) {
+ FreePool(Self->Queue);
+ Self->Queue = NULL; // Zombie catcher
+ }
+ FreePool(Self);
+}
+
+/** Empty the FIFO, discarding up to NumToFlush elements.
+
+ @param[in] Self Pointer to the FIFO instance.
+ @param[in] NumToFlush Number of elements to flush from the FIFO.
+ If larger than the number of elements in the
+ FIFO, the FIFO is emptied.
+
+ @return Returns the number of elements remaining in the FIFO after the flush.
+**/
+static
+size_t
+EFIAPI
+FIFO_Flush (
+ cFIFO *Self,
+ size_t NumToFlush
+ )
+{
+ size_t NumInQ;
+ size_t Remainder;
+
+ assert(Self != NULL);
+
+ NumInQ = FIFO_FreeSpace(Self, AsElements);
+ if(NumToFlush >= NumInQ) {
+ Self->ReadIndex = 0;
+ Self->WriteIndex = 0;
+ Remainder = 0;
+ }
+ else {
+ Remainder = FIFO_Reduce(Self, NumToFlush);
+ }
+ return Remainder;
+}
+
+/** Remove the most recently added element from the FIFO.
+
+ @param[in] Self Pointer to the FIFO instance.
+
+ @return Returns the number of elements remaining in the FIFO.
+**/
+static
+size_t
+EFIAPI
+FIFO_Truncate (
+ cFIFO *Self
+ )
+{
+ size_t Remainder;
+
+ assert(Self != NULL);
+
+ Remainder = Self->Count(Self, AsElements);
+ if(Remainder > 0) {
+ Self->WriteIndex = (UINT32)ModuloDecrement(Self->WriteIndex, Self->NumElements);
+ --Remainder;
+ }
+ return Remainder;
+}
+
+/** Construct a new instance of a FIFO Queue.
+
+ @param[in] NumElements Number of elements to be contained in the new FIFO.
+ @param[in] ElementSize Size, in bytes, of an element.
+
+ @retval NULL Unable to create the instance.
+ @retval NonNULL Pointer to the new FIFO instance.
+**/
+cFIFO *
+EFIAPI
+New_cFIFO(
+ UINT32 NumElements,
+ size_t ElementSize
+ )
+{
+ cFIFO *FIFO;
+ UINT8 *Queue;
+
+ FIFO = NULL;
+ if((NumElements > 2) && (ElementSize > 0)) {
+ FIFO = (cFIFO *)AllocatePool(sizeof(cFIFO));
+ if(FIFO != NULL) {
+ Queue = (UINT8 *)AllocateZeroPool(NumElements * ElementSize);
+ if(Queue != NULL) {
+ FIFO->Write = FIFO_Enqueue;
+ FIFO->Read = FIFO_Read;
+ FIFO->Copy = FIFO_Copy;
+ FIFO->IsEmpty = FIFO_IsEmpty;
+ FIFO->IsFull = FIFO_IsFull;
+ FIFO->Count = FIFO_NumInQueue;
+ FIFO->FreeSpace = FIFO_FreeSpace;
+ FIFO->Flush = FIFO_Flush;
+ FIFO->Truncate = FIFO_Truncate;
+ FIFO->Delete = FIFO_Delete;
+ FIFO->GetRDex = FIFO_GetRDex;
+ FIFO->GetWDex = FIFO_GetWDex;
+
+ FIFO->Queue = Queue;
+ FIFO->ElementSize = (UINT32)ElementSize;
+ FIFO->NumElements = (UINT32)NumElements;
+ FIFO->ReadIndex = 0;
+ FIFO->WriteIndex = 0;
+ }
+ else {
+ FreePool(FIFO);
+ FIFO = NULL;
+ }
+ }
+ }
+ return FIFO;
+}
diff --git a/StdLib/LibC/Main/Main.c b/StdLib/LibC/Main/Main.c
index 5736428db5..0c84c160e0 100644
--- a/StdLib/LibC/Main/Main.c
+++ b/StdLib/LibC/Main/Main.c
@@ -158,9 +158,9 @@ ShellAppMain (
mfd[i].MyFD = (UINT16)i;
}
- i = open("stdin:", O_RDONLY, 0444);
+ i = open("stdin:", (O_RDONLY | O_TTY_INIT), 0444);
if(i == 0) {
- i = open("stdout:", O_WRONLY, 0222);
+ i = open("stdout:", (O_WRONLY | O_TTY_INIT), 0222);
if(i == 1) {
i = open("stderr:", O_WRONLY, 0222);
}
diff --git a/StdLib/LibC/Stdio/fvwrite.c b/StdLib/LibC/Stdio/fvwrite.c
index 12773eff68..feddc348c1 100644
--- a/StdLib/LibC/Stdio/fvwrite.c
+++ b/StdLib/LibC/Stdio/fvwrite.c
@@ -106,11 +106,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
GETIOV(;);
w = (*fp->_write)(fp->_cookie, p,
(int)MIN(len, BUFSIZ));
- if (w <= 0)
+ if (w < 0)
goto err;
p += w;
len -= w;
- } while ((uio->uio_resid -= w) != 0);
+ } while ((uio->uio_resid -= w) > 0);
+ uio->uio_resid = 0; // Just in case it went negative such as when NL is expanded to CR NL
} else if ((fp->_flags & __SLBF) == 0) {
/*
* Fully buffered: fill partially full buffer, if any,
diff --git a/StdLib/LibC/Uefi/Devices/Console/daConsole.c b/StdLib/LibC/Uefi/Devices/Console/daConsole.c
index 4897a2e56e..927ec944ea 100644
--- a/StdLib/LibC/Uefi/Devices/Console/daConsole.c
+++ b/StdLib/LibC/Uefi/Devices/Console/daConsole.c
@@ -3,6 +3,13 @@
Manipulates abstractions for stdin, stdout, stderr.
+ This device is a WIDE device and this driver returns WIDE
+ characters. It this the responsibility of the caller to convert between
+ narrow and wide characters in order to perform the desired operations.
+
+ The devices status as a wide device is indicatd by _S_IWTTY being set in
+ f_iflags.
+
Copyright (c) 2010 - 2012, 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.
@@ -30,6 +37,7 @@
#include <unistd.h>
#include <kfile.h>
#include <Device/Device.h>
+#include <Device/IIO.h>
#include <MainData.h>
static const CHAR16* const
@@ -46,7 +54,7 @@ static const int stdioFlags[NUM_SPECIAL] = {
static DeviceNode *ConNode[NUM_SPECIAL];
static ConInstance *ConInstanceList;
-static wchar_t *ConReadBuf;
+static cIIO *IIO;
/* Flags settable by Ioctl */
static BOOLEAN TtyCooked;
@@ -58,10 +66,10 @@ static BOOLEAN TtyEcho;
large enough to hold the converted results. It is guaranteed
that there will be fewer than n characters placed in dest.
- @param dest WCS buffer to receive the converted string.
- @param buf MBCS string to convert to WCS.
- @param n Number of BYTES contained in buf.
- @param Cs Pointer to the character state object for this stream
+ @param[out] dest WCS buffer to receive the converted string.
+ @param[in] buf MBCS string to convert to WCS.
+ @param[in] n Number of BYTES contained in buf.
+ @param[in,out] Cs Pointer to the character state object for this stream
@return The number of BYTES consumed from buf.
**/
@@ -94,6 +102,13 @@ WideTtyCvt( CHAR16 *dest, const char *buf, ssize_t n, mbstate_t *Cs)
return i;
}
+/** Close an open file.
+
+ @param[in] filp Pointer to the file descriptor structure for this file.
+
+ @retval 0 The file has been successfully closed.
+ @retval -1 filp does not point to a valid console descriptor.
+**/
static
int
EFIAPI
@@ -106,13 +121,25 @@ da_ConClose(
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
// Quick check to see if Stream looks reasonable
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
+ errno = EINVAL;
EFIerrno = RETURN_INVALID_PARAMETER;
return -1; // Looks like a bad File Descriptor pointer
}
gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed
- return RETURN_SUCCESS;
+ return 0;
}
+/** Position the console cursor to the coordinates specified by Position.
+
+ @param[in] filp Pointer to the file descriptor structure for this file.
+ @param[in] Position A value containing the target X and Y coordinates.
+ @param[in] whence Ignored by the Console device.
+
+ @retval Position Success. Returns a copy of the Position argument.
+ @retval -1 filp is not associated with a valid console stream.
+ @retval -1 This console stream is attached to stdin.
+ @retval -1 The SetCursorPosition operation failed.
+**/
static
off_t
EFIAPI
@@ -155,11 +182,14 @@ da_ConSeek(
/* Write a NULL terminated WCS to the EFI console.
- @param[in,out] BufferSize Number of bytes in Buffer. Set to zero if
- the string couldn't be displayed.
+ NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters received
+ by da_ConWrite are WIDE characters. It is the responsibility of the
+ higher-level function(s) to perform any necessary conversions.
+
+ @param[in,out] BufferSize Number of characters in Buffer.
@param[in] Buffer The WCS string to be displayed
- @return The number of BYTES written. Because of MBCS, this may be more than number of characters.
+ @return The number of Characters written.
*/
static
ssize_t
@@ -174,8 +204,10 @@ da_ConWrite(
EFI_STATUS Status;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
ConInstance *Stream;
- ssize_t NumBytes;
+ ssize_t NumChar;
+ XY_OFFSET CursorPos;
+ NumChar = -1;
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
// Quick check to see if Stream looks reasonable
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
@@ -190,35 +222,45 @@ da_ConWrite(
// Everything is OK to do the write.
Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;
- // Convert string from MBCS to WCS and translate \n to \r\n.
- NumBytes = WideTtyCvt(gMD->UString, (const char *)Buffer, (ssize_t)BufferSize, &Stream->CharState);
- BufferSize = NumBytes;
+ Status = EFI_SUCCESS;
+ if(Position != NULL) {
+ CursorPos.Offset = *Position;
+ Status = Proto->SetCursorPosition(Proto,
+ (INTN)CursorPos.XYpos.Column,
+ (INTN)CursorPos.XYpos.Row);
+ }
+ if(!RETURN_ERROR(Status)) {
// Send the Unicode buffer to the console
- Status = Proto->OutputString( Proto, gMD->UString);
- // Depending on status, update BufferSize and return
- if(RETURN_ERROR(Status)) {
- BufferSize = 0; // We don't really know how many characters made it out
+ Status = Proto->OutputString( Proto, (CHAR16 *)Buffer);
}
- else {
- //BufferSize = NumBytes;
- Stream->NumWritten += NumBytes;
+
+ // Depending on status, update BufferSize and return
+ if(!RETURN_ERROR(Status)) {
+ //BufferSize = NumChar;
+ NumChar = BufferSize;
+ Stream->NumWritten += NumChar;
}
EFIerrno = Status; // Make error reason available to caller
- return BufferSize;
+ return NumChar;
}
-/** Read characters from the console input device.
+/** Read a wide character from the console input device.
+
+ NOTE: The UEFI Console is a wide device, _S_IWTTY, so characters returned
+ by da_ConRead are WIDE characters. It is the responsibility of the
+ higher-level function(s) to perform any necessary conversions.
- @param[in,out] filp Pointer to file descriptor for this file.
- @param[in,out] offset Ignored.
+ @param[in,out] BufferSize Number of characters in Buffer.
+ @param[in] filp Pointer to file descriptor for this file.
+ @param[in] offset Ignored.
@param[in] BufferSize Buffer size, in bytes.
@param[out] Buffer Buffer in which to place the read characters.
- @return Number of bytes actually placed into Buffer.
-
- @todo Handle encodings other than ASCII-7 and UEFI.
+ @retval -1 An error has occurred. Reason in errno and EFIerrno.
+ @retval -1 No data is available. errno is set to EAGAIN
+ @retval 1 One wide character has been placed in Buffer
**/
static
ssize_t
@@ -232,84 +274,80 @@ da_ConRead(
{
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;
ConInstance *Stream;
- wchar_t *OutPtr;
- EFI_INPUT_KEY Key;
- UINTN NumChar;
- UINTN Edex;
+ cIIO *Self;
+ EFI_INPUT_KEY Key = {0,0};
EFI_STATUS Status = RETURN_SUCCESS;
- UINTN i;
- char EchoBuff[MB_CUR_MAX + 1];
- int NumEcho;
+ UINTN Edex;
+ ssize_t NumRead;
+ int Flags;
+ wchar_t RetChar; // Default to No Data
- Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
- // Quick check to see if Stream looks reasonable
- if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
- EFIerrno = RETURN_INVALID_PARAMETER;
- return -1; // Looks like a bad This pointer
- }
- if(Stream->InstanceNum != STDIN_FILENO) {
- // Read only valid for stdin
- EFIerrno = RETURN_UNSUPPORTED;
- return -1;
+ NumRead = -1;
+ if(BufferSize < sizeof(wchar_t)) {
+ errno = EINVAL; // Buffer is too small to hold one character
}
- // It looks like things are OK for trying to read
- // We will accumulate *BufferSize characters or until we encounter
- // an "activation" character. Currently any control character.
+ else {
+ Self = (cIIO *)filp->devdata;
+ Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;
- OutPtr = ConReadBuf;
- NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;
- i = 0;
- do {
+ Flags = filp->Oflags;
if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {
+ // No data pending in the Un-get buffer. Get a char from the hardware.
+ if((Flags & O_NONBLOCK) == 0) {
+ // Read a byte in Blocking mode
Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);
- if(Status != RETURN_SUCCESS) {
- break;
+ EFIerrno = Status;
+ if(Status != EFI_SUCCESS) {
+ errno = EINVAL;
}
+ else {
Status = Proto->ReadKeyStroke(Proto, &Key);
- if(Status != RETURN_SUCCESS) {
- break;
+ if(Status == EFI_SUCCESS) {
+ NumRead = 1; // Indicate that Key holds the data
+ }
+ else {
+ errno = EIO;
+ }
+ }
+ }
+ else {
+ // Read a byte in Non-Blocking mode
+ Status = Proto->ReadKeyStroke(Proto, &Key);
+ EFIerrno = Status;
+ if(Status == EFI_SUCCESS) {
+ // Got a keystroke.
+ NumRead = 1; // Indicate that Key holds the data
+ }
+ else if(Status == EFI_NOT_READY) {
+ // Keystroke data is not available
+ errno = EAGAIN;
+ }
+ else {
+ // Hardware error
+ errno = EIO;
+ }
}
}
else {
+ // Use the data in the Un-get buffer
Key.ScanCode = Stream->UnGetKey.ScanCode;
Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;
Stream->UnGetKey.ScanCode = SCAN_NULL;
Stream->UnGetKey.UnicodeChar = CHAR_NULL;
+ NumRead = 1; // Indicate that Key holds the data
}
- if(Key.ScanCode == SCAN_NULL) {
- NumEcho = 0;
- if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
- *OutPtr++ = CHAR_LINEFEED;
- NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);
- }
- else {
- *OutPtr++ = Key.UnicodeChar;
- NumEcho = wctomb(EchoBuff, Key.UnicodeChar);
+ // If we have data, prepare it for return.
+ if(NumRead == 1) {
+ RetChar = Key.UnicodeChar;
+ if((RetChar == 0) && ((Self->Termio.c_iflag & IGNSPEC) == 0)) {
+ // Must be a control, function, or other non-printable key.
+ // Map it into the Platform portion of the Unicode private use area
+ RetChar = (Key.ScanCode == 0) ? 0 : 0xF900U - Key.ScanCode;
}
- ++i;
- EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */
- if(TtyEcho) {
- /* Echo the character just input */
- da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);
+ *((wchar_t *)Buffer) = RetChar;
}
}
- if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code
- break;
- }
- } while(i < NumChar);
-
- *OutPtr = L'\0'; // Terminate the input buffer
-
- /* Convert the input buffer and place in Buffer.
- If the fully converted input buffer won't fit, write what will and
- leave the rest in ConReadBuf with ConReadLeft indicating how many
- unconverted characters remain in ConReadBuf.
- */
- NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */
- /* More work needs to be done before locales other than C can be supported. */
-
- EFIerrno = Status;
- return (ssize_t)NumEcho; // Will be 0 if we didn't get a key
+ return NumRead;
}
/** Console-specific helper function for the fstat() function.
@@ -320,6 +358,14 @@ da_ConRead(
st_blksize Set to 1 since this is a character device
All other members of the stat structure are left unchanged.
+
+ @param[in] filp Pointer to file descriptor for this file.
+ @param[out] Buffer Pointer to a stat structure to receive the information.
+ @param[in,out] Something Ignored.
+
+ @retval 0 Successful completion.
+ @retval -1 Either filp is not associated with a console stream, or
+ Buffer is NULL. errno is set to EINVAL.
**/
static
int
@@ -343,6 +389,7 @@ da_ConStat(
if ((Stream->Cookie != CON_COOKIE) || // Cookie == 'IoAb'
(Buffer == NULL))
{
+ errno = EINVAL;
EFIerrno = RETURN_INVALID_PARAMETER;
return -1;
}
@@ -378,6 +425,14 @@ da_ConStat(
return 0;
}
+/** Console-specific helper for the ioctl system call.
+
+ The console device does not directly participate in ioctl operations.
+ This function completes the device abstraction and returns an error value
+ to indicate that the function is not supported for this device.
+
+ @retval -1 Function is not supported for this device.
+**/
static
int
EFIAPI
@@ -387,10 +442,21 @@ da_ConIoctl(
va_list argp
)
{
- return -EPERM;
+ errno = ENODEV;
+ return -1;
}
/** Open an abstract Console Device.
+
+ @param[in] DevNode Pointer to the Device control structure for this stream.
+ @param[in] filp Pointer to the new file control structure for this stream.
+ @param[in] DevInstance Not used for the console device.
+ @param[in] Path Not used for the console device.
+ @param[in] MPath Not used for the console device.
+
+ @retval 0 This console stream has been successfully opened.
+ @retval -1 The DevNode or filp pointer is NULL.
+ @retval -1 DevNode does not point to a valid console stream device.
**/
int
EFIAPI
@@ -403,36 +469,57 @@ da_ConOpen(
)
{
ConInstance *Stream;
+ UINT32 Instance;
+ int RetVal = -1;
- if((filp == NULL) ||
- (DevNode == NULL))
+ if((filp != NULL) &&
+ (DevNode != NULL))
{
- EFIerrno = RETURN_INVALID_PARAMETER;
- errno = EINVAL;
- return -1;
- }
Stream = (ConInstance *)DevNode->InstanceList;
// Quick check to see if Stream looks reasonable
- if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
+ if(Stream->Cookie == CON_COOKIE)
+ {
+ Instance = Stream->InstanceNum;
+ if(Instance < NUM_SPECIAL) {
+ gMD->StdIo[Instance] = Stream;
+ filp->f_iflags |= (_S_IFCHR | _S_ITTY | _S_IWTTY | _S_ICONSOLE);
+ filp->f_offset = 0;
+ filp->f_ops = &Stream->Abstraction;
+ filp->devdata = (void *)IIO;
+ RetVal = 0;
+ }
+ }
+ }
+ if (RetVal < 0) {
EFIerrno = RETURN_INVALID_PARAMETER;
errno = EINVAL;
- return -1; // Looks like a bad This pointer
}
- gMD->StdIo[Stream->InstanceNum] = Stream;
- filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);
- filp->f_offset = 0;
- filp->f_ops = &Stream->Abstraction;
+ return RetVal;
- return 0;
}
#include <sys/poll.h>
/* Returns a bit mask describing which operations could be completed immediately.
+ Testable Events for this device are:
(POLLIN | POLLRDNORM) A Unicode character is available to read
(POLLIN) A ScanCode is ready.
(POLLOUT) The device is ready for output - always set on stdout and stderr.
+ Non-testable Events which are only valid in return values are:
+ POLLERR The specified device is not one of stdin, stdout, or stderr.
+ POLLHUP The specified stream has been disconnected
+ POLLNVAL da_ConPoll was called with an invalid parameter.
+
+ NOTE: The "Events" handled by this function are not UEFI events.
+
+ @param[in] filp Pointer to the file control structure for this stream.
+ @param[in] events A bit mask identifying the events to be examined
+ for this device.
+
+ @return Returns a bit mask comprised of both testable and non-testable
+ event codes indicating both the state of the operation and the
+ status of the device.
*/
static
short
@@ -450,6 +537,7 @@ da_ConPoll(
Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);
// Quick check to see if Stream looks reasonable
if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'
+ errno = EINVAL;
EFIerrno = RETURN_INVALID_PARAMETER;
return POLLNVAL; // Looks like a bad filp pointer
}
@@ -495,15 +583,18 @@ __Cons_construct(
)
{
ConInstance *Stream;
- RETURN_STATUS Status = RETURN_SUCCESS;
+ RETURN_STATUS Status;
int i;
+ Status = RETURN_OUT_OF_RESOURCES;
ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));
- ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));
- if((ConInstanceList == NULL) || (ConReadBuf == NULL)) {
- return RETURN_OUT_OF_RESOURCES;
+ if(ConInstanceList != NULL) {
+ IIO = New_cIIO();
+ if(IIO == NULL) {
+ FreePool(ConInstanceList);
}
-
+ else {
+ Status = RETURN_SUCCESS;
for( i = 0; i < NUM_SPECIAL; ++i) {
// Get pointer to instance.
Stream = &ConInstanceList[i];
@@ -553,9 +644,10 @@ __Cons_construct(
if(Stream->Dev == NULL) {
continue; // No device for this stream.
}
- ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream, 1, sizeof(ConInstance), stdioFlags[i]);
+ ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream,
+ 1, sizeof(ConInstance), stdioFlags[i]);
if(ConNode[i] == NULL) {
- Status = EFIerrno;
+ Status = EFIerrno; // Grab error code that DevRegister produced.
break;
}
Stream->Parent = ConNode[i];
@@ -563,7 +655,8 @@ __Cons_construct(
/* Initialize Ioctl flags until Ioctl is really implemented. */
TtyCooked = TRUE;
TtyEcho = TRUE;
-
+ }
+ }
return Status;
}
@@ -584,15 +677,16 @@ __Cons_deconstruct(
if(ConInstanceList != NULL) {
FreePool(ConInstanceList);
}
- if(ConReadBuf != NULL) {
- FreePool(ConReadBuf);
+ if(IIO != NULL) {
+ IIO->Delete(IIO);
+ IIO = NULL;
}
return RETURN_SUCCESS;
}
/* ######################################################################### */
-#if 0 /* Not implemented for Console */
+#if 0 /* Not implemented (yet?) for Console */
static
int
diff --git a/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c b/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c
index f6d375e6db..8d95fbad5e 100644
--- a/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c
+++ b/StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c
@@ -1,7 +1,7 @@
/** @file
Device Abstraction: device creation utility functions.
- Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011 - 2012, 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
@@ -44,22 +44,40 @@ int EFIAPI fnullop_flush (struct __filedes *filp)
{ return 0; }
int EFIAPI fbadop_stat (struct __filedes *filp, struct stat *StatBuf, void *Buf)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
int EFIAPI fbadop_ioctl (struct __filedes *filp, ULONGN Cmd, va_list argp)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
int EFIAPI fbadop_delete (struct __filedes *filp)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
int EFIAPI fbadop_mkdir (const char *path, __mode_t perms)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
int EFIAPI fbadop_rename (const char *from, const char *to)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
int EFIAPI fbadop_rmdir (struct __filedes *filp)
-{ return -EPERM; }
+{
+ errno = EPERM;
+ return -1;
+}
/** Add a new device to the device list.
If both DevName and DevProto are NULL, register this as the Default device.
diff --git a/StdLib/LibC/Uefi/Devices/daConsole.inf b/StdLib/LibC/Uefi/Devices/daConsole.inf
index 802c6eb13c..e23193f4e2 100644
--- a/StdLib/LibC/Uefi/Devices/daConsole.inf
+++ b/StdLib/LibC/Uefi/Devices/daConsole.inf
@@ -1,7 +1,7 @@
## @file
# Standard C library: Console Device Abstraction.
#
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2012, 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
@@ -44,8 +44,9 @@
LibC
LibWchar
LibUefi
+ LibIIO
DevUtility
[Protocols]
- gEfiSimpleTextInProtocolGuid
- gEfiSimpleTextOutProtocolGuid
+ gEfiSimpleTextInProtocolGuid ## CONSUMED
+ gEfiSimpleTextOutProtocolGuid ## CONSUMED
diff --git a/StdLib/LibC/Uefi/InteractiveIO/CanonRead.c b/StdLib/LibC/Uefi/InteractiveIO/CanonRead.c
new file mode 100644
index 0000000000..db6af6e4bf
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/CanonRead.c
@@ -0,0 +1,161 @@
+/** @file
+ Canonical Interactive Input Function.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <sys/syslimits.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include <MainData.h>
+#include "IIOutilities.h"
+#include "IIOechoCtrl.h"
+
+/** Read a line from the input file in canonical mode.
+ Perform echoing and input processing as directed by the termios flags.
+
+ @param[in] filp A pointer to a file descriptor structure.
+
+ @return The number of characters in the input buffer, or -1 if there
+ was an error.
+**/
+ssize_t
+IIO_CanonRead (
+ struct __filedes *filp
+ )
+{
+ cIIO *This;
+ cFIFO *InBuf;
+ struct termios *Termio;
+ struct __filedes *fpOut;
+ size_t NumRead;
+ wint_t InChar;
+ tcflag_t IFlag;
+ tcflag_t LFlag;
+ BOOLEAN EchoIsOK;
+ BOOLEAN Activate;
+ BOOLEAN FirstRead;
+ int OutMode;
+ UINTN MaxColumn;
+ UINTN MaxRow;
+
+ NumRead = MAX_INPUT; // Workaround "potentially uninitialized" warning
+ EchoIsOK = FALSE;
+ FirstRead = TRUE;
+ This = filp->devdata;
+ Termio = &This->Termio;
+ InBuf = This->InBuf;
+
+ // Get a copy of the flags we are going to use
+ IFlag = Termio->c_iflag;
+ LFlag = Termio->c_lflag;
+
+ /* Determine what the current screen size is. Also validates the output device. */
+ OutMode = IIO_GetOutputSize(STDOUT_FILENO, &MaxColumn, &MaxRow);
+ if(OutMode >= 0) {
+ /* Set the maximum screen dimensions. */
+ This->MaxColumn = MaxColumn;
+ This->MaxRow = MaxRow;
+
+ /* Record where the cursor is at the beginning of this Input operation.
+ The currently set stdout device is used to determine this. If there is
+ no stdout, or stdout is not an interactive device, nothing is recorded.
+ */
+ if (IIO_GetCursorPosition(STDOUT_FILENO, &This->InitialXY.Column, &This->InitialXY.Row) >= 0) {
+ This->CurrentXY.Column = This->InitialXY.Column;
+ This->CurrentXY.Row = This->InitialXY.Row;
+ EchoIsOK = TRUE; // Can only echo to stdout
+ }
+ }
+
+ // For now, we only echo to stdout.
+ fpOut = &gMD->fdarray[STDOUT_FILENO];
+
+ // Input and process characters until BufferSize is exhausted.
+ do {
+ InChar = IIO_GetInChar(filp, FirstRead);
+ FirstRead = FALSE;
+ Activate = TRUE;
+ if(InChar == CHAR_CARRIAGE_RETURN) {
+ if((IFlag & IGNCR) != 0) {
+ continue; // Restart the do loop, discarding the CR
+ }
+ else if((IFlag & ICRNL) != 0) {
+ InChar = L'\n';
+ }
+ }
+ else if(InChar == CHAR_LINEFEED) {
+ if((IFlag & INLCR) != 0) {
+ InChar = L'\r';
+ }
+ }
+ else if(CCEQ(Termio->c_cc[VINTR], InChar)) {
+ if((LFlag & ISIG) != 0) {
+ // Raise Signal
+ // Flush Input Buffer
+ // Return to caller
+ InChar = IIO_ECHO_DISCARD;
+ errno = EINTR;
+ }
+ else {
+ Activate = FALSE;
+ }
+ }
+ else if(CCEQ(Termio->c_cc[VQUIT], InChar)) {
+ if((LFlag & ISIG) != 0) {
+ // Raise Signal
+ // Flush Input Buffer
+ // Return to caller
+ InChar = IIO_ECHO_DISCARD;
+ errno = EINTR;
+ }
+ else {
+ Activate = FALSE;
+ }
+ }
+ else if(CCEQ(Termio->c_cc[VEOF], InChar)) {
+ InChar = WEOF;
+ }
+ else if(CCEQ(Termio->c_cc[VEOL], InChar)) {
+ EchoIsOK = FALSE; // Buffer, but don't echo this character
+ }
+ else if(CCEQ(Termio->c_cc[VERASE], InChar)) {
+ InChar = IIO_ECHO_ERASE;
+ Activate = FALSE;
+ }
+ else if(CCEQ(Termio->c_cc[VKILL], InChar)) {
+ InChar = IIO_ECHO_KILL;
+ Activate = FALSE;
+ }
+ else {
+ if((InChar < TtySpecKeyMin) || (InChar >= TtyFunKeyMax)) {
+ Activate = FALSE;
+ }
+ }
+ /** The Echo function is responsible for:
+ * Adding the character to the input buffer, if appropriate.
+ * Removing characters from the input buffer for ERASE and KILL processing.
+ * Visually removing characters from the screen if ECHOE is set.
+ * Ensuring one can not backspace beyond the beginning of the input text.
+ * Sending final echo strings to output.
+ **/
+ (void)This->Echo(fpOut, (wchar_t)InChar, EchoIsOK);
+ NumRead = InBuf->Count(InBuf, AsElements);
+ } while((NumRead < MAX_INPUT) &&
+ (Activate == FALSE));
+
+ return (ssize_t)NumRead;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIO.c b/StdLib/LibC/Uefi/InteractiveIO/IIO.c
new file mode 100644
index 0000000000..65b61d9bcc
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIO.c
@@ -0,0 +1,373 @@
+/** @file
+ Definitions for the Interactive IO library.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/syslimits.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include <MainData.h>
+#include "IIOutilities.h"
+#include "IIOechoCtrl.h"
+
+/** Read from an Interactive IO device.
+
+ NOTE: If _S_IWTTY is set, the internal buffer contains WIDE characters.
+ They will need to be converted to MBCS when returned.
+
+ Input is line buffered if ICANON is set,
+ otherwise MIN determines how many characters to input.
+ Currently MIN is always zero, meaning 0 or 1 character is input in
+ noncanonical mode.
+
+ @param[in] filp Pointer to the descriptor of the device (file) to be read.
+ @param[in] BufferSize Maximum number of bytes to be returned to the caller.
+ @param[out] Buffer Pointer to the buffer where the input is to be stored.
+
+ @retval -1 An error occurred. No data is available.
+ @retval 0 No data was available. Try again later.
+ @retval >0 The number of bytes consumed by the returned data.
+**/
+static
+ssize_t
+EFIAPI
+IIO_Read(
+ struct __filedes *filp,
+ size_t BufferSize,
+ VOID *Buffer
+ )
+{
+ cIIO *This;
+ ssize_t NumRead;
+ tcflag_t Flags;
+ size_t XlateSz;
+ size_t Needed;
+
+ NumRead = -1;
+ This = filp->devdata;
+ if(This != NULL) {
+ Flags = This->Termio.c_lflag;
+ if(Flags & ICANON) {
+ NumRead = IIO_CanonRead(filp);
+ }
+ else {
+ NumRead = IIO_NonCanonRead(filp);
+ }
+ // At this point, the input has been accumulated in the input buffer.
+ if(filp->f_iflags & _S_IWTTY) {
+ // Data in InBuf is wide characters. Convert to MBCS
+ // First, convert into a linear buffer
+ NumRead = This->InBuf->Copy(This->InBuf, gMD->UString2, (INT32)UNICODE_STRING_MAX-1);
+ gMD->UString2[NumRead] = 0; // Ensure that the buffer is terminated
+ // Determine the needed space
+ XlateSz = EstimateWtoM((const wchar_t *)gMD->UString2, BufferSize, &Needed);
+
+ // Now translate this into MBCS in Buffer
+ NumRead = wcstombs((char *)Buffer, (const wchar_t *)gMD->UString2, XlateSz);
+
+ // Consume the translated characters
+ (void)This->InBuf->Flush(This->InBuf, Needed);
+ }
+ else {
+ // Data in InBuf is narrow characters. Use verbatim.
+ NumRead = This->InBuf->Read(This->InBuf, Buffer, (INT32)BufferSize);
+ }
+ }
+ return NumRead;
+}
+
+/** Process characters from buffer buf and write them to the output device
+ specified by filp.
+
+ @param[in] filp Pointer to a file descriptor structure.
+ @param[in] buf Pointer to the MBCS string to be output.
+ @param[in] N Number of bytes in buf.
+
+ @retval >=0 Number of bytes sent to the output device.
+**/
+static
+ssize_t
+EFIAPI
+IIO_Write(
+ struct __filedes *filp,
+ const char *buf,
+ ssize_t N
+ )
+{
+ cIIO *This;
+ cFIFO *OutBuf;
+ mbstate_t *OutState;
+ char *MbcsPtr;
+ ssize_t NumWritten;
+ ssize_t NumProc;
+ size_t CharLen;
+ UINTN MaxColumn;
+ UINTN MaxRow;
+ wchar_t OutChar[2]; // Just in case we run into 4-byte MBCS character
+ int OutMode;
+
+ errno = 0; // indicate no error as default
+ NumWritten = -1;
+
+ /* Determine what the current screen size is. Also validates the output device. */
+ OutMode = IIO_GetOutputSize(filp->MyFD, &MaxColumn, &MaxRow);
+
+ This = filp->devdata;
+ if((This != NULL) && (OutMode >= 0)) {
+ if(filp->MyFD == STDERR_FILENO) {
+ OutBuf = This->ErrBuf;
+ OutState = &This->ErrState;
+ }
+ else {
+ OutBuf = This->OutBuf;
+ OutState = &This->OutState;
+ }
+
+ /* Set the maximum screen dimensions. */
+ This->MaxColumn = MaxColumn;
+ This->MaxRow = MaxRow;
+
+ /* Record where the cursor is at the beginning of the Output operation. */
+ (void)IIO_GetCursorPosition(filp->MyFD, &This->InitialXY.Column, &This->InitialXY.Row);
+ This->CurrentXY.Column = This->InitialXY.Column;
+ This->CurrentXY.Row = This->InitialXY.Row;
+
+
+ NumWritten = 0;
+ OutChar[0] = (wchar_t)buf[0];
+ while((OutChar[0] != 0) && (NumWritten < N)) {
+ CharLen = mbrtowc(OutChar, (const char *)&buf[NumWritten], MB_CUR_MAX, OutState);
+ NumProc = IIO_WriteOne(filp, OutBuf, OutChar[0]);
+ if(NumProc > 0) {
+ // Successfully processed and buffered one character
+ NumWritten += CharLen; // Index of start of next character
+ }
+ else if(NumProc == -1) {
+ // Encoding Error
+ (void)mbrtowc(NULL, NULL, 1, OutState); // Re-Initialize the conversion state
+ errno = EILSEQ;
+ break;
+ }
+ else {
+ // Last character was incomplete
+ break;
+ }
+ }
+ // At this point, the characters to write are in OutBuf
+ // First, linearize the buffer
+ NumWritten = OutBuf->Copy(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);
+ gMD->UString[NumWritten] = 0; // Ensure that the buffer is terminated
+
+ if(filp->f_iflags & _S_IWTTY) {
+ // Output device expects wide characters, Output what we have
+ NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, gMD->UString);
+ }
+ else {
+ // Output device expects narrow characters, convert to MBCS
+ MbcsPtr = (char *)gMD->UString2;
+ // Determine the needed space
+ NumProc = (ssize_t)EstimateWtoM((const wchar_t *)gMD->UString, UNICODE_STRING_MAX * sizeof(wchar_t), &CharLen);
+
+ // Now translate this into MBCS in Buffer
+ NumWritten = wcstombs(MbcsPtr, (const wchar_t *)gMD->UString, NumProc);
+ MbcsPtr[NumWritten] = 0; // Ensure the buffer is terminated
+
+ // Send the MBCS buffer to Output
+ NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, MbcsPtr);
+ }
+ // Consume the translated characters
+ (void)OutBuf->Flush(OutBuf, NumWritten);
+ }
+ else {
+ if(This == NULL) {
+ errno = EINVAL;
+ }
+ // Otherwise, errno is already set.
+ }
+ return NumWritten;
+}
+
+/** Echo a character to an output device.
+ Performs translation and edit processing depending upon termios flags.
+
+ @param[in] filp A pointer to a file descriptor structure.
+ @param[in] EChar The character to echo.
+ @param[in] EchoIsOK TRUE if the caller has determined that characters
+ should be echoed. Otherwise, just buffer.
+
+ @return Returns the number of characters actually output.
+**/
+static
+ssize_t
+EFIAPI
+IIO_Echo(
+ struct __filedes *filp,
+ wchar_t EChar,
+ BOOLEAN EchoIsOK
+ )
+{
+ cIIO *This;
+ ssize_t NumWritten;
+ cFIFO *OutBuf;
+ char *MbcsPtr;
+ ssize_t NumProc;
+ tcflag_t LFlags;
+
+ NumWritten = -1;
+ This = filp->devdata;
+ if(This != NULL) {
+ OutBuf = This->OutBuf;
+ LFlags = This->Termio.c_lflag & (ECHOK | ECHOE);
+
+ if((EChar >= TtyFunKeyMin) && (EChar < TtyFunKeyMax)) {
+ // A special function key was pressed, buffer it, don't echo, and activate.
+ // Process and buffer the character. May produce multiple characters.
+ NumProc = IIO_EchoOne(filp, EChar, FALSE); // Don't echo this character
+ EChar = CHAR_LINEFEED; // Every line must end with '\n' (legacy)
+ }
+ // Process and buffer the character. May produce multiple characters.
+ NumProc = IIO_EchoOne(filp, EChar, EchoIsOK);
+
+ // At this point, the character(s) to write are in OutBuf
+ // First, linearize the buffer
+ NumWritten = OutBuf->Copy(OutBuf, gMD->UString, UNICODE_STRING_MAX-1);
+ gMD->UString[NumWritten] = 0; // Ensure that the buffer is terminated
+
+ if((EChar == IIO_ECHO_KILL) && (LFlags & ECHOE) && EchoIsOK) {
+ // Position the cursor to the start of input.
+ (void)IIO_SetCursorPosition(filp, &This->InitialXY);
+ }
+ // Output the buffer
+ if(filp->f_iflags & _S_IWTTY) {
+ // Output device expects wide characters, Output what we have
+ NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, gMD->UString);
+ }
+ else {
+ // Output device expects narrow characters, convert to MBCS
+ MbcsPtr = (char *)gMD->UString2;
+ // Determine the needed space
+ NumProc = (ssize_t)EstimateWtoM((const wchar_t *)gMD->UString, UNICODE_STRING_MAX * sizeof(wchar_t), NULL);
+
+ // Now translate this into MBCS in Buffer
+ NumWritten = wcstombs(MbcsPtr, (const wchar_t *)gMD->UString, NumProc);
+ MbcsPtr[NumWritten] = 0; // Ensure the buffer is terminated
+
+ // Send the MBCS buffer to Output
+ NumWritten = filp->f_ops->fo_write(filp, NULL, NumWritten, MbcsPtr);
+ }
+ // Consume the echoed characters
+ (void)OutBuf->Flush(OutBuf, NumWritten);
+
+ if(EChar == IIO_ECHO_KILL) {
+ if(LFlags == ECHOK) {
+ NumWritten = IIO_WriteOne(filp, OutBuf, CHAR_LINEFEED);
+ }
+ else if((LFlags & ECHOE) && EchoIsOK) {
+ // Position the cursor to the start of input.
+ (void)IIO_SetCursorPosition(filp, &This->InitialXY);
+ }
+ NumWritten = 0;
+ }
+ }
+ else {
+ errno = EINVAL;
+ }
+
+ return NumWritten;
+}
+
+static
+void
+FifoDelete(cFIFO *Member)
+{
+ if(Member != NULL) {
+ Member->Delete(Member);
+ }
+}
+
+/** Destructor for an IIO instance.
+
+ Releases all resources used by a particular IIO instance.
+**/
+static
+void
+EFIAPI
+IIO_Delete(
+ cIIO *Self
+ )
+{
+ if(Self != NULL) {
+ FifoDelete(Self->ErrBuf);
+ FifoDelete(Self->OutBuf);
+ FifoDelete(Self->InBuf);
+ if(Self->AttrBuf != NULL) {
+ FreePool(Self->AttrBuf);
+ }
+ FreePool(Self);
+ }
+}
+
+/** Constructor for new IIO instances.
+
+ @return Returns NULL or a pointer to a new IIO instance.
+**/
+cIIO *
+EFIAPI
+New_cIIO(void)
+{
+ cIIO *IIO;
+ cc_t *TempBuf;
+ int i;
+
+ IIO = (cIIO *)AllocateZeroPool(sizeof(cIIO));
+ if(IIO != NULL) {
+ IIO->InBuf = New_cFIFO(MAX_INPUT, sizeof(wchar_t));
+ IIO->OutBuf = New_cFIFO(MAX_OUTPUT, sizeof(wchar_t));
+ IIO->ErrBuf = New_cFIFO(MAX_OUTPUT, sizeof(wchar_t));
+ IIO->AttrBuf = (UINT8 *)AllocateZeroPool(MAX_OUTPUT);
+
+ if((IIO->InBuf == NULL) || (IIO->OutBuf == NULL) ||
+ (IIO->ErrBuf == NULL) || (IIO->AttrBuf == NULL))
+ {
+ IIO_Delete(IIO);
+ IIO = NULL;
+ }
+ else {
+ IIO->Delete = IIO_Delete;
+ IIO->Read = IIO_Read;
+ IIO->Write = IIO_Write;
+ IIO->Echo = IIO_Echo;
+ }
+ // Initialize Termio member
+ TempBuf = &IIO->Termio.c_cc[0];
+ TempBuf[0] = 8; // Default length for TABs
+ for(i=1; i < NCCS; ++i) {
+ TempBuf[i] = _POSIX_VDISABLE;
+ }
+ TempBuf[VMIN] = 0;
+ TempBuf[VTIME] = 0;
+ IIO->Termio.c_ispeed = B115200;
+ IIO->Termio.c_ospeed = B115200;
+ IIO->Termio.c_iflag = ICRNL;
+ IIO->Termio.c_oflag = OPOST | ONLCR | ONOCR | ONLRET;
+ IIO->Termio.c_cflag = 0;
+ IIO->Termio.c_lflag = ECHO | ECHONL;
+ }
+ return IIO;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIO.inf b/StdLib/LibC/Uefi/InteractiveIO/IIO.inf
new file mode 100644
index 0000000000..dd21e85b13
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIO.inf
@@ -0,0 +1,51 @@
+## @file
+# Interactive I/O Library.
+#
+# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LibIIO
+ FILE_GUID = c1e9fffb-5557-4cb5-a5f5-1fbd902a74ed
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LibIIO
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ IIO.c
+ NonCanonRead.c
+ CanonRead.c
+ TerminalFunctions.c
+ IIOutilities.c
+ IIOwrite.c
+ IIOecho.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ StdLib/StdLib.dec
+ StdLibPrivateInternalFiles/DoNotUse.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ LibC
+ LibWchar
+ LibContainer
+
+[Protocols]
+ gEfiSimpleTextInProtocolGuid ## CONSUMES
+ gEfiSimpleTextOutProtocolGuid ## CONSUMES
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIOecho.c b/StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
new file mode 100644
index 0000000000..14369de95b
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
@@ -0,0 +1,141 @@
+/** @file
+ Echo characters to an Interactive I/O Output device.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+ Since the UEFI console is a WIDE character device, these functions do all
+ processing using wide characters.
+
+ It is the responsibility of the caller, or higher level function, to perform
+ any necessary translation between wide and narrow characters.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include "IIOutilities.h"
+#include "IIOechoCtrl.h"
+
+/** Echo one character to an IIO file.
+
+ If character InCh is a special "echo control" character, process it and output
+ the resultant character(s), if any. Otherwise pass the character on to the
+ IIO_WriteOne() function which performs generic output processing, if needed.
+
+ @param[in] filp Pointer to an open IIO file's file descriptor structure.
+ @param[in] InCh The wide character to be echoed.
+ @param[in] EchoIsOK A flag indicating whether echoing is appropriate for this
+ device or not.
+
+ @retval -1 The filp argument does not refer to an IIO device.
+ Global value errno is set to EINVAL.
+ @retval >=0 The number of characters actually output.
+
+ @sa IIO_WriteOne
+**/
+ssize_t
+IIO_EchoOne (
+ struct __filedes *filp,
+ wchar_t InCh,
+ BOOLEAN EchoIsOK
+ )
+{
+ cIIO *This;
+ cFIFO *OutBuf;
+ cFIFO *InBuf;
+ UINT8 *AttrBuf;
+ ssize_t NumEcho;
+ tcflag_t LFlags;
+ UINT32 AttrDex;
+ int i;
+
+ NumEcho = -1;
+ This = filp->devdata;
+
+ if(This != NULL) {
+ LFlags = This->Termio.c_lflag;
+ OutBuf = This->OutBuf;
+ InBuf = This->InBuf;
+ AttrBuf = This->AttrBuf;
+ AttrDex = InBuf->GetWDex(InBuf);
+
+ switch(InCh) {
+ case IIO_ECHO_DISCARD:
+ // Do not buffer or otherwise process
+ NumEcho = 0;
+ break;
+
+ case IIO_ECHO_ERASE:
+ // Delete last character from InBuf
+ if(!InBuf->IsEmpty(InBuf)) {
+ (void)InBuf->Truncate(InBuf);
+
+ // Erase screen character(s) based on Attrib value
+ if(LFlags & ECHO) {
+ AttrDex = (UINT32)ModuloDecrement(AttrDex, InBuf->NumElements);
+ NumEcho = AttrBuf[AttrDex];
+ for(i = 0; i < NumEcho; ++i) {
+ (void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
+ }
+ if(LFlags & ECHOE) {
+ for(i = 0; i < NumEcho; ++i) {
+ (void)IIO_WriteOne(filp, OutBuf, L' ');
+ }
+ for(i = 0; i < NumEcho; ++i) {
+ (void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
+ }
+ }
+ }
+ else {
+ NumEcho = 0;
+ }
+ }
+ break;
+
+ case IIO_ECHO_KILL:
+ // Flush contents of InBuf and OutBuf
+ InBuf->Flush(InBuf, (size_t)-1);
+ OutBuf->Flush(OutBuf, (size_t)-1);
+
+ // Erase characters from screen.
+ if(LFlags & ECHOE) {
+ NumEcho = IIO_CursorDelta(This, &This->InitialXY, &This->CurrentXY);
+ for(i = 0; i < NumEcho; ++i) {
+ (void)IIO_WriteOne(filp, OutBuf, L' ');
+ }
+ }
+ break;
+
+ default:
+ // Add character to input buffer
+ (void)InBuf->Write(InBuf, &InCh, 1);
+
+ NumEcho = 0; // In case echoing is not enabled or OK
+ // If echoing is OK and enabled, "echo" character using IIO_WriteOne
+ if( EchoIsOK &&
+ ( (LFlags & ECHO) ||
+ ((LFlags & ECHONL) && (InCh == CHAR_LINEFEED))))
+ {
+ NumEcho = IIO_WriteOne(filp, OutBuf, InCh);
+ }
+ AttrBuf[AttrDex] = (UINT8)NumEcho;
+ break;
+ }
+ }
+ else {
+ errno = EINVAL;
+ }
+ return NumEcho;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h b/StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h
new file mode 100644
index 0000000000..69d040af01
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIOechoCtrl.h
@@ -0,0 +1,33 @@
+/** @file
+ Constants and declarations for the Echo function.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _IIO_ECHO_CTRL_H
+#define _IIO_ECHO_CTRL_H
+#include <sys/termios.h>
+
+__BEGIN_DECLS
+
+/* These constants are assigned values within the Unicode Private Use range.
+ The value of IIO_ECHO_MIN must be adjusted to ensure that IIO_ECHO_MAX
+ never exceeds the value of 0xF900.
+*/
+typedef enum {
+ IIO_ECHO_MIN = (TtyFunKeyMin - 3),
+ IIO_ECHO_DISCARD = IIO_ECHO_MIN, // Ignore this character completely
+ IIO_ECHO_ERASE, // Erase previous character
+ IIO_ECHO_KILL, // Kill the entire line
+ IIO_ECHO_MAX
+} IioEchoCtrl;
+
+__END_DECLS
+
+#endif /* _IIO_ECHO_CTRL_H */
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c b/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c
new file mode 100644
index 0000000000..2da0628840
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.c
@@ -0,0 +1,288 @@
+/** @file
+ Utilities for Interactive I/O Functions.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Protocol/SimpleTextOut.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/syslimits.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include <MainData.h>
+#include "IIOutilities.h"
+
+/** Get the low-level UEFI protocol associated with an open file.
+
+ @param[in] fd File descriptor for an open file.
+ @param[out] filp NULL, or a pointer to where a pointer to the file's
+ file descriptor structure is to be stored.
+
+ @return Returns NULL if fd is not a valid file descriptor, otherwise
+ a pointer to the file's associated UEFI protocol is returned.
+**/
+void *
+EFIAPI
+IIO_GetDeviceProto (
+ int fd,
+ struct __filedes **filp
+ )
+{
+ void *Proto;
+ ConInstance *Stream;
+ struct __filedes *pfil;
+
+ Proto = NULL;
+ if(ValidateFD( fd, VALID_OPEN)) {
+ pfil = &gMD->fdarray[fd];
+ Stream = BASE_CR(pfil->f_ops, ConInstance, Abstraction);
+ Proto = (void *)Stream->Dev;
+ if(filp != NULL) {
+ *filp = pfil;
+ }
+ }
+ return Proto;
+}
+
+/** Get a character either from the input buffer or from hardware.
+
+ @param[in] filp Pointer to a file descriptor structure.
+ @param[in] First Set to TRUE to identify the initial read.
+
+ @return Returns a character read from either the input buffer
+ or from the open file (device) identified by filp.
+ A return value of WEOF indicates an error has occurred.
+**/
+wint_t
+EFIAPI
+IIO_GetInChar (
+ struct __filedes *filp,
+ BOOLEAN First
+)
+{
+ cIIO *This;
+ cFIFO *InBuf;
+ EFI_STATUS Status;
+ ssize_t NumRead;
+ wint_t RetVal;
+ wchar_t InChar;
+
+ static size_t BufCnt;
+
+ This = filp->devdata;
+ InBuf = This->InBuf;
+
+ NumRead = -1;
+ InChar = 0;
+ if(First) {
+ BufCnt = InBuf->Count(InBuf, AsElements);
+ }
+ if(BufCnt > 0) {
+ Status = InBuf->Read(InBuf, &InChar, 1);
+ --BufCnt;
+ NumRead = 1;
+ }
+ else {
+ NumRead = filp->f_ops->fo_read(filp, &filp->f_offset, sizeof(wchar_t), &InChar);
+ }
+ if(NumRead <= 0) {
+ RetVal = WEOF;
+ }
+ else {
+ RetVal = (wint_t)InChar;
+ }
+ return InChar;
+}
+
+/** Get the current cursor position.
+
+ @param[in] fd File descriptor for an open file.
+ @param[out] Column Pointer to where the current cursor column is to be stored.
+ @param[out] Row Pointer to where the current cursor row is to be stored.
+
+ @retval -1 fd is not an IIO output device.
+ @retval 0 Cursor position retrieved, Cursor is Not Visible.
+ @retval 1 Cursor position retrieved, Cursor is Visible.
+**/
+int
+EFIAPI
+IIO_GetCursorPosition (
+ int fd,
+ UINT32 *Column,
+ UINT32 *Row
+ )
+{
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ struct __filedes *pStdOut;
+ int RetVal;
+
+ RetVal = -1;
+
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
+ if(Proto != NULL) {
+ if(((pStdOut->f_iflags & _S_ITTY) != 0) && // file is a TTY
+ ((pStdOut->Oflags & O_ACCMODE) != 0)) // and it is open for output
+ {
+ // fd is for a TTY or "Interactive IO" device
+ *Column = Proto->Mode->CursorColumn;
+ *Row = Proto->Mode->CursorRow;
+ if(Proto->Mode->CursorVisible) {
+ RetVal = 1;
+ }
+ else {
+ RetVal = 0;
+ }
+ }
+ }
+ return RetVal;
+}
+
+/** Set the cursor position.
+
+ @param[in] filp Pointer to the output device's file descriptor structure.
+ @param[in] StartXY Pointer to a cursor coordinate (XY) structure indicating
+ the desired coordinate to move the cursor to.
+
+ @retval -1 fd is not an IIO output device
+ @retval 0 Cursor position set successfully.
+**/
+int
+EFIAPI
+IIO_SetCursorPosition (
+ struct __filedes *filp,
+ CURSOR_XY *CursorXY
+ )
+{
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ cIIO *This;
+ EFI_STATUS Status;
+ int RetVal;
+
+ RetVal = -1;
+
+ This = filp->devdata;
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(filp->MyFD, NULL);
+ if(Proto != NULL) {
+ if(((filp->f_iflags & _S_ITTY) != 0) && // file is a TTY
+ ((filp->Oflags & O_ACCMODE) != 0)) // and it is open for output
+ {
+ // fd is for a TTY or "Interactive IO" device
+ Status = Proto->SetCursorPosition(Proto, CursorXY->Column, CursorXY->Row);
+ if(Status == EFI_SUCCESS) {
+ This->CurrentXY.Column = CursorXY->Column;
+ This->CurrentXY.Row = CursorXY->Row;
+ RetVal = 0;
+ }
+ }
+ }
+ return RetVal;
+}
+
+/** Get Output screen size and mode.
+
+ @param[in] fd File descriptor of the output device.
+ @param[out] Col Pointer to where to store the MAX Column, or NULL.
+ @param[out] Row Pointer to where to store the MAX Row, or NULL.
+
+ @retval <0 An error occurred. The reason is in errno and EFIerrno.
+ * EIO UEFI QueryMode failed
+ * ENOTTY fd does not refer to an interactive output device
+ @retval >=0 Current output mode
+**/
+int
+EFIAPI
+IIO_GetOutputSize (
+ int fd,
+ UINTN *Col,
+ UINTN *Row
+)
+{
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;
+ struct __filedes *pStdOut;
+ EFI_STATUS Status;
+ UINTN TempCol;
+ UINTN TempRow;
+ UINTN TempMode;
+ int RetVal;
+
+ RetVal = -1;
+
+ Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
+ if(Proto != NULL) {
+ if(((pStdOut->f_iflags & _S_ITTY) != 0) && // file is a TTY
+ ((pStdOut->Oflags & O_ACCMODE) != 0)) // and it is open for output
+ {
+ // fd is for a TTY or "Interactive IO" device
+ TempMode = Proto->Mode->Mode;
+ Status = Proto->QueryMode(Proto, TempMode, &TempCol, &TempRow);
+ if(EFI_ERROR(Status)) {
+ EFIerrno = Status;
+ errno = EIO;
+ }
+ else {
+ *Col = TempCol;
+ *Row = TempRow;
+ RetVal = (int)TempMode;
+ }
+ }
+ else {
+ errno = ENOTTY;
+ }
+ }
+ return RetVal;
+}
+
+/** Calculate the number of character positions between two X/Y coordinate pairs.
+
+ Using the current output device characteristics, calculate the number of
+ characters between two coordinates. It is assumed that EndXY points to
+ an output location that occurs after StartXY.
+
+ RowDelta is the computed difference between the ending and starting rows.
+ If RowDelta < 0, then EndXY is NOT after StartXY, so assert.
+
+ ColumnDelta is the computed number of character positions (columns) between
+ the starting position and the ending position. If ColumnDelta is < 0,
+ then EndXY is NOT after StartXY, so assert.
+
+ @param[in] This Pointer to the IIO instance to be examined.
+ @param[in] StartXY Pointer to the starting coordinate pair.
+ @param[in] EndXY Pointer to the ending coordinate pair.
+
+ @return Returns the difference between the starting and ending coordinates.
+**/
+UINT32
+EFIAPI
+IIO_CursorDelta (
+ cIIO *This,
+ CURSOR_XY *StartXY,
+ CURSOR_XY *EndXY
+)
+{
+ INT32 ColumnDelta;
+ INT32 RowDelta;
+
+ RowDelta = (int)EndXY->Row - (int)StartXY->Row;
+
+ assert(RowDelta >= 0); // assert if EndXY is NOT after StartXY
+
+ ColumnDelta = (INT32)((This->MaxColumn * RowDelta) + EndXY->Column);
+ ColumnDelta -= (INT32)StartXY->Column;
+
+ assert(ColumnDelta >= 0); // assert if EndXY is NOT after StartXY
+
+ return (UINT32)ColumnDelta;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h b/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h
new file mode 100644
index 0000000000..778b612ea5
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIOutilities.h
@@ -0,0 +1,129 @@
+/** @file
+ Utilities for Interactive I/O Functions.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _IIO_UTILITIES_H
+#define _IIO_UTILITIES_H
+
+#include <sys/EfiSysCall.h>
+
+__BEGIN_DECLS
+
+/** Get the low-level UEFI protocol associated with an open file.
+
+ @param[in] fd File descriptor for an open file.
+ @param[out] filp NULL, or a pointer to where a pointer to the file's
+ file descriptor structure is to be stored.
+
+ @return Returns NULL if fd is not a valid file descriptor, otherwise
+ a pointer to the file's associated UEFI protocol is returned.
+**/
+void *
+EFIAPI
+IIO_GetDeviceProto (
+ int fd,
+ struct __filedes **filp // Optional - filp == NULL if unused
+ );
+
+/** Get a character either from the input buffer or from hardware.
+
+ @param[in] filp Pointer to a file descriptor structure.
+ @param[in] First Set to TRUE to identify the initial read.
+
+ @return Returns a character read from either the input buffer
+ or from the open file (device) identified by filp.
+ A return value of WEOF indicates an error has occurred.
+**/
+wint_t
+EFIAPI
+IIO_GetInChar (
+ struct __filedes *filp,
+ BOOLEAN First
+ );
+
+/** Get the current cursor position.
+
+ @param[in] fd File descriptor for an open file.
+ @param[out] Column Pointer to where the current cursor column is to be stored.
+ @param[out] Row Pointer to where the current cursor row is to be stored.
+
+ @retval -1 fd is not an IIO output device.
+ @retval 0 Cursor position retrieved, Cursor is Not Visible.
+ @retval 1 Cursor position retrieved, Cursor is Visible.
+**/
+int
+EFIAPI
+IIO_GetCursorPosition (
+ int fd,
+ UINT32 *Column,
+ UINT32 *Row
+ );
+
+/** Set the cursor position.
+
+ @param[in] filp Pointer to the output device's file descriptor structure.
+ @param[in] StartXY Pointer to a cursor coordinate (XY) structure indicating
+ the desired coordinate to move the cursor to.
+
+ @retval -1 fd is not an IIO output device
+ @retval 0 Cursor position set successfully.
+**/
+int
+EFIAPI
+IIO_SetCursorPosition (
+ struct __filedes *filp,
+ CURSOR_XY *StartXY
+ );
+
+/** Get Output screen size and mode.
+
+ @param[in] fd File descriptor of the output device.
+ @param[out] Col Pointer to where to store the MAX Column, or NULL.
+ @param[out] Row Pointer to where to store the MAX Row, or NULL.
+
+ @retval <0 An error occurred. The reason is in errno and EFIerrno.
+ * EIO UEFI QueryMode failed
+ * ENOTTY fd does not refer to an interactive output device
+ @retval >=0 Current output mode
+**/
+int
+EFIAPI
+IIO_GetOutputSize (
+ int fd,
+ UINTN *Col,
+ UINTN *Row
+);
+
+/** Calculate the number of character positions between two X/Y coordinate pairs.
+
+ Using the current output device characteristics, calculate the number of
+ characters between two coordinates.
+
+ @param[in] This Pointer to the IIO instance to be examined.
+ @param[in] StartXY Pointer to the starting coordinate pair.
+ @param[in] EndXY Pointer to the ending coordinate pair.
+
+ @return Returns the difference between the starting and ending coordinates.
+ The return value is positive if the coordinates contained in EndXY
+ are larger than StartXY, otherwise the return value is negative.
+**/
+int
+EFIAPI
+IIO_CursorDelta (
+ cIIO *This,
+ CURSOR_XY *StartXY,
+ CURSOR_XY *EndXY
+ );
+
+__END_DECLS
+#endif /* _IIO_UTILITIES_H */
diff --git a/StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c b/StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c
new file mode 100644
index 0000000000..927f4f4ff3
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/IIOwrite.c
@@ -0,0 +1,210 @@
+/** @file
+ Write to an Interactive I/O Output device.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+ Since the UEFI console is a WIDE character device, these functions do all
+ processing using wide characters.
+
+ It is the responsibility of the caller, or higher level function, to perform
+ any necessary translation between wide and narrow characters.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+
+#include <LibConfig.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+
+static wchar_t Spaces[] = L" "; // Spaces for expanding TABs
+
+#define MAX_TAB_WIDTH ((int)(sizeof(Spaces) / sizeof(wchar_t)) - 1)
+
+#define MAX_EXPANSION 3
+
+/** Process and buffer one character for output.
+
+ @param[in] filp Pointer to a file descriptor structure.
+ @param[out] OBuf Pointer to the Output Buffer FIFO.
+ @param[in] InCh The wide character to process.
+
+ @retval <0 An error occurred. Reason is in errno.
+ * EINVAL The pointer to the IIO object is NULL.
+ * ENOSPC The OBuf FIFO is full.
+
+ @retval 0 A character was input but not placed in the output buffer.
+
+ @retval >0 The number of characters buffered. Normally 1, or 2.
+ If a character is discarded because of flag settings, a
+ 1 will be returned.
+**/
+ssize_t
+IIO_WriteOne(struct __filedes *filp, cFIFO *OBuf, wchar_t InCh)
+{
+ cIIO *This;
+ struct termios *Termio;
+ tcflag_t OFlag;
+ ssize_t RetVal;
+ wchar_t wc[MAX_EXPANSION]; // Sub-buffer for conversions
+ wchar_t *wcb; // Pointer to either wc or spaces
+ int numW = 0; // Wide characters placed in OBuf
+ INT32 TabWidth; // Each TAB expands into this number of spaces
+ UINT32 CurColumn; // Current cursor column on the screen
+ UINT32 CurRow; // Current cursor row on the screen
+ UINT32 PrevColumn; // Previous column. Used to detect wrapping.
+ UINT32 AdjColumn; // Current cursor column on the screen
+ UINT32 AdjRow; // Current cursor row on the screen
+
+ RetVal = -1;
+ wcb = wc;
+ This = filp->devdata;
+ if((This != NULL) && (OBuf->FreeSpace(OBuf, AsElements) >= MAX_EXPANSION)) {
+ Termio = &This->Termio;
+ OFlag = Termio->c_oflag;
+ TabWidth = (INT32)This->Termio.c_cc[VTABLEN];
+ if(TabWidth > MAX_TAB_WIDTH) {
+ TabWidth = MAX_TAB_WIDTH;
+ }
+ CurColumn = This->CurrentXY.Column;
+ CurRow = This->CurrentXY.Row;
+
+ numW = 1; // The majority of characters buffer one character
+ AdjRow = 0; // Most characters just cause horizontal movement
+ AdjColumn = 0;
+ if(OFlag & OPOST) {
+ /* Perform output processing */
+ switch(InCh) {
+ case CHAR_TAB: //{{
+ if(OFlag & OXTABS) {
+ if(TabWidth > 0) {
+ int SpaceIndex;
+
+ SpaceIndex = CurColumn % TabWidth; // Number of spaces after a Tab Stop
+ numW = TabWidth - SpaceIndex; // Number of spaces to the next Tab Stop
+ SpaceIndex = MAX_TAB_WIDTH - numW; // Index into the Spaces array
+ wcb = &Spaces[SpaceIndex]; // Point to the appropriate number of spaces
+ }
+ else {
+ wc[0] = L' ';
+ }
+ AdjColumn = numW;
+ }
+ else {
+ wc[0] = InCh; // Send the TAB itself - assumes that it does not move cursor.
+ }
+ break; //}}
+
+ case CHAR_CARRIAGE_RETURN: //{{
+ if((OFlag & OCRNL) == 0) {
+ if((OFlag & ONLRET) == 0) {
+ numW = 0; /* Discard the CR */
+ // Cursor doesn't move
+ }
+ else {
+ wc[0] = CHAR_CARRIAGE_RETURN;
+ CurColumn = 0;
+ }
+ break;
+ }
+ else {
+ InCh = CHAR_LINEFEED;
+ } //}}
+ // Fall through to the NL case
+ case CHAR_LINEFEED: //{{
+ if(OFlag & ONLCR) {
+ wc[0] = CHAR_CARRIAGE_RETURN;
+ wc[1] = CHAR_LINEFEED;
+ numW = 2;
+ CurColumn = 0;
+ }
+ AdjRow = 1;
+ break; //}}
+
+ case CHAR_BACKSPACE: //{{
+ if(CurColumn > 0) {
+ wc[0] = CHAR_BACKSPACE;
+ CurColumn = (UINT32)ModuloDecrement(CurColumn, (UINT32)This->MaxColumn);
+ }
+ else {
+ numW = 0; // Discard the backspace if in column 0
+ }
+ break; //}}
+
+ case CHAR_EOT: //{{
+ if(OFlag & ONOEOT) {
+ numW = 0; // Discard the EOT character
+ // Cursor doesn't move
+ break;
+ } //}}
+ // Fall through to default in order to potentially output "^D"
+ default: //{{
+ if((InCh >= 0) && (InCh < L' ')) {
+ // InCh contains a control character
+ if(OFlag & OCTRL) {
+ wc[1] = InCh + L'@';
+ wc[0] = L'^';
+ numW = 2;
+ AdjColumn = 2;
+ }
+ else {
+ numW = 0; // Discard. Not a UEFI supported control character.
+ }
+ }
+ else {
+ // Regular printing character
+ wc[0] = InCh;
+ AdjColumn = 1;
+ }
+ break; //}}
+ }
+ if(numW < MAX_EXPANSION) {
+ wc[numW] = 0; // Terminate the sub-buffer
+ }
+ if(AdjColumn != 0) {
+ // Adjust the cursor position
+ PrevColumn = CurColumn;
+ CurColumn = ModuloAdd(PrevColumn, AdjColumn, (UINT32)This->MaxColumn);
+ if(CurColumn < PrevColumn) {
+ // We must have wrapped, so we are on the next Row
+ ++CurRow;
+ if(CurRow >= This->MaxRow) {
+ // The screen has scrolled so need to adjust Initial location.
+ --This->InitialXY.Row; // Initial row has moved up one
+ CurRow = (UINT32)(This->MaxRow - 1); // We stay on the bottom row
+ }
+ }
+ }
+ This->CurrentXY.Column = CurColumn;
+ This->CurrentXY.Row = CurRow;
+ }
+ else {
+ // Output processing disabled -- RAW output mode
+ wc[0] = InCh;
+ wc[1] = 0;
+ }
+ // Put the character(s) into the output buffer
+ if(numW > 0) {
+ (void)OBuf->Write(OBuf, (const void *)wcb, (size_t)numW);
+ }
+ RetVal = numW;
+ }
+ else {
+ if(This == NULL) {
+ errno = EINVAL;
+ }
+ else {
+ errno = ENOSPC;
+ }
+ }
+ return RetVal;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c b/StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c
new file mode 100644
index 0000000000..15bf43e260
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/NonCanonRead.c
@@ -0,0 +1,89 @@
+/** @file
+ NonCanonical Interactive Input Function.
+
+ The functions assume that isatty() is TRUE at the time they are called.
+ If _S_IWTTY is set, the device returns WIDE characters.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <LibConfig.h>
+
+#include <sys/syslimits.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include <Containers/Fifo.h>
+
+/** Perform a noncanonical read of input.
+
+ @param[in] filp Pointer to a file descriptor structure.
+ @param[in] BufferSize Maximum number of bytes to return.
+
+ @retval -1 An error has occurred. Reason in errno.
+ @retval -1 No data returned. None was ready.
+ @retval >0 The number of elements returned
+**/
+ssize_t
+IIO_NonCanonRead (
+ struct __filedes *filp
+ )
+{
+ cIIO *This;
+ cFIFO *InBuf;
+ struct termios *Termio;
+ EFI_STATUS Status;
+ ssize_t NumRead;
+ cc_t tioMin;
+ cc_t tioTime;
+ UINT32 InputType;
+ wchar_t InChar; // Intermediate character buffer
+
+ NumRead = -1;
+ InChar = 0; // Initialize so compilers don't complain.
+ This = filp->devdata;
+ Termio = &This->Termio;
+ InBuf = This->InBuf;
+ tioMin = Termio->c_cc[VMIN];
+ tioTime = Termio->c_cc[VTIME];
+
+ if(tioMin >= MAX_INPUT) {
+ tioMin = MAX_INPUT;
+ }
+ /* There are four types of processing that may be done, based on
+ the values of tioMin and tioTime.
+ Min Time Type
+ --- ---- ----
+ 0 0 0 Return buffer contents or 1 new char
+ 0 >0 1 Return 0 or 1 character depending on timeout
+ >0 0 2 Buffer Min chars. Return BufferSize chars.
+ >0 >0 3 Return up to Min chars. Unless the inter-byte timer expires.
+
+ Currently, only type 0 is implemented.
+ */
+ InputType = 0;
+ if(tioMin != 0) InputType = 2;
+ if(tioTime != 0) ++InputType;
+ //switch(InputType) {
+ // case 0:
+ if(InBuf->IsEmpty(InBuf)) {
+ NumRead = filp->f_ops->fo_read(filp, &filp->f_offset, sizeof(wchar_t), &InChar);
+ if(NumRead > 0) {
+ Status = InBuf->Write(InBuf, &InChar, 1); // Buffer the character
+ }
+ }
+ // break;
+ // case 1:
+ // break;
+ // case 2:
+ // break;
+ // case 3:
+ // break;
+ //}
+ return NumRead;
+}
diff --git a/StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c b/StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c
new file mode 100644
index 0000000000..807ab1fd4c
--- /dev/null
+++ b/StdLib/LibC/Uefi/InteractiveIO/TerminalFunctions.c
@@ -0,0 +1,285 @@
+/** @file
+ "Terminal" Control functions for Interactive IO.
+
+ Copyright (c) 2012, 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
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <LibConfig.h>
+
+#include <errno.h>
+#include <sys/termios.h>
+#include <Device/IIO.h>
+#include <MainData.h>
+
+/** Get input baud rate.
+
+ Extracts the input baud rate from the termios structure pointed to by the
+ pTermios argument.
+
+ @param[in] pTermios A pointer to the termios structure from which to extract
+ the input baud rate.
+
+ @return The value of the input speed is returned exactly as it is contained
+ in the termios structure, without interpretation.
+**/
+speed_t
+cfgetispeed (
+ const struct termios *pTermios
+ )
+{
+ return pTermios->c_ispeed;
+}
+
+/** Get output baud rate.
+
+ Extracts the output baud rate from the termios structure pointed to by the
+ pTermios argument.
+
+ @param[in] pTermios A pointer to the termios structure from which to extract
+ the output baud rate.
+
+ @return The value of the output speed is returned exactly as it is contained
+ in the termios structure, without interpretation.
+**/
+speed_t
+cfgetospeed (
+ const struct termios *pTermios
+ )
+{
+ return pTermios->c_ospeed;
+}
+
+/** Set input baud rate.
+
+ Replaces the input baud rate, in the termios structure pointed to by the
+ pTermios argument, with the value of NewSpeed.
+
+ @param[out] pTermios A pointer to the termios structure into which to set
+ the input baud rate.
+ @param[in] NewSpeed The new input baud rate.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EINVAL - The value of NewSpeed is outside the range of
+ possible speed values as specified in <sys/termios.h>.
+**/
+int
+cfsetispeed (
+ struct termios *pTermios,
+ speed_t NewSpeed
+ )
+{
+ int RetVal;
+
+ if(NewSpeed < B921600) {
+ pTermios->c_ispeed = NewSpeed;
+ RetVal = 0;
+ }
+ else {
+ RetVal = -1;
+ errno = EINVAL;
+ }
+ return RetVal;
+}
+
+/** Set output baud rate.
+
+ Replaces the output baud rate, in the termios structure pointed to by the
+ pTermios argument, with the value of NewSpeed.
+
+ @param[out] pTermios A pointer to the termios structure into which to set
+ the output baud rate.
+ @param[in] NewSpeed The new output baud rate.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EINVAL - The value of NewSpeed is outside the range of
+ possible speed values as specified in <sys/termios.h>.
+**/
+int
+cfsetospeed (
+ struct termios *pTermios,
+ speed_t NewSpeed
+ )
+{
+ int RetVal;
+
+ if(NewSpeed < B921600) {
+ pTermios->c_ospeed = NewSpeed;
+ RetVal = 0;
+ }
+ else {
+ RetVal = -1;
+ errno = EINVAL;
+ }
+ return RetVal;
+}
+
+/** Get the parameters associated with an interactive IO device.
+
+ Get the parameters associated with the device referred to by
+ fd and store them into the termios structure referenced by pTermios.
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+ @param[out] pTermios A pointer to a termios structure into which to store
+ attributes of the interactive IO device.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+**/
+int
+tcgetattr (
+ int fd,
+ struct termios *pTermios
+ )
+{
+ cIIO *IIO;
+ int RetVal;
+ struct __filedes *filp;
+ struct termios *Termio;
+
+ RetVal = 0;
+ if(ValidateFD( fd, VALID_OPEN)) {
+ filp = &gMD->fdarray[fd];
+
+ if((filp->f_iflags & _S_ITTY) != 0) {
+ // fd is for a TTY or "Interactive IO" device
+ IIO = (cIIO *)filp->devdata;
+ Termio = &IIO->Termio;
+ (void)CopyMem((void *)pTermios, (const void *)Termio, sizeof(struct termios));
+ }
+ else {
+ errno = ENOTTY;
+ RetVal = -1;
+ }
+ }
+ else {
+ errno = EBADF;
+ RetVal = -1;
+ }
+ return RetVal;
+}
+
+/** Set the parameters associated with an interactive IO device.
+
+ Set the parameters associated with the device referred to by
+ fd to the values in the termios structure referenced by pTermios.
+
+ Behavior is modified by the value of the OptAct parameter:
+ * TCSANOW: The change shall occur immediately.
+ * TCSADRAIN: The change shall occur after all output written to fd is
+ transmitted. This action should be used when changing parameters which
+ affect output.
+ * TCSAFLUSH: The change shall occur after all output written to fd is
+ transmitted, and all input so far received but not read shall be
+ discarded before the change is made.
+
+ @param[in] fd The file descriptor for an open interactive IO device.
+ @param[in] OptAct Currently has no effect.
+ @param[in] pTermios A pointer to a termios structure into which to retrieve
+ attributes to set in the interactive IO device.
+
+ @retval 0 The operation completed successfully.
+ @retval -1 An error occured and errno is set to indicate the error.
+ * EBADF - The fd argument is not a valid file descriptor.
+ * ENOTTY - The file associated with fd is not an interactive IO device.
+**/
+int
+tcsetattr (
+ int fd,
+ int OptAct, // Currently ignored
+ const struct termios *pTermios
+ )
+{
+ cIIO *IIO;
+ int RetVal;
+ struct __filedes *filp;
+ struct termios *Termio;
+
+ RetVal = 0;
+ if(ValidateFD( fd, VALID_OPEN)) {
+ filp = &gMD->fdarray[fd];
+
+ if((filp->f_iflags & _S_ITTY) != 0) {
+ // fd is for a TTY or "Interactive IO" device
+ IIO = (cIIO *)filp->devdata;
+ Termio = &IIO->Termio;
+ (void)CopyMem((void *)Termio, (const void *)pTermios, sizeof(struct termios));
+ }
+ else {
+ errno = ENOTTY;
+ RetVal = -1;
+ }
+ }
+ else {
+ errno = EBADF;
+ RetVal = -1;
+ }
+ return RetVal;
+}
+
+/** Transmit pending output.
+
+ Function is not yet implemented for UEFI.
+
+ @param[in] fd Ignored
+
+ @retval -1 This function is not yet supported. errno is set to ENOTSUP.
+**/
+int
+tcdrain (int fd)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+/** Suspend or restart the transmission or reception of data.
+
+ This function will suspend or resume transmission or reception of data on
+ the file referred to by fd, depending on the value of Action.
+
+ Function is not yet implemented for UEFI.
+
+ @param[in] fd Ignored
+ @param[in] Action Ignored
+
+ @retval -1 This function is not yet supported. errno is set to ENOTSUP.
+**/
+int
+tcflow (
+ int fd,
+ int Action)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+/** Discard non-transmitted output data, non-read input data, or both.
+
+ Function is not yet implemented for UEFI.
+
+ @param[in] fd Ignored
+ @param[in] QueueSelector Ignored
+
+ @retval -1 This function is not yet supported. errno is set to ENOTSUP.
+**/
+int
+tcflush (
+ int fd,
+ int QueueSelector)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
diff --git a/StdLib/LibC/Uefi/SysCalls.c b/StdLib/LibC/Uefi/SysCalls.c
index 5576938f8e..a2b627bd12 100644
--- a/StdLib/LibC/Uefi/SysCalls.c
+++ b/StdLib/LibC/Uefi/SysCalls.c
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <kfile.h>
#include <Device/Device.h>
+#include <Device/IIO.h>
#include <MainData.h>
#include <extern.h>
@@ -114,12 +115,14 @@ DeleteOnClose(int fd)
return retval;
}
-/** The isatty() function tests whether fildes, an open file descriptor,
+/** The isatty() function tests whether fd, an open file descriptor,
is associated with a terminal device.
- @retval 1 fildes is associated with a terminal.
- @retval 0 fildes is not associated with a terminal. errno is set to
- EBADF if fildes is not a valid open FD.
+ @param[in] fd File Descriptor for the file to be examined.
+
+ @retval 1 fd is associated with a terminal.
+ @retval 0 fd is not associated with a terminal. errno is set to
+ EBADF if fd is not a valid open FD.
**/
int
isatty (int fd)
@@ -129,7 +132,7 @@ isatty (int fd)
if(ValidateFD( fd, VALID_OPEN)) {
Fp = &gMD->fdarray[fd];
- retval = Fp->f_iflags & _S_ITTY;
+ retval = (Fp->f_iflags & _S_ITTY) ? 1 : 0;
}
else {
errno = EBADF;
@@ -169,13 +172,14 @@ IsDupFd( int fd)
return Ret;
}
-/** Close a file and set its fd to the specified state.
+/** Worker function to Close a file and set its fd to the specified state.
@param[in] fd The file descriptor to close.
@param[in] NewState State to set the fd to after the file is closed.
@retval 0 The operation completed successfully.
@retval -1 The operation failed. Further information is in errno.
+ * EBADF fd is not a valid or open file descriptor.
**/
static int
_closeX (int fd, int NewState)
@@ -221,6 +225,8 @@ _closeX (int fd, int NewState)
descriptors. All outstanding record locks owned by the process on the file
associated with the file descriptor are removed (that is, unlocked).
+ @param[in] fd Descriptor for the File to close.
+
@retval 0 Successful completion.
@retval -1 An error occurred and errno is set to identify the error.
**/
@@ -230,7 +236,14 @@ close (int fd)
return _closeX(fd, 0);
}
-/**
+/** Delete the file specified by path.
+
+ @param[in] path The MBCS path of the file to delete.
+
+ @retval -1 Unable to open the file specified by path.
+ @retval -1 If (errno == EPERM), unlink is not permited for this file.
+ @retval -1 Low-level delete filed. Reason is in errno.
+ @retval 0 The file was successfully deleted.
**/
int
unlink (const char *path)
@@ -315,6 +328,10 @@ unlink (const char *path)
descriptors greater than or equal to arg are available.
[EOVERFLOW] One of the values to be returned cannot be represented correctly.
+ @param[in] fildes Descriptor for the file to be controlled.
+ @param[in] cmd Command to be acted upon.
+ @param[in,out] ... Optional additional parameters as required by cmd.
+
@return Upon successful completion, the value returned shall depend on
cmd as follows:
- F_DUPFD - A new file descriptor.
@@ -407,6 +424,8 @@ fcntl (int fildes, int cmd, ...)
shall be equivalent to:
- fid = fcntl(fildes, F_DUPFD, 0);
+ @param[in] fildes Descriptor for the file to be examined.
+
@return Upon successful completion a non-negative integer, namely the
file descriptor, shall be returned; otherwise, -1 shall be
returned and errno set to indicate the error.
@@ -417,7 +436,9 @@ dup (int fildes)
return fcntl(fildes, F_DUPFD, 0);
}
-/** The dup2() function provides an alternative interface to the
+/** Make fildes2 refer to a duplicate of fildes.
+
+ The dup2() function provides an alternative interface to the
service provided by fcntl() using the F_DUPFD command. The call:
- fid = dup2(fildes, fildes2);
shall be equivalent to:
@@ -433,6 +454,9 @@ dup (int fildes)
- The value returned shall be equal to the value of fildes2 upon
successful completion, or -1 upon failure.
+ @param[in] fildes File Descriptor to be duplicated.
+ @param[in] fildes2 File Descriptor to be made a duplicate of fildes.
+
@return Upon successful completion a non-negative integer, namely
fildes2, shall be returned; otherwise, -1 shall be
returned and errno set to EBADF indicate the error.
@@ -470,13 +494,13 @@ dup2 (int fildes, int fildes2)
fildes must be an open file descriptor. lseek() repositions the file
pointer fildes as follows:
- If how is SEEK_SET, the offset is set to offset bytes.
+ - If how is SEEK_SET, the offset is set to offset bytes.
- If how is SEEK_CUR, the offset is set to its current location
- plus offset bytes.
+ - If how is SEEK_CUR, the offset is set to its current location
+ plus offset bytes.
- If how is SEEK_END, the offset is set to the size of the file
- plus offset bytes.
+ - If how is SEEK_END, the offset is set to the size of the file
+ plus offset bytes.
The lseek() function allows the file offset to be set beyond the end of
the existing end-of-file of the file. If data is later written at this
@@ -486,6 +510,10 @@ dup2 (int fildes, int fildes2)
Some devices are incapable of seeking. The value of the pointer associ-
ated with such a device is undefined.
+ @param[in] fd Descriptor for the File to be affected.
+ @param[in] offset Value to adjust the file position by.
+ @param[in] how How the file position is to be adjusted.
+
@return Upon successful completion, lseek() returns the resulting offset
location as measured in bytes from the beginning of the file.
Otherwise, a value of -1 is returned and errno is set to
@@ -524,6 +552,9 @@ lseek (int fd, __off_t offset, int how)
The directory is closed after it is created.
+ @param[in] path The path to a directory to create.
+ @param[in] perms Permissions as defined in <sys/stat.h>
+
@retval 0 The directory was created successfully.
@retval -1 An error occurred and error codes are stored in errno and EFIerrno.
**/
@@ -606,19 +637,19 @@ mkdir (const char *path, __mode_t perms)
@param[in] oflags File status flags and file access modes of the
open file description.
@param[in] mode File access permission bits as defined in
- <sys/stat.h>.
+ <sys/stat.h>. Only used if a file is created
+ as a result of the open.
@return Upon successful completion, open() opens the file and returns
a non-negative integer representing the lowest numbered
unused file descriptor. Otherwise, open returns -1 and sets
errno to indicate the error. If a negative value is
returned, no files are created or modified.
-
- @retval EMFILE No file descriptors available -- Max number already open.
- @retval EINVAL Bad value specified for oflags or mode.
- @retval ENOMEM Failure allocating memory for internal buffers.
- @retval EEXIST File exists and open attempted with (O_EXCL | O_CREAT) set.
- @retval EIO UEFI failure. Check value in EFIerrno.
+ - EMFILE - No file descriptors available -- Max number already open.
+ - EINVAL - Bad value specified for oflags or mode.
+ - ENOMEM - Failure allocating memory for internal buffers.
+ - EEXIST - File exists and open attempted with (O_EXCL | O_CREAT) set.
+ - EIO - UEFI failure. Check value in EFIerrno.
**/
int
open(
@@ -631,18 +662,20 @@ open(
wchar_t *MPath;
DeviceNode *Node;
struct __filedes *filp;
+ struct termios *Termio;
int Instance = 0;
RETURN_STATUS Status;
- UINT64 OpenMode;
+ UINT32 OpenMode;
int fd = -1;
int doresult;
Status = ParsePath(path, &NewPath, &Node, &Instance, &MPath);
if(Status == RETURN_SUCCESS) {
if((Node == NULL) ||
- (Node->InstanceList == NULL)) {
+ (Node->InstanceList == NULL))
+ {
errno = EPERM;
- }
+ }
else {
// Could add a test to see if the file name begins with a period.
// If it does, then add the HIDDEN flag to Attributes.
@@ -666,23 +699,31 @@ open(
fd = -1; // Indicate an error
}
else {
- // Re-use OpenMode in order to build our final f_iflags value
+ // Build our final f_iflags value
OpenMode = ( mode & S_ACC_READ ) ? S_ACC_READ : 0;
OpenMode |= ( mode & S_ACC_WRITE ) ? S_ACC_WRITE : 0;
- filp->f_iflags |= (UINT32)OpenMode;
+ filp->f_iflags |= OpenMode;
+
+ if((oflags & O_TTY_INIT) && (filp->f_iflags & _S_ITTY) && (filp->devdata != NULL)) {
+ // Initialize the device's termios flags to a "sane" value
+ Termio = &((cIIO *)filp->devdata)->Termio;
+ Termio->c_iflag = ICRNL | IGNSPEC;
+ Termio->c_oflag = OPOST | ONLCR | OXTABS | ONOEOT | ONOCR | ONLRET | OCTRL;
+ Termio->c_lflag = ECHO | ECHOE | ECHONL | ICANON;
+ Termio->c_cc[VERASE] = 0x08; // ^H Backspace
+ Termio->c_cc[VKILL] = 0x15; // ^U
+ Termio->c_cc[VINTR] = 0x03; // ^C Interrupt character
+ }
++filp->RefCount;
FILE_SET_MATURE(filp);
}
}
}
- if(NewPath != NULL) {
free(NewPath);
}
- }
- if(MPath != NULL) {
free(MPath); // We don't need this any more.
- }
+
// return the fd of our now open file
return fd;
}
@@ -699,11 +740,11 @@ open(
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html">POSIX</a>
documentation is available online.
- @param [in] pfd Address of an array of pollfd structures.
+ @param[in] pfd Address of an array of pollfd structures.
- @param [in] nfds Number of elements in the array of pollfd structures.
+ @param[in] nfds Number of elements in the array of pollfd structures.
- @param [in] timeout Length of time in milliseconds to wait for the event
+ @param[in] timeout Length of time in milliseconds to wait for the event
@return The number of file descriptors with detected events. Zero
indicates that the call timed out and -1 indicates an error.
@@ -841,38 +882,44 @@ poll (
/** The rename() function changes the name of a file.
- The old argument points to the pathname of the file to be renamed. The new
+ The From argument points to the pathname of the file to be renamed. The To
argument points to the new pathname of the file.
- If the old argument points to the pathname of a file that is not a
- directory, the new argument shall not point to the pathname of a
- directory. If the file named by the new argument exists, it shall be
- removed and old renamed to new. Write access permission is required for
- both the directory containing old and the directory containing new.
+ If the From argument points to the pathname of a file that is not a
+ directory, the To argument shall not point to the pathname of a
+ directory. If the file named by the To argument exists, it shall be
+ removed and From renamed to To. Write access permission is required for
+ both the directory containing old and the directory containing To.
- If the old argument points to the pathname of a directory, the new
+ If the From argument points to the pathname of a directory, the To
argument shall not point to the pathname of a file that is not a
- directory. If the directory named by the new argument exists, it shall be
- removed and old renamed to new.
+ directory. If the directory named by the To argument exists, it shall be
+ removed and From renamed to To.
- The new pathname shall not contain a path prefix that names old. Write
- access permission is required for the directory containing old and the
- directory containing new. If the old argument points to the pathname of a
+ The To pathname shall not contain a path prefix that names From. Write
+ access permission is required for the directory containing From and the
+ directory containing To. If the From argument points to the pathname of a
directory, write access permission may be required for the directory named
- by old, and, if it exists, the directory named by new.
+ by From, and, if it exists, the directory named by To.
If the rename() function fails for any reason other than [EIO], any file
- named by new shall be unaffected.
+ named by To shall be unaffected.
- @return Upon successful completion, rename() shall return 0; otherwise,
- -1 shall be returned, errno shall be set to indicate the error,
- and neither the file named by old nor the file named by new
- shall be changed or created.
+ @param[in] From Path to the file to be renamed.
+ @param[in] To The new name of From.
+
+ @retval 0 Successful completion.
+ @retval -1 An error has occured and errno has been set to further specify the error.
+ Neither the file named by From nor the file named by To are
+ changed or created.
+ - ENXIO: Path specified is not supported by any loaded driver.
+ - ENOMEM: Insufficient memory to calloc a MapName buffer.
+ - EINVAL: The path parameter is not valid.
**/
int
rename(
- const char *from,
- const char *to
+ const char *From,
+ const char *To
)
{
wchar_t *FromPath;
@@ -882,7 +929,7 @@ rename(
RETURN_STATUS Status;
int retval = -1;
- Status = ParsePath(from, &FromPath, &FromNode, &Instance, NULL);
+ Status = ParsePath(From, &FromPath, &FromNode, &Instance, NULL);
if(Status == RETURN_SUCCESS) {
GenI = FromNode->InstanceList;
if(GenI == NULL) {
@@ -891,14 +938,19 @@ rename(
}
else {
//GenI += (Instance * FromNode->InstanceSize);
- retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( from, to);
+ retval = ((GenericInstance *)GenI)->Abstraction.fo_rename( From, To);
}
free(FromPath);
}
return retval;
}
-/**
+/** Delete a specified directory.
+
+ @param[in] path Path to the directory to delete.
+
+ @retval -1 The directory couldn't be opened (doesn't exist).
+ @retval -1 The directory wasn't empty or an IO error occured.
**/
int
rmdir(
@@ -921,10 +973,10 @@ rmdir(
}
/** The fstat() function obtains information about an open file associated
- with the file descriptor fildes, and shall write it to the area pointed to
- by buf.
+ with the file descriptor fd, and writes it to the area pointed to
+ by statbuf.
- The buf argument is a pointer to a stat structure, as defined
+ The statbuf argument is a pointer to a stat structure, as defined
in <sys/stat.h>, into which information is placed concerning the file.
The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime,
@@ -939,7 +991,7 @@ rmdir(
The stat structure members which don't have direct analogs to EFI file
information are filled in as follows:
- - st_mode Populated with information from fildes
+ - st_mode Populated with information from fd
- st_ino Set to zero. (inode)
- st_dev Set to zero.
- st_uid Set to zero.
@@ -974,6 +1026,9 @@ fstat (int fd, struct stat *statbuf)
Opens the file pointed to by path, calls _EFI_FileInfo with the file's handle,
then closes the file.
+ @param[in] path Path to the file to obtain information about.
+ @param[out] statbuf Buffer in which the file status is put.
+
@retval 0 Successful Completion.
@retval -1 An error has occurred and errno has been set to
identify the error.
@@ -994,7 +1049,15 @@ stat (const char *path, struct stat *statbuf)
return retval;
}
-/** Same as stat since EFI doesn't have symbolic links. **/
+/** Same as stat since EFI doesn't have symbolic links.
+
+ @param[in] path Path to the file to obtain information about.
+ @param[out] statbuf Buffer in which the file status is put.
+
+ @retval 0 Successful Completion.
+ @retval -1 An error has occurred and errno has been set to
+ identify the error.
+**/
int
lstat (const char *path, struct stat *statbuf)
{
@@ -1002,6 +1065,13 @@ lstat (const char *path, struct stat *statbuf)
}
/** Control a device.
+
+ @param[in] fd Descriptor for the file to be acted upon.
+ @param[in] request Specifies the operation to perform.
+ @param[in,out] ... Zero or more parameters as required for request.
+
+ @retval >=0 The operation completed successfully.
+ @retval -1 An error occured. More information is in errno.
**/
int
ioctl(
@@ -1098,6 +1168,10 @@ ioctl(
directory entries, the read returns a zero-length buffer.
EFI_FILE_INFO is the structure returned as the directory entry.
+ @param[in] fildes Descriptor of the file to be read.
+ @param[out] buf Pointer to location in which to store the read data.
+ @param[in] nbyte Maximum number of bytes to be read.
+
@return Upon successful completion, read() returns a non-negative integer
indicating the number of bytes actually read. Otherwise, the
functions return a negative value and sets errno to indicate the
@@ -1109,62 +1183,91 @@ ssize_t
read (int fildes, void *buf, size_t nbyte)
{
struct __filedes *filp;
+ cIIO *IIO;
ssize_t BufSize;
BufSize = (ssize_t)nbyte;
- if(ValidateFD( fildes, VALID_OPEN)) {
- filp = &gMD->fdarray[fildes];
+ if(BufSize > 0) {
+ if(ValidateFD( fildes, VALID_OPEN)) {
+ filp = &gMD->fdarray[fildes];
- BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf);
- }
- else {
- errno = EBADF;
- BufSize = -EBADF;
+ IIO = filp->devdata;
+ if(isatty(fildes) && (IIO != NULL)) {
+ BufSize = IIO->Read(filp, nbyte, buf);
+ }
+ else {
+ BufSize = filp->f_ops->fo_read(filp, &filp->f_offset, nbyte, buf);
+ }
+ }
+ else {
+ errno = EBADF;
+ BufSize = -1;
+ }
}
return BufSize;
}
/** Write data to a file.
- This function writes the specified number of bytes to the file at the current
- file position. The current file position is advanced the actual number of bytes
- written, which is returned in BufferSize. Partial writes only occur when there
- has been a data error during the write attempt (such as "volume space full").
- The file is automatically grown to hold the data if required. Direct writes to
- opened directories are not supported.
-
- If fildes refers to a terminal device, isatty() returns TRUE, a partial write
- will occur if a NULL or EOF character is encountered before n characters have
- been written. Characters inserted due to line-end translations will not be
- counted. Unconvertable characters are translated into the UEFI character
- BLOCKELEMENT_LIGHT_SHADE.
-
- Since the UEFI console device works on wide characters, the buffer is assumed
- to contain a single-byte character stream which is then translated to wide
- characters using the btowc() functions. The resulting wide character stream
- is what is actually sent to the UEFI console.
-
- QUESTION: Should writes to stdout or stderr always succeed?
+ This function writes the specified number of bytes to the file at the current
+ file position. The current file position is advanced the actual number of bytes
+ written, which is returned in BufferSize. Partial writes only occur when there
+ has been a data error during the write attempt (such as "volume space full").
+ The file is automatically grown to hold the data if required. Direct writes to
+ opened directories are not supported.
+
+ If fildes refers to a terminal device, isatty() returns TRUE, a partial write
+ will occur if a NULL or EOF character is encountered before n characters have
+ been written. Characters inserted due to line-end translations will not be
+ counted. Unconvertable characters are translated into the UEFI character
+ BLOCKELEMENT_LIGHT_SHADE.
+
+ Since the UEFI console device works on wide characters, the buffer is assumed
+ to contain a single-byte character stream which is then translated to wide
+ characters using the mbtowc() functions. The resulting wide character stream
+ is what is actually sent to the UEFI console.
+
+ @param[in] fd Descriptor of file to be written to.
+ @param[in] buf Pointer to data to write to the file.
+ @param[in] nbyte Number of bytes to be written to the file.
+
+ @retval >=0 Number of bytes actually written to the file.
+ @retval <0 An error occurred. More data is provided by errno.
**/
ssize_t
write (int fd, const void *buf, size_t nbyte)
{
struct __filedes *filp;
+ cIIO *IIO;
ssize_t BufSize;
-// EFI_FILE_HANDLE FileHandle;
-// RETURN_STATUS Status = RETURN_SUCCESS;
BufSize = (ssize_t)nbyte;
if(ValidateFD( fd, VALID_OPEN)) {
filp = &gMD->fdarray[fd];
-
- BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf);
+ if ((filp->Oflags & O_ACCMODE) != 0) {
+ // File is open for writing
+ IIO = filp->devdata;
+ if(isatty(fd) && (IIO != NULL)) {
+ // Output to an Interactive I/O device
+ BufSize = IIO->Write(filp, buf, nbyte);
+ }
+ else {
+ // Output to a file, socket, pipe, etc.
+ BufSize = filp->f_ops->fo_write(filp, &filp->f_offset, nbyte, buf);
+ }
}
else {
+ // File is NOT open for writing
+ errno = EINVAL;
+ BufSize = -1;
+ }
+ }
+ else {
+ // fd is not for a valid open file
errno = EBADF;
- BufSize = -EBADF;
- }
+ BufSize = -1;
+ }
return BufSize;
}
@@ -1260,11 +1363,29 @@ chdir (const char *path)
return -1;
}
+/** Get the foreground process group ID associated with a terminal.
+
+ Just returns the Image Handle for the requestor since UEFI does not have
+ a concept of processes or groups.
+
+ @param[in] x Ignored.
+
+ @return Returns the Image Handle of the application or driver which
+ called this function.
+**/
pid_t tcgetpgrp (int x)
{
return ((pid_t)(UINTN)(gImageHandle));
}
+/** Get the process group ID of the calling process.
+
+ Just returns the Image Handle for the requestor since UEFI does not have
+ a concept of processes or groups.
+
+ @return Returns the Image Handle of the application or driver which
+ called this function.
+**/
pid_t getpgrp(void)
{
return ((pid_t)(UINTN)(gImageHandle));
@@ -1300,10 +1421,11 @@ va_Utimes(
/** Set file access and modification times.
- @param[in] path
- @param[in] times
+ @param[in] path Path to the file to be modified.
+ @param[in] times Pointer to an array of two timeval structures
- @return
+ @retval 0 File times successfully set.
+ @retval -1 An error occured. Error type in errno.
**/
int
utimes(
@@ -1313,4 +1435,3 @@ utimes(
{
return va_Utimes(path, times);
}
-
diff --git a/StdLib/StdLib.dsc b/StdLib/StdLib.dsc
index c352b22455..f9f28b872b 100644
--- a/StdLib/StdLib.dsc
+++ b/StdLib/StdLib.dsc
@@ -113,11 +113,15 @@
StdLib/LibC/Uefi/Devices/daConsole.inf
StdLib/LibC/Uefi/Devices/daShell.inf
+# Additional, non-standard, libraries
+ StdLib/LibC/Containers/ContainerLib.inf
+
# Additional libraries for POSIX functionality.
StdLib/PosixLib/Err/LibErr.inf
StdLib/PosixLib/Gen/LibGen.inf
StdLib/PosixLib/Glob/LibGlob.inf
StdLib/PosixLib/Stringlist/LibStringlist.inf
+ StdLib/LibC/Uefi/InteractiveIO/IIO.inf
# Socket Libraries - LibC based
StdLib/BsdSocketLib/BsdSocketLib.inf
diff --git a/StdLib/StdLib.inc b/StdLib/StdLib.inc
index 4b7e37eb65..9b014b9fc6 100644
--- a/StdLib/StdLib.inc
+++ b/StdLib/StdLib.inc
@@ -54,6 +54,10 @@
LibGen|StdLib/PosixLib/Gen/LibGen.inf
LibGlob|StdLib/PosixLib/Glob/LibGlob.inf
LibStringlist|StdLib/PosixLib/Stringlist/LibStringlist.inf
+ LibIIO|StdLib/LibC/Uefi/InteractiveIO/IIO.inf
+
+# Additional, non-standard, libraries
+ LibContainer|StdLib/LibC/Containers/ContainerLib.inf
# Libraries for device abstractions within the Standard C Library
# Applications should not directly access any functions defined in these libraries.
diff --git a/StdLibPrivateInternalFiles/Include/Device/IIO.h b/StdLibPrivateInternalFiles/Include/Device/IIO.h
new file mode 100644
index 0000000000..4eb3623cdc
--- /dev/null
+++ b/StdLibPrivateInternalFiles/Include/Device/IIO.h
@@ -0,0 +1,81 @@
+/** @file
+ Constants and declarations for the Interactive IO library.
+
+ Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _INTERACTIVE_IO_H
+#define _INTERACTIVE_IO_H
+
+#include <sys/EfiSysCall.h>
+#include <sys/termios.h>
+#include <Containers/Fifo.h>
+#include <kfile.h>
+
+__BEGIN_DECLS
+
+typedef struct _IIO_Instance cIIO;
+
+cIIO * EFIAPI New_cIIO(void); // Creates a new cIIO structure
+
+/* Types of Member functions of the TTY I/O "class". */
+typedef void (EFIAPI *cIIO_Delete) (cIIO *This);
+
+typedef ssize_t (EFIAPI *cIIO_Read) (struct __filedes *filp, size_t BufferSize, VOID *Buffer);
+
+typedef ssize_t (EFIAPI *cIIO_Write) (struct __filedes *filp, const char *buf, ssize_t n);
+
+typedef ssize_t (EFIAPI *cIIO_Echo) (struct __filedes *filp, wchar_t EChar, BOOLEAN EchoIsOK);
+
+/** Structure defining an instance of the Interactive I/O "class". **/
+struct _IIO_Instance {
+ /* ######## Public Functions ######## */
+ cIIO_Delete Delete;
+ cIIO_Read Read;
+ cIIO_Write Write;
+ cIIO_Echo Echo;
+
+ /* ######## PRIVATE Data ######## */
+
+ // Wide input buffer -- stdin
+ cFIFO *InBuf;
+
+ // Wide output buffer -- stdout
+ cFIFO *OutBuf;
+
+ // Attributes for characters in the output buffer
+ UINT8 *AttrBuf;
+
+ // Wide output buffer -- stderr
+ cFIFO *ErrBuf;
+
+ // Character conversion states for the buffers
+ mbstate_t OutState;
+ mbstate_t ErrState;
+
+ // Cursor position at beginning of operation
+ // and at each character thereafter.
+ CURSOR_XY InitialXY;
+ CURSOR_XY CurrentXY;
+
+ UINTN MaxColumn; // Width of the output device
+ UINTN MaxRow; // Height of the output device
+
+ // termios structure
+ struct termios Termio;
+};
+
+// Helper Functions
+ssize_t IIO_CanonRead (struct __filedes *filp);
+ssize_t IIO_NonCanonRead (struct __filedes *filp);
+ssize_t IIO_WriteOne (struct __filedes *filp, cFIFO *Buf, wchar_t InCh);
+ssize_t IIO_EchoOne (struct __filedes *filp, wchar_t InCh, BOOLEAN EchoIsOK);
+
+__END_DECLS
+#endif /* _INTERACTIVE_IO_H */