bloggerads

2014年6月12日 星期四

UEFI : Boot Service: HandleProtocol () / OpenProtocol (), LocateHandle() / LocateHandleBuffer()


     在寫UEFI code的時候,常常需要找到某個特定的handle, 然後打開這個handle底下特定的Protocol。如找到某個Pci Controller Handle, 然後打開他底下的gEfiPciIoProtocolGuid, 之後才能順利access此controller的Pci Space/Mem Space, 使用的方法不外乎是呼叫Boot Service所提供的HandleProtocol () / OpenProtocol (), LocateHandle() / LocateHandleBuffer()。

這幾個function說明如下:

■ HandleProtocol():

Queries a handle to determine if it supports a specified protocol.
The HandleProtocol() function is still available for use by old EFI applications and drivers. However, all new applications and drivers should use OpenProtocol() in place of HandleProtocol().

注意spec有說明HandleProtocol ()這個function應該要由OpenProtocol()來取代。因為它其實是長這樣的

EFI_STATUS
HandleProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface
)
{
return OpenProtocol (
          Handle,
          Protocol,
          Interface,
          EfiCoreImageHandle,
          NULL,
          EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
          );
}

■ OpenProtocol()

Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the handle, it opens the protocol on behalf of the calling agent. This is an extended version of the EFI boot service HandleProtocol().

■ LocateHandle() / ■ LocateHandleBuffer() <== 這個比較常用!!

先分別看兩個的原型

typedef
EFI_STATUS
(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) (
          IN EFI_LOCATE_SEARCH_TYPE SearchType,
          IN EFI_GUID * Protocol OPTIONAL,
          IN VOID *SearchKey OPTIONAL,
          IN OUT UINTN *NumberHandles,
          OUT EFI_HANDLE **Buffer
);
typedef
EFI_STATUS
(EFIAPI *EFI_LOCATE_HANDLE) (
          IN EFI_LOCATE_SEARCH_TYPE SearchType,
          IN EFI_GUID * Protocol OPTIONAL,
          IN VOID *SearchKey OPTIONAL,
          IN OUT UINTN *BufferSize, // On input, the size in bytes of Buffer. On output, the size in bytes of the array returned in Buffer (if the buffer was large enough) or the size, in bytes, of the buffer needed to obtain the array (if the buffer was not large enough).
          OUT EFI_HANDLE * Buffer // The buffer in which the array is returned
);

Description

The LocateHandle() function returns an array of handles that match the SearchType request. If the input value of BufferSize is too small, the function returns EFI_BUFFER_TOO_SMALL and updates BufferSize to the size of the buffer needed to obtain the array.

兩者差別在LocateHandle()需要自己”分配allocate”跟釋放Buffer。而LocateHandleBuffer() 使用者僅需釋放Buffer,allocate buffer 由此函式做掉

沒有留言:

張貼留言