MdeModulePkg: Add CxlIo.h protocol Create a CXL protocol for interacting with CXL endpoint devices. CXL devices are necessarily also PCI devices, so the PCI IO protocol is also provided as part of the CXL protocol. The protocol provides access to the following operations for CXL devices: - Read from a DVSEC register block - Write to a DVSEC register block - Perform DOE transaction This set of operation is sufficient to implement BIOS-level CXL functionality. Signed-off-by: Nick Graves <nicholasgraves@google.com> Signed-off-by: Oleksandr Tymoshenko <ovt@google.com>
diff --git a/MdeModulePkg/Include/Protocol/CxlIo.h b/MdeModulePkg/Include/Protocol/CxlIo.h new file mode 100644 index 0000000..30f9eb0 --- /dev/null +++ b/MdeModulePkg/Include/Protocol/CxlIo.h
@@ -0,0 +1,154 @@ +/** @file + EFI CXL I/O Protocol provides the interfaces to interact with the CXL-specific + subsystems of CXL devices. Other interactions with CXL devices should be + routed through EFI_PCI_IO_PROTOCOL + + Copyright (c) 2026, Google, LLC. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __CXL_IO_H__ +#define __CXL_IO_H__ + +#include <Uefi/UefiBaseType.h> +#include "IndustryStandard/Cxl20.h" +#include "Protocol/PciIo.h" + +#include <IndustryStandard/Cxl.h> +#include <IndustryStandard/CxlCdat.h> + +/// +/// Global ID for the CXL I/O Protocol +/// +// 8fac60b2-bbc1-41de-a797-9875cdd3a8f8 + +#define EDKII_CXL_IO_PROTOCOL_GUID \ + { \ + 0x8fac60b2, 0xbbc1, 0x41de, {0xa7, 0x97, 0x98, 0x75, 0xcd, 0xd3, 0xa8, 0xf8 } \ + } + +typedef struct _EDKII_CXL_IO_PROTOCOL EDKII_CXL_IO_PROTOCOL; + +/** + Performs a CXL DOE transaction. + + @param This A pointer to the EDKII_CXL_IO_PROTOCOL instance. + @param RequestBuffer Payload of the request. This buffer should contain anything needed + for the DOE request beyond the standard 2 DWORD header. If not extra + data is required, this may be NULL. + @param RequestBufferSize Size of the request buffer in bytes. If RequestBuffer is NULL, + RequestBufferSize must be 0. + @param ResponseBuffer Destination buffer for the response. + @param ResponseBufferSize As an input parameter, the maximum size of the buffer. + As an output parameter, the actual size of the response. + + @retval EFI_SUCCESS The data was read from or written to the CXL controller. + @retval EFI_UNSUPPORTED This device does not support DOE. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_CXL_IO_PROTOCOL_IO_DOE_TRANSACT)( + IN EDKII_CXL_IO_PROTOCOL *This, + IN CONST VOID *RequestBuffer, + IN UINTN RequestBufferSize, + OUT VOID *ResponseBuffer, + IN OUT UINTN *ResponseBufferSize + ); + +/** + Transacts a set of regblock registers. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] RegBlock The type of regblock regs. + @param[in] Offset Offset from the start of the regblock. + @param[in, out] Buf The bufer to write or fill. + @param[in] Size The size of the buffer. + + @retval EFI_SUCCESS All bytes were written or read successfully. + @retval other Something went wrong. +*/ +typedef +EFI_STATUS +(EFIAPI *EDKII_CXL_IO_PROTOCOL_IO_REGBLOCK)( + IN EDKII_CXL_IO_PROTOCOL *This, + IN UINT32 RegBlock, + IN UINT64 Offset, + IN VOID *Buf, + IN UINTN Size + ); + +typedef struct { + /// + /// Read CXL DVSEC. + /// + EDKII_CXL_IO_PROTOCOL_IO_REGBLOCK Read; + /// + /// Write CXL DVSEC. + /// + EDKII_CXL_IO_PROTOCOL_IO_REGBLOCK Write; +} EDKII_CXL_IO_PROTOCOL_REGBLOCK_ACCESS; + +/** + Reads a set of DVSEC registers. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] CxlDvsecId The DVSEC to read or write. See #defines prefixed with CXL_DVSEC_ID_. + @param[in] Offset Offset from the start of the DVSEC. + @param[in, out] Buf The buffer to write or fill. + @param[in] Size The size of the buffer. + + @retval EFI_SUCCESS All bytes were written or read successfully. + @retval other Something went wrong. +*/ +typedef +EFI_STATUS +(EFIAPI *EDKII_CXL_IO_PROTOCOL_IO_DVSEC)( + IN EDKII_CXL_IO_PROTOCOL *This, + IN UINT32 CxlDvsecId, + IN UINT32 Offset, + IN VOID *Buf, + IN UINTN Size + ); + +typedef struct { + /// + /// Read CXL DVSEC. + /// + EDKII_CXL_IO_PROTOCOL_IO_DVSEC Read; + /// + /// Write CXL DVSEC. + /// + EDKII_CXL_IO_PROTOCOL_IO_DVSEC Write; +} EDKII_CXL_IO_PROTOCOL_DVSEC_ACCESS; + +/// +/// EFI CXL I/O Protocol provides the interfaces to interact with the CXL-specific +/// subsystems of CXL devices. Other interactions with CXL devices should be +/// routed through EFI_PCI_IO_PROTOCOL. +/// +struct _EDKII_CXL_IO_PROTOCOL { + /// + /// Access to the associated PciIo protocol for this CXL device. + /// + EFI_PCI_IO_PROTOCOL *PciIo; + /// + /// Data object exchange request-response transaction. + /// + EDKII_CXL_IO_PROTOCOL_IO_DOE_TRANSACT DoeTransact; + /// + /// Regblock register getter/setter. + /// + EDKII_CXL_IO_PROTOCOL_REGBLOCK_ACCESS Regblock; + /// + /// DVSEC register getter/setter. + /// + EDKII_CXL_IO_PROTOCOL_DVSEC_ACCESS Dvsec; +}; + +extern EFI_GUID gEdkiiCxlIoProtocolGuid; + +#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index b578da7..a2c714f 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec
@@ -759,6 +759,9 @@ ## Include/Protocol/UsbEthernetProtocol.h gEdkIIUsbEthProtocolGuid = { 0x8d8969cc, 0xfeb0, 0x4303, { 0xb2, 0x1a, 0x1f, 0x11, 0x6f, 0x38, 0x56, 0x43 } } + ## Include/Protocol/CxlIo.h + gEdkiiCxlIoProtocolGuid = { 0x8FAC60B2, 0xBBC1, 0x41DE, {0xA7, 0x97, 0x98, 0x75, 0xCD, 0xD3, 0xA8, 0xF8 } } + [PcdsFeatureFlag] ## Indicates if the platform can support update capsule across a system reset.<BR><BR> # TRUE - Supports update capsule across a system reset.<BR>