]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / BaseAcpiTimerLib.c
1 /** @file
2 Provide constructor and GetTick for Base instance of ACPI Timer Library
3
4 Copyright (C) 2014, Gabriel L. Somlo <somlo@cmu.edu>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8
9 #include <Library/DebugLib.h>
10 #include <Library/IoLib.h>
11 #include <Library/PciLib.h>
12 #include <OvmfPlatforms.h>
13
14 //
15 // Cached ACPI Timer IO Address
16 //
17 STATIC UINT32 mAcpiTimerIoAddr;
18
19 /**
20 The constructor function caches the ACPI tick counter address, and,
21 if necessary, enables ACPI IO space.
22
23 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
24
25 **/
26 RETURN_STATUS
27 EFIAPI
28 AcpiTimerLibConstructor (
29 VOID
30 )
31 {
32 UINT16 HostBridgeDevId;
33 UINTN Pmba;
34 UINT32 PmbaAndVal;
35 UINT32 PmbaOrVal;
36 UINTN AcpiCtlReg;
37 UINT8 AcpiEnBit;
38
39 //
40 // Query Host Bridge DID to determine platform type
41 //
42 HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
43 switch (HostBridgeDevId) {
44 case INTEL_82441_DEVICE_ID:
45 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
46 PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
47 PmbaOrVal = PIIX4_PMBA_VALUE;
48 AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
49 AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
50 break;
51 case INTEL_Q35_MCH_DEVICE_ID:
52 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
53 PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
54 PmbaOrVal = ICH9_PMBASE_VALUE;
55 AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
56 AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
57 break;
58 default:
59 DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
60 __FUNCTION__, HostBridgeDevId));
61 ASSERT (FALSE);
62 return RETURN_UNSUPPORTED;
63 }
64
65 //
66 // Check to see if the Power Management Base Address is already enabled
67 //
68 if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
69 //
70 // If the Power Management Base Address is not programmed,
71 // then program it now.
72 //
73 PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
74
75 //
76 // Enable PMBA I/O port decodes
77 //
78 PciOr8 (AcpiCtlReg, AcpiEnBit);
79 }
80
81 mAcpiTimerIoAddr = (PciRead32 (Pmba) & ~PMBA_RTE) + ACPI_TIMER_OFFSET;
82 return RETURN_SUCCESS;
83 }
84
85 /**
86 Internal function to read the current tick counter of ACPI.
87
88 Read the current ACPI tick counter using the counter address cached
89 by this instance's constructor.
90
91 @return The tick counter read.
92
93 **/
94 UINT32
95 InternalAcpiGetTimerTick (
96 VOID
97 )
98 {
99 //
100 // Return the current ACPI timer value.
101 //
102 return IoRead32 (mAcpiTimerIoAddr);
103 }