]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
OvmfPkg: replace PcdAcpiPmBaseAddress with PIIX4_PMBA_VALUE
[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 This program and the accompanying materials are licensed and made
7 available under the terms and conditions of the BSD License which
8 accompanies this distribution. The full text of the license may
9 be found at http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 **/
14
15 #include <Library/DebugLib.h>
16 #include <Library/IoLib.h>
17 #include <Library/PciLib.h>
18 #include <OvmfPlatforms.h>
19
20 //
21 // Cached ACPI Timer IO Address
22 //
23 STATIC UINT32 mAcpiTimerIoAddr;
24
25 /**
26 The constructor function caches the ACPI tick counter address, and,
27 if necessary, enables ACPI IO space.
28
29 @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
30
31 **/
32 RETURN_STATUS
33 EFIAPI
34 AcpiTimerLibConstructor (
35 VOID
36 )
37 {
38 UINT16 HostBridgeDevId;
39 UINTN Pmba;
40 UINTN AcpiCtlReg;
41 UINT8 AcpiEnBit;
42
43 //
44 // Query Host Bridge DID to determine platform type
45 //
46 HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
47 switch (HostBridgeDevId) {
48 case INTEL_82441_DEVICE_ID:
49 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
50 AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
51 AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
52 break;
53 case INTEL_Q35_MCH_DEVICE_ID:
54 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
55 AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
56 AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;
57 break;
58 default:
59 DEBUG ((EFI_D_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, (UINT32) ~0xFFC0, PIIX4_PMBA_VALUE);
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 }