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 ()