diff options
Diffstat (limited to 'MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c')
-rw-r--r-- | MiscFramework/Library/Dxe/EfiRegTableLib/EfiRegTableLib.c | 313 |
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++; + } +} |