summaryrefslogtreecommitdiff
path: root/MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c')
-rw-r--r--MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c313
1 files changed, 313 insertions, 0 deletions
diff --git a/MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c b/MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c
new file mode 100644
index 0000000..ee8afab
--- /dev/null
+++ b/MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c
@@ -0,0 +1,313 @@
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+--*/
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ EfiRegTableLib.c
+
+Abstract:
+
+ Lib function for table driven register initialization.
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiDriverLib.h"
+#include "EfiRegTableLib.h"
+#include "EfiDebug.h"
+
+//
+// Local Functions
+//
+STATIC
+VOID
+PciWrite (
+ EFI_REG_TABLE_PCI_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+/*++
+
+Routine Description:
+ Local worker function to process PCI_WRITE table entries. Performs write and
+ may also call BootScriptSave protocol if indicated in the Entry flags
+
+Arguments:
+ Entry - A pointer to the PCI_WRITE entry to process
+
+ PciRootBridgeIo - A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+Returns:
+ Nothing.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &Entry->Data
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = BootScriptSavePciCfgWrite (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &Entry->Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+STATIC
+VOID
+PciReadModifyWrite (
+ EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+/*++
+
+Routine Description:
+ Local worker function to process PCI_READ_MODIFY_WRITE table entries.
+ Performs RMW write and may also call BootScriptSave protocol if indicated in
+ the Entry flags.
+
+Arguments:
+ Entry - A pointer to the PCI_READ_MODIFY_WRITE entry to process.
+
+ PciRootBridgeIo - A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+Returns:
+ Nothing.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 TempData;
+
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Entry->OrMask &= Entry->AndMask;
+ TempData &= ~Entry->AndMask;
+ TempData |= Entry->OrMask;
+
+ Status = PciRootBridgeIo->Pci.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = BootScriptSavePciCfgReadWrite (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->PciAddress,
+ &Entry->OrMask,
+ &Entry->AndMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+STATIC
+VOID
+MemReadModifyWrite (
+ EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
+ )
+/*++
+
+Routine Description:
+ Local worker function to process MEM_READ_MODIFY_WRITE table entries.
+ Performs RMW write and may also call BootScriptSave protocol if indicated in
+ the Entry flags.
+
+Arguments:
+ Entry - A pointer to the MEM_READ_MODIFY_WRITE entry to process.
+
+ PciRootBridgeIo - A pointer to the instance of PciRootBridgeIo that is used
+ when processing the entry.
+
+Returns:
+ Nothing.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 TempData;
+
+ Status = PciRootBridgeIo->Mem.Read (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->MemAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Entry->OrMask &= Entry->AndMask;
+ TempData &= ~Entry->AndMask;
+ TempData |= Entry->OrMask;
+
+ Status = PciRootBridgeIo->Mem.Write (
+ PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ (UINT64) Entry->MemAddress,
+ 1,
+ &TempData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
+ Status = BootScriptSaveMemReadWrite (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
+ Entry->MemAddress,
+ &Entry->OrMask,
+ &Entry->AndMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+//
+// Exported functions
+//
+VOID
+ProcessRegTablePci (
+ EFI_REG_TABLE *RegTableEntry,
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ EFI_CPU_IO_PROTOCOL *CpuIo
+ )
+/*++
+
+Routine Description:
+ Processes register table assuming which may contain PCI, IO, MEM, and STALL
+ entries.
+
+ No parameter checking is done so the caller must be careful about omitting
+ values for PciRootBridgeIo or CpuIo parameters. If the regtable does
+ not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
+ NULL). If the regtable does not contain any IO or Mem entries, it is safe to
+ omit the CpuIo (supply NULL).
+
+ The RegTableEntry parameter is not checked, but is required.
+
+ gBS is assumed to have been defined and is used when processing stalls.
+
+ The function processes each entry sequentially until an OP_TERMINATE_TABLE
+ entry is encountered.
+
+Arguments:
+ RegTableEntry - A pointer to the register table to process
+
+ PciRootBridgeIo - A pointer to the instance of PciRootBridgeIo that is used
+ when processing PCI table entries
+
+ CpuIo - A pointer to the instance of CpuIo that is used when processing IO and
+ MEM table entries
+
+Returns:
+ Nothing.
+
+--*/
+{
+ while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+ switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+ case OP_PCI_WRITE:
+ PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ case OP_PCI_READ_MODIFY_WRITE:
+ PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ case OP_MEM_READ_MODIFY_WRITE:
+ MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
+ break;
+
+ default:
+ DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+ ASSERT (0);
+ break;
+ }
+
+ RegTableEntry++;
+ }
+}
+
+VOID
+ProcessRegTableCpu (
+ EFI_REG_TABLE *RegTableEntry,
+ EFI_CPU_IO_PROTOCOL *CpuIo
+ )
+/*++
+
+Routine Description:
+ Processes register table assuming which may contain IO, MEM, and STALL
+ entries, but must NOT contain any PCI entries. Any PCI entries cause an
+ ASSERT in a DEBUG build and are skipped in a free build.
+
+ No parameter checking is done. Both RegTableEntry and CpuIo parameters are
+ required.
+
+ gBS is assumed to have been defined and is used when processing stalls.
+
+ The function processes each entry sequentially until an OP_TERMINATE_TABLE
+ entry is encountered.
+
+Arguments:
+ RegTableEntry - A pointer to the register table to process
+
+ CpuIo - A pointer to the instance of CpuIo that is used when processing IO and
+ MEM table entries
+
+Returns:
+ Nothing.
+
+--*/
+{
+ while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
+ switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
+ default:
+ DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
+ ASSERT (0);
+ break;
+ }
+
+ RegTableEntry++;
+ }
+}