/** @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
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
@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
@param Delay A period of time to delay in ticks.\r
\r
**/\r
-STATIC\r
VOID\r
InternalAcpiDelay (\r
IN UINT32 Delay\r