]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
OvmfPkg: new macros for platform specific register addresses and values
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / BaseAcpiTimerLib.c
CommitLineData
170ef2d9
GS
1/** @file\r
2 Provide constructor and GetTick for Base instance of ACPI Timer Library\r
3\r
4 Copyright (C) 2014, Gabriel L. Somlo <somlo@cmu.edu>\r
5\r
6 This program and the accompanying materials are licensed and made\r
7 available under the terms and conditions of the BSD License which\r
8 accompanies this distribution. The full text of the license may\r
9 be found at http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13**/\r
14\r
15#include <Library/DebugLib.h>\r
16#include <Library/IoLib.h>\r
17#include <Library/PciLib.h>\r
f122712b 18#include <Library/PcdLib.h>\r
170ef2d9
GS
19#include <OvmfPlatforms.h>\r
20\r
21//\r
22// Power Management PCI Configuration Register fields\r
23//\r
e2ab3f81
GS
24#define PMBA_RTE BIT0\r
25#define PIIX4_PMIOSE BIT0\r
26#define Q35_ACPI_EN BIT7\r
170ef2d9
GS
27\r
28//\r
29// Offset in the Power Management Base Address to the ACPI Timer\r
30//\r
31#define ACPI_TIMER_OFFSET 0x8\r
32\r
33//\r
34// Cached ACPI Timer IO Address\r
35//\r
36STATIC UINT32 mAcpiTimerIoAddr;\r
37\r
38/**\r
f122712b
GS
39 The constructor function caches the ACPI tick counter address, and,\r
40 if necessary, enables ACPI IO space.\r
170ef2d9
GS
41\r
42 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.\r
43\r
44**/\r
45RETURN_STATUS\r
46EFIAPI\r
47AcpiTimerLibConstructor (\r
48 VOID\r
49 )\r
50{\r
51 UINT16 HostBridgeDevId;\r
52 UINTN Pmba;\r
e2ab3f81
GS
53 UINTN AcpiCtlReg;\r
54 UINT8 AcpiEnBit;\r
170ef2d9
GS
55\r
56 //\r
57 // Query Host Bridge DID to determine platform type\r
58 //\r
59 HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
60 switch (HostBridgeDevId) {\r
61 case INTEL_82441_DEVICE_ID:\r
e2ab3f81
GS
62 Pmba = POWER_MGMT_REGISTER_PIIX4 (0x40);\r
63 AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (0x80); // PMREGMISC\r
64 AcpiEnBit = PIIX4_PMIOSE;\r
170ef2d9
GS
65 break;\r
66 case INTEL_Q35_MCH_DEVICE_ID:\r
e2ab3f81
GS
67 Pmba = POWER_MGMT_REGISTER_Q35 (0x40);\r
68 AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (0x44); // ACPI_CNTL\r
69 AcpiEnBit = Q35_ACPI_EN;\r
170ef2d9
GS
70 break;\r
71 default:\r
72 DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
73 __FUNCTION__, HostBridgeDevId));\r
74 ASSERT (FALSE);\r
75 return RETURN_UNSUPPORTED;\r
76 }\r
77\r
78 mAcpiTimerIoAddr = (PciRead32 (Pmba) & ~PMBA_RTE) + ACPI_TIMER_OFFSET;\r
79\r
f122712b
GS
80 //\r
81 // Check to see if the Power Management Base Address is already enabled\r
82 //\r
e2ab3f81 83 if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {\r
f122712b
GS
84 //\r
85 // If the Power Management Base Address is not programmed,\r
86 // then program the Power Management Base Address from a PCD.\r
87 //\r
88 PciAndThenOr32 (Pmba, (UINT32) ~0xFFC0, PcdGet16 (PcdAcpiPmBaseAddress));\r
89\r
90 //\r
e2ab3f81 91 // Enable PMBA I/O port decodes\r
f122712b 92 //\r
e2ab3f81 93 PciOr8 (AcpiCtlReg, AcpiEnBit);\r
f122712b
GS
94 }\r
95\r
170ef2d9
GS
96 return RETURN_SUCCESS;\r
97}\r
98\r
99/**\r
100 Internal function to read the current tick counter of ACPI.\r
101\r
102 Read the current ACPI tick counter using the counter address cached\r
103 by this instance's constructor.\r
104\r
105 @return The tick counter read.\r
106\r
107**/\r
108UINT32\r
109InternalAcpiGetTimerTick (\r
110 VOID\r
111 )\r
112{\r
113 //\r
114 // Return the current ACPI timer value.\r
115 //\r
116 return IoRead32 (mAcpiTimerIoAddr);\r
117}\r