1*f439973dSWarner Losh /** @file 2*f439973dSWarner Losh This file declares EFI PCI Hot Plug Init Protocol. 3*f439973dSWarner Losh 4*f439973dSWarner Losh This protocol provides the necessary functionality to initialize the Hot Plug 5*f439973dSWarner Losh Controllers (HPCs) and the buses that they control. This protocol also provides 6*f439973dSWarner Losh information regarding resource padding. 7*f439973dSWarner Losh 8*f439973dSWarner Losh @par Note: 9*f439973dSWarner Losh This protocol is required only on platforms that support one or more PCI Hot 10*f439973dSWarner Losh Plug* slots or CardBus sockets. 11*f439973dSWarner Losh 12*f439973dSWarner Losh The EFI_PCI_HOT_PLUG_INIT_PROTOCOL provides a mechanism for the PCI bus enumerator 13*f439973dSWarner Losh to properly initialize the HPCs and CardBus sockets that require initialization. 14*f439973dSWarner Losh The HPC initialization takes place before the PCI enumeration process is complete. 15*f439973dSWarner Losh There cannot be more than one instance of this protocol in a system. This protocol 16*f439973dSWarner Losh is installed on its own separate handle. 17*f439973dSWarner Losh 18*f439973dSWarner Losh Because the system may include multiple HPCs, one instance of this protocol 19*f439973dSWarner Losh should represent all of them. The protocol functions use the device path of 20*f439973dSWarner Losh the HPC to identify the HPC. When the PCI bus enumerator finds a root HPC, it 21*f439973dSWarner Losh will call EFI_PCI_HOT_PLUG_INIT_PROTOCOL.InitializeRootHpc(). If InitializeRootHpc() 22*f439973dSWarner Losh is unable to initialize a root HPC, the PCI enumerator will ignore that root HPC 23*f439973dSWarner Losh and continue the enumeration process. If the HPC is not initialized, the devices 24*f439973dSWarner Losh that it controls may not be initialized, and no resource padding will be provided. 25*f439973dSWarner Losh 26*f439973dSWarner Losh From the standpoint of the PCI bus enumerator, HPCs are divided into the following 27*f439973dSWarner Losh two classes: 28*f439973dSWarner Losh 29*f439973dSWarner Losh - Root HPC: 30*f439973dSWarner Losh These HPCs must be initialized by calling InitializeRootHpc() during the 31*f439973dSWarner Losh enumeration process. These HPCs will also require resource padding. The 32*f439973dSWarner Losh platform code must have a priori knowledge of these devices and must know 33*f439973dSWarner Losh how to initialize them. There may not be any way to access their PCI 34*f439973dSWarner Losh configuration space before the PCI enumerator programs all the upstream 35*f439973dSWarner Losh bridges and thus enables the path to these devices. The PCI bus enumerator 36*f439973dSWarner Losh is responsible for determining the PCI bus address of the HPC before it 37*f439973dSWarner Losh calls InitializeRootHpc(). 38*f439973dSWarner Losh - Nonroot HPC: 39*f439973dSWarner Losh These HPCs will not need explicit initialization during enumeration process. 40*f439973dSWarner Losh These HPCs will require resource padding. The platform code does not have 41*f439973dSWarner Losh to have a priori knowledge of these devices. 42*f439973dSWarner Losh 43*f439973dSWarner Losh Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> 44*f439973dSWarner Losh SPDX-License-Identifier: BSD-2-Clause-Patent 45*f439973dSWarner Losh 46*f439973dSWarner Losh @par Revision Reference: 47*f439973dSWarner Losh This Protocol is defined in UEFI Platform Initialization Specification 1.2 48*f439973dSWarner Losh Volume 5: Standards 49*f439973dSWarner Losh 50*f439973dSWarner Losh **/ 51*f439973dSWarner Losh 52*f439973dSWarner Losh #ifndef _EFI_PCI_HOT_PLUG_INIT_H_ 53*f439973dSWarner Losh #define _EFI_PCI_HOT_PLUG_INIT_H_ 54*f439973dSWarner Losh 55*f439973dSWarner Losh /// 56*f439973dSWarner Losh /// Global ID for the EFI_PCI_HOT_PLUG_INIT_PROTOCOL 57*f439973dSWarner Losh /// 58*f439973dSWarner Losh #define EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID \ 59*f439973dSWarner Losh { \ 60*f439973dSWarner Losh 0xaa0e8bc1, 0xdabc, 0x46b0, {0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea } \ 61*f439973dSWarner Losh } 62*f439973dSWarner Losh 63*f439973dSWarner Losh /// 64*f439973dSWarner Losh /// Forward declaration for EFI_PCI_HOT_PLUG_INIT_PROTOCOL 65*f439973dSWarner Losh /// 66*f439973dSWarner Losh typedef struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL EFI_PCI_HOT_PLUG_INIT_PROTOCOL; 67*f439973dSWarner Losh 68*f439973dSWarner Losh /// 69*f439973dSWarner Losh /// Describes the current state of an HPC 70*f439973dSWarner Losh /// 71*f439973dSWarner Losh typedef UINT16 EFI_HPC_STATE; 72*f439973dSWarner Losh 73*f439973dSWarner Losh /// 74*f439973dSWarner Losh /// The HPC initialization function was called and the HPC completed 75*f439973dSWarner Losh /// initialization, but it was not enabled for some reason. The HPC may be 76*f439973dSWarner Losh /// disabled in hardware, or it may be disabled due to user preferences, 77*f439973dSWarner Losh /// hardware failure, or other reasons. No resource padding is required. 78*f439973dSWarner Losh /// 79*f439973dSWarner Losh #define EFI_HPC_STATE_INITIALIZED 0x01 80*f439973dSWarner Losh 81*f439973dSWarner Losh /// 82*f439973dSWarner Losh /// The HPC initialization function was called, the HPC completed 83*f439973dSWarner Losh /// initialization, and it was enabled. Resource padding is required. 84*f439973dSWarner Losh /// 85*f439973dSWarner Losh #define EFI_HPC_STATE_ENABLED 0x02 86*f439973dSWarner Losh 87*f439973dSWarner Losh /// 88*f439973dSWarner Losh /// Location definition for PCI Hot Plug Controller 89*f439973dSWarner Losh /// 90*f439973dSWarner Losh typedef struct { 91*f439973dSWarner Losh /// 92*f439973dSWarner Losh /// 93*f439973dSWarner Losh /// The device path to the root HPC. An HPC cannot control its parent buses. 94*f439973dSWarner Losh /// The PCI bus driver requires this information so that it can pass the 95*f439973dSWarner Losh /// correct HpcPciAddress to the InitializeRootHpc() and GetResourcePadding() 96*f439973dSWarner Losh /// functions. 97*f439973dSWarner Losh /// 98*f439973dSWarner Losh EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath; 99*f439973dSWarner Losh /// 100*f439973dSWarner Losh /// The device path to the Hot Plug Bus (HPB) that is controlled by the root 101*f439973dSWarner Losh /// HPC. The PCI bus driver uses this information to check if a particular PCI 102*f439973dSWarner Losh /// bus has hot-plug slots. The device path of a PCI bus is the same as the 103*f439973dSWarner Losh /// device path of its parent. For Standard(PCI) Hot Plug Controllers (SHPCs) 104*f439973dSWarner Losh /// and PCI Express*, HpbDevicePath is the same as HpcDevicePath. 105*f439973dSWarner Losh /// 106*f439973dSWarner Losh EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath; 107*f439973dSWarner Losh } EFI_HPC_LOCATION; 108*f439973dSWarner Losh 109*f439973dSWarner Losh /// 110*f439973dSWarner Losh /// Describes how resource padding should be applied 111*f439973dSWarner Losh /// 112*f439973dSWarner Losh typedef enum { 113*f439973dSWarner Losh /// 114*f439973dSWarner Losh /// Apply the padding at a PCI bus level. In other words, the resources 115*f439973dSWarner Losh /// that are allocated to the bus containing hot-plug slots are padded by 116*f439973dSWarner Losh /// the specified amount. If the hot-plug bus is behind a PCI-to-PCI 117*f439973dSWarner Losh /// bridge, the PCI-to-PCI bridge apertures will indicate the padding 118*f439973dSWarner Losh /// 119*f439973dSWarner Losh EfiPaddingPciBus, 120*f439973dSWarner Losh /// 121*f439973dSWarner Losh /// Apply the padding at a PCI root bridge level. If a PCI root bridge 122*f439973dSWarner Losh /// includes more than one hot-plug bus, the resource padding requests 123*f439973dSWarner Losh /// for these buses are added together and the resources that are 124*f439973dSWarner Losh /// allocated to the root bridge are padded by the specified amount. This 125*f439973dSWarner Losh /// strategy may reduce the total amount of padding, but requires 126*f439973dSWarner Losh /// reprogramming of PCI-to-PCI bridges in a hot-add event. If the hotplug 127*f439973dSWarner Losh /// bus is behind a PCI-to-PCI bridge, the PCI-to-PCI bridge 128*f439973dSWarner Losh /// apertures do not indicate the padding for that bus. 129*f439973dSWarner Losh /// 130*f439973dSWarner Losh EfiPaddingPciRootBridge 131*f439973dSWarner Losh } EFI_HPC_PADDING_ATTRIBUTES; 132*f439973dSWarner Losh 133*f439973dSWarner Losh /** 134*f439973dSWarner Losh Returns a list of root Hot Plug Controllers (HPCs) that require initialization 135*f439973dSWarner Losh during the boot process. 136*f439973dSWarner Losh 137*f439973dSWarner Losh This procedure returns a list of root HPCs. The PCI bus driver must initialize 138*f439973dSWarner Losh these controllers during the boot process. The PCI bus driver may or may not be 139*f439973dSWarner Losh able to detect these HPCs. If the platform includes a PCI-to-CardBus bridge, it 140*f439973dSWarner Losh can be included in this list if it requires initialization. The HpcList must be 141*f439973dSWarner Losh self consistent. An HPC cannot control any of its parent buses. Only one HPC can 142*f439973dSWarner Losh control a PCI bus. Because this list includes only root HPCs, no HPC in the list 143*f439973dSWarner Losh can be a child of another HPC. This policy must be enforced by the 144*f439973dSWarner Losh EFI_PCI_HOT_PLUG_INIT_PROTOCOL. The PCI bus driver may not check for such 145*f439973dSWarner Losh invalid conditions. The callee allocates the buffer HpcList 146*f439973dSWarner Losh 147*f439973dSWarner Losh @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. 148*f439973dSWarner Losh @param[out] HpcCount The number of root HPCs that were returned. 149*f439973dSWarner Losh @param[out] HpcList The list of root HPCs. HpcCount defines the number of 150*f439973dSWarner Losh elements in this list. 151*f439973dSWarner Losh 152*f439973dSWarner Losh @retval EFI_SUCCESS HpcList was returned. 153*f439973dSWarner Losh @retval EFI_OUT_OF_RESOURCES HpcList was not returned due to insufficient 154*f439973dSWarner Losh resources. 155*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER HpcCount is NULL or HpcList is NULL. 156*f439973dSWarner Losh 157*f439973dSWarner Losh **/ 158*f439973dSWarner Losh typedef 159*f439973dSWarner Losh EFI_STATUS 160*f439973dSWarner Losh (EFIAPI *EFI_GET_ROOT_HPC_LIST)( 161*f439973dSWarner Losh IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, 162*f439973dSWarner Losh OUT UINTN *HpcCount, 163*f439973dSWarner Losh OUT EFI_HPC_LOCATION **HpcList 164*f439973dSWarner Losh ); 165*f439973dSWarner Losh 166*f439973dSWarner Losh /** 167*f439973dSWarner Losh Initializes one root Hot Plug Controller (HPC). This process may causes 168*f439973dSWarner Losh initialization of its subordinate buses. 169*f439973dSWarner Losh 170*f439973dSWarner Losh This function initializes the specified HPC. At the end of initialization, 171*f439973dSWarner Losh the hot-plug slots or sockets (controlled by this HPC) are powered and are 172*f439973dSWarner Losh connected to the bus. All the necessary registers in the HPC are set up. For 173*f439973dSWarner Losh a Standard (PCI) Hot Plug Controller (SHPC), the registers that must be set 174*f439973dSWarner Losh up are defined in the PCI Standard Hot Plug Controller and Subsystem 175*f439973dSWarner Losh Specification. 176*f439973dSWarner Losh 177*f439973dSWarner Losh @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. 178*f439973dSWarner Losh @param[in] HpcDevicePath The device path to the HPC that is being initialized. 179*f439973dSWarner Losh @param[in] HpcPciAddress The address of the HPC function on the PCI bus. 180*f439973dSWarner Losh @param[in] Event The event that should be signaled when the HPC 181*f439973dSWarner Losh initialization is complete. Set to NULL if the 182*f439973dSWarner Losh caller wants to wait until the entire initialization 183*f439973dSWarner Losh process is complete. 184*f439973dSWarner Losh @param[out] HpcState The state of the HPC hardware. The state is 185*f439973dSWarner Losh EFI_HPC_STATE_INITIALIZED or EFI_HPC_STATE_ENABLED. 186*f439973dSWarner Losh 187*f439973dSWarner Losh @retval EFI_SUCCESS If Event is NULL, the specific HPC was successfully 188*f439973dSWarner Losh initialized. If Event is not NULL, Event will be 189*f439973dSWarner Losh signaled at a later time when initialization is complete. 190*f439973dSWarner Losh @retval EFI_UNSUPPORTED This instance of EFI_PCI_HOT_PLUG_INIT_PROTOCOL 191*f439973dSWarner Losh does not support the specified HPC. 192*f439973dSWarner Losh @retval EFI_OUT_OF_RESOURCES Initialization failed due to insufficient 193*f439973dSWarner Losh resources. 194*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER HpcState is NULL. 195*f439973dSWarner Losh 196*f439973dSWarner Losh **/ 197*f439973dSWarner Losh typedef 198*f439973dSWarner Losh EFI_STATUS 199*f439973dSWarner Losh (EFIAPI *EFI_INITIALIZE_ROOT_HPC)( 200*f439973dSWarner Losh IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, 201*f439973dSWarner Losh IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, 202*f439973dSWarner Losh IN UINT64 HpcPciAddress, 203*f439973dSWarner Losh IN EFI_EVENT Event OPTIONAL, 204*f439973dSWarner Losh OUT EFI_HPC_STATE *HpcState 205*f439973dSWarner Losh ); 206*f439973dSWarner Losh 207*f439973dSWarner Losh /** 208*f439973dSWarner Losh Returns the resource padding that is required by the PCI bus that is controlled 209*f439973dSWarner Losh by the specified Hot Plug Controller (HPC). 210*f439973dSWarner Losh 211*f439973dSWarner Losh This function returns the resource padding that is required by the PCI bus that 212*f439973dSWarner Losh is controlled by the specified HPC. This member function is called for all the 213*f439973dSWarner Losh root HPCs and nonroot HPCs that are detected by the PCI bus enumerator. This 214*f439973dSWarner Losh function will be called before PCI resource allocation is completed. This function 215*f439973dSWarner Losh must be called after all the root HPCs, with the possible exception of a 216*f439973dSWarner Losh PCI-to-CardBus bridge, have completed initialization. 217*f439973dSWarner Losh 218*f439973dSWarner Losh @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL instance. 219*f439973dSWarner Losh @param[in] HpcDevicePath The device path to the HPC. 220*f439973dSWarner Losh @param[in] HpcPciAddress The address of the HPC function on the PCI bus. 221*f439973dSWarner Losh @param[in] HpcState The state of the HPC hardware. 222*f439973dSWarner Losh @param[out] Padding The amount of resource padding that is required by the 223*f439973dSWarner Losh PCI bus under the control of the specified HPC. 224*f439973dSWarner Losh @param[out] Attributes Describes how padding is accounted for. The padding 225*f439973dSWarner Losh is returned in the form of ACPI 2.0 resource descriptors. 226*f439973dSWarner Losh 227*f439973dSWarner Losh @retval EFI_SUCCESS The resource padding was successfully returned. 228*f439973dSWarner Losh @retval EFI_UNSUPPORTED This instance of the EFI_PCI_HOT_PLUG_INIT_PROTOCOL 229*f439973dSWarner Losh does not support the specified HPC. 230*f439973dSWarner Losh @retval EFI_NOT_READY This function was called before HPC initialization 231*f439973dSWarner Losh is complete. 232*f439973dSWarner Losh @retval EFI_INVALID_PARAMETER HpcState or Padding or Attributes is NULL. 233*f439973dSWarner Losh @retval EFI_OUT_OF_RESOURCES ACPI 2.0 resource descriptors for Padding 234*f439973dSWarner Losh cannot be allocated due to insufficient resources. 235*f439973dSWarner Losh 236*f439973dSWarner Losh **/ 237*f439973dSWarner Losh typedef 238*f439973dSWarner Losh EFI_STATUS 239*f439973dSWarner Losh (EFIAPI *EFI_GET_HOT_PLUG_PADDING)( 240*f439973dSWarner Losh IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, 241*f439973dSWarner Losh IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, 242*f439973dSWarner Losh IN UINT64 HpcPciAddress, 243*f439973dSWarner Losh OUT EFI_HPC_STATE *HpcState, 244*f439973dSWarner Losh OUT VOID **Padding, 245*f439973dSWarner Losh OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes 246*f439973dSWarner Losh ); 247*f439973dSWarner Losh 248*f439973dSWarner Losh /// 249*f439973dSWarner Losh /// This protocol provides the necessary functionality to initialize the 250*f439973dSWarner Losh /// Hot Plug Controllers (HPCs) and the buses that they control. This protocol 251*f439973dSWarner Losh /// also provides information regarding resource padding. 252*f439973dSWarner Losh /// 253*f439973dSWarner Losh struct _EFI_PCI_HOT_PLUG_INIT_PROTOCOL { 254*f439973dSWarner Losh /// 255*f439973dSWarner Losh /// Returns a list of root HPCs and the buses that they control. 256*f439973dSWarner Losh /// 257*f439973dSWarner Losh EFI_GET_ROOT_HPC_LIST GetRootHpcList; 258*f439973dSWarner Losh 259*f439973dSWarner Losh /// 260*f439973dSWarner Losh /// Initializes the specified root HPC. 261*f439973dSWarner Losh /// 262*f439973dSWarner Losh EFI_INITIALIZE_ROOT_HPC InitializeRootHpc; 263*f439973dSWarner Losh 264*f439973dSWarner Losh /// 265*f439973dSWarner Losh /// Returns the resource padding that is required by the HPC. 266*f439973dSWarner Losh /// 267*f439973dSWarner Losh EFI_GET_HOT_PLUG_PADDING GetResourcePadding; 268*f439973dSWarner Losh }; 269*f439973dSWarner Losh 270*f439973dSWarner Losh extern EFI_GUID gEfiPciHotPlugInitProtocolGuid; 271*f439973dSWarner Losh 272*f439973dSWarner Losh #endif 273