]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
When SOURCE_DEBUG_ENABLE is set, a TimerLib is linked into the SEC Phase to support...
[mirror_edk2.git] / OvmfPkg / Library / AcpiTimerLib / AcpiTimerLib.c
index 201ef48d2df959ea2dc39b007087a38fd2ad440e..c6441281b4b6b750a976bade3e3336e4e3bddc76 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   ACPI Timer implements one instance of Timer Library.\r
 \r
-  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
 \r
   This program and the accompanying materials are\r
 #include <Library/DebugLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <IndustryStandard/Pci22.h>\r
+#include <IndustryStandard/Acpi.h>\r
 \r
 //\r
-// PIIX4 Power Management Base Address\r
+// PCI Location of PIIX4 Power Management PCI Configuration Registers\r
 //\r
-STATIC UINT32 mPmba;\r
+#define PIIX4_POWER_MANAGEMENT_BUS       0x00\r
+#define PIIX4_POWER_MANAGEMENT_DEVICE    0x01\r
+#define PIIX4_POWER_MANAGEMENT_FUNCTION  0x03\r
 \r
-#define PCI_BAR_IO             0x1\r
-#define ACPI_TIMER_FREQUENCY   3579545\r
-#define ACPI_TIMER_COUNT_SIZE  0x01000000\r
+//\r
+// Macro to access PIIX4 Power Management PCI Configuration Registers\r
+//\r
+#define PIIX4_PCI_POWER_MANAGEMENT_REGISTER(Register) \\r
+  PCI_LIB_ADDRESS (                                   \\r
+    PIIX4_POWER_MANAGEMENT_BUS,                       \\r
+    PIIX4_POWER_MANAGEMENT_DEVICE,                    \\r
+    PIIX4_POWER_MANAGEMENT_FUNCTION,                  \\r
+    Register                                          \\r
+    )\r
+\r
+//\r
+// PIIX4 Power Management PCI Configuration Registers\r
+//\r
+#define PMBA                PIIX4_PCI_POWER_MANAGEMENT_REGISTER (0x40)\r
+#define   PMBA_RTE          BIT0\r
+#define PMREGMISC           PIIX4_PCI_POWER_MANAGEMENT_REGISTER (0x80)\r
+#define   PMIOSE            BIT0\r
+\r
+//\r
+// The ACPI Time in the PIIX4 is a 24-bit counter\r
+//\r
+#define ACPI_TIMER_COUNT_SIZE  BIT24\r
+\r
+//\r
+// Offset in the PIIX4 Power Management Base Address to the ACPI Timer \r
+//\r
 #define ACPI_TIMER_OFFSET      0x8\r
 \r
 /**\r
@@ -48,30 +75,22 @@ AcpiTimerLibConstructor (
   VOID\r
   )\r
 {\r
-  UINT8 Device;\r
-\r
-  Device = 1;\r
-  // Device = 7;\r
-\r
-  if (PciRead8 (PCI_LIB_ADDRESS (0,Device,3,0x80)) & 1) {\r
-    mPmba = PciRead32 (PCI_LIB_ADDRESS (0,Device,3,0x40));\r
-    ASSERT (mPmba & PCI_BAR_IO);\r
-    mPmba &= ~PCI_BAR_IO;\r
-  } else {\r
-    mPmba = PcdGet16 (PcdAcpiPmBaseAddress);\r
-\r
-    PciAndThenOr32 (PCI_LIB_ADDRESS (0,Device,3,0x40),\r
-                    (UINT32) ~0xFFC0, mPmba);\r
-    PciOr8 (\r
-      PCI_LIB_ADDRESS (0, Device, 3, PCI_COMMAND_OFFSET),\r
-      EFI_PCI_COMMAND_IO_SPACE\r
-      );\r
-  }\r
-\r
   //\r
-  // ACPI Timer enable is in Bus 0, Device ?, Function 3\r
+  // Check to see if the PIIX4 Power Management Base Address is already enabled\r
   //\r
-  PciOr8         (PCI_LIB_ADDRESS (0,Device,3,0x80), 0x01);\r
+  if ((PciRead8 (PMREGMISC) & PMIOSE) == 0) {\r
+    //\r
+    // If the PIIX4 Power Management Base Address is not programmed, \r
+    // then program the PIIX4 Power Management Base Address from a PCD.\r
+    //\r
+    PciAndThenOr32 (PMBA, (UINT32)(~0x0000FFC0), PcdGet16 (PcdAcpiPmBaseAddress));\r
+\r
+    //\r
+    // Enable PMBA I/O port decodes in PMREGMISC\r
+    //\r
+    PciOr8 (PMREGMISC, PMIOSE);\r
+  }\r
+  \r
   return RETURN_SUCCESS;\r
 }\r
 \r
@@ -83,13 +102,15 @@ AcpiTimerLibConstructor (
   @return The tick counter read.\r
 \r
 **/\r
-STATIC\r
 UINT32\r
 InternalAcpiGetTimerTick (\r
   VOID\r
   )\r
 {\r
-  return IoRead32 (mPmba + ACPI_TIMER_OFFSET);\r
+  //\r
+  //   Read PMBA to read and return the current ACPI timer value.\r
+  //\r
+  return IoRead32 ((PciRead32 (PMBA) & ~PMBA_RTE) + ACPI_TIMER_OFFSET);\r
 }\r
 \r
 /**\r
@@ -101,7 +122,6 @@ InternalAcpiGetTimerTick (
   @param  Delay     A period of time to delay in ticks.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 InternalAcpiDelay (\r
   IN      UINT32                    Delay\r