From e5251a3139e6f3b2c4de5b7d53c77e6a030e84c1 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 7 Jul 2017 17:11:02 +0800 Subject: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- Core/MdePkg/Include/Library/SmmIoLib.h | 42 ++ Core/MdePkg/Include/Protocol/BluetoothAttribute.h | 283 ++++++++++ Core/MdePkg/Include/Protocol/BluetoothLeConfig.h | 634 ++++++++++++++++++++++ Core/MdePkg/Library/SmmIoLib/SmmIoLib.c | 330 +++++++++++ Core/MdePkg/Library/SmmIoLib/SmmIoLib.inf | 53 ++ Core/MdePkg/Library/SmmIoLib/SmmIoLib.uni | 23 + 6 files changed, 1365 insertions(+) create mode 100644 Core/MdePkg/Include/Library/SmmIoLib.h create mode 100644 Core/MdePkg/Include/Protocol/BluetoothAttribute.h create mode 100644 Core/MdePkg/Include/Protocol/BluetoothLeConfig.h create mode 100644 Core/MdePkg/Library/SmmIoLib/SmmIoLib.c create mode 100644 Core/MdePkg/Library/SmmIoLib/SmmIoLib.inf create mode 100644 Core/MdePkg/Library/SmmIoLib/SmmIoLib.uni (limited to 'Core') diff --git a/Core/MdePkg/Include/Library/SmmIoLib.h b/Core/MdePkg/Include/Library/SmmIoLib.h new file mode 100644 index 0000000000..7820f1ec10 --- /dev/null +++ b/Core/MdePkg/Include/Library/SmmIoLib.h @@ -0,0 +1,42 @@ +/** @file + Provides services for SMM IO Operation. + + The SMM IO Library provides function for checking if IO resource is accessible inside of SMM. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ 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_IO_LIB_H_ +#define _SMM_IO_LIB_H_ + +/** + This function check if the MMIO resource is valid per processor architecture and + valid per platform design. + + @param BaseAddress The MMIO start address to be checked. + @param Length The MMIO length to be checked. + @param Owner A GUID representing the owner of the resource. + This GUID may be used by producer to correlate the device ownership of the resource. + NULL means no specific owner. + + @retval TRUE This MMIO resource is valid per processor architecture and valid per platform design. + @retval FALSE This MMIO resource is not valid per processor architecture or valid per platform design. +**/ +BOOLEAN +EFIAPI +SmmIsMmioValid ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN EFI_GUID *Owner OPTIONAL + ); + +#endif + diff --git a/Core/MdePkg/Include/Protocol/BluetoothAttribute.h b/Core/MdePkg/Include/Protocol/BluetoothAttribute.h new file mode 100644 index 0000000000..f168422cf0 --- /dev/null +++ b/Core/MdePkg/Include/Protocol/BluetoothAttribute.h @@ -0,0 +1,283 @@ +/** @file + EFI Bluetooth Attribute Protocol as defined in UEFI 2.7. + This protocol provides service for Bluetooth ATT (Attribute Protocol) and GATT (Generic + Attribute Profile) based protocol interfaces. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ 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.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. + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.7 + +**/ + +#ifndef __EFI_BLUETOOTH_ATTRIBUTE_H__ +#define __EFI_BLUETOOTH_ATTRIBUTE_H__ + +#define EFI_BLUETOOTH_ATTRIBUTE_SERVICE_BINDING_PROTOCOL_GUID \ + { \ + 0x5639867a, 0x8c8e, 0x408d, { 0xac, 0x2f, 0x4b, 0x61, 0xbd, 0xc0, 0xbb, 0xbb } \ + } + +#define EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL_GUID \ + { \ + 0x898890e9, 0x84b2, 0x4f3a, { 0x8c, 0x58, 0xd8, 0x57, 0x78, 0x13, 0xe0, 0xac } \ + } + +typedef struct _EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL; + +#pragma pack(1) + +// +// Bluetooth UUID +// +typedef struct { + UINT8 Length; + union { + UINT16 Uuid16; + UINT32 Uuid32; + UINT8 Uuid128[16]; + } Data; +} EFI_BLUETOOTH_UUID; + + +#define UUID_16BIT_TYPE_LEN 2 +#define UUID_32BIT_TYPE_LEN 4 +#define UUID_128BIT_TYPE_LEN 16 + +#define BLUETOOTH_IS_ATTRIBUTE_OF_TYPE(a,t) ((a)->Type.Length == UUID_16BIT_TYPE_LEN && (a)->Type.Data.Uuid16 == (t)) + +// +// Bluetooth Attribute Permission +// +typedef union { + struct { + UINT16 Readable : 1; + UINT16 ReadEncryption : 1; + UINT16 ReadAuthentication : 1; + UINT16 ReadAuthorization : 1; + UINT16 ReadKeySize : 5; + UINT16 Reserved1 : 7; + UINT16 Writeable : 1; + UINT16 WriteEncryption : 1; + UINT16 WriteAuthentication : 1; + UINT16 WriteAuthorization : 1; + UINT16 WriteKeySize : 5; + UINT16 Reserved2 : 7; + } Permission; + UINT32 Data32; +} EFI_BLUETOOTH_ATTRIBUTE_PERMISSION; + +typedef struct { + EFI_BLUETOOTH_UUID Type; + UINT16 Length; + UINT16 AttributeHandle; + EFI_BLUETOOTH_ATTRIBUTE_PERMISSION AttributePermission; +} EFI_BLUETOOTH_ATTRIBUTE_HEADER; + +typedef struct { + EFI_BLUETOOTH_ATTRIBUTE_HEADER Header; + UINT16 EndGroupHandle; + EFI_BLUETOOTH_UUID ServiceUuid; +} EFI_BLUETOOTH_GATT_PRIMARY_SERVICE_INFO; + +typedef struct { + EFI_BLUETOOTH_ATTRIBUTE_HEADER Header; + UINT16 StartGroupHandle; + UINT16 EndGroupHandle; + EFI_BLUETOOTH_UUID ServiceUuid; +} EFI_BLUETOOTH_GATT_INCLUDE_SERVICE_INFO; + +typedef struct { + EFI_BLUETOOTH_ATTRIBUTE_HEADER Header; + UINT8 CharacteristicProperties; + UINT16 CharacteristicValueHandle; + EFI_BLUETOOTH_UUID CharacteristicUuid; +} EFI_BLUETOOTH_GATT_CHARACTERISTIC_INFO; + +typedef struct { + EFI_BLUETOOTH_ATTRIBUTE_HEADER Header; + EFI_BLUETOOTH_UUID CharacteristicDescriptorUuid; +} EFI_BLUETOOTH_GATT_CHARACTERISTIC_DESCRIPTOR_INFO; + +#pragma pack() + +typedef struct { + UINT16 AttributeHandle; +} EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER_NOTIFICATION; + +typedef struct { + UINT16 AttributeHandle; +} EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER_INDICATION; + +typedef struct { + UINT32 Version; + UINT8 AttributeOpCode; + union { + EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER_NOTIFICATION Notification; + EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER_INDICATION Indication; + } Parameter; +} EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER; + +typedef struct { + UINT32 Version; + BLUETOOTH_LE_ADDRESS BD_ADDR; + BLUETOOTH_LE_ADDRESS DirectAddress; + UINT8 RSSI; + UINTN AdvertisementDataSize; + VOID *AdvertisementData; +} EFI_BLUETOOTH_LE_DEVICE_INFO; + +/** + The callback function to send request. + + @param[in] This Pointer to the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL instance. + @param[in] Data Data received. The first byte is the attribute opcode, followed by opcode specific + fields. See Bluetooth specification, Vol 3, Part F, Attribute Protocol. It might be a + normal RESPONSE message, or ERROR RESPONSE messag + @param[in] DataLength The length of Data in bytes. + @param[in] Context The context passed from the callback registration request. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_FUNCTION) ( + IN EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL *This, + IN VOID *Data, + IN UINTN DataLength, + IN VOID *Context + ); + +/** + Send a "REQUEST" or "COMMAND" message to remote server and receive a "RESPONSE" message + for "REQUEST" from remote server according to Bluetooth attribute protocol data unit(PDU). + + @param[in] This Pointer to the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL instance. + @param[in] Data Data of a REQUEST or COMMAND message. The first byte is the attribute PDU + related opcode, followed by opcode specific fields. See Bluetooth specification, + Vol 3, Part F, Attribute Protocol. + @param[in] DataLength The length of Data in bytes. + @param[in] Callback Callback function to notify the RESPONSE is received to the caller, with the + response buffer. Caller must check the response buffer content to know if the + request action is success or fail. It may be NULL if the data is a COMMAND. + @param[in] Context Data passed into Callback function. It is optional parameter and may be NULL. + + @retval EFI_SUCCESS The request is sent successfully. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid due to following conditions: + - The Buffer is NULL. + - The BufferLength is 0. + - The opcode in Buffer is not a valid OPCODE according to Bluetooth specification. + - The Callback is NULL. + @retval EFI_DEVICE_ERROR Sending the request failed due to the host controller or the device error. + @retval EFI_NOT_READY A GATT operation is already underway for this device. + @retval EFI_UNSUPPORTED The attribute does not support the corresponding operation. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_ATTRIBUTE_SEND_REQUEST) ( + IN EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL *This, + IN VOID *Data, + IN UINTN DataLength, + IN EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_FUNCTION Callback, + IN VOID *Context + ); + +/** + Register or unregister a server initiated message, such as NOTIFICATION or INDICATION, on a + characteristic value on remote server. + + @param[in] This Pointer to the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL instance. + @param[in] CallbackParameter The parameter of the callback. + @param[in] Callback Callback function for server initiated attribute protocol. NULL callback + function means unregister the server initiated callback. + @param[in] Context Data passed into Callback function. It is optional parameter and may be NULL. + + @retval EFI_SUCCESS The callback function is registered or unregistered successfully + @retval EFI_INVALID_PARAMETER The attribute opcode is not server initiated message opcode. See + Bluetooth specification, Vol 3, Part F, Attribute Protocol. + @retval EFI_ALREADY_STARTED A callback function is already registered on the same attribute + opcode and attribute handle, when the Callback is not NULL. + @retval EFI_NOT_STARTED A callback function is not registered on the same attribute opcode + and attribute handle, when the Callback is NULL. + @retval EFI_NOT_READY A GATT operation is already underway for this device. + @retval EFI_UNSUPPORTED The attribute does not support notification. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_ATTRIBUTE_REGISTER_FOR_SERVER_NOTIFICATION)( + IN EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL *This, + IN EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_PARAMETER *CallbackParameter, + IN EFI_BLUETOOTH_ATTRIBUTE_CALLBACK_FUNCTION Callback, + IN VOID *Context + ); + +/** + Get Bluetooth discovered service information. + + @param[in] This Pointer to the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL instance. + @param[out] ServiceInfoSize A pointer to the size, in bytes, of the ServiceInfo buffer. + @param[out] ServiceInfo A pointer to a callee allocated buffer that returns Bluetooth + discovered service information. Callee allocates this buffer by + using EFI Boot Service AllocatePool(). + + @retval EFI_SUCCESS The Bluetooth discovered service information is returned successfully. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the Bluetooth discovered + service information. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_ATTRIBUTE_GET_SERVICE_INFO)( + IN EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL *This, + OUT UINTN *ServiceInfoSize, + OUT VOID **ServiceInfo + ); + +/** + Get Bluetooth device information. + + @param[in] This Pointer to the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL instance. + @param[out] DeviceInfoSize A pointer to the size, in bytes, of the DeviceInfo buffer. + @param[out] DeviceInfo A pointer to a callee allocated buffer that returns Bluetooth + device information. Callee allocates this buffer by using EFI Boot + Service AllocatePool(). If this device is Bluetooth classic + device, EFI_BLUETOOTH_DEVICE_INFO should be used. If + this device is Bluetooth LE device, EFI_BLUETOOTH_LE_DEVICE_INFO + should be used. + + @retval EFI_SUCCESS The Bluetooth device information is returned successfully. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the Bluetooth device + information + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_ATTRIBUTE_GET_DEVICE_INFO)( + IN EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL *This, + OUT UINTN *DeviceInfoSize, + OUT VOID **DeviceInfo + ); + +struct _EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL { + EFI_BLUETOOTH_ATTRIBUTE_SEND_REQUEST SendRequest; + EFI_BLUETOOTH_ATTRIBUTE_REGISTER_FOR_SERVER_NOTIFICATION RegisterForServerNotification; + EFI_BLUETOOTH_ATTRIBUTE_GET_SERVICE_INFO GetServiceInfo; + EFI_BLUETOOTH_ATTRIBUTE_GET_DEVICE_INFO GetDeviceInfo; +}; + + +extern EFI_GUID gEfiBluetoothAttributeProtocolGuid; +extern EFI_GUID gEfiBluetoothAttributeServiceBindingProtocolGuid; + +#endif + diff --git a/Core/MdePkg/Include/Protocol/BluetoothLeConfig.h b/Core/MdePkg/Include/Protocol/BluetoothLeConfig.h new file mode 100644 index 0000000000..92d4fc2667 --- /dev/null +++ b/Core/MdePkg/Include/Protocol/BluetoothLeConfig.h @@ -0,0 +1,634 @@ +/** @file + EFI Bluetooth LE Config Protocol as defined in UEFI 2.7. + This protocol abstracts user interface configuration for BluetoothLe device. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ 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.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. + + @par Revision Reference: + This Protocol is introduced in UEFI Specification 2.7 + +**/ + +#ifndef __EFI_BLUETOOTH_LE_CONFIG_H__ +#define __EFI_BLUETOOTH_LE_CONFIG_H__ + +#include +#include + +#define EFI_BLUETOOTH_LE_CONFIG_PROTOCOL_GUID \ + { \ + 0x8f76da58, 0x1f99, 0x4275, { 0xa4, 0xec, 0x47, 0x56, 0x51, 0x5b, 0x1c, 0xe8 } \ + } + +typedef struct _EFI_BLUETOOTH_LE_CONFIG_PROTOCOL EFI_BLUETOOTH_LE_CONFIG_PROTOCOL; + +/** + Initialize BluetoothLE host controller and local device. + + The Init() function initializes BluetoothLE host controller and local device. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + + @retval EFI_SUCCESS The BluetoothLE host controller and local device is initialized successfully. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to initialize the BluetoothLE host controller + and local device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_INIT)( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This + ); + +typedef struct { + /// + /// The version of the structure. A value of zero represents the EFI_BLUETOOTH_LE_CONFIG_SCAN_PARAMETER + /// structure as defined here. Future version of this specification may extend this data structure in a + /// backward compatible way and increase the value of Version. + /// + UINT32 Version; + /// + /// Passive scanning or active scanning. See Bluetooth specification. + /// + UINT8 ScanType; + /// + /// Recommended scan interval to be used while performing scan. + /// + UINT16 ScanInterval; + /// + /// Recommended scan window to be used while performing a scan. + /// + UINT16 ScanWindow; + /// + /// Recommended scanning filter policy to be used while performing a scan. + /// + UINT8 ScanningFilterPolicy; + /// + /// This is one byte flag to serve as a filter to remove unneeded scan + /// result. For example, set BIT0 means scan in LE Limited Discoverable + /// Mode. Set BIT1 means scan in LE General Discoverable Mode. + /// + UINT8 AdvertisementFlagFilter; +} EFI_BLUETOOTH_LE_CONFIG_SCAN_PARAMETER; + +typedef struct{ + BLUETOOTH_LE_ADDRESS BDAddr; + BLUETOOTH_LE_ADDRESS DirectAddress; + UINT8 RemoteDeviceState; + INT8 RSSI; + UINTN AdvertisementDataSize; + VOID *AdvertisementData; +} EFI_BLUETOOTH_LE_SCAN_CALLBACK_INFORMATION; + +/** + Callback function, it is called if a BluetoothLE device is found during scan process. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Context Context passed from scan request. + @param[in] CallbackInfo Data related to scan result. NULL CallbackInfo means scan complete. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_SCAN_CALLBACK_FUNCTION) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN VOID *Context, + IN EFI_BLUETOOTH_LE_SCAN_CALLBACK_INFORMATION *CallbackInfo + ); + +/** + Scan BluetoothLE device. + + The Scan() function scans BluetoothLE device. When this function is returned, it just means scan + request is submitted. It does not mean scan process is started or finished. Whenever there is a + BluetoothLE device is found, the Callback function will be called. Callback function might be + called before this function returns or after this function returns + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] ReScan If TRUE, a new scan request is submitted no matter there is scan result before. + If FALSE and there is scan result, the previous scan result is returned and no scan request + is submitted. + @param[in] Timeout Duration in milliseconds for which to scan. + @param[in] ScanParameter If it is not NULL, the ScanParameter is used to perform a scan by the BluetoothLE bus driver. + If it is NULL, the default parameter is used. + @param[in] Callback The callback function. This function is called if a BluetoothLE device is found during + scan process. + @param[in] Context Data passed into Callback function. This is optional parameter and may be NULL. + + @retval EFI_SUCCESS The Bluetooth scan request is submitted. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to scan the BluetoothLE device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_SCAN)( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN BOOLEAN ReScan, + IN UINT32 Timeout, + IN EFI_BLUETOOTH_LE_CONFIG_SCAN_PARAMETER *ScanParameter, OPTIONAL + IN EFI_BLUETOOTH_LE_CONFIG_SCAN_CALLBACK_FUNCTION Callback, + IN VOID *Context + ); + +typedef struct { + /// + /// The version of the structure. A value of zero represents the + /// EFI_BLUETOOTH_LE_CONFIG_CONNECT_PARAMETER + /// structure as defined here. Future version of this specification may + /// extend this data structure in a backward compatible way and + /// increase the value of Version. + /// + UINT32 Version; + /// + /// Recommended scan interval to be used while performing scan before connect. + /// + UINT16 ScanInterval; + /// + /// Recommended scan window to be used while performing a connection + /// + UINT16 ScanWindow; + /// + /// Minimum allowed connection interval. Shall be less than or equal to ConnIntervalMax. + /// + UINT16 ConnIntervalMin; + /// + /// Maximum allowed connection interval. Shall be greater than or equal to ConnIntervalMin. + /// + UINT16 ConnIntervalMax; + /// + /// Slave latency for the connection in number of connection events. + /// + UINT16 ConnLatency; + /// + /// Link supervision timeout for the connection. + /// + UINT16 SupervisionTimeout; +} EFI_BLUETOOTH_LE_CONFIG_CONNECT_PARAMETER; + +/** + Connect a BluetoothLE device. + + The Connect() function connects a Bluetooth device. When this function is returned successfully, + a new EFI_BLUETOOTH_IO_PROTOCOL is created. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] AutoReconnect If TRUE, the BluetoothLE host controller needs to do an auto + reconnect. If FALSE, the BluetoothLE host controller does not do + an auto reconnect. + @param[in] DoBonding If TRUE, the BluetoothLE host controller needs to do a bonding. + If FALSE, the BluetoothLE host controller does not do a bonding. + @param[in] ConnectParameter If it is not NULL, the ConnectParameter is used to perform a + scan by the BluetoothLE bus driver. If it is NULL, the default + parameter is used. + @param[in] BD_ADDR The address of the BluetoothLE device to be connected. + + @retval EFI_SUCCESS The BluetoothLE device is connected successfully. + @retval EFI_ALREADY_STARTED The BluetoothLE device is already connected. + @retval EFI_NOT_FOUND The BluetoothLE device is not found. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to connect the BluetoothLE device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_CONNECT)( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN BOOLEAN AutoReconnect, + IN BOOLEAN DoBonding, + IN EFI_BLUETOOTH_LE_CONFIG_CONNECT_PARAMETER *ConnectParameter, OPTIONAL + IN BLUETOOTH_LE_ADDRESS *BD_ADDR + ); + +/** + Disconnect a BluetoothLE device. + + The Disconnect() function disconnects a BluetoothLE device. When this function is returned + successfully, the EFI_BLUETOOTH_ATTRIBUTE_PROTOCOL associated with this device is + destroyed and all services associated are stopped. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] BD_ADDR The address of BluetoothLE device to be connected. + @param[in] Reason Bluetooth disconnect reason. See Bluetooth specification for detail. + + @retval EFI_SUCCESS The BluetoothLE device is disconnected successfully. + @retval EFI_NOT_STARTED The BluetoothLE device is not connected. + @retval EFI_NOT_FOUND The BluetoothLE device is not found. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to disconnect the BluetoothLE device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_DISCONNECT)( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN BLUETOOTH_LE_ADDRESS *BD_ADDR, + IN UINT8 Reason + ); + +/** + Get BluetoothLE configuration data. + + The GetData() function returns BluetoothLE configuration data. For remote BluetoothLE device + configuration data, please use GetRemoteData() function with valid BD_ADDR. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in, out] DataSize On input, indicates the size, in bytes, of the data buffer specified by Data. + On output, indicates the amount of data actually returned. + @param[in, out] Data A pointer to the buffer of data that will be returned. + + @retval EFI_SUCCESS The BluetoothLE configuration data is returned successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - DataSize is NULL. + - *DataSize is 0. + - Data is NULL. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The DataType is not found. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the buffer. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_GET_DATA) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_CONFIG_DATA_TYPE DataType, + IN OUT UINTN *DataSize, + IN OUT VOID *Data OPTIONAL + ); + +/** + Set BluetoothLE configuration data. + + The SetData() function sets local BluetoothLE device configuration data. Not all DataType can be + set. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in] DataSize Indicates the size, in bytes, of the data buffer specified by Data. + @param[in] Data A pointer to the buffer of data that will be set. + + @retval EFI_SUCCESS The BluetoothLE configuration data is set successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - DataSize is 0. + - Data is NULL. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_WRITE_PROTECTED Cannot set configuration data. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_SET_DATA) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_CONFIG_DATA_TYPE DataType, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Get remove BluetoothLE device configuration data. + + The GetRemoteData() function returns remote BluetoothLE device configuration data. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in] BDAddr Remote BluetoothLE device address. + @param[in, out] DataSize On input, indicates the size, in bytes, of the data buffer specified by Data. + On output, indicates the amount of data actually returned. + @param[in, out] Data A pointer to the buffer of data that will be returned. + + @retval EFI_SUCCESS The remote BluetoothLE device configuration data is returned successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + - DataSize is NULL. + - *DataSize is 0. + - Data is NULL. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The DataType is not found. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the buffer. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_GET_REMOTE_DATA) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_CONFIG_DATA_TYPE DataType, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN OUT UINTN *DataSize, + IN OUT VOID *Data + ); + +typedef enum { + /// + /// It indicates an authorization request. No data is associated with the callback + /// input. In the output data, the application should return the authorization value. + /// The data structure is BOOLEAN. TRUE means YES. FALSE means NO. + /// + EfiBluetoothSmpAuthorizationRequestEvent, + /// + /// It indicates that a passkey has been generated locally by the driver, and the same + /// passkey should be entered at the remote device. The callback input data is the + /// passkey of type UINT32, to be displayed by the application. No output data + /// should be returned. + /// + EfiBluetoothSmpPasskeyReadyEvent, + /// + /// It indicates that the driver is requesting for the passkey has been generated at + /// the remote device. No data is associated with the callback input. The output data + /// is the passkey of type UINT32, to be entered by the user. + /// + EfiBluetoothSmpPasskeyRequestEvent, + /// + /// It indicates that the driver is requesting for the passkey that has been pre-shared + /// out-of-band with the remote device. No data is associated with the callback + /// input. The output data is the stored OOB data of type UINT8[16]. + /// + EfiBluetoothSmpOOBDataRequestEvent, + /// + /// In indicates that a number have been generated locally by the bus driver, and + /// also at the remote device, and the bus driver wants to know if the two numbers + /// match. The callback input data is the number of type UINT32. The output data + /// is confirmation value of type BOOLEAN. TRUE means comparison pass. FALSE + /// means comparison fail. + /// + EfiBluetoothSmpNumericComparisonEvent, +} EFI_BLUETOOTH_LE_SMP_EVENT_DATA_TYPE; + +/** + The callback function for SMP. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Context Data passed into callback function. This is optional parameter + and may be NULL. + @param[in] BDAddr Remote BluetoothLE device address. + @param[in] EventDataType Event data type in EFI_BLUETOOTH_LE_SMP_EVENT_DATA_TYPE. + @param[in] DataSize Indicates the size, in bytes, of the data buffer specified by Data. + @param[in] Data A pointer to the buffer of data. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_SMP_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN VOID *Context, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN EFI_BLUETOOTH_LE_SMP_EVENT_DATA_TYPE EventDataType, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Register Security Manager Protocol callback function for user authentication/authorization. + + The RegisterSmpAuthCallback() function register Security Manager Protocol callback + function for user authentication/authorization. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Callback Callback function for user authentication/authorization. + @param[in] Context Data passed into Callback function. This is optional parameter and may be NULL. + + @retval EFI_SUCCESS The SMP callback function is registered successfully. + @retval EFI_ALREADY_STARTED A callback function is already registered on the same attribute + opcode and attribute handle, when the Callback is not NULL. + @retval EFI_NOT_STARTED A callback function is not registered on the same attribute opcode + and attribute handle, when the Callback is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_REGISTER_SMP_AUTH_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_LE_SMP_CALLBACK Callback, + IN VOID *Context + ); + +/** + Send user authentication/authorization to remote device. + + The SendSmpAuthData() function sends user authentication/authorization to remote device. It + should be used to send these information after the caller gets the request data from the callback + function by RegisterSmpAuthCallback(). + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] BDAddr Remote BluetoothLE device address. + @param[in] EventDataType Event data type in EFI_BLUETOOTH_LE_SMP_EVENT_DATA_TYPE. + @param[in] DataSize The size of Data in bytes, of the data buffer specified by Data. + @param[in] Data A pointer to the buffer of data that will be sent. The data format + depends on the type of SMP event data being responded to. + + @retval EFI_SUCCESS The SMP authorization data is sent successfully. + @retval EFI_NOT_READY SMP is not in the correct state to receive the auth data. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_SEND_SMP_AUTH_DATA) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN EFI_BLUETOOTH_LE_SMP_EVENT_DATA_TYPE EventDataType, + IN UINTN DataSize, + IN VOID *Data + ); + +typedef enum { + // For local device only + EfiBluetoothSmpLocalIR, /* If Key hierarchy is supported */ + EfiBluetoothSmpLocalER, /* If Key hierarchy is supported */ + EfiBluetoothSmpLocalDHK, /* If Key hierarchy is supported. OPTIONAL */ + // For peer specific + EfiBluetoothSmpKeysDistributed = 0x1000, + EfiBluetoothSmpKeySize, + EfiBluetoothSmpKeyType, + EfiBluetoothSmpPeerLTK, + EfiBluetoothSmpPeerIRK, + EfiBluetoothSmpPeerCSRK, + EfiBluetoothSmpPeerRand, + EfiBluetoothSmpPeerEDIV, + EfiBluetoothSmpPeerSignCounter, + EfiBluetoothSmpLocalLTK, /* If Key hierarchy not supported */ + EfiBluetoothSmpLocalIRK, /* If Key hierarchy not supported */ + EfiBluetoothSmpLocalCSRK, /* If Key hierarchy not supported */ + EfiBluetoothSmpLocalSignCounter, + EfiBluetoothSmpLocalDIV, +} EFI_BLUETOOTH_LE_SMP_DATA_TYPE; + +/** + The callback function to get SMP data. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Context Data passed into callback function. This is optional parameter + and may be NULL. + @param[in] BDAddr Remote BluetoothLE device address. For Local device setting, it + should be NULL. + @param[in] DataType Data type in EFI_BLUETOOTH_LE_SMP_DATA_TYPE. + @param[in, out] DataSize On input, indicates the size, in bytes, of the data buffer specified + by Data. On output, indicates the amount of data actually returned. + @param[out] Data A pointer to the buffer of data that will be returned. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_BLUETOOTH_LE_CONFIG_SMP_GET_DATA_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN VOID *Context, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN EFI_BLUETOOTH_LE_SMP_DATA_TYPE DataType, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +/** + Register a callback function to get SMP related data. + + The RegisterSmpGetDataCallback() function registers a callback function to get SMP related data. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Callback Callback function for SMP get data. + @param[in] Context Data passed into Callback function. This is optional parameter and may be NULL. + + @retval EFI_SUCCESS The SMP get data callback function is registered successfully. + @retval EFI_ALREADY_STARTED A callback function is already registered on the same attribute + opcode and attribute handle, when the Callback is not NULL. + @retval EFI_NOT_STARTED A callback function is not registered on the same attribute opcode + and attribute handle, when the Callback is NULL +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_BLUETOOTH_LE_CONFIG_REGISTER_SMP_GET_DATA_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_LE_CONFIG_SMP_GET_DATA_CALLBACK Callback, + IN VOID *Context + ); + +/** + The callback function to set SMP data. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Context Data passed into callback function. This is optional parameter + and may be NULL. + @param[in] BDAddr Remote BluetoothLE device address. + @param[in] DataType Data type in EFI_BLUETOOTH_LE_SMP_DATA_TYPE. + @param[in] DataSize Indicates the size, in bytes, of the data buffer specified by Data. + @param[in] Data A pointer to the buffer of data. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_BLUETOOTH_LE_CONFIG_SMP_SET_DATA_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN VOID *Context, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN EFI_BLUETOOTH_LE_SMP_DATA_TYPE Type, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Register a callback function to set SMP related data. + + The RegisterSmpSetDataCallback() function registers a callback function to set SMP related data. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Callback Callback function for SMP set data. + @param[in] Context Data passed into Callback function. This is optional parameter and may be NULL. + + @retval EFI_SUCCESS The SMP set data callback function is registered successfully. + @retval EFI_ALREADY_STARTED A callback function is already registered on the same attribute + opcode and attribute handle, when the Callback is not NULL. + @retval EFI_NOT_STARTED A callback function is not registered on the same attribute opcode + and attribute handle, when the Callback is NULL +**/ +typedef +EFI_STATUS +(EFIAPI * EFI_BLUETOOTH_LE_CONFIG_REGISTER_SMP_SET_DATA_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_LE_CONFIG_SMP_SET_DATA_CALLBACK Callback, + IN VOID *Context + ); + +/** + The callback function to hook connect complete event. + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Context Data passed into callback function. This is optional parameter + and may be NULL. + @param[in] CallbackType The value defined in EFI_BLUETOOTH_CONNECT_COMPLETE_CALLBACK_TYPE. + @param[in] BDAddr Remote BluetoothLE device address. + @param[in] InputBuffer A pointer to the buffer of data that is input from callback caller. + @param[in] InputBufferSize Indicates the size, in bytes, of the data buffer specified by InputBuffer. + + @retval EFI_SUCCESS The callback function complete successfully. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_CONNECT_COMPLETE_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN VOID *Context, + IN EFI_BLUETOOTH_CONNECT_COMPLETE_CALLBACK_TYPE CallbackType, + IN BLUETOOTH_LE_ADDRESS *BDAddr, + IN VOID *InputBuffer, + IN UINTN InputBufferSize + ); + +/** + Register link connect complete callback function. + + The RegisterLinkConnectCompleteCallback() function registers Bluetooth link connect + complete callback function. The Bluetooth Configuration driver may call + RegisterLinkConnectCompleteCallback() to register a callback function. During pairing, + Bluetooth bus driver must trigger this callback function to report device state, if it is registered. + Then Bluetooth Configuration driver will get information on device connection, according to + CallbackType defined by EFI_BLUETOOTH_CONNECT_COMPLETE_CALLBACK_TYPE + + @param[in] This Pointer to the EFI_BLUETOOTH_LE_CONFIG_PROTOCOL instance. + @param[in] Callback The callback function. NULL means unregister. + @param[in] Context Data passed into Callback function. This is optional parameter and may be NULL. + + @retval EFI_SUCCESS The link connect complete callback function is registered successfully. + @retval EFI_ALREADY_STARTED A callback function is already registered on the same attribute + opcode and attribute handle, when the Callback is not NULL. + @retval EFI_NOT_STARTED A callback function is not registered on the same attribute opcode + and attribute handle, when the Callback is NULL +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_BLUETOOTH_LE_CONFIG_REGISTER_CONNECT_COMPLETE_CALLBACK) ( + IN EFI_BLUETOOTH_LE_CONFIG_PROTOCOL *This, + IN EFI_BLUETOOTH_LE_CONFIG_CONNECT_COMPLETE_CALLBACK Callback, + IN VOID *Context + ); + +/// +/// This protocol abstracts user interface configuration for BluetoothLe device. +/// +struct _EFI_BLUETOOTH_LE_CONFIG_PROTOCOL { + EFI_BLUETOOTH_LE_CONFIG_INIT Init; + EFI_BLUETOOTH_LE_CONFIG_SCAN Scan; + EFI_BLUETOOTH_LE_CONFIG_CONNECT Connect; + EFI_BLUETOOTH_LE_CONFIG_DISCONNECT Disconnect; + EFI_BLUETOOTH_LE_CONFIG_GET_DATA GetData; + EFI_BLUETOOTH_LE_CONFIG_SET_DATA SetData; + EFI_BLUETOOTH_LE_CONFIG_GET_REMOTE_DATA GetRemoteData; + EFI_BLUETOOTH_LE_REGISTER_SMP_AUTH_CALLBACK RegisterSmpAuthCallback; + EFI_BLUETOOTH_LE_SEND_SMP_AUTH_DATA SendSmpAuthData; + EFI_BLUETOOTH_LE_CONFIG_REGISTER_SMP_GET_DATA_CALLBACK RegisterSmpGetDataCallback; + EFI_BLUETOOTH_LE_CONFIG_REGISTER_SMP_SET_DATA_CALLBACK RegisterSmpSetDataCallback; + EFI_BLUETOOTH_LE_CONFIG_REGISTER_CONNECT_COMPLETE_CALLBACK RegisterLinkConnectCompleteCallback; +}; + +extern EFI_GUID gEfiBluetoothLeConfigProtocolGuid; + +#endif + diff --git a/Core/MdePkg/Library/SmmIoLib/SmmIoLib.c b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.c new file mode 100644 index 0000000000..181abb8e25 --- /dev/null +++ b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.c @@ -0,0 +1,330 @@ +/** @file + Instance of SMM IO check library. + + SMM IO check library library implementation. This library consumes GCD to collect all valid + IO space defined by a platform. + A platform may have its own SmmIoLib instance to exclude more IO space. + + Copyright (c) 2017, Intel Corporation. All rights reserved.
+ 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mSmmIoLibGcdMemSpace = NULL; +UINTN mSmmIoLibGcdMemNumberOfDesc = 0; + +EFI_PHYSICAL_ADDRESS mSmmIoLibInternalMaximumSupportMemAddress = 0; + +VOID *mSmmIoLibRegistrationEndOfDxe; +VOID *mSmmIoLibRegistrationReadyToLock; + +BOOLEAN mSmmIoLibReadyToLock = FALSE; + +/** + Calculate and save the maximum support address. + +**/ +VOID +SmmIoLibInternalCalculateMaximumSupportAddress ( + VOID + ) +{ + VOID *Hob; + UINT32 RegEax; + UINT8 MemPhysicalAddressBits; + + // + // Get physical address bits supported. + // + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + MemPhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + MemPhysicalAddressBits = (UINT8) RegEax; + } else { + MemPhysicalAddressBits = 36; + } + } + // + // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. + // + ASSERT (MemPhysicalAddressBits <= 52); + if (MemPhysicalAddressBits > 48) { + MemPhysicalAddressBits = 48; + } + + // + // Save the maximum support address in one global variable + // + mSmmIoLibInternalMaximumSupportMemAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, MemPhysicalAddressBits) - 1); + DEBUG ((DEBUG_INFO, "mSmmIoLibInternalMaximumSupportMemAddress = 0x%lx\n", mSmmIoLibInternalMaximumSupportMemAddress)); +} + +/** + This function check if the MMIO resource is valid per processor architecture and + valid per platform design. + + @param BaseAddress The MMIO start address to be checked. + @param Length The MMIO length to be checked. + @param Owner A GUID representing the owner of the resource. + This GUID may be used by producer to correlate the device ownership of the resource. + NULL means no specific owner. + + @retval TRUE This MMIO resource is valid per processor architecture and valid per platform design. + @retval FALSE This MMIO resource is not valid per processor architecture or valid per platform design. +**/ +BOOLEAN +EFIAPI +SmmIsMmioValid ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN EFI_GUID *Owner OPTIONAL + ) +{ + UINTN Index; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc; + BOOLEAN InValidRegion; + + // + // Check override. + // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid. + // + if ((Length > mSmmIoLibInternalMaximumSupportMemAddress) || + (BaseAddress > mSmmIoLibInternalMaximumSupportMemAddress) || + ((Length != 0) && (BaseAddress > (mSmmIoLibInternalMaximumSupportMemAddress - (Length - 1)))) ) { + // + // Overflow happen + // + DEBUG (( + DEBUG_ERROR, + "SmmIsMmioValid: Overflow: BaseAddress (0x%lx) - Length (0x%lx), MaximumSupportMemAddress (0x%lx)\n", + BaseAddress, + Length, + mSmmIoLibInternalMaximumSupportMemAddress + )); + return FALSE; + } + + // + // Check override for valid MMIO region + // + if (mSmmIoLibReadyToLock) { + InValidRegion = FALSE; + for (Index = 0; Index < mSmmIoLibGcdMemNumberOfDesc; Index ++) { + Desc = &mSmmIoLibGcdMemSpace[Index]; + if ((Desc->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && + (BaseAddress >= Desc->BaseAddress) && + ((BaseAddress + Length) <= (Desc->BaseAddress + Desc->Length))) { + InValidRegion = TRUE; + } + } + + if (!InValidRegion) { + DEBUG (( + DEBUG_ERROR, + "SmmIsMmioValid: Not in valid MMIO region: BaseAddress (0x%lx) - Length (0x%lx)\n", + BaseAddress, + Length + )); + return FALSE; + } + } + return TRUE; +} + +/** + Merge continous entries whose type is EfiGcdMemoryTypeMemoryMappedIo. + + @param[in, out] GcdMemoryMap A pointer to the buffer in which firmware places + the current GCD memory map. + @param[in, out] NumberOfDescriptors A pointer to the number of the + GcdMemoryMap buffer. On input, this is the number of + the current GCD memory map. On output, + it is the number of new GCD memory map after merge. +**/ +STATIC +VOID +MergeGcdMmioEntry ( + IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *GcdMemoryMap, + IN OUT UINTN *NumberOfDescriptors + ) +{ + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *GcdMemoryMapEntry; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *GcdMemoryMapEnd; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *NewGcdMemoryMapEntry; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *NextGcdMemoryMapEntry; + + GcdMemoryMapEntry = GcdMemoryMap; + NewGcdMemoryMapEntry = GcdMemoryMap; + GcdMemoryMapEnd = (EFI_GCD_MEMORY_SPACE_DESCRIPTOR *) ((UINT8 *) GcdMemoryMap + (*NumberOfDescriptors) * sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); + while ((UINTN)GcdMemoryMapEntry < (UINTN)GcdMemoryMapEnd) { + CopyMem (NewGcdMemoryMapEntry, GcdMemoryMapEntry, sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); + NextGcdMemoryMapEntry = GcdMemoryMapEntry + 1; + + do { + if (((UINTN)NextGcdMemoryMapEntry < (UINTN)GcdMemoryMapEnd) && + (GcdMemoryMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && (NextGcdMemoryMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && + ((GcdMemoryMapEntry->BaseAddress + GcdMemoryMapEntry->Length) == NextGcdMemoryMapEntry->BaseAddress)) { + GcdMemoryMapEntry->Length += NextGcdMemoryMapEntry->Length; + if (NewGcdMemoryMapEntry != GcdMemoryMapEntry) { + NewGcdMemoryMapEntry->Length += NextGcdMemoryMapEntry->Length; + } + + NextGcdMemoryMapEntry = NextGcdMemoryMapEntry + 1; + continue; + } else { + GcdMemoryMapEntry = NextGcdMemoryMapEntry - 1; + break; + } + } while (TRUE); + + GcdMemoryMapEntry = GcdMemoryMapEntry + 1; + NewGcdMemoryMapEntry = NewGcdMemoryMapEntry + 1; + } + + *NumberOfDescriptors = ((UINTN)NewGcdMemoryMapEntry - (UINTN)GcdMemoryMap) / sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR); + + return ; +} + +/** + Notification for SMM EndOfDxe protocol. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification runs successfully. +**/ +EFI_STATUS +EFIAPI +SmmIoLibInternalEndOfDxeNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + UINTN NumberOfDescriptors; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap; + EFI_STATUS Status; + + Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap); + if (!EFI_ERROR (Status)) { + + MergeGcdMmioEntry (MemSpaceMap, &NumberOfDescriptors); + + mSmmIoLibGcdMemSpace = AllocateCopyPool (NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR), MemSpaceMap); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + gBS->FreePool (MemSpaceMap); + return Status; + } + + mSmmIoLibGcdMemNumberOfDesc = NumberOfDescriptors; + gBS->FreePool (MemSpaceMap); + } + + return EFI_SUCCESS; +} + +/** + Notification for SMM ReadyToLock protocol. + + @param[in] Protocol Points to the protocol's unique identifier. + @param[in] Interface Points to the interface instance. + @param[in] Handle The handle on which the interface was installed. + + @retval EFI_SUCCESS Notification runs successfully. +**/ +EFI_STATUS +EFIAPI +SmmIoLibInternalReadyToLockNotify ( + IN CONST EFI_GUID *Protocol, + IN VOID *Interface, + IN EFI_HANDLE Handle + ) +{ + mSmmIoLibReadyToLock = TRUE; + return EFI_SUCCESS; +} + +/** + The constructor function initializes the Smm IO library + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +SmmIoLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Calculate and save maximum support address + // + SmmIoLibInternalCalculateMaximumSupportAddress (); + + // + // Register EndOfDxe to get GCD resource map + // + Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, SmmIoLibInternalEndOfDxeNotify, &mSmmIoLibRegistrationEndOfDxe); + ASSERT_EFI_ERROR (Status); + + // + // Register ready to lock so that we can know when to check valid resource region + // + Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, SmmIoLibInternalReadyToLockNotify, &mSmmIoLibRegistrationReadyToLock); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +/** + The destructor function frees resource used in the Smm IO library + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS. +**/ +EFI_STATUS +EFIAPI +SmmIoLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, NULL, &mSmmIoLibRegistrationEndOfDxe); + gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, NULL, &mSmmIoLibRegistrationReadyToLock); + return EFI_SUCCESS; +} diff --git a/Core/MdePkg/Library/SmmIoLib/SmmIoLib.inf b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.inf new file mode 100644 index 0000000000..d508408975 --- /dev/null +++ b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.inf @@ -0,0 +1,53 @@ +## @file +# Instance of SMM IO check library. +# +# SMM IO check library library implementation. This library consumes GCD to collect all valid +# IO space defined by a platform. +# A platform may have its own SmmIoLib instance to exclude more IO space. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# 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 = SmmIoLib + MODULE_UNI_FILE = SmmIoLib.uni + FILE_GUID = F0F5A845-E3ED-4C6E-82D6-4ECE85DAC00F + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmIoLib|DXE_SMM_DRIVER SMM_CORE + CONSTRUCTOR = SmmIoLibConstructor + DESTRUCTOR = SmmIoLibDestructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SmmIoLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + SmmServicesTableLib + UefiBootServicesTableLib + DxeServicesTableLib + DebugLib + BaseMemoryLib + MemoryAllocationLib + HobLib + +[Protocols] + gEfiSmmReadyToLockProtocolGuid ## CONSUMES + gEfiSmmEndOfDxeProtocolGuid ## CONSUMES diff --git a/Core/MdePkg/Library/SmmIoLib/SmmIoLib.uni b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.uni new file mode 100644 index 0000000000..5d20b4daa1 --- /dev/null +++ b/Core/MdePkg/Library/SmmIoLib/SmmIoLib.uni @@ -0,0 +1,23 @@ +// /** @file +// Instance of SMM IO check library. +// +// SMM IO check library library implementation. This library consumes GCD to collect all valid +// IO space defined by a platform. +// A platform may have its own SmmIoLib instance to exclude more IO space. +// +// Copyright (c) 2017, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php. +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Instance of SMM IO check library." + +#string STR_MODULE_DESCRIPTION #language en-US "SMM IO check library library implementation. This library consumes GCD to collect all valid IO space defined by a platform. A platform may have its own SmmIoLib instance to exclude more IO space." + -- cgit v1.2.3