15. CPU I/O Protocol

This document describes the CPU I/O Protocol. This protocol provides an I/O abstraction for a system processor. This protocol is used by a PCI root bridge I/O driver to perform memory-mapped I/O and I/O transactions. The I/O or memory primitives can be used by the consumer of the protocol to materialize bus-specific configuration cycles, such as the transitional configuration address and data ports for PCI. Only drivers that require direct access to the entire system should use this protocol. This is a boot-services only protocol.

15.1. CPU I/O Protocol Terms

The following are the terms that are used throughout this document to describe the CPU I/O Protocol.

coherency domain

The address resources of a system as seen by a processor. It consists of both system memory and I/O space.

CPU I/O Protocol

A software abstraction that provides access to the I/O and memory regions in a single coherency domain.

SMP

Symmetric multiprocessing. A collection of processors that share a common view of I/O and memory-mapped I/O.

15.2. CPU I/O Protocol2 Description

This section describes the CPU I/O Protocol. This protocol is used by code–typically PCI root bridge I/O drivers and drivers that need I/O prior to the loading of the PCI root bridge I/O driver–that is running in the EFI Boot Services environment to access memory and I/O.This protocol can be also used by non-PC-AT* systems to abstract the I/O mechanism published by the processor and/or integrated CPU-I/O complex.

See Code Definitions for the definition of EFI_CPU_IO_PROTOCOL2 .

15.2.1. EFI CPU I/O Overview

The interfaces that are provided in the EFI_CPU_IO2_PROTOCOL are for performing basic operations to memory and I/O. The system provides abstracted access to basic system resources to allow a driver to have a programmatic method to access these basic system resources.

The EFI_CPU_IO2_PROTOCOL allows for future innovation of the platform. It abstracts processor-device-specific code from the system memory map. This abstraction allows system designers to make changes to the system memory map without impacting platform-independent code that is consuming basic system resources.

Systems with one to many processors in a symmetric multiprocessing (SMP) configuration will contain a single instance of the E FI_CPU_IO2_PROTOCOL . This protocol is an abstraction from a software point of view. This protocol is attached to the device handle of a processor driver. The CPU I/O Protocol is the parent to a set of PCI Root Bridge I/O Protocol instances that may contain many PCI segments. A CPU I/O Protocol instance might also be the parent of a series of protocols that abstract host-bus attached devices.

CPU I/O Protocol instances are either produced by the system firmware or an EFI driver. When a CPU I/O Protocol is produced, it is placed on a device handle without an EFI Device Path Protocol instance. The figure below shows a device handle that has the EFI_CPU_IO2_PROTOCOL installed on it.

_images/V5_CPU_I_O_Protocol-2.png

Fig. 15.1 EFI CPU I/O2 Protocol

EFI CPU I/O2 Protocol Other characteristics of the CPU I/O Protocol include the following:

  • The protocol uses re-entrancy to enable possible use by a debugger agent that is outside of the generic EFI Task Priority Level (TPL) priority mechanism.

See Code Definitions for the definition of EFI_CPU_IO2_PROTOCOL.

15.3. Code Definitions

This section contains the basic definitions of the CPU I/O Protocol ( EFI_CPU_IO2_PROTOCOL ).

This section also contains the definitions for additional data types and structures that are subordinate to the structures in which they are called. The following types or structures can be found in “Related Definitions” of the parent protocol or function definition:

  • EFI_CPU_IO_PROTOCOL_ACCESS

  • EFI_CPU_IO_PROTOCOL_WIDTH

15.3.1. CPU I/O Protocol

15.3.2. EFI_CPU_IO2_PROTOCOL

Summary

Provides the basic memory and I/O interfaces that are used to abstract accesses to devices in a system.

GUID

#define EFI_CPU_IO2_PROTOCOL_GUID \
  {0xad61f191, 0xae5f, 0x4c0e, 0xb9, 0xfa, 0xe8, 0x69, 0xd2, \\
  0x88, 0xc6, 0x4f}

