4/25/2016

gRT GetTime/SetTime

Sample code name:
https://github.com/EfiPy/EfiPy2/blob/main/Efi/Apps/EfiPy2Sample/EfiPyTime.py

Description:
It is simple example of comparison between C language with EfiPy2 (ctypes)

# EFI_TIME TimeCur;
TimeCur = EfiPy2.EFI_TIME ()
# EFI_TIME_CAPABILITIES TimeCap;
TimeCap = EfiPy2.EFI_TIME_CAPABILITIES ()

# Status = gRT->GetTime (&TimeCur, &TimeCap);
Status  = EfiPy2.gRT.GetTime (EfiPy2.byref(TimeCur), EfiPy2.byref(TimeCap))

# TimeCur.Year = 2014;
TimeCur.Year = 2014
# TimeCur.Hour = 3;
TimeCur.Hour = 3

# Status = gRT->SetTime (&TimeCur);
Status  = 
EfiPy2.gRT.SetTime (EfiPy2.byref(TimeCur))
# Status = gRT->GetTime (&TimeCur, NULL);
Status  = 
EfiPy2.gRT.GetTime (EfiPy2.byref(TimeCur), None)

EfiPy2.byref is the sample as address of (&) in C language.

4/22/2016

x86 instruction CPUID in CorePy/EfiPy

Sample code
https://github.com/EfiPy/EfiPy2/blob/main/Efi/Apps/EfiPy2Sample/CpuIdBasic.py

Description

In this demo, the sample script shows how to uses x86 instruction CPUID with CorePy/EfiPy2.
We have put CpuId module in EfiPy2.Lib in EfiPy2, that is the re-usable CpuId module need to be import as
from EfiPy2.Lib import CpuId

In CpuId module, it has class named "CpuIdClass". and create object as
CpuIdObj  = CpuId.CpuIdClass()

CpuId module also provide generic register suit for CPUID instruction operation by CorePy.
CpuIdReg  = CpuId.CPUID_GENERIC_REGISTERs()

CpuIdClass has two member functions... GetId () and GetId2 (). Both functions take three parameters. The first two parameters are EAX and ECX by instruction CPUID. But the third parameter is memory address by GetId (),  CPUID_GENERIC_REGISTERs object for GetId2 ().

Also, user can create its own register with pack structure type for CPUID, for example...

import EfiPy2.MdePkg.Register.Intel.Cpuid as CpuidRegs

class CpuIdRegisters (EfiPy.Structure):
  _pack_   = 1
  _fields_ = [
    ('EAX',  CpuidRegs.CPUID_VERSION_INFO_EAX),
    ('EBX',  CpuidRegs.CPUID_VERSION_INFO_EBX),
    ('ECX',  CpuidRegs.CPUID_VERSION_INFO_ECX),
    ('EDX',  CpuidRegs.CPUID_VERSION_INFO_EDX)
  ]
CpuIdReg  = CpuIdRegisters()

This registers can be used to get CPU version infor by...

rax = CpuIdObj.GetId2 (CpuidRegs.CPUID_VERSION_INFO, 0, CpuIdReg)

Due to CpuidRegs.CPUID_VERSION_INFO_EAXCpuidRegs.CPUID_VERSION_INFO_EBXCpuidRegs.CPUID_VERSION_INFO_ECX and CpuidRegs.CPUID_VERSION_INFO_EDX are union type including each bit field, Python script can also dump version information detail.



4/02/2016

PCI Scan

Sample Code Name
https://github.com/EfiPy/EfiPy2/blob/main/Efi/Apps/EfiPy2Sample/PciScan.py

Description

PCI Scanning program is the sample of how data returned by CorePy then transfer to EfiPy2.

It uses below functions, constants and structure in  EfiPy2
EfiPy2.MdePkg.IndustryStandard.Pci
Structure PCI_TYPE_GENERIC
Structure PCI_CONFIG_ACCESS_CF8
PCI_MAX_BUS
PCI_MAX_DEVICE
PCI_MAX_FUNC
IS_PCI_MULTI_FUNC

CorePy code in PCI scanning script, it uses I/O port 0x0cf8, 0x0cfc for scanning PCI generic register.
It also needs input parameter for assigning PCI bus, Device, function and registers.

EfiPy2 full package is from https://github.com/EfiPy/EfiPy2

Pseudo Sample Code

class PciScan:

  #
  # Prebuild assembly code
  #
  def __init__ (self):
    self.code.add(x86.mov(reg.rax, mem.MemRef(reg.rbp, 16)))
    self.code.add(x86.mov(reg.dx, 0x0cf8))
    self.code.add(x86.out(reg.dx, reg.eax))

    self.code.add(x86.mov(reg.dx, 0x0cfc))
    self.code.add(x86.in_(reg.eax, reg.dx))


  #
  # Get PCI register entry, return UINT32 value
  #
  def scan (self, Bus = 0, Dev = 0, Func = 0, Reg = 0):
    reg = pci.PCI_CONFIG_ACCESS_CF8((Reg & 0xFC, Func, Dev, Bus, 0, 1))

    self.params.p1 = reg.Uint32
    ret = self.proc.execute(self.code,
                            params = self.params,
                            mode = 'int')

    return ret


if __name__ == '__main__':

  PciDev  = PciScan()
  ret = PciDev.scan(Bus, Dev, Func, Reg)

Result