]> git.proxmox.com Git - mirror_edk2.git/commitdiff
When SOURCE_DEBUG_ENABLE is set, a TimerLib is linked into the SEC Phase to support...
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Oct 2012 20:58:21 +0000 (20:58 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Oct 2012 20:58:21 +0000 (20:58 +0000)
The TimerLib in the OvmfPkg uses a global variable called mPmba and depends on that global being updated.  This works for modules loaded into memory, but not  XIP modules in ROM/FLASH.

This patch removes the mPmba global variable and instead reads the PIIX4 Power Management Base Address from PCI configuration space when it is needed.  This patch also simplifies the initialization logic in the constructor and introduces #defines to eliminate hard coded values in the function implementations.  According to the PIIX4 documentation, the IO Space enable bit in the PCI Command Register does not have to be set for the Power Management Base Address to be decoded, so that one op has been removed from the constructor.

I have tested this patch with QEMU and verified that the UDK Debugger us functional when SOURCE_DEBUG_ENABLE is set.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
I also tested it with RHEL-6.3 guest boot/shutdown, Fedora 18 Alpha XFCE
guest boot/shutdown, and Windows 8 Consumer Preview guest
boot/reboot/shutdown. (RHEL-6.3 host.) I didn't notice any adverse effects.

Tested-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13783 6f19259b-4bc3-4df7-8a09-765794883524

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