Protocol Interface Structure

typedef struct \_EFI_CPU_IO2_PROTOCOL {
  EFI_CPU_IO_PROTOCOL_ACCESS         Mem;
  EFI_CPU_IO_PROTOCOL_ACCESS         Io;
} EFI_CPU_IO2_PROTOCOL;

Parameters

Mem.Read

Allows reads from memory-mapped I/O space. See the Mem.Read() function description. Type EFI_CPU_IO_PROTOCOL_ACCESS is defined in “Related Definitions” below.

Mem.Write

Allows writes to memory-mapped I/O space. See the Mem.Write() function description.

Io.Read

Allows reads from I/O space. See the Io.Read() function description. Type EFI_CPU_IO_PROTOCOL_ACCESS is defined in “Related Definitions” below.

Io.Write

Allows writes to I/O space. See the Io.Write( ) function description.

Description

The EFI_CPU_IO2_PROTOCOL provides the basic memory and I/O interfaces that are used to abstract accesses to platform hardware. This hardware can include PCI- or host-bus-attached peripherals and buses. There is one EFI_CPU_IO2_PROTOCOL instance for each PI System. Embedded systems, desktops, and workstations will typically have only one PI System. Non-symmetric multiprocessing (non-SMP), high-end servers may have multiple PI Systems. A device driver that wishes to make I/O transactions in a system will have to retrieve the EFI_CPU_IO2_PROTOCOL instance. A device handle for an PI System will minimally contain an EFI_CPU_IO2_PROTOCOL instance.

//******************************************************\*
// EFI_CPU_IO2_PROTOCOL_ACCESS
//******************************************************\*
typedef struct {
  EFI_CPU_IO_PROTOCOL_IO_MEM       Read;
  EFI_CPU_IO_PROTOCOL_IO_MEM       Write;
} EFI_CPU_IO_PROTOCOL_ACCESS;
Read

This service provides the various modalities of memory and I/O read.

Write

This service provides the various modalities of memory and I/O write.

15.3.3. EFI_CPU_IO2_PROTOCOL.Mem.Read() and Mem.Write()

Summary

Enables a driver to access memory-mapped registers in the PI System memory space.

Prototype

typedef
EFI_STATUS

(EFIAPI \*EFI_CPU_IO_PROTOCOL_IO_MEM) (
  IN EFI_CPU_IO2_PROTOCOL               *This,
  IN EFI_CPU_IO_PROTOCOL_WIDTH          Width,
  IN UINT64                             Address,
  IN UINTN                              Count,
  IN OUT VOID                           *Buffer
  );

Parameters

This

A pointer to the EFI_CPU_IO2_PROTOCOL instance.

Width

Signifies the width of the memory operation. Type EFI_CPU_IO_PROTOCOL_WIDTH is defined in “Related Definitions” below.

Address

The base address of the memory operation.

Count

The number of memory operations to perform. The number of bytes moved is Width size * Count , starting at Address .

Buffer

For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data.

Description

The Mem.Read() and Mem.Write() functions enable a driver to access memory-mapped registers in the PI System memory space.

The memory operations are carried out exactly as requested. The caller is responsible for satisfying any alignment and memory width restrictions that a PI System on a platform might require. For example, on some platforms, width requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver.

If Width is EfiCpuIoWidthUint8 , EfiCpuIoWidthUint16 , EfiCpuIoWidthUint32 , or EfiCpuIoWidthUint64 , then both Address and Buffer are incremented for each of the Count operations that is performed. If Width is EfiCpuIoWidthFifoUint8 , EfiCpuIoWidthFifoUint16 , EfiCpuIoWidthFifoUint32 , or EfiCpuIoWidthFifoUint64 , then only Buffer is incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address .

