From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 70892D81111 for ; Wed, 24 Apr 2024 18:12:26 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=8WVEG0pYnFHbzK50/EMvsGRpLaHdfMQdAB94JRlTyEw=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1713982345; v=1; b=Xo3edWZqxaJgltIt87UywmH+xCI37FowX82rKl80H31HZaMh8e6HQ9QlhtblYyy/x0Ckjd9e m1F82ehzBISCQ/6KfCDHFIJC6HgBVHlCtNVqmxxLhYq0+SgvGuwSULBCD8A14eakS7CusDJoqQo 2rrqi/fT/YL30kH7aNbR/PG3TnaVcKrIqHdLZD+IFN/YS/SKP/M7WaTB3xcAh8PSfxwRmZjXEp6 l+lNAl2U5DMpYTVjD0NyJ5xdpuFbWytl0KF9z4wiVTQzaZ0OVckY92ElB+iiLCprk9Xja0vwMlf hTqZujIdDboh/Zy2NwvqREln3woNu88piQxhIoAP01hyQ== X-Received: by 127.0.0.2 with SMTP id mkJKYY7687511xd6CkWMf9qm; Wed, 24 Apr 2024 11:12:25 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by mx.groups.io with SMTP id smtpd.web11.3801.1713982342964984038 for ; Wed, 24 Apr 2024 11:12:24 -0700 X-CSE-ConnectionGUID: Zru8BxfwRSa44PIHFw9YiA== X-CSE-MsgGUID: HpyndaPVT/maTWdBNUlzmA== X-IronPort-AV: E=McAfee;i="6600,9927,11054"; a="9503016" X-IronPort-AV: E=Sophos;i="6.07,226,1708416000"; d="scan'208";a="9503016" X-Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2024 11:12:24 -0700 X-CSE-ConnectionGUID: Yna19fmOSzScu+nZ/NEhow== X-CSE-MsgGUID: ZIEs7WHIRa6Ovvr+OA0Pwg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,226,1708416000"; d="scan'208";a="55749265" X-Received: from njayapra-mobl.gar.corp.intel.com ([10.247.135.165]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2024 11:12:22 -0700 From: "Jayaprakash, N" To: devel@edk2.groups.io Cc: Jayaprakash N , Rebecca Cran , Michael D Kinney Subject: [edk2-devel] [edk2-libc Patch v2 1/1] edk2-libc : add rdmsr_ex and wrmsr_ex to read/write msr from specific cpus Date: Wed, 24 Apr 2024 23:40:34 +0530 Message-ID: <20240424181213.393-2-n.jayaprakash@intel.com> In-Reply-To: <20240424181213.393-1-n.jayaprakash@intel.com> References: <20240424181213.393-1-n.jayaprakash@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Wed, 24 Apr 2024 11:12:24 -0700 Resent-From: n.jayaprakash@intel.com Reply-To: devel@edk2.groups.io,n.jayaprakash@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 9v8zdYkwadvPNLJqRLVPSwkTx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=Xo3edWZq; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none) REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4746 The rdmsr_ex and wrmsr_ex are extension APIs to the rdmsr and wrmsr APIs supported in edk2 module. These extension APIs makes it possible to read / write MSRs from specific processors. This fills an important gap in reading / writing these registers from specific cpu cores using python scripts from UEFI shell. Cc: Rebecca Cran Cc: Michael D Kinney Cc: Jayaprakash N Signed-off-by: Jayaprakash N --- .../PyMod-3.6.8/Modules/edk2module.c | 258 +++++++++++++++++- .../Python/Python-3.6.8/Python368.inf | 3 + 2 files changed, 252 insertions(+), 9 deletions(-) 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 f688b51..13e5de5 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.
- Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.
+ Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.
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 @@ -22,16 +22,30 @@ #include #include #include +#include // Needed for the definition of EFI_AP_PROCEDURE #include #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif PyTypeObject EfiGuidType; +EFI_MP_SERVICES_PROTOCOL *gpMpService = NULL; +UINTN gCurrentBSPProcessorNumber = 0; +UINTN gNumberOfProcessors = 0; +UINTN gNumberOfEnabledProcessors = 0; + +typedef struct { + UINT32 msr; // msr value + UINT64 data; // data, to be filled by the AP function +} AP_FUNCTION_MSR_ARGS; + +#define AP_FUNCTION_EXECUTION_TIMEOUT 5000000 // setting the max time out value to be 5 seconds 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 @@ -169,6 +183,46 @@ PyDoc_STRVAR(edk2__doc__, /* dummy version. _PyVerify_fd() is already defined in fileobject.h */ #define _PyVerify_fd_dup2(A, B) (1) +/* MPServices Protocol wrapper function definitions */ +static EFI_STATUS +MpServicesWhoAmI ( + IN EFI_MP_SERVICES_PROTOCOL *pMpService, + OUT UINTN *pProcessorNumber + ) +{ + return pMpService->WhoAmI (pMpService, pProcessorNumber); +} + +static EFI_STATUS +MpServicesGetNumberOfProcessors ( + IN EFI_MP_SERVICES_PROTOCOL *pMpService, + OUT UINTN *pNumberOfProcessors, + OUT UINTN *pNumberOfEnabledProcessors + + ) +{ + return pMpService->GetNumberOfProcessors (pMpService, + pNumberOfProcessors, + pNumberOfEnabledProcessors); +} + +// MSR read function to run on specific cpu core using MPServices Protocol +VOID EFIAPI MSRReadToRunOnAP(IN VOID *context) +{ + AP_FUNCTION_MSR_ARGS *args = (AP_FUNCTION_MSR_ARGS *)context; + UINT32 msr = args->msr; + args->data = AsmReadMsr64(msr); +} + +// MSR write function to run on specific cpu core using MPServices Protocol +VOID EFIAPI MSRWriteToRunOnAP(IN VOID *context) +{ + AP_FUNCTION_MSR_ARGS *args = (AP_FUNCTION_MSR_ARGS *)context; + UINT32 msr = args->msr; + UINT64 data = args->data; + AsmWriteMsr64(msr, data); +} + #ifndef UEFI_C_SOURCE /* Return a dictionary corresponding to the POSIX environment table */ extern char **environ; @@ -3864,6 +3918,91 @@ edk2_rdmsr(PyObject *self, PyObject *args) vedx = (UINT64)data >> 32; return Py_BuildValue("(II)", (unsigned long)veax, (unsigned long)vedx); } + +PyDoc_STRVAR(efi_rdmsr_ex__doc__, +"rdmsr_ex(cpu, msr) -> (lower_32bits, higher_32bits)\n\ +\n\ +Read the given msr from the specific cpu and return the data as tuple,\n\ +provided the cpu number is less than the max number of processors on\n\ +this system, otherwise generates OSError/ValueError to indicate API failure.\n\ +\n\ +Parameters:\n\ + cpu - The cpu number in hex or int format\n\ + msr - The msr in hex or int format\n\ +\n\ +Return Value:\n\ + a tuple with lower and higher 32 bit values read from the msr\n\ +"); + +static PyObject * +edk2_rdmsr_ex(PyObject *self, PyObject *args) +{ + unsigned int cpu, msr, veax, vedx; + EFI_STATUS status = 0; + UINT64 data = 0; + BOOLEAN is_function_finished = FALSE; + AP_FUNCTION_MSR_ARGS ap_function_args = {0}; + + if (!PyArg_ParseTuple(args, "II", &cpu, &msr)) + return NULL; + ap_function_args.msr = msr; + + Py_BEGIN_ALLOW_THREADS + if (cpu == gCurrentBSPProcessorNumber) + { + // cpu provided as input is same as the current BSP processor + // then directly call the AsmReadMsr64 function to read msr + // on current BSP processor itself. + data = AsmReadMsr64(msr); + } + else if (cpu < gNumberOfProcessors) + { + // if cpu provided as input is different from the current + // BSP processor and is less than the number of processors + // on this system, then make use of the MPService protocols + // StartupThisAP function to run the MSR read function on + // specific AP indicated by cpu parameter. + // Start the AP with the arguments structure + status = gpMpService->StartupThisAP( + gpMpService, + MSRReadToRunOnAP, // Function to run + cpu, // AP number + NULL, // WaitEvent (optional) + AP_FUNCTION_EXECUTION_TIMEOUT, // Timeout in microseconds + &ap_function_args, // Buffer to pass to the function + &is_function_finished // Finished (optional) + ); + + if (EFI_ERROR(status)) + { + PyErr_SetString(PyExc_OSError, "Could not start the requested cpu"); + Py_INCREF(Py_None); + return Py_None; + } + + if (!is_function_finished) + { + PyErr_SetString(PyExc_OSError, + "Timeout while running the msr read function on given cpu"); + Py_INCREF(Py_None); + return Py_None; + } + data = ap_function_args.data; + } + else + { + // if cpu provided exeeds the number of processors + // then set the ValueError exception and return Py_None + PyErr_SetString(PyExc_ValueError, + "Invalid cpu number provided"); + Py_INCREF(Py_None); + return Py_None; + } + 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(msr, lower_32bits, higher_32bits) -> None\n\ @@ -3893,6 +4032,93 @@ edk2_wrmsr(PyObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } + +PyDoc_STRVAR(efi_wrmsr_ex__doc__, +"wrmsr_ex(cpu, msr, lower_32bits, higher_32bits) -> None\n\ +\n\ +Writes higher_32bits:lower_32bits to the given msr,\n\ +provided the cpu input is less than the max number of\n\ +processors on this system, otherwise generates\n\ +OSError/ValueError to indicate API failure.\n\ +\n\ +Parameters:\n\ + cpu - The cpu number in hex or int format\n\ + msr - The msr in hex or int format\n\ + lower_32bits - The lower 32 bit data for the msr\n\ + higher_32bits - The higher 32 bit data for the msr\n\ +\n\ +Return Value:\n\ + None\n\ +"); + +static PyObject * +edk2_wrmsr_ex(PyObject *self, PyObject *args) +{ + unsigned int cpu, msr, veax, vedx; + EFI_STATUS status = 0; + UINT64 data = 0; + BOOLEAN is_function_finished = FALSE; + AP_FUNCTION_MSR_ARGS ap_function_args = {0}; + + if (!PyArg_ParseTuple(args, "IIII", &cpu, &msr, &veax, &vedx)) + return NULL; + data = LShiftU64(vedx, 32) | veax; + ap_function_args.msr = msr; + ap_function_args.data = data; + + Py_BEGIN_ALLOW_THREADS + if (cpu == gCurrentBSPProcessorNumber) + { + // cpu provided as input is same as the current BSP processor + // then directly call the AsmWriteMsr64 function to write msr + // on current BSP processor itself. + AsmWriteMsr64(msr, data); + } + else if (cpu < gNumberOfProcessors) + { + // if cpu provided as input is different from the current + // BSP processor, then make use of the MPService protocols + // StartupThisAP function to run the MSR write function on + // specific AP indicated by cpu parameter. + // Start the AP with the arguments structure + status = gpMpService->StartupThisAP( + gpMpService, + MSRWriteToRunOnAP, // Function to run + cpu, // AP number + NULL, // WaitEvent (optional) + AP_FUNCTION_EXECUTION_TIMEOUT, // Timeout in microseconds + &ap_function_args, // Buffer to pass to the function + &is_function_finished // Finished (optional) + ); + + if (EFI_ERROR(status)) + { + PyErr_SetString(PyExc_OSError, "Could not start the requested cpu"); + Py_INCREF(Py_None); + return Py_None; + } + + if (!is_function_finished) + { + PyErr_SetString(PyExc_OSError, + "Timeout while running the msr write function on given cpu"); + Py_INCREF(Py_None); + return Py_None; + } + } + else + { + // if cpu provided exeeds the number of processors + // then set the ValueError exception and return Py_None + PyErr_SetString(PyExc_ValueError, + "Invalid cpu number provided"); + Py_INCREF(Py_None); + return Py_None; + } + 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\ @@ -4575,8 +4801,10 @@ static PyMethodDef edk2_methods[] = { {"pathconf", edk2_pathconf, METH_VARARGS, edk2_pathconf__doc__}, #endif {"abort", edk2_abort, METH_NOARGS, edk2_abort__doc__}, - {"rdmsr", edk2_rdmsr, METH_VARARGS, efi_rdmsr__doc__}, - {"wrmsr", edk2_wrmsr, METH_VARARGS, efi_wrmsr__doc__}, + {"rdmsr", edk2_rdmsr, METH_VARARGS, efi_rdmsr__doc__}, + {"rdmsr_ex", edk2_rdmsr_ex, METH_VARARGS, efi_rdmsr_ex__doc__}, + {"wrmsr", edk2_wrmsr, METH_VARARGS, efi_wrmsr__doc__}, + {"wrmsr_ex", edk2_wrmsr_ex, METH_VARARGS, efi_wrmsr_ex__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__}, @@ -4814,12 +5042,27 @@ PyMODINIT_FUNC PyEdk2__Init(void) { PyObject *m; + EFI_STATUS Status = 0; #ifndef UEFI_C_SOURCE PyObject *v; #endif - - m = PyModule_Create(&edk2module); + Status = gBS->LocateProtocol(&gEfiMpServiceProtocolGuid, + NULL, + &gpMpService); + if (EFI_ERROR(Status)) + { + Print(L"Unable to locate the Protocol MpServices protocol: %r\n", Status); + return NULL; + } + // Get the current BSP processor number + MpServicesWhoAmI(gpMpService, &gCurrentBSPProcessorNumber); + // Get the number of processors + MpServicesGetNumberOfProcessors(gpMpService, + &gNumberOfProcessors, + &gNumberOfEnabledProcessors); + + m = PyModule_Create(&edk2module); if (m == NULL) return m; @@ -4870,12 +5113,9 @@ PyEdk2__Init(void) //PyModule_AddObject(m, "statvfs_result", // (PyObject*) &StatVFSResultType); initialized = 1; - return m; - + return m; } #ifdef __cplusplus } #endif - - diff --git a/AppPkg/Applications/Python/Python-3.6.8/Python368.inf b/AppPkg/Applications/Python/Python-3.6.8/Python368.inf index 8b7f677..eca98b5 100644 --- a/AppPkg/Applications/Python/Python-3.6.8/Python368.inf +++ b/AppPkg/Applications/Python/Python-3.6.8/Python368.inf @@ -46,6 +46,9 @@ #BsdSocketLib #EfiSocketLib +[Protocols] + gEfiMpServiceProtocolGuid ## CONSUMES + [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0F gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040 -- 2.44.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118231): https://edk2.groups.io/g/devel/message/118231 Mute This Topic: https://groups.io/mt/105715630/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-