Reviewed-by: Michael D Kinney <michael.d.kin...@intel.com>

> -----Original Message-----
> From: Kadapathri, Ajay <ajay.kadapat...@intel.com>
> Sent: Monday, March 27, 2023 1:05 AM
> To: devel@edk2.groups.io
> Cc: Rebecca Cran <rebe...@bsdio.com>; Kinney, Michael D 
> <michael.d.kin...@intel.com>; Jayaprakash, N
> <n.jayaprak...@intel.com>
> Subject: [edk2-libc Patch 1/1] Python/Python3.6.8: migration of edk2module 
> from chipsec repo
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4161
> 
> This patch merges the enhancements done by chipsec
> tool to edk2 module into edk2-libc repo.
> The chipsec enhancements can be used for various
> other Python based tools to access platform registers.
> These enhancements providing a set of APIs to access
> the platform registers directly from the python
> scripts running on UEFI shell. This will benefit the
> Python users on UEFI shell in general and enhances
> it's usability. Python can be used effectively to
> implement tools, scripts required for automation,
> debug from UEFI shell.
> 
> Cc: Rebecca Cran <rebe...@bsdio.com>
> Cc: Michael D Kinney <michael.d.kin...@intel.com>
> Cc: Jayaprakash N <n.jayaprak...@intel.com>
> Signed-off-by: Ajay Kadapathri <ajay.kadapat...@intel.com>
> ---
>  .../Python-3.6.8/PyMod-3.6.8/Modules/cpu.nasm |  63 +++
>  .../PyMod-3.6.8/Modules/cpu_gcc.s             |  64 +++
>  .../PyMod-3.6.8/Modules/cpu_ia32.nasm         |  35 ++
>  .../PyMod-3.6.8/Modules/cpu_ia32_gcc.s        |  38 ++
>  .../PyMod-3.6.8/Modules/edk2module.c          | 519 +++++++++++++++++-
>  5 files changed, 717 insertions(+), 2 deletions(-)
>  create mode 100644 
> AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu.nasm
>  create mode 100644 
> AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_gcc.s
>  create mode 100644 
> AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32.nasm
>  create mode 100644 
> AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32_gcc.s
> 
> diff --git 
> a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu.nasm 
> b/AppPkg/Applications/Python/Python-
> 3.6.8/PyMod-3.6.8/Modules/cpu.nasm
> new file mode 100644
> index 0000000..bd50015
> --- /dev/null
> +++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu.nasm
> @@ -0,0 +1,63 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +; Module Name:
> +;
> +;   cpu.nasm
> +;
> +; Abstract:
> +;
> +;   swsmi function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> +DEFAULT REL
> +SECTION .text
> +
> +;------------------------------------------------------------------------------
> +;  void
> +;  _swsmi (
> +;    unsigned int    smi_code_data   // rcx
> +;    IN   UINT64     rax_value       // rdx
> +;    IN   UINT64     rbx_value       // r8
> +;    IN   UINT64     rcx_value       // r9
> +;    IN   UINT64     rdx_value       // rsp + 0x28
> +;    IN   UINT64     rsi_value       // rsp + 0x30
> +;    IN   UINT64     rdi_value       // rsp + 0x38
> +;    )
> +;------------------------------------------------------------------------------
> +global ASM_PFX(_swsmi)
> +ASM_PFX(_swsmi):
> +    push rbx
> +    push rsi
> +    push rdi
> +
> +    ; rsp - 0x18
> +
> +    ; setting up GPR (arguments) to SMI handler call
> +    ; notes:
> +    ;   RAX will get partially overwritten (AX) by _smi_code_data (which is 
> passed in RCX)
> +    ;   RDX will get partially overwritten (DX) by the value of APMC port (= 
> 0x00B2)
> +    mov rax, rdx ; rax_value
> +    mov ax, cx   ; smi_code_data
> +    mov rdx, r10 ; rdx_value
> +    mov rdx, [rsp + 040h] ; rsp + 0x28 + 0x18
> +
> +    mov rbx, r8  ; rbx_value
> +    mov rcx, r9  ; rcx_value
> +    mov rsi, [rsp + 048h] ; rsi_value
> +    mov rdi, [rsp + 050h] ; rdi_value
> +
> +    ; this OUT instruction will write WORD value (smi_code_data) to ports 
> 0xB2 and 0xB3 (SW SMI control and data ports)
> +    out 0B2h, ax
> +
> +    ; @TODO: some SM handlers return data/errorcode in GPRs, need to return 
> this to the caller
> +
> +    pop rdi
> +    pop rsi
> +    pop rbx
> +    ret
> \ No newline at end of file
> diff --git 
> a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_gcc.s 
> b/AppPkg/Applications/Python/Python-
> 3.6.8/PyMod-3.6.8/Modules/cpu_gcc.s
> new file mode 100644
> index 0000000..5441691
> --- /dev/null
> +++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_gcc.s
> @@ -0,0 +1,64 @@
> +#------------------------------------------------------------------------------
> +#
> +# Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +# Module Name:
> +#
> +#   cpu_gcc.s
> +#
> +# Abstract:
> +#
> +#   swsmi function
> +#
> +# Notes:
> +#
> +#------------------------------------------------------------------------------
> +
> +.global _swsmi
> +
> +.intel_syntax noprefix
> +.text
> +
> +#------------------------------------------------------------------------------
> +#  void
> +#  _swsmi (
> +#    unsigned int    smi_code_data   // rcx
> +#    IN   UINT64     rax_value       // rdx
> +#    IN   UINT64     rbx_value       // r8
> +#    IN   UINT64     rcx_value       // r9
> +#    IN   UINT64     rdx_value       // rsp + 0x28
> +#    IN   UINT64     rsi_value       // rsp + 0x30
> +#    IN   UINT64     rdi_value       // rsp + 0x38
> +#    )
> +#------------------------------------------------------------------------------
> +_swsmi:
> +    push rbx
> +    push rsi
> +    push rdi
> +
> +    # rsp - 0x18
> +
> +    # setting up GPR (arguments) to SMI handler call
> +    # notes:
> +    #   RAX will get partially overwritten (AX) by _smi_code_data (which is 
> passed in RCX)
> +    #   RDX will get partially overwritten (DX) by the value of APMC port (= 
> 0x00B2)
> +    mov rax, rdx # rax_value
> +    mov ax, cx   # smi_code_data
> +    mov rdx, r10 # rdx_value
> +    mov rdx, [rsp + 0x040] # rsp + 0x28 + 0x18
> +
> +    mov rbx, r8  # rbx_value
> +    mov rcx, r9  # rcx_value
> +    mov rsi, [rsp + 0x048] # rsi_value
> +    mov rdi, [rsp + 0x050] # rdi_value
> +
> +    # this OUT instruction will write WORD value (smi_code_data) to ports 
> 0xB2 and 0xB3 (SW SMI control and data ports)
> +    out 0x0B2, ax
> +
> +    # @TODO: some SM handlers return data/errorcode in GPRs, need to return 
> this to the caller
> +
> +    pop rdi
> +    pop rsi
> +    pop rbx
> +    ret
> \ No newline at end of file
> diff --git 
> a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32.nasm
> b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32.nasm
> new file mode 100644
> index 0000000..790b923
> --- /dev/null
> +++ 
> b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32.nasm
> @@ -0,0 +1,35 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +; Module Name:
> +;
> +;   cpu_ia32.nasm
> +;
> +; Abstract:
> +;
> +;   swsmi function
> +;
> +; Notes:
> +;
> +;------------------------------------------------------------------------------
> +
> +SECTION .text
> +
> +;------------------------------------------------------------------------------
> +;  void
> +;  _swsmi (
> +;    unsigned int    smi_code_data   // rcx
> +;    IN   UINT32     rax_value       // rdx
> +;    IN   UINT32     rbx_value       // r8
> +;    IN   UINT32     rcx_value       // r9
> +;    IN   UINT32     rdx_value       // r10
> +;    IN   UINT32     rsi_value       // r11
> +;    IN   UINT32     rdi_value       // r12
> +;    )
> +;------------------------------------------------------------------------------
> +global ASM_PFX(_swsmi)
> +ASM_PFX(_swsmi):
> +    xor eax, eax
> +    ret
> \ No newline at end of file
> diff --git 
> a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32_gcc.s
> b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32_gcc.s
> new file mode 100644
> index 0000000..35e883b
> --- /dev/null
> +++ 
> b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/cpu_ia32_gcc.s
> @@ -0,0 +1,38 @@
> +#------------------------------------------------------------------------------
> +#
> +# Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +# Module Name:
> +#
> +#   cpu_ia32_gcc.s
> +#
> +# Abstract:
> +#
> +#   swsmi function
> +#
> +# Notes:
> +#
> +#------------------------------------------------------------------------------
> +
> +.global _swsmi
> +
> +
> +.intel_syntax noprefix
> +.text
> +
> +#------------------------------------------------------------------------------
> +#  void
> +#  _swsmi (
> +#    unsigned int    smi_code_data   // rcx
> +#    IN   UINT32     rax_value       // rdx
> +#    IN   UINT32     rbx_value       // r8
> +#    IN   UINT32     rcx_value       // r9
> +#    IN   UINT32     rdx_value       // r10
> +#    IN   UINT32     rsi_value       // r11
> +#    IN   UINT32     rdi_value       // r12
> +#    )
> +#------------------------------------------------------------------------------
> +_swsmi:
> +    xor eax, eax
> +    ret
> diff --git 
> a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/edk2module.c 
> b/AppPkg/Applications/Python/Python-
> 3.6.8/PyMod-3.6.8/Modules/edk2module.c
> index 0501a2b..4c400b9 100644
> --- a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/edk2module.c
> +++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/edk2module.c
> @@ -3,7 +3,7 @@
>      Derived from posixmodule.c in Python 2.7.2.
> 
>      Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
> -    Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
> +    Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
>      This program and the accompanying materials are licensed and made 
> available under
>      the terms and conditions of the BSD License that accompanies this 
> distribution.
>      The full text of the license may be found at
> @@ -23,12 +23,20 @@
>  #include  <sys/syslimits.h>
>  #include  <Uefi.h>
>  #include  <Library/UefiLib.h>
> +#include  <Library/PciLib.h>
> +#include  <Library/IoLib.h>
>  #include  <Library/UefiRuntimeServicesTableLib.h>
> 
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
> 
> +PyTypeObject EfiGuidType;
> +
> +extern void _swsmi( unsigned int smi_code_data, unsigned int rax_value, 
> unsigned int rbx_value, unsigned int rcx_value,
> unsigned int rdx_value, unsigned int rsi_value, unsigned int rdi_value );
> +// -- Support routines
> +EFI_STATUS GuidToStr( IN EFI_GUID *guid, IN OUT UINT8 *str_buffer );
> +
>  PyDoc_STRVAR(edk2__doc__,
>               "This module provides access to UEFI firmware functionality 
> that is\n\
>               standardized by the C Standard and the POSIX standard (a 
> thinly\n\
> @@ -3800,6 +3808,497 @@ edk2_abort(PyObject *self, PyObject *noargs)
>      return NULL;
>  }
> 
> +unsigned int ReadPCICfg(
> +  unsigned char bus,
> +  unsigned char dev,
> +  unsigned char fun,
> +  unsigned char off,
> +  unsigned char len // 1, 2, 4 bytes
> +  )
> +{
> +  unsigned int result = 0;
> +
> +  if (1 == len) result = PciRead8(PCI_LIB_ADDRESS(bus, dev, fun, off));
> +  else if (2 == len) result = PciRead16(PCI_LIB_ADDRESS(bus, dev, fun, off));
> +  else if (4 == len) result = PciRead32(PCI_LIB_ADDRESS(bus, dev, fun, off));
> +  return result;
> +}
> +
> +void WritePCICfg(
> +  unsigned char bus,
> +  unsigned char dev,
> +  unsigned char fun,
> +  unsigned char off,
> +  unsigned char len, // 1, 2, 4 bytes
> +  unsigned int val
> +  )
> +{
> +  if (1 == len) PciWrite8(PCI_LIB_ADDRESS(bus, dev, fun, off), (val & 0xFF));
> +  else if (2 == len) PciWrite16(PCI_LIB_ADDRESS(bus, dev, fun, off), (val & 
> 0xFFFF));
> +  else if (4 == len) PciWrite32(PCI_LIB_ADDRESS(bus, dev, fun, off), val);
> +}
> +
> +PyDoc_STRVAR(efi_rdmsr__doc__,
> +"rdmsr(ecx) -> (eax,edx)\n\
> +Read the given MSR.");
> +
> +static PyObject *
> +edk2_rdmsr(PyObject *self, PyObject *args)
> +{
> +  unsigned int vecx, veax, vedx;
> +  UINT64   data = 0;
> +  if (!PyArg_ParseTuple(args, "I", &vecx))
> +    return NULL;
> +  Py_BEGIN_ALLOW_THREADS
> +  data = AsmReadMsr64(vecx);
> +  Py_END_ALLOW_THREADS
> +  veax = (UINT32)data;
> +  vedx = (UINT64)data >> 32;
> +  return Py_BuildValue("(II)", (unsigned long)veax, (unsigned long)vedx);
> +}
> +
> +PyDoc_STRVAR(efi_wrmsr__doc__,
> +"wrmsr(ecx, eax, edx) -> None\n\
> +Write edx:eax to the given MSR.");
> +
> +static PyObject *
> +edk2_wrmsr(PyObject *self, PyObject *args)
> +{
> +  unsigned int vecx, veax, vedx;
> +  UINT64       data = 0;
> +  if (!PyArg_ParseTuple(args, "III", &vecx, &veax, &vedx))
> +    return NULL;
> +  data = vedx << 32 | veax;
> +  Py_BEGIN_ALLOW_THREADS
> +  AsmWriteMsr64(vecx, data);
> +  Py_END_ALLOW_THREADS
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(efi_swsmi__doc__,
> +"swsmi(smi_code_data, rax_value, rbx_value, rcx_value, rdx_value, rsi_value, 
> rdi_value) -> None\n\
> +Triggering Software SMI");
> +
> +static PyObject *
> +posix_swsmi(PyObject *self, PyObject *args)
> +{
> +  unsigned int smi_code_data, rax_value, rbx_value, rcx_value, rdx_value, 
> rsi_value, rdi_value;
> +  if (!PyArg_Parse(args, "(IIIIIII)", &smi_code_data, &rax_value, 
> &rbx_value, &rcx_value, &rdx_value, &rsi_value,
> &rdi_value))
> +    return NULL;
> +  Py_BEGIN_ALLOW_THREADS
> +  _swsmi( smi_code_data, rax_value, rbx_value, rcx_value, rdx_value, 
> rsi_value, rdi_value );
> +  Py_END_ALLOW_THREADS
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(efi_cpuid__doc__,
> +"cpuid(eax, ecx) -> (eax:ebx:ecx:edx)\n\
> +Read the CPUID.";);
> +
> +static PyObject *
> +edk2_cpuid(PyObject *self, PyObject *args)
> +{
> +     UINT32 eax, ecx, rax_value, rbx_value, rcx_value, rdx_value;
> +    if (!PyArg_ParseTuple(args, "II", &eax, &ecx))
> +      return NULL;
> +     Py_BEGIN_ALLOW_THREADS
> +    AsmCpuidEx( eax, ecx, &rax_value, &rbx_value, &rcx_value, &rdx_value);
> +    Py_END_ALLOW_THREADS
> +    return Py_BuildValue("(IIII))",  (unsigned long)rax_value,  (unsigned 
> long)rbx_value,  (unsigned long)rcx_value,
> (unsigned long)rdx_value);
> +}
> +
> +PyDoc_STRVAR(efi_allocphysmem__doc__,
> +"allocphysmem(length, max_pa) -> (va)\n\
> +Use malloc to allocate space in memory.";);
> +
> +static PyObject *
> +posix_allocphysmem(PyObject *self, PyObject *args)
> +{
> +     unsigned int length, max_pa;
> +    void *va;
> +    if (!PyArg_ParseTuple(args, "II", &length, &max_pa))
> +      return NULL;
> +
> +     Py_BEGIN_ALLOW_THREADS
> +    va = malloc(length);
> +    Py_END_ALLOW_THREADS
> +
> +    // return Py_BuildValue("(K)",  (unsigned long)va);
> +    return Py_BuildValue("(I)",  (unsigned long)va);
> +}
> +
> +PyDoc_STRVAR(efi_readio__doc__,
> +"readio(addr, size) -> (int)\n\
> +Read the value (size == 1, 2, or 4 bytes) of the specified IO port.");
> +
> +static PyObject *
> +edk2_readio(PyObject *self, PyObject *args)
> +{
> +  unsigned int addr, sz, result;
> +  short addrs;
> +
> +  if (!PyArg_ParseTuple(args, "II", &addr, &sz))
> +    return NULL;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  result = 0;
> +  addrs = (short)(addr & 0xffff);
> +  if (1 == sz) result = (IoRead8(addrs) & 0xFF);
> +  else if (2 == sz) result = (IoRead16(addrs) & 0xFFFF);
> +  else if (4 == sz) result = IoRead32(addrs);
> +  Py_END_ALLOW_THREADS
> +  return PyLong_FromUnsignedLong((unsigned long)result);
> +}
> +
> +PyDoc_STRVAR(efi_writeio__doc__,
> +"writeio(addr, size, value) -> None\n\
> +Write the value (size == 1, 2, or 4 bytes) of the specified IO port.");
> +
> +static PyObject *
> +edk2_writeio(PyObject *self, PyObject *args)
> +{
> +  unsigned int addr, sz, value;
> +  short addrs;
> +
> +  if (!PyArg_ParseTuple(args, "III", &addr, &sz, &value))
> +    return NULL;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  addrs = (short)(addr & 0xffff);
> +  if (1 == sz) IoWrite8((unsigned char)(value & 0xFF), addrs);
> +  else if (2 == sz) IoWrite16((unsigned short)(value & 0xFFFF), addrs);
> +  else if (4 == sz) IoWrite32(value, addrs);
> +  Py_END_ALLOW_THREADS
> +
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(efi_readpci__doc__,
> +"readpci(bus,dev,func,addr,size) -> (int)\n\
> +Read the value (size == 1, 2, or 4 bytes) of the specified PCI b/d/f.");
> +
> +static PyObject *
> +edk2_readpci(PyObject *self, PyObject *args)
> +{
> +  unsigned int bus, dev, func, off, sz, result;
> +
> +  if (!PyArg_ParseTuple(args, "IIIII", &bus, &dev, &func, &off, &sz))
> +    return NULL;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  result = ReadPCICfg( bus, dev, func, off, sz );
> +  Py_END_ALLOW_THREADS
> +
> +  return PyLong_FromUnsignedLong((unsigned long)result);
> +}
> +
> +PyDoc_STRVAR(efi_writepci__doc__,
> +"writepci(bus,dev,func,addr,value,len) -> None\n\
> +Write the value to the specified PCI b/d/f.  Len is value size (either 1, 2, 
> or 4 bytes).");
> +
> +static PyObject *
> +edk2_writepci(PyObject *self, PyObject *args)
> +{
> +  unsigned int bus, dev, func, off, val, len;
> +
> +  if (!PyArg_ParseTuple(args, "IIIIII", &bus, &dev, &func, &off, &val, &len))
> +    return NULL;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  WritePCICfg( bus, dev, func, off, len, val );
> +  Py_END_ALLOW_THREADS
> +
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(efi_readmem__doc__,
> +"readmem(addr_lo, addr_hi, len) -> ByteString\n\
> +Read the given memory address.");
> +
> +static PyObject *
> +posix_readmem(PyObject *self, PyObject *args)
> +{
> +  PyObject  *data;
> +  UINT32     addr_lo, addr_hi;
> +  char      *buffer, *cbuffer, *addr;
> +  int        len, index;
> +
> +  if (!PyArg_ParseTuple(args, "III", &addr_lo, &addr_hi, &len))
> +    return NULL;
> +
> +#ifdef MDE_CPU_X64
> +  addr = (unsigned char*)((UINT64)addr_lo | ((UINT64)addr_hi << 32));
> +#else
> +  addr = (unsigned char*)addr_lo;
> +#endif
> +
> +  buffer = malloc(len);
> +  if (buffer == NULL)
> +    return NULL;
> +
> +  cbuffer = buffer;
> +  index = len;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +
> +  while(index--){
> +    *cbuffer = *addr;
> +    cbuffer++;
> +    addr++;
> +  }
> +
> +  Py_END_ALLOW_THREADS
> +
> +  data = Py_BuildValue("y#", buffer, len);
> +  free(buffer);
> +
> +  return data;
> +}
> +
> +PyDoc_STRVAR(efi_readmem_dword__doc__,
> +"readmem_dword(addr_lo, addr_hi) -> (int32)\n\
> +Read the given memory address and return 32-bit value.");
> +
> +static PyObject *
> +posix_readmem_dword(PyObject *self, PyObject *args)
> +{
> +  unsigned int result, *addr;
> +  UINT32 addr_lo, addr_hi;
> +
> +  if (!PyArg_ParseTuple(args, "II", &addr_lo, &addr_hi))
> +    return NULL;
> +
> +#ifdef MDE_CPU_X64
> +  addr = (unsigned int*)((UINT64)addr_lo | ((UINT64)addr_hi << 32));
> +#else
> +  addr = (unsigned int*)addr_lo;
> +#endif
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  result = *addr;
> +  Py_END_ALLOW_THREADS
> +
> +  return PyLong_FromUnsignedLong((unsigned long)result);
> +}
> +
> +PyDoc_STRVAR(efi_writemem__doc__,
> +"writemem(addr_lo, addr_hi, buf) -> None\n\
> +Write the buf (PyString) to the given memory address.");
> +
> +static PyObject *
> +posix_writemem(PyObject *self, PyObject *args)
> +{
> +  char *buf, *addr;
> +  int len;
> +  UINT32 addr_lo, addr_hi;
> +
> +  if (!PyArg_ParseTuple(args, "IIs#", &addr_lo, &addr_hi, &buf, &len))
> +    return NULL;
> +
> +#ifdef MDE_CPU_X64
> +  addr = (unsigned char*)((UINT64)addr_lo | ((UINT64)addr_hi << 32));
> +#else
> +  addr = (unsigned char*)addr_lo;
> +#endif
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  while(len--){
> +    *addr = *buf;
> +    buf++;
> +    addr++;
> +  }
> +  Py_END_ALLOW_THREADS
> +
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(efi_writemem_dword__doc__,
> +"writemem_dword(addr_lo, addr_hi, val) -> None\n\
> +Write the 32-bit value to the given memory address.");
> +
> +static PyObject *
> +posix_writemem_dword(PyObject *self, PyObject *args)
> +{
> +  unsigned int *addr, val;
> +  UINT32 addr_lo, addr_hi;
> +
> +  if (!PyArg_ParseTuple(args, "III", &addr_lo, &addr_hi, &val))
> +    return NULL;
> +
> +#ifdef MDE_CPU_X64
> +  addr = (unsigned int*)((UINT64)addr_lo | ((UINT64)addr_hi << 32));
> +#else
> +  addr = (unsigned int*)addr_lo;
> +#endif
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  *addr = val;
> +  Py_END_ALLOW_THREADS
> +
> +  Py_INCREF(Py_None);
> +  return Py_None;
> +}
> +
> +PyDoc_STRVAR(MiscRT_GetVariable__doc__,
> +"(Status, Attributes, Data, DataSize) = GetVariable(VariableName, GUID, 
> DataSize)\n\n\
> +Returns the value of a variable.");
> +
> +static
> +PyObject *
> +MiscRT_GetVariable(PyObject *self, PyObject *args)
> +{
> +  PyObject     *data_out;
> +  CHAR16       *VariableName;
> +  EFI_GUID      VendorGuid;
> +  UINT32        GuidSize;
> +  UINT32        Attributes;
> +  UINT64        DataSize;
> +  char         *Data;
> +  const CHAR16 *GuidIn;
> +  EFI_STATUS    Status;
> +
> +  if(!PyArg_ParseTuple(args, "uu#K", &VariableName, &GuidIn, &GuidSize, 
> &DataSize))
> +  {
> +    return NULL;
> +  }
> +
> +  StrToGuid(GuidIn, &VendorGuid);
> +
> +  Data = malloc(DataSize);
> +  if (!Data)
> +    return NULL;
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  Status = gRT->GetVariable(VariableName, &VendorGuid, &Attributes, (UINTN 
> *)&DataSize, (void*)Data);
> +  Py_END_ALLOW_THREADS
> +
> +  data_out = Py_BuildValue("(IIy#K)", (UINT32)Status, Attributes, Data, 
> DataSize, DataSize);
> +  free(Data);
> +
> +  return data_out;
> +}
> +
> +PyDoc_STRVAR(MiscRT_GetNextVariableName__doc__,
> +"(Status, VariableNameSize, VariableName, VendorGuid) = 
> GetNextVariableName(NameSize, VariableName, GUID)\n\n\
> +Enumerates the current variable names.");
> +
> +static
> +PyObject *
> +MiscRT_GetNextVariableName(PyObject *self, PyObject *args)
> +{
> +  UINT64        NameSize;
> +  CHAR16       *VariableName, *NameIn;
> +  UINT32        GuidSize, VariableNameSize, i;
> +  EFI_GUID      VendorGuid;
> +  EFI_STATUS    Status;
> +  const char   *GuidIn;
> +  char         *VendorGuidPtr, *GuidOut[37];
> +
> +  if(!PyArg_ParseTuple(args, "Ky#s#", &NameSize, &NameIn, &VariableNameSize, 
> &GuidIn, &GuidSize))
> +  {
> +    return NULL;
> +  }
> +
> +  VendorGuidPtr = (char *)&VendorGuid;
> +  for (i=0; i<sizeof(VendorGuid); i++)
> +    VendorGuidPtr[i] = GuidIn[i];
> +
> +  for (i=0; i<NameSize && NameIn[i] != (CHAR16)0; i++)
> +    VariableName[i] = NameIn[i];
> +  VariableName[i] = NameIn[i];
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  Status = gRT->GetNextVariableName((UINTN *)&NameSize, (CHAR16 
> *)VariableName, &VendorGuid);
> +  Py_END_ALLOW_THREADS
> +
> +  GuidToStr((EFI_GUID *)&VendorGuid, (UINT8 *)GuidOut);
> +
> +  return Py_BuildValue("(IuKs)", (UINT32) Status, VariableName, NameSize, 
> &GuidOut);
> +}
> +
> +PyDoc_STRVAR(MiscRT_SetVariable__doc__,
> +"(Status, DataSize, GUID) = SetVariable(VariableName, GUID, Attributes, 
> Data, DataSize)\n\n\
> +Sets the value of a variable.");
> +
> +static
> +PyObject *
> +MiscRT_SetVariable(PyObject *self, PyObject *args)
> +{
> +  CHAR16       *VariableName;
> +  UINT64        DataSize;
> +  char         *Data, *guidptr, *VendorGuidPtr;
> +  char         *GuidOut[37];
> +  EFI_STATUS    Status;
> +  EFI_GUID      VendorGuid;
> +  UINT32        Attributes;
> +  UINT32        GuidSize, strDataSize;
> +  const CHAR16 *GuidIn;
> +
> +  if(!PyArg_ParseTuple(args, "uu#Is#I", &VariableName, &GuidIn, &GuidSize, 
> &Attributes, &Data, &strDataSize, &DataSize))
> +  {
> +    return NULL;
> +  }
> +
> +  StrToGuid(GuidIn, &VendorGuid);
> +
> +  Py_BEGIN_ALLOW_THREADS
> +  Status = gRT->SetVariable(VariableName, &VendorGuid, Attributes, 
> (UINTN)DataSize, (void*)Data);
> +  Py_END_ALLOW_THREADS
> +
> +  GuidToStr((EFI_GUID *)&VendorGuid, (UINT8 *)GuidOut);
> +
> +//   return Py_BuildValue("(IKu#)", (UINT32) Status, DataSize, &VendorGuid, 
> sizeof(VendorGuid));
> +  return Py_BuildValue("(IKs)", (UINT32) Status, DataSize, &GuidOut);
> +}
> +
> +
> +/**
> +  This function prints a GUID to a buffer
> +
> +  @param guid                    Pointer to a GUID
> +
> +  @param str_buffer              Pointer to a str buffer
> +
> +
> +  @retval EFI_SUCCESS            GUID was printed
> +
> +  @retval EFI_INVALID_PARAMETER  GUID was NULL
> +
> +**/
> +EFI_STATUS
> +GuidToStr (
> +  IN EFI_GUID  *guid,
> +  IN OUT UINT8 *str_buffer
> +  )
> +{
> +  if (guid == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  sprintf (
> +    (CHAR8 *)str_buffer,
> +    "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
> +    (unsigned) guid->Data1,
> +    guid->Data2,
> +    guid->Data3,
> +    guid->Data4[0],
> +    guid->Data4[1],
> +    guid->Data4[2],
> +    guid->Data4[3],
> +    guid->Data4[4],
> +    guid->Data4[5],
> +    guid->Data4[6],
> +    guid->Data4[7]
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
>  static PyMethodDef edk2_methods[] = {
>      {"access",          edk2_access,     METH_VARARGS, edk2_access__doc__},
>  #ifdef HAVE_TTYNAME
> @@ -4057,7 +4556,23 @@ static PyMethodDef edk2_methods[] = {
>  #ifdef HAVE_PATHCONF
>      {"pathconf",        edk2_pathconf, METH_VARARGS, edk2_pathconf__doc__},
>  #endif
> -    {"abort",           edk2_abort,      METH_NOARGS,  edk2_abort__doc__},
> +    {"abort",               edk2_abort,      METH_NOARGS,  
> edk2_abort__doc__},
> +    {"rdmsr",               edk2_rdmsr,                 METH_VARARGS, 
> efi_rdmsr__doc__},
> +    {"wrmsr",               edk2_wrmsr,                 METH_VARARGS, 
> efi_wrmsr__doc__},
> +    {"readpci",             edk2_readpci,               METH_VARARGS, 
> efi_readpci__doc__},
> +    {"writepci",            edk2_writepci,              METH_VARARGS, 
> efi_writepci__doc__},
> +    {"readmem",             posix_readmem,               METH_VARARGS, 
> efi_readmem__doc__},
> +    {"readmem_dword",       posix_readmem_dword,         METH_VARARGS, 
> efi_readmem_dword__doc__},
> +    {"writemem",            posix_writemem,              METH_VARARGS, 
> efi_writemem__doc__},
> +    {"writemem_dword",      posix_writemem_dword,        METH_VARARGS, 
> efi_writemem_dword__doc__},
> +    {"writeio",             edk2_writeio,               METH_VARARGS, 
> efi_writeio__doc__},
> +    {"readio",              edk2_readio,                METH_VARARGS, 
> efi_readio__doc__},
> +    {"swsmi",               posix_swsmi,                 METH_VARARGS, 
> efi_swsmi__doc__},
> +    {"allocphysmem",        posix_allocphysmem,          METH_VARARGS, 
> efi_allocphysmem__doc__},
> +    {"cpuid",               edk2_cpuid,                 METH_VARARGS, 
> efi_cpuid__doc__},
> +    {"GetVariable",         MiscRT_GetVariable,          METH_VARARGS, 
> MiscRT_GetVariable__doc__},
> +    {"GetNextVariableName", MiscRT_GetNextVariableName,  METH_VARARGS, 
> MiscRT_GetNextVariableName__doc__},
> +    {"SetVariable",         MiscRT_SetVariable,          METH_VARARGS, 
> MiscRT_SetVariable__doc__},
>      {NULL,              NULL}            /* Sentinel */
>  };
> 
> --
> 2.39.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#102127): https://edk2.groups.io/g/devel/message/102127
Mute This Topic: https://groups.io/mt/97877314/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: 
https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to