10/03/2024

Some scripts (build.sh/build.bat/build_deb.sh install.sh/install.bat)

In Short

build.sh/build.bat/build_deb.sh install.sh/install.bat

Fake gST/gRT/gBS are created in EfiPy2 when it is imported on Windows or Linux system.

This makes EfiPy2.MdePkg.IndustryStandard is also re-usable on OS environment.

These building/installation scripts are created by above reason to be used on Windows and Liinux system handy.

Note 1.

IndustryStandard packge are used to touch system platform feature, it recommends to install it by supervisor privilege.

Note 2.

gST/gRT/gBS are fake on OS environment.


8/22/2024

ACPI Library

 Introduction

ACPI related library is added.

AcpiLib.py

AcpiTableDb.py

According to Overview of the System Description Table Architecture, it provides these APIs.

def ScanAcpiRsdp ():

def BuildAcpiHub ():

def GetAcpiVersion (AcpiEntries):

def RetrieveAcpiType (SignatureByte = None, SignatureInt = None, AcpiEntries = {}):

ScanAcpiRsdp ()

It returns (Rsdp, Rsdt, Xsdt, TableAddresses).

RsdpEFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER's object from gST's configuration table.

Rsdt, ACPI Rsdt object

Xsdt, ACPI Xsdt object

TableAddresses, each ACPI table address in ctypes array type.

BuildAcpiHub ()

It returns (DsdtAddress, SsdtAddress, AcpiEntries).

DsdtAddress, Dsdt physical address recorded in gST configuration table.

SsdtAddress, Ssdt physical addresses recorded in gST configuration table. python list type.

AcpiEntries, remaining ACPI tables in Python dict type. {Signature: AcpiAddress}

GetAcpiVersion (AcpiEntries)

Return ACPI version information from FADT, return type is (Major, Minor, Errata).

RetrieveAcpiType (SignatureByte, SignatureInt, AcpiEntries)

It checks if AcpiEntries have ACPI table with its signature matching SignatureByte or SignatureInt. It returns (AcpiType, AcpiAddr) if above condition is true.

AcpiType, due to each ACPI table has its own revision, this function returns the type with most approaching ACPI table revision.

AcpiAddr, ACPI table's physical address.

Example

Here it is.

There will be another post to list ACPI samples.



8/13/2024

Configuration Table in EFI System Table (gST)

 Introduction

UEFI defines Configuration table in EFI system table. The structure with EfiPy style is as below

class EFI_CONFIGURATION_TABLE (Structure): _fields_ = [ ("VendorGuid", EFI_GUID), ("VendorTable", PVOID) ]




class EFI_SYSTEM_TABLE (Structure):

_fields_ = [ ("Hdr", EFI_TABLE_HEADER), ("FirmwareVendor", PCHAR16), ("FirmwareRevision", UINT32), ("ConsoleInHandle", EFI_HANDLE), ("ConIn", POINTER(EFI_SIMPLE_TEXT_INPUT_PROTOCOL)), ("ConsoleOutHandle", EFI_HANDLE), ("ConOut", POINTER(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL)), ("StandardErrorHandle", EFI_HANDLE), ("StdErr", POINTER(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL)), ("RuntimeServices", POINTER(EFI_RUNTIME_SERVICES)), ("BootServices", POINTER(EFI_BOOT_SERVICES)), ("NumberOfTableEntries", UINTN), ("ConfigurationTable", POINTER(EFI_CONFIGURATION_TABLE)) ]








EfiPy2 added related library named EfiPy2.Lib.gStConfiguration.

This module makes user enumerate system configuration friendly.

Usage

from EfiPy2.Lib.gStConfiguration import RetrieveConfiguration, \

                                        FindConfiguration

Functions

RetrieveConfiguration ()

This function returns iterable list object. Each object in list is (EFI_GUID, VendorTable) pair tuple. That is this function convert ConfigurationTable to this format.

[(GUID, Address), (GUID, Address), (GUID, Address), ...]

FindConfiguration (Guid, CfgType = None)

This function finds configuration table according its parameter GUID.

This return object depend on the second parameter CfgType which is subvlass of ctypes._CData.
This function returns address if CfgType is None or it returns CfgType's instance.

Example

gStConfigurationSample.py, it does some things.

This get EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER's instance by gEfiAcpiTableGuid.

Table = FindConfiguration (gEfiAcpiTableGuid, EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER) print (f''' Looking Configuration table from gEfiAcpiTableGuid with class parameter EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER Guid, {gEfiAcpiTableGuid}, Table type.... {type (Table).__name__} Signature: {Table.Signature.to_bytes (8, 'little')} OemId : {bytes (Table.OemId[:])}''')