If Width is EfiCpuIoWidthFillUint8 , EfiCpuIoWidthFillUint16, EfiCpuIoWidthFillUint32, or EfiCpuIoWidthFillUint64 , then only Address is incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer .

//******************************************************\*
// EFI_CPU_IO_PROTOCOL_WIDTH
//******************************************************\*
typedef enum {
  EfiCpuIoWidthUint8,
  EfiCpuIoWidthUint16,
  EfiCpuIoWidthUint32,
  EfiCpuIoWidthUint64,
  EfiCpuIoWidthFifoUint8,
  EfiCpuIoWidthFifoUint16,
  EfiCpuIoWidthFifoUint32,
  EfiCpuIoWidthFifoUint64,
  EfiCpuIoWidthFillUint8,
  EfiCpuIoWidthFillUint16,
  EfiCpuIoWidthFillUint32,
  EfiCpuIoWidthFillUint64,
  EfiCpuIoWidthMaximum
} EFI_CPU_IO_PROTOCOL_WIDTH;

Status Codes Returned

EFI_SUCCESS

The data was read from or written to the PI System

EFI_INVALID_PARAMETER

Width is invalid for this PI System

EFI_INVALID_PARAMETER

Buffer is NULL

EFI_UNSUPPORTED

The Buffer is not aligned for the given Width

EFI_UNSUPPORTED

The address range specified by Address Width and Count is not valid for this PI System

15.3.4. EFI_CPU_IO2_PROTOCOL.Io.Read() and Io.Write()

Summary

Enables a driver to access registers in the PI CPU I/O space.

Prototype

typedef
EFI_STATUS
  (EFIAPI \*EFI_CPU_IO_PROTOCOL_IO_MEM) (
   IN EFI_CPU_IO2_PROTOCOL          *This,
   IN EFI_CPU_IO_PROTOCOL_WIDTH     Width,
   IN UINT64                        Address,
   IN UINTN                         Count,
   IN OUT VOID                      *Buffer
   );

Parameters

This

A pointer to the EFI_CPU_IO2_PROTOCOL instance.

Width

Signifies the width of the I/O operation. Type EFI_CPU_IO_PROTOCOL_WIDTH is defined in EFI_CPU_IO2_PROTOCOL.Mem().

Address

The base address of the I/O operation. The caller is responsible for aligning the Address if required.

Count

The number of I/O operations to perform. The number of bytes moved is Width size * Count , starting at Address .

Buffer

For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data.

Description

The Io.Read() and Io.Write() functions enable a driver to access PCI controller registers in the PI CPU I/O space.

The I/O operations are carried out exactly as requested. The caller is responsible for satisfying any alignment and I/O width restrictions that a PI System on a platform might require. For example on some platforms, width requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will be handled by the driver.

If Width is EfiCpuIoWidthUint8 , EfiCpuIoWidthUint16 , EfiCpuIoWidthUint32 , or EfiCpuIoWidthUint64 , then both Address and Buffer are incremented for each of the Count operations that is performed.

If Width is EfiCpuIoWidthFifoUint8 , EfiCpuIoWidthFifoUint16 , EfiCpuIoWidthFifoUint32 , or EfiCpuIoWidthFifoUint64 , then only Buffer is incremented for each of the Count operations that is performed. The read or write operation is performed Count times on the same Address .

If Width is EfiCpuIoWidthFillUint8 , EfiCpuIoWidthFillUint16 , EfiCpuIoWidthFillUint32 , or EfiCpuIoWidthFillUint64 , then only Address is incremented for each of the Count operations that is performed. The read or write operation is performed Count times from the first element of Buffer .

Status Codes Returned

EFI_SUCCESS

The data was read from or written to the PI System

EFI_INVALID_PARAMETER

Width is invalid for this PI System

EFI_INVALID_PARAMETER

Buffer is NULL

EFI_UNSUPPORTED

The Buffer is not aligned for the given Width

EFI_UNSUPPORTED

The address range specified by Address Width and Count is not valid for this PI System