123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*++
- Copyright (c) 1999 - 2019, Intel Corporation. All rights reserved
- SPDX-License-Identifier: BSD-2-Clause-Patent
- Module Name:
- EfiRegTableLib.c
- Abstract:
- Lib function for table driven register initialization.
- Revision History
- --*/
- #include <Library/EfiRegTableLib.h>
- #include <Library/S3BootScriptLib.h>
- //
- // Local Functions
- //
- /**
- Local worker function to process PCI_WRITE table entries. Performs write and
- may also call BootScriptSave protocol if indicated in the Entry flags
- @param Entry A pointer to the PCI_WRITE entry to process
- @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
- when processing the entry.
- @retval Nothing.
- **/
- STATIC
- VOID
- PciWrite (
- EFI_REG_TABLE_PCI_WRITE *Entry,
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
- )
- {
- 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 = S3BootScriptSavePciCfgWrite (
- (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
- (UINT64) Entry->PciAddress,
- 1,
- &Entry->Data
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
- /**
- 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.
- @param Entry A pointer to the PCI_READ_MODIFY_WRITE entry to process.
- @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
- when processing the entry.
- @retval Nothing.
- **/
- STATIC
- VOID
- PciReadModifyWrite (
- EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
- )
- {
- 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 = S3BootScriptSavePciCfgReadWrite (
- (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
- (UINT64) Entry->PciAddress,
- &Entry->OrMask,
- &Entry->AndMask
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
- /**
- 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.
- @param Entry A pointer to the MEM_READ_MODIFY_WRITE entry to process.
- @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
- when processing the entry.
- @retval Nothing.
- **/
- STATIC
- VOID
- MemReadModifyWrite (
- EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
- )
- {
- 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 = S3BootScriptSaveMemReadWrite (
- (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
- Entry->MemAddress,
- &Entry->OrMask,
- &Entry->AndMask
- );
- ASSERT_EFI_ERROR (Status);
- }
- }
- //
- // Exported functions
- //
- /**
- 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 parameters. If the regtable does
- not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (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.
- @param RegTableEntry A pointer to the register table to process
- @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
- when processing PCI table entries
- @retval Nothing.
- **/
- VOID
- ProcessRegTablePci (
- EFI_REG_TABLE *RegTableEntry,
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
- )
- {
- 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++;
- }
- }
|