This statement will return None because it gives empty GUID to FindConfiguration()

DummyGuid = EfiPy.EFI_GUID() Table = FindConfiguration (DummyGuid) print (f''' Looking dummy guid {DummyGuid} Table shoud be None, Table: {Table}''')





Finaly, this get all configuration's GUID and its physical address in tuple form.

Cfg = RetrieveConfiguration () for Guid, Table in Cfg: print (f' Guid {Guid}, Table 0x{Table:08X}')



Result



8/05/2024

EFI variable library - II

 Introduction

The EfiPyVariables module includes an iterable class named EfiPyVariables(). This class uses EfiPy2.gRT.GetNextVariableName() to enumerate each EFI variable and its GUID.

EfiPyVariables

This class has these object initialization parameters, Name, Guid and CaseSensitive. Then user script can use for loop to enumerate UEFI variables name and GUID by these parameters as filter condition.

Name:

    If this parameter is not None and it is substring of variable name, then the variable name/GUID will return to user script.

    If this parameter is None then UEFI variable name will not be in filter condition.

Guid:

    If this parameter is not None then each enumerating result will compare UEFI variable GUID to this parameter. And only comparing result TRUE will return to user script.

    If this parameter is None then UEFI variable GUID will not be in filter condition.

Above two parameters are logic AND combination when they are not None.

CaseSensitive:

    This parameter indicates whether the comparison of UEFI variable names is case-sensitive. Default is none case-sensitive.


The modules and its sample code is here (module) and here (sample code).

Example

from EfiPy2.MdePkg.Guid.GlobalVariable import gEfiGlobalVariableGuid

#

# Enumerate every UEFI variables

#

with Variables() as Vars:

  for n, g in Vars:

    print (n, g)

#

# Enumerate any UEFI variables which name include sub-string 'BOOT'

# It is none case-sensitve.

#

with Variables('BOOT') as Vars:

  for n, g in Vars:

    print (n, g)

#

# Enumerate any UEFI variables which name include sub-string 'BOOT' 

# and its GUID is equal to gEfiGlobalVariableGuid

# This is case-insensitive example

with Variables('BOOT', gEfiGlobalVariableGuid) as Vars:

  for n, g in Vars:

    print (n, g)

#

# Enumerate any UEFI variables which name include sub-string 'BOOT' 

# and its GUID is equal to gEfiGlobalVariableGuid

# This is case-sensitive example

with Variables('BOOT', gEfiGlobalVariableGuid, CaseSensitive = True) as Vars:

  for n, g in Vars:

    print (n, g)


EFI variable library - I

Introduction

This talks about how EfiPy2 use runtime service (EfiPy2.gRT) to read/write EFI variable. It is native interface in UEFI system. In EDKII libraries. For user, it could have more convenience method to enumerate/read/write variable.

EfiPy2 creates more two python style modules, EfiPyVariable and EfiPyVariables. Of course, sample codes are needed, they are VariableSamples.py and VariablesSamples.py.

This post introduces EfiPyVariable first and EfiPyVariables will be explained in next post.

EfiPyVariable

This module includes class Variable which uses gRT.GetVariable and gRT.SetVariable for EFI variable operation. This class required at least one parameter, Variable Name, to created an variable object, and Guid parameter and Attribute parameter are optional.
    Variable.__init__ (self, Name, Guid = EfiPyVarGuid, Attribute = EfiPyVarAttr)
In this module, two default variables EfiPyVarGuid and EfiPyVarAttr are used by Variable's object if variable GUID and variable attribute are not provided in object initialization function Variable.__init__().
EfiPyVarGuid is equal to gEfiGlobalVariableGuid while EfiPyVarAttr is variable full range access attribute.

Variable object has SetVariable()/GetVariable() member function. these two functions invoke EDKII gRT functions SetVariable()/GetVariable().

Before SetVariable() is called, its attribute and value can be changed by @attribute.setter and @value.setter. But variable's GUID and name cannot be changed.

After GetVariable() is invoke, user can get its value and attribute by their @property. Variable's name and GUID can only by given when object created.

Both SetVariable()/GetVariable() raise SystemError exception when function failed.

Examples - GetVariable()

VariableSamples.py is this module's example. It retrieves 'Boot0001' variable with global GUID.
  var = Variable ('Boot0001')
  var.GetVariable ()

Then print this variable's value, size and attribute
  print (f'{var.Value}\n  size: {len(var)}, Attribute: {var.Attribute}')

Examples - GetVariable()

This sample code creates a new variable 'EfiPy2VariableTest' with specified GUID. In the variable object creating stage, it has GUID parameter in it.
  var = Variable ('EfiPy2VariableTest', VariableGuid)

Until now, the variable's buffer only accept binary array object. In this stage, variable buffer's size is decided, too.
  var.Value = bytearray (b'\x01abcde\x001234')

After all parameter are set done, SetVariable() can be called.
  var.SetVariable ()

7/28/2024

PanelLib

Introduction

At the very beginning of EfiPy announcement, there is a demo program and introduction for EfiPy capability for graphics function. This program’s kernel is moved to be python library in Efi\StdLib\lib\python36.8\EfiPy2\Lib\PanelLib.py.

Example

Although this library structure is not beautiful enough, but multiple test example feature reused the class in PanelLib.py

from EfiPy2.Lib.PanelLib import EfiPyGfx, EfiPyFont, HintPrompt

And demo functions are divided into scripts. Here are these scripts description…

Efi\Apps\EfiPy2Sample\PanelGrid.py

It uses EfiPyGfx:: Rect() function to show small rectangle in screen.












Efi\Apps\EfiPy2Sample\PanelRuler.py

It uses EfiPyGfx() class to draw vertical and horizontal ruler.













Efi\Apps\EfiPy2Sample\PanelFont.py

It displays fonts with variable color in one screen.













Efi\Apps\EfiPy2Sample\PanelModeList.py

It uses GOP QueryMode() capsuled in EfiPyGfx class to lists available GOP mode.











Efi\Apps\EfiPy2Sample\PanelModeSet.py

It uses GOP SetMode() to set GOP mode number from GOP QueryMode().

7/14/2024

Blog update

Summarize

More than half of post in this blog are old. Some of them are out of date and will be hidden.

Another will be modified then these posts information can be referenced by EfiPy2.

Exception

The fist pot in this blog(EfiPy initial) will be keep for available for tagging the born of EfiPy.

Labels

EfiPy2 as post labels indicated that they are reviewed and run well on EfiPy2 environment.


7/11/2024

What is ctypesCallback.py in Efi/Apps /EfiPy2Sample/

 Background

At the beginning of porting ctypes to EFI environment, there are some validation programs. This is one of them to be used to test CFUNCTYPE if it works or not.

Test point

This script is mainly to declare a c types structure which is used for EFI protocol including member function pointer (EFIPY2_CFUNCTYPE1) and unsigned integer.

This statement is CFUNCTYPE check point.

Status = EfiPy2SampleProtocol.P1Func1 (20, None)

Procedure - python callback function by ctypes

1. Declaire python function (EfiPy2cFunc1 or EfiPy2cFunc2) for callback from ctypes.Structure object.

def EfiPy2cFunc1 (Val1, Val2):

  print ("   EfiPy2cFunc1 Val1:", Val1)

  return 0

2. Create EFIPY2_CFUNCTYPE1 from ctypes.CFUNCTYPE with the same with EfiPy2cFunc1 input/output interface.

EFIPY2_CFUNCTYPE1 = ctypes.CFUNCTYPE (

     ctypes.c_uint64,                 # Return value.

     ctypes.c_uint64,                 # first parameter.

     ctypes.POINTER(ctypes.c_uint32)  # second parameter.

     )

3. And assign an object P1 which is EFIPY2_CFUNCTYPE1 object has callback EfiPy2cFunc1.

P1 = EFIPY2_CFUNCTYPE1 (EfiPy2cFunc1)

Procedure - ctypes structure object with member EFIPY2_CFUNCTYPE1

1. This is ctypes structure EFIPY2_SAMPLEPROTOCOL_CLASS which can be used for EFI protocol
#
# Protocol Structure
#
class EFIPY2_SAMPLEPROTOCOL_CLASS (ctypes.Structure):
  _fields_ = [("P1Func1", EFIPY2_CFUNCTYPE1),
              ("P1Val",   ctypes.c_uint32),
              # ("P1Func2", EFIPY2_CFUNCTYPE2)
             ]
2. Create EFIPY2_SAMPLEPROTOCOL_CLASS's object
EfiPy2SampleProtocol = EFIPY2_SAMPLEPROTOCOL_CLASS (P1, 3)

Go for run

This is the content in previous section Test Point

Status = EfiPy2SampleProtocol.P1Func1 (20, None)

7/10/2024

MsrBasic.py

Quick update

This is the same as CpuIdBasic.py. It  calls corepy library to achieve reading MSR data.

Here is new version of CpuIdBasic.py.

Instruction rdmsr in corepy is missed for months and it is patched in Efi/StdLib/lib/python36.8/corepy/arch/x86_64/isa/x86_64_isa.py

Both CpuId and Msr register query program run in BSP (Boot Strap Processor, not Board Support Package), only.