Written at the top, excerpted from K&r
The only legal operations on a structure is copying it or assigning to it as a unit, taking its address with & (read
Ampersand), and accessing its members,
For a struct, the only legal action is to assign it as a whole or copy it to another place. "
Take its address and access its members.
UEFI defines a number of I (interface). In other word, it is a function pointer, or a function prototype, which defines this interface
What functions are required and what parameters are required. As for the specific implementation of this function, each IBV will be able to do. Like what
Efi_pci_io_protocol. Pollmem () was excerpted from the UEFI SPEC Chapter 13.
Reads from the memory space of a PCI Root Bridge.
Read from PCI Root bridge (a piece of data)
Function prototypes
Typedefefi_status (EFI *api_pci_root_bridge_io_protocol_poll_io_mem) (in Efi_pci_root_bridge_io_protocol *This , in Efi_pci_root_bridge_io_protocol_width WIDTH, in UINT64 Address, in UINT64 Mask, in UINT64 Value, In UINT64 Delay, out UINT64 *result); parameter this one pointer to efi_pci_root_bridge_io_protocol width Identifies the base address of the memory operation's width address for the memory operation , and the function that invokes the function is obliged to assign it a definite value mask to detect the polling (polling) standard, i.e. whether the standard value of the end polling is reached A value that is used to compare to the exit criteria dealy the delay in 100 nanosecond units. Result A pointer to the last value read after the operation. Pointer to the last value of read from the memory location.
This function provides a standard way to poll the PCI memory location, of course, before the address is specified, it will be a memory read operation,
Depending on the width of the parameter, the operation repeats until timeout, (in 100 nanoseconds) or Resut & Mask = Value.
....
That's a lot to say, but how do we implement this function?
First of all, it is the operation of PCI memory, so, the BIOS code, it will certainly be a lot of use, we use it as the keyword, with the source insight search.
Returns two results:
Typedefefi_status (Efiapi *efi_pci_root_bridge_io_protocol_poll_io_mem) (in Efi_pci_root_bridge_io_protocol *this, in Efi_pci_root_bridge_io_protocol_width WIDTH, in UINT64 Address, in UINT64 Mask, in UINT64 Value, in UINT64 Delay, out UINT64 *result );
struct _efi_pci_root_bridge_io_protocol {/////The Efi_handle of the PCI Host Bridge of which this PCI ROOT bridge is A member. Efi_handle Parenthandle; Efi_pci_root_bridge_io_protocol_poll_io_mem Pollmem; Efi_pci_root_bridge_io_protocol_poll_io_mem Pollio; Efi_pci_root_bridge_io_protocol_access Mem; Efi_pci_root_bridge_io_protocol_access IO; Efi_pci_root_bridge_io_protocol_access PCI; Efi_pci_root_bridge_io_protocol_copy_mem Copymem; Efi_pci_root_bridge_io_protocol_map MAP; Efi_pci_root_bridge_io_protocol_unmap UNMAP; Efi_pci_root_bridge_io_protocol_allocate_buffer Allocatebuffer; Efi_pci_root_bridge_io_protocol_free_buffer FreeBuffer; Efi_pci_root_bridge_io_protocol_flush FLUSH; Efi_pci_root_bridge_io_protocol_get_attributes getattributes; Efi_pci_root_bridge_io_protocol_set_attributes SetAttributes; Efi_pci_root_bridge_io_protocol_configuratioN Configuration; The segment number that this is the PCI root bridge resides. UINT32 Segmentnumber;}
The first one is its definition, and the second is to declare it as a type (pointer type) with a variable.
Since it is a type, it is the same as int, float, double, and, essentially, the same, identifying the different lengths.
At this time, back to the beginning of the article, for the structure of the operation, it can only be used as a whole to assign values.
So we're going to search for a key word in the name of the struct.
typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Efi_pci_root_bridge_io_protocol;
It renames this type, renaming it in order to Efi_pci_root_bridge_io_protocol. Later _efi_pci_root_bridge_io_protocol is Efi_pci_root_bridge_io_protocol
Then take a efi_pci_root_bridge_io_protocol again, this time, out a large, because everywhere to use, this is the essence of UEFI
As you can see, most of the cases declare a pointer to the struct type (easy to use)
But!! Along the way, there can be a paragraph:
Static Efi_pci_io_protocol gpciioinstance = { Pciiopollmem, Pciiopollio, { pciiomemread, Pciiomemwrite }, { pciioioread, pciioiowrite }, { pciioconfigread, Pciioconfigwrite }, Pciiocopymem, pciiomap, pciiounmap, Pciioallocatebuffer, Pciiofreebuffer, Pciioflush, pciiogetlocation, pciioattributes, pciiogetbarattributes, Pciiosetbarattributes, 0, //romsize; NULL //romimage};
There is no very excited, inside, pendulum is the function name of real deal, with your source Insight direct jump to Definition bar
Procedure:pciiomemread ()////Description:protocol Function performs a PCI Memory Read cycle////notes:see EFI specifi cation for detail description////----------------------------------------------------------------------------// <ami_phdr_end>efi_status Pciiomemread (in Efi_pci_io_protocol *this,in efi_pci_io_protocol_width Width,IN UIN T8 barindex,in UINT64 offset,in uintn count,in out VOID *buffer) {Efi_status STATUS; pci_dev_info*dev= (pci_dev_info*) this;//---------------------------------------------if (Width < 0 | | Width >= efipciiowidthmaximum) return efi_invalid_parameter; Status=pciiocheckbar (Dev, Barindex, Tbarmem, Width, Count, &offset); if (Efi_error (Status)) return efi_unsupported; Status=dev->rbio->mem.read (Dev->rbio, (efi_pci_root_bridge_io_protocol_width) WIDTH, Offset, Count, Buffer ); return Status;
At this point, the end of the article, patiently go after code it ....
What if the implementation of the function is found in the UEFI BIOS code?