Suppose:
There is PORTOCOL which is not defined in UEFI/PI and is built in BIOS image.
This PROTOCOL interface is known by C language header file:
#ifndef _XYZ_DXE_H_
#define _XYZ_DXE_H_
#define USER_XYZ_PROTOCOL_GIUD \
{ \
0x2a339172, 0x7ef6, 0x4f2b, { 0x95, 0xb9, 0x83, 0xf2, 0x15, 0x18, 0xeb, 0xf7} \
}
typedef struct _USER_XYZ_PROTOCOL USER_XYZ_PROTOCOL;
typedef
EFI_STATUS
(EFIAPI *USER_XYZ_GET_VERSION)(
IN CONST USER_XYZ_PROTOCOL *This,
OUT UINT64 *VersionSize
);
typedef
EFI_STATUS
(EFIAPI *USER_XYZ_DUMMY)(
VOID
);
///
/// XYZ Protocol structure
///
struct _USER_XYZ_PROTOCOL {
USER_XYZ_GET_VERSION GetVersion;
USER_XYZ_DUMMY Dummy;
};
#endif // _XYZ_DXE_H_
PROTOCOL's EfiPy2 form and How to use it:
#
# xyzProtocol.py
#
#
# XYX PROTOCOL declare in EfiPy2 format
#
from EfiPy2 import *
#
# XYZ protocol GUID
#
# #define USER_XYZ_PROTOCOL_GIUD \
# { \
# 0x2a339172, 0x7ef6, 0x4f2b, { 0x95, 0xb9, 0x83, 0xf2, 0x15, 0x18, 0xeb, 0xf7} \
# }
# EFI_GUID gUserXyzProtocolGuid = USER_XYZ_PROTOCOL_GIUD;
#
gUserXyzProtocolGuid = \
EFI_GUID (0x2a339172, 0x7ef6, 0x4f2b, (0x95, 0xb9, 0x83, 0xf2, 0x15, 0x18, 0xeb, 0xf7))
#
# XYZ protocol declare
#
# typedef struct _USER_XYZ_PROTOCOL USER_XYZ_PROTOCOL;
#
class USER_XYZ_PROTOCOL (Structure):
pass
#
# USER_XYZ_GET_VERSION function declare
#
# typedef
# EFI_STATUS
# (EFIAPI *USER_XYZ_GET_VERSION)(
# IN CONST USER_XYZ_PROTOCOL *This,
# OUT UINT64 *VersionSize
# );
#
USER_XYZ_GET_VERSION = CFUNCTYPE (
EFI_STATUS,
POINTER (USER_XYZ_PROTOCOL),
POINTER (UINT64)
)
#
# USER_XYZ_DUMMY function declare
#
# typedef
# EFI_STATUS
# (EFIAPI *USER_XYZ_DUMMY)(
# VOID
# );
#
# Return type: EFI_STATUS
# Input parameter: None
#
USER_XYZ_DUMMY = CFUNCTYPE (
EFI_STATUS
)
#
# XYZ Protocol structure
#
# struct _USER_XYZ_PROTOCOL {
# USER_XYZ_GET_VERSION GetVersion;
# USER_XYZ_DUMMY Dummy;
# };
#
USER_XYZ_PROTOCOL._fields_ = [
("GetVersion", USER_XYZ_GET_VERSION),
("Dummy", USER_XYZ_DUMMY)
]
#
# Test program for verifying protocol conversation
#
if __name__ == '__main__':
Interface = PVOID ()
Status = gBS.LocateProtocol (
byref (gUserXyzProtocolGuid),
None,
byref (Interface)
)
if Status != 0x00:
print "Locate Protocol Error (Status:%x)" % Status
exit (0)
XyzProtocol = cast (Interface, POINTER(USER_XYZ_PROTOCOL))
Version = UINT64(0)
Status = XyzProtocol[0].GetVersion (XyzProtocol, byref(Version))
print "Get Version: %x (Status:%x)" % (Version.value, Status)
Advanced
After this EfiPy2 protocol program test is done, it can be put into package folder, including __init__.py.
Setting PYTHONPATH uefi shell environment variable lets user specified protocol in anywhere.
Example: Folder fs0:\Xyz includes xyzProtocol.py and __init__.py
set PYTHONPATH fs0:\Xyz
USER_XYZ_PROTOCOL can be called from anywhere by
import xyzProtocol
Q&A: Should EfiPy2 programmer needs to reference protocol implementation source code?
Answer:
No, it is the same as EFI caller program, EfiPy2 programmer needs Protocol header file and transfer it to Python code, only.
Q&A: Should python.efi needs to be compiled, again, for user specified PROTOCOL?
Answer:
No, python.efi includes ctypes.
ctypes
for UEFI is a foreign function library for Python. It provides C
compatible data types, and allows calling functions in UEFI PROTOCOL. It
can be used to wrap PROTOCOLs in pure Python. (ref. from Here)
No comments:
Post a Comment