Saturday, October 21, 2023

CpuIdBasic.py

Introduction

We had the CPUID in EfiPy introduction in it. there are new implemented CpuId library in EfiPy2.

Recently EDK2 added each CPUID data structure in it. CpuIdBasic.py uses these data structure to get detail data more easily.

CpuId Library

EfiPy2 adds EfiPy2.Lib.CpuId module, it contain...

  1. Assembly code ready class CpuIdClass() to get CPUID and,
  2. Generic data structure CPUID_GENERIC_REGISTERs, sink of cpuid return value.
CpuIdClass recommend to use GetId2() method for reading cpuid.

  #
  # UINT32 GetId (UINT32 eax, UINT32 ecx, struct CpuIdReg &CpuIdReg);
  #
  def GetId2 (self, eax, ecx, CpuIdReg):
eax and ecx is cpuid instruction input parameter and CpuIdReg is GetId2() return value which includes EAX/EBX/ECX/EDX packed in it.

If there is no suitable EAX/EBX/ECX/EDX definition exiting in EfiPy2 package (EfiPy2.MdePkg.Register.Intel.Cpuid for example), user application can have self-defined structure like CPUID_GENERIC_REGISTERs

class CPUID_GENERIC_REGISTERs (EfiPy.Structure):
  _pack_   = 1
  _fields_ = [
    ('EAX',  EfiPy.UINT32),
    ('EBX',  EfiPy.UINT32),
    ('ECX',  EfiPy.UINT32),
    ('EDX',  EfiPy.UINT32)
  ]

Example 1 - Using CPUID_GENERIC_REGISTERs

import basic library

import EfiPy2 as EfiPy
import EfiPy2.MdePkg.Register.Intel.Cpuid as CpuidRegs
from EfiPy2.Lib import CpuId

Create object from CpuIdClass

CpuIdObj  = CpuId.CpuIdClass()

pick CPUID_GENERIC_REGISTERs as cpuid return value

CpuIdReg  = CpuId.CPUID_GENERIC_REGISTERs()

Execution

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

Dump execution result and pre-defined value

#
# CpuIdReg.??? are return value.
#
print (f'''
CPU signature From cpuid instruction
============================================
  EAX = 0x{CpuIdReg.EAX:08X}
  EBX = 0x{CpuIdReg.EBX:08X}
  ECX = 0x{CpuIdReg.ECX:08X}
  EDX = 0x{CpuIdReg.EDX:08X}
''')

#
CpuidRegs.CPUID_SIGNATURE_GENUINE_INTEL_E?are pre-defined value
in EfiPy2.MdePkg.Register.Intel.Cpuid
#
print (f'''
CPU signature from pre-defined constant
============================================
  EBX = 0x{CpuidRegs.CPUID_SIGNATURE_GENUINE_INTEL_EBX:08X}
  ECX = 0x{CpuidRegs.CPUID_SIGNATURE_GENUINE_INTEL_ECX:08X}
  EDX = 0x{CpuidRegs.CPUID_SIGNATURE_GENUINE_INTEL_EDX:08X}
''')

Example 2 - Get CPUID EXA=0x01

EAX=0x01 is know as CPUID_VERSION_INFO.

Efipy2.MdePkg.Intel.CpuId also define version information detailed item.
This example packed these structure into single structure
CPUID_VERSION_INFO_EAX
CPUID_VERSION_INFO_EBX
CPUID_VERSION_INFO_ECX
CPUID_VERSION_INFO_EDX

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

By these pre-defined bit field data, each needed data can be extract from python code.
For example...

print (f'''
CPU version information in bit field format
============================================
  CpuIdReg.EAX.Bits.SteppingId:    {CpuIdReg.EAX.Bits.SteppingId}
  CpuIdReg.EAX.Bits.Model:         {CpuIdReg.EAX.Bits.Model}
  CpuIdReg.EAX.Bits.FamilyId:      {CpuIdReg.EAX.Bits.FamilyId}
....
''')

Conclusion

This example can run in both UEFI and Linux.












































And the assmeblt code by corepy is
or

AT&T syntax format or Intel syntax format as wish.




EfiPy2 working environment

Introduction

EfiPy2 is python 3 library, is original designed for UEFI shell application. Static data strcuture in EfiPy2 are also suitable being used in OS environmrnt if user can read low layer data, for example PCIe configuration space and complex registers in CPU.

While import EfiPy2 in OS environment, the global data gBS, gST, gRT and gImage are set as fake value to them. That is only static data structure can be apply to Python application and EFI protocol are disabled.

In Windows/Linux system, user can import EfiPy2 without ModuleNotFoundError exception. Thus user Python application can import data structure in EfiPy2.MdePkg.Indusctry and EfiPy2.MdePkg.Register properly. With suitable modifying corepy package, it can also work on EDK2 and Linux system, too.


The conclusion for current stats...

EfiPy2 is full support in UEFI environment.

In Linux system, Python application can import EfiPy2 and corepy. And application can launch corepy code

    % PYTHONPATH=$EfiPy2Path python3

In Windows system, Python application can import EfiPy2

    X:\>set PYTHONPATH=%EfiPy2Path%

    X:\>python


There are two samples for above condition

1. CpuIdBasic.py

    This application leverage corepy excuting cpuid instruction to fetch CPUID data in both UEFI and Linux system.

2. MsrBasic.py

    It can be launched in both Linux and UEFI

    This applicaiton uses rdmsr/wrmsr instructions from corepy, these instrucitons are ring 0 privilege.
    UEFI is a ring 0 environment, too. MsrBasic.py fully achieve msr read/write purpose.
    In Linux, Python run in ring 3 privilege, only related assmbly code is printed in this design while MsrBasic.py is launched.


Monday, October 9, 2023

CorePy

CorePy

 It is taken back to EfiPy.

There is little of information about corepy. We still can find the fist paper about corepy in PDF.

High-Performance Code Generation Using CorePy

With some modification,  most instructins list in x86_64_isa.py can be used in Linux and EfiPy2, again, with python 3.X. Modified code is here,

PciScan.py, CpuId.py levelage corepy making EfiPy doing low  level operation easier.

Here is snapshot how CpuId.py using cpuid instruction based on corepy library.


Saturday, October 7, 2023

SMBIOS in EfiPy2

EfiPy2Smbios.py

 It is not a new one. The upgrated code it put here.

This sample dumps all SMBIOS items in system as part of screenshot.









Comment

In following comment, due to &SmbiosPointer is not lvalue. It it hard to assign variable SmbiosPointer's address to be other pointer object's adress in C.

Python Efipy (ctypes) capability makes it.






Todo

Although this sample all SMBIOS items in system, There can be improved

1. Dump array objects in SMBIOS

2. Fit variable SMBIOS version

3. Be a SMBIOS library.