From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mx.groups.io with SMTP id smtpd.web11.12299.1647966046517391362 for ; Tue, 22 Mar 2022 09:20:46 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@linux.microsoft.com header.s=default header.b=oiEZJnCd; spf=pass (domain: linux.microsoft.com, ip: 13.77.154.182, mailfrom: mikuback@linux.microsoft.com) Received: from localhost.localdomain (unknown [47.202.59.224]) by linux.microsoft.com (Postfix) with ESMTPSA id 3B26820B4783; Tue, 22 Mar 2022 09:20:45 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3B26820B4783 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1647966046; bh=R1M1gyQnX6Fis7iqm6eVF7NdwLIMx1pYUYHx7LUzlpc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oiEZJnCd1pxoqmUkuYk/eZ0WgB6A4VzfPQnZjJVLuFdoJW+yQFc6Jd6BGCTSgmlCZ 6SfRyxzt3FYRiG6UNjP47205753nvEI5q7yN2+wlA7IBldrqNtbu5inU4muxnAMeId ieL1r5THf8ifw3i0dBq5jRqfzJZOXwGe1d6DgPo4= From: "Michael Kubacki" To: devel@edk2.groups.io Cc: Andrew Fish , Kang Gao , Michael D Kinney , Michael Kubacki , Leif Lindholm , Benjamin You , Liu Yun , Ankit Sinha , Nate DeSimone Subject: [PATCH v1 07/41] PrmPkg: Add initial PrmSampleHardwareAccessModule Date: Tue, 22 Mar 2022 12:19:13 -0400 Message-Id: <20220322161947.9319-8-mikuback@linux.microsoft.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20220322161947.9319-1-mikuback@linux.microsoft.com> References: <20220322161947.9319-1-mikuback@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Michael Kubacki REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D3812 Adds a sample PRM module that demonstrates: 1. How to write a PRM module 2. How to use multiple PRM handlers in a module 3. How to use a basic PRM OS service 4. MSR access at OS runtime Note: This module contains a PRM handler to read from the HPET MMIO range but the memory map changes needed for this to succeed are currently not implemented. These will be implemented in a future change. Cc: Andrew Fish Cc: Kang Gao Cc: Michael D Kinney Cc: Michael Kubacki Cc: Leif Lindholm Cc: Benjamin You Cc: Liu Yun Cc: Ankit Sinha Cc: Nate DeSimone Signed-off-by: Michael Kubacki --- PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModu= le.c | 537 ++++++++++++++++++++ PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h = | 105 ++++ PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModu= le.inf | 42 ++ 3 files changed, 684 insertions(+) diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwa= reAccessModule.c b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSample= HardwareAccessModule.c new file mode 100644 index 000000000000..87fe9cafc912 --- /dev/null +++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAcces= sModule.c @@ -0,0 +1,537 @@ +/** @file + + A sample PRM Module implementation. This PRM Module provides PRM handl= ers that perform various types + of hardware access. This is simply meant to demonstrate hardware acces= s capabilities from a PRM handler. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "Hpet.h" + +// +// PRM Handler GUIDs +// + +// {2120cd3c-848b-4d8f-abbb-4b74ce64ac89} +#define MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x2120cd3c, 0x8= 48b, 0x4d8f, {0xab, 0xbb, 0x4b, 0x74, 0xce, 0x64, 0xac, 0x89}} + +// {ea0935a7-506b-4159-bbbb-48deeecb6f58} +#define MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID {0xea0935a7, 0x506b, 0x415= 9, {0xbb, 0xbb, 0x48, 0xde, 0xee, 0xcb, 0x6f, 0x58}} + +// {1bd1bda9-909a-4614-9699-25ec0c2783f7} +#define MMIO_ACCESS_HPET_PRM_HANDLER_GUID {0x1bd1bda9, 0x909a, 0x4614, {= 0x96, 0x99, 0x25, 0xec, 0x0c, 0x27, 0x83, 0xf7}} + +#define HPET_BASE_ADDRESS 0xFED00000 + +// +// BEGIN: MtrrLib internal library globals and function prototypes here = for testing +// +extern CONST CHAR8 *mMtrrMemoryCacheTypeShortName[]; + +/** + Initializes the valid bits mask and valid address mask for MTRRs. + + This function initializes the valid bits mask and valid address mask f= or MTRRs. + + @param[out] MtrrValidBitsMask The mask for the valid bit of the M= TRR + @param[out] MtrrValidAddressMask The valid address mask for the MTRR + +**/ +VOID +MtrrLibInitializeMtrrMask ( + OUT UINT64 *MtrrValidBitsMask, + OUT UINT64 *MtrrValidAddressMask + ); + +/** + Convert variable MTRRs to a RAW MTRR_MEMORY_RANGE array. + One MTRR_MEMORY_RANGE element is created for each MTRR setting. + The routine doesn't remove the overlap or combine the near-by region. + + @param[in] VariableSettings The variable MTRR values to shadow + @param[in] VariableMtrrCount The number of variable MTRRs + @param[in] MtrrValidBitsMask The mask for the valid bit of the M= TRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs = content + + @return Number of MTRRs which has been used. + +**/ +UINT32 +MtrrLibGetRawVariableRanges ( + IN MTRR_VARIABLE_SETTINGS *VariableSettings, + IN UINTN VariableMtrrCount, + IN UINT64 MtrrValidBitsMask, + IN UINT64 MtrrValidAddressMask, + OUT MTRR_MEMORY_RANGE *VariableMtrr + ); + +/** + Apply the fixed MTRR settings to memory range array. + + @param Fixed The fixed MTRR settings. + @param Ranges Return the memory range array holding memory = type + settings for all memory address. + @param RangeCapacity The capacity of memory range array. + @param RangeCount Return the count of memory range. + + @retval RETURN_SUCCESS The memory range array is returned suc= cessfully. + @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds cap= acity. +**/ +RETURN_STATUS +MtrrLibApplyFixedMtrrs ( + IN MTRR_FIXED_SETTINGS *Fixed, + IN OUT MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCapacity, + IN OUT UINTN *RangeCount + ); + +/** + Apply the variable MTRR settings to memory range array. + + @param VariableMtrr The variable MTRR array. + @param VariableMtrrCount The count of variable MTRRs. + @param Ranges Return the memory range array with new MTRR s= ettings applied. + @param RangeCapacity The capacity of memory range array. + @param RangeCount Return the count of memory range. + + @retval RETURN_SUCCESS The memory range array is returned suc= cessfully. + @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds cap= acity. +**/ +RETURN_STATUS +MtrrLibApplyVariableMtrrs ( + IN CONST MTRR_MEMORY_RANGE *VariableMtrr, + IN UINT32 VariableMtrrCount, + IN OUT MTRR_MEMORY_RANGE *Ranges, + IN UINTN RangeCapacity, + IN OUT UINTN *RangeCount + ); + +// +// END: MtrrLib internal library function prototypes here for testing +// + +/** + Prints all MTRR values including architectural and variable MTTRs. + +**/ +VOID +EFIAPI +PrintAllMtrrs ( + IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint + ) +{ + MTRR_SETTINGS LocalMtrrs; + MTRR_SETTINGS *Mtrrs; + UINTN Index; + UINTN RangeCount; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + UINT32 VariableMtrrCount; + BOOLEAN ContainVariableMtrr; + CHAR8 DebugMessage[256]; + + MTRR_MEMORY_RANGE Ranges[ + MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs-= >Variables.Mtrr) + 1 + ]; + MTRR_MEMORY_RANGE RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)= ]; + + if (OsServiceDebugPrint =3D=3D NULL || !IsMtrrSupported ()) { + return; + } + + VariableMtrrCount =3D GetVariableMtrrCount (); + + MtrrGetAllMtrrs (&LocalMtrrs); + Mtrrs =3D &LocalMtrrs; + + // + // Dump RAW MTRR contents + // + OsServiceDebugPrint (" MTRR Settings:\n"); + OsServiceDebugPrint (" =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " MTRR Default Type: %016lx\n", + Mtrrs->MtrrDefType + ); + OsServiceDebugPrint (&DebugMessage[0]); + + for (Index =3D 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " Fixed MTRR[%02d] : %016lx\n", + Index, + Mtrrs->Fixed.Mtrr[Index] + ); + OsServiceDebugPrint (&DebugMessage[0]); + } + ContainVariableMtrr =3D FALSE; + for (Index =3D 0; Index < VariableMtrrCount; Index++) { + if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) =3D=3D 0) { + // + // If mask is not valid, then do not display range + // + continue; + } + ContainVariableMtrr =3D TRUE; + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " Variable MTRR[%02d]: Base=3D%016lx Mask=3D%016lx\n", + Index, + Mtrrs->Variables.Mtrr[Index].Base, + Mtrrs->Variables.Mtrr[Index].Mask + ); + OsServiceDebugPrint (&DebugMessage[0]); + } + if (!ContainVariableMtrr) { + OsServiceDebugPrint (" Variable MTRR : None.\n"); + } + OsServiceDebugPrint ("\n"); + + // + // Dump MTRR setting in ranges + // + OsServiceDebugPrint (" Memory Ranges:\n"); + OsServiceDebugPrint (" =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"); + MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); + Ranges[0].BaseAddress =3D 0; + Ranges[0].Length =3D MtrrValidBitsMask + 1; + Ranges[0].Type =3D MtrrGetDefaultMemoryType (); + RangeCount =3D 1; + + MtrrLibGetRawVariableRanges ( + &Mtrrs->Variables, VariableMtrrCount, + MtrrValidBitsMask, MtrrValidAddressMask, RawVariableRanges + ); + MtrrLibApplyVariableMtrrs ( + RawVariableRanges, VariableMtrrCount, + Ranges, ARRAY_SIZE (Ranges), &RangeCount + ); + + MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &R= angeCount); + + for (Index =3D 0; Index < RangeCount; Index++) { + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " %a:%016lx-%016lx\n", + mMtrrMemoryCacheTypeShortName[Ranges[Index].Type], + Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Inde= x].Length - 1 + ); + OsServiceDebugPrint (&DebugMessage[0]); + } +} + +/** + Reads a HPET MMIO register. + + Reads the 64-bit HPET MMIO register specified by Address. + + This function must guarantee that all MMIO read and write + operations are serialized. + + If Address is not aligned on a 64-bit boundary, zero will be returned. + + @param Offset Specifies the offset of the HPET regis= ter to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +HpetRead ( + IN UINTN Offset + ) +{ + UINTN Address; + UINT64 Value; + + Address =3D HPET_BASE_ADDRESS + Offset; + + if ((Address & 7) =3D=3D 0) { + return 0; + } + + MemoryFence (); + Value =3D *(volatile UINT64*)Address; + MemoryFence (); + + return Value; +} + +/** + Prints HPET configuration information. + +**/ +VOID +EFIAPI +PrintHpetConfiguration ( + IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint + ) +{ + UINTN TimerIndex; + HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetGeneralCapabilities; + HPET_GENERAL_CONFIGURATION_REGISTER HpetGeneralConfiguration; + CHAR8 DebugMessage[256]; + + if (OsServiceDebugPrint =3D=3D NULL) { + return; + } + + HpetGeneralCapabilities.Uint64 =3D HpetRead (HPET_GENERAL_CAPABILITIE= S_ID_OFFSET); + HpetGeneralConfiguration.Uint64 =3D HpetRead (HPET_GENERAL_CONFIGURATI= ON_OFFSET); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET Base Address =3D 0x%08x\n", + HPET_BASE_ADDRESS + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_GENERAL_CAPABILITIES_ID =3D 0x%016lx\n", + HpetGeneralCapabilities + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_GENERAL_CONFIGURATION =3D 0x%016lx\n", + HpetGeneralConfiguration.Uint64 + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_GENERAL_INTERRUPT_STATUS =3D 0x%016lx\n", + HpetRead (HPET_GENERAL_INTERRUPT_STATUS_OFFSET) + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_MAIN_COUNTER =3D 0x%016lx\n", + HpetRead (HPET_MAIN_COUNTER_OFFSET) + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET Main Counter Period =3D %d (fs)\n", + HpetGeneralCapabilities.Bits.CounterClockPeriod + ); + OsServiceDebugPrint (&DebugMessage[0]); + + for (TimerIndex =3D 0; TimerIndex <=3D HpetGeneralCapabilities.Bits.Nu= mberOfTimers; TimerIndex++) { + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_TIMER%d_CONFIGURATION =3D 0x%016lx\n", + TimerIndex, + HpetRead (HPET_TIMER_CONFIGURATION_OFFSET + TimerIndex * HPET_TIME= R_STRIDE) + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_TIMER%d_COMPARATOR =3D 0x%016lx\n", + TimerIndex, + HpetRead (HPET_TIMER_COMPARATOR_OFFSET + TimerIndex * HPET_TIME= R_STRIDE) + ); + OsServiceDebugPrint (&DebugMessage[0]); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " HPET_TIMER%d_MSI_ROUTE =3D 0x%016lx\n", + TimerIndex, + HpetRead (HPET_TIMER_MSI_ROUTE_OFFSET + TimerIndex * HPET_TIME= R_STRIDE) + ); + OsServiceDebugPrint (&DebugMessage[0]); + } +} + +/** + Prints the microcode update signature as read from architectural MSR 0= x8B. + +**/ +VOID +EFIAPI +PrintMicrocodeUpdateSignature ( + IN PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint + ) +{ + MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr; + CHAR8 DebugMessage[256]; + + if (OsServiceDebugPrint =3D=3D NULL) { + return; + } + + AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); + BiosSignIdMsr.Uint64 =3D AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); + + AsciiSPrint ( + &DebugMessage[0], + ARRAY_SIZE (DebugMessage), + " Signature read =3D 0x%x.\n", + BiosSignIdMsr.Bits.MicrocodeUpdateSignature + ); + OsServiceDebugPrint (&DebugMessage[0]); +} + +/** + A sample Platform Runtime Mechanism (PRM) handler. + + This sample handler attempts to read the microcode update signature MS= R and print the result to a debug message. + + @param[in] ParameterBuffer A pointer to the PRM handler parameter= buffer + @param[in] ContextBUffer A pointer to the PRM handler context b= uffer + + @retval EFI_STATUS The PRM handler executed successfully. + @retval Others An error occurred in the PRM handler. + +**/ +PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler) +{ + PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint; + + if (ParameterBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // In the POC, the OS debug print service is assumed to be at the begi= nning of ParameterBuffer + OsServiceDebugPrint =3D *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuff= er); + if (OsServiceDebugPrint =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHa= ndler entry.\n"); + OsServiceDebugPrint (" Attempting to read the Microcode Update Signat= ure MSR (0x8B)...\n"); + PrintMicrocodeUpdateSignature (OsServiceDebugPrint); + OsServiceDebugPrint ("Hardware Access MsrAccessMicrocodeSignaturePrmHa= ndler exit.\n"); + + return EFI_SUCCESS; +} + +/** + A sample Platform Runtime Mechanism (PRM) handler. + + This sample handler attempts to read the current MTRR settings and pri= nt the result to a debug message. + + @param[in] ParameterBuffer A pointer to the PRM handler parameter= buffer + @param[in] ContextBUffer A pointer to the PRM handler context b= uffer + + @retval EFI_STATUS The PRM handler executed successfully. + @retval Others An error occurred in the PRM handler. + +**/ +PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler) +{ + PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint; + + if (ParameterBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // In the POC, the OS debug print service is assumed to be at the begi= nning of ParameterBuffer + OsServiceDebugPrint =3D *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuff= er); + if (OsServiceDebugPrint =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler entr= y.\n"); + OsServiceDebugPrint (" Attempting to dump MTRR values:\n"); + PrintAllMtrrs (OsServiceDebugPrint); + OsServiceDebugPrint ("Hardware Access MsrAccessMtrrDumpPrmHandler exit= .\n"); + + return EFI_SUCCESS; +} + +/** + A sample Platform Runtime Mechanism (PRM) handler. + + This sample handler attempts to read from a HPET MMIO resource and pri= nt the result to a debug message. + + @param[in] ParameterBuffer A pointer to the PRM handler parameter= buffer + @param[in] ContextBUffer A pointer to the PRM handler context b= uffer + + @retval EFI_STATUS The PRM handler executed successfully. + @retval Others An error occurred in the PRM handler. + +**/ +PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler) +{ + PRM_OS_SERVICE_DEBUG_PRINT OsServiceDebugPrint; + + if (ParameterBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // In the POC, the OS debug print service is assumed to be at the begi= nning of ParameterBuffer + OsServiceDebugPrint =3D *((PRM_OS_SERVICE_DEBUG_PRINT *) ParameterBuff= er); + if (OsServiceDebugPrint =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler entry.\= n"); + OsServiceDebugPrint (" Attempting to read HPET configuration...\n"); + PrintHpetConfiguration (OsServiceDebugPrint); + OsServiceDebugPrint ("Hardware Access MmioAccessHpetPrmHandler exit.\n= "); + + return EFI_SUCCESS; +} + +// +// Register the PRM export information for this PRM Module +// +PRM_MODULE_EXPORT ( + PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_G= UID, MsrAccessMicrocodeSignaturePrmHandler), + PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID, MsrAc= cessMtrrDumpPrmHandler), + PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAcces= sHpetPrmHandler) + ); + +/** + Module entry point. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable A pointer to the system table. + + @retval EFI_SUCCESS This function always returns success. + +**/ +EFI_STATUS +EFIAPI +PrmSampleHardwareAccessModuleInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h b/PrmPkg= /Samples/PrmSampleHardwareAccessModule/Hpet.h new file mode 100644 index 000000000000..c7eb0cbfa747 --- /dev/null +++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/Hpet.h @@ -0,0 +1,105 @@ +/** @file + HPET register definitions from the IA-PC HPET (High Precision Event Ti= mers) + Specification, Revision 1.0a, October 2004. + + PRM Module Note: + This specific header was copied from PcAtChipsetPkg to avoid a module = dependency on the package + just for this header. This is done for temporary testing purposes of t= he PRM module. + + Copyright (c) Microsoft Corporation + Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HPET_REGISTER_H_ +#define HPET_REGISTER_H_ + +/// +/// HPET General Register Offsets +/// +#define HPET_GENERAL_CAPABILITIES_ID_OFFSET 0x000 +#define HPET_GENERAL_CONFIGURATION_OFFSET 0x010 +#define HPET_GENERAL_INTERRUPT_STATUS_OFFSET 0x020 + +/// +/// HPET Timer Register Offsets +/// +#define HPET_MAIN_COUNTER_OFFSET 0x0F0 +#define HPET_TIMER_CONFIGURATION_OFFSET 0x100 +#define HPET_TIMER_COMPARATOR_OFFSET 0x108 +#define HPET_TIMER_MSI_ROUTE_OFFSET 0x110 + +/// +/// Stride between sets of HPET Timer Registers +/// +#define HPET_TIMER_STRIDE 0x20 + +#pragma pack(1) + +/// +/// HPET General Capabilities and ID Register +/// +typedef union { + struct { + UINT32 Revision:8; + UINT32 NumberOfTimers:5; + UINT32 CounterSize:1; + UINT32 Reserved0:1; + UINT32 LegacyRoute:1; + UINT32 VendorId:16; + UINT32 CounterClockPeriod:32; + } Bits; + UINT64 Uint64; +} HPET_GENERAL_CAPABILITIES_ID_REGISTER; + +/// +/// HPET General Configuration Register +/// +typedef union { + struct { + UINT32 MainCounterEnable:1; + UINT32 LegacyRouteEnable:1; + UINT32 Reserved0:30; + UINT32 Reserved1:32; + } Bits; + UINT64 Uint64; +} HPET_GENERAL_CONFIGURATION_REGISTER; + +/// +/// HPET Timer Configuration Register +/// +typedef union { + struct { + UINT32 Reserved0:1; + UINT32 LevelTriggeredInterrupt:1; + UINT32 InterruptEnable:1; + UINT32 PeriodicInterruptEnable:1; + UINT32 PeriodicInterruptCapability:1; + UINT32 CounterSizeCapability:1; + UINT32 ValueSetEnable:1; + UINT32 Reserved1:1; + UINT32 CounterSizeEnable:1; + UINT32 InterruptRoute:5; + UINT32 MsiInterruptEnable:1; + UINT32 MsiInterruptCapability:1; + UINT32 Reserved2:16; + UINT32 InterruptRouteCapability; + } Bits; + UINT64 Uint64; +} HPET_TIMER_CONFIGURATION_REGISTER; + +/// +/// HPET Timer MSI Route Register +/// +typedef union { + struct { + UINT32 Value:32; + UINT32 Address:32; + } Bits; + UINT64 Uint64; +} HPET_TIMER_MSI_ROUTE_REGISTER; + +#pragma pack() + +#endif diff --git a/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwa= reAccessModule.inf b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSamp= leHardwareAccessModule.inf new file mode 100644 index 000000000000..302183c576f9 --- /dev/null +++ b/PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAcces= sModule.inf @@ -0,0 +1,42 @@ +## @file +# Sample PRM Driver +# +# A sample PRM Module implementation. This PRM Module provides PRM hand= lers that perform various types +# of hardware access. This is simply meant to demonstrate hardware acce= ss capabilities from a PRM handler. +# +# Copyright (c) Microsoft Corporation +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PrmSampleHardwareAccessModule + FILE_GUID =3D 0EF93ED7-14AE-425B-928F-B85A6213B57= E + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D PrmSampleHardwareAccessModuleInit + +[Sources] + Hpet.h + PrmSampleHardwareAccessModule.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + PrmPkg/PrmPkg.dec + +[LibraryClasses] + BaseLib + MtrrLib + PrintLib + UefiDriverEntryPoint + UefiLib + +[Depex] + TRUE + +[BuildOptions.common] + MSFT:*_*_*_DLINK_FLAGS =3D /DLL /SUBSYSTEM:CONSOLE /VERSION:1.0 --=20 2.28.0.windows.1