EFI_STATUS EFIAPI InstallPchSpi ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Entry point for the SPI host controller driver. Arguments: ImageHandle Image handle of this driver. SystemTable Global system service table. Returns: EFI_SUCCESS Initialization complete. EFI_UNSUPPORTED The chipset is unsupported by this driver. EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. EFI_DEVICE_ERROR Device error, driver exits abnormally. --*/ { EFI_STATUS Status; // // Allocate pool for SPI protocol instance // Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, // MemoryType don't care sizeof (SPI_INSTANCE), (VOID **) &mSpiInstance ); if (EFI_ERROR (Status)) { return Status; } if (mSpiInstance == NULL) { return EFI_OUT_OF_RESOURCES; } ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE)); // // Initialize the SPI protocol instance // Status = SpiProtocolConstructor (mSpiInstance); if (EFI_ERROR (Status)) { return Status; } // // Install the SMM EFI_SPI_PROTOCOL interface // Status = gSmst->SmmInstallProtocolInterface ( &(mSpiInstance->Handle), &gEfiSmmSpiProtocolGuid, EFI_NATIVE_INTERFACE, &(mSpiInstance->SpiProtocol) ); if (EFI_ERROR (Status)) { gSmst->SmmFreePool (mSpiInstance); return EFI_DEVICE_ERROR; } return EFI_SUCCESS; }
EFI_STATUS EFIAPI InstallPchSpi ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Entry point for the SPI host controller driver. Arguments: ImageHandle Image handle of this driver. SystemTable Global system service table. Returns: EFI_SUCCESS Initialization complete. EFI_UNSUPPORTED The chipset is unsupported by this driver. EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver. EFI_DEVICE_ERROR Device error, driver exits abnormally. --*/ { EFI_STATUS Status; UINT64 BaseAddress; UINT64 Length; EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor; UINT64 Attributes; EFI_EVENT Event; DEBUG ((DEBUG_INFO, "InstallPchSpi() Start\n")); // // Allocate Runtime memory for the SPI protocol instance. // mSpiInstance = AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE)); if (mSpiInstance == NULL) { return EFI_OUT_OF_RESOURCES; } // // Initialize the SPI protocol instance // Status = SpiProtocolConstructor (mSpiInstance); if (EFI_ERROR (Status)) { return Status; } // // Install the EFI_SPI_PROTOCOL interface // Status = gBS->InstallMultipleProtocolInterfaces ( &(mSpiInstance->Handle), &gEfiSpiProtocolGuid, &(mSpiInstance->SpiProtocol), NULL ); if (EFI_ERROR (Status)) { FreePool (mSpiInstance); return EFI_DEVICE_ERROR; } // // Set RCBA space in GCD to be RUNTIME so that the range will be supported in // virtual address mode in EFI aware OS runtime. // It will assert if RCBA Memory Space is not allocated // The caller is responsible for the existence and allocation of the RCBA Memory Spaces // BaseAddress = (EFI_PHYSICAL_ADDRESS) (mSpiInstance->PchRootComplexBar); Length = PcdGet64 (PcdRcbaMmioSize); Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdMemorySpaceDescriptor); ASSERT_EFI_ERROR (Status); Attributes = GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME; Status = gDS->AddMemorySpace ( EfiGcdMemoryTypeMemoryMappedIo, BaseAddress, Length, EFI_MEMORY_RUNTIME | EFI_MEMORY_UC ); ASSERT_EFI_ERROR(Status); Status = gDS->SetMemorySpaceAttributes ( BaseAddress, Length, Attributes ); ASSERT_EFI_ERROR (Status); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, PchSpiVirtualddressChangeEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &Event ); ASSERT_EFI_ERROR (Status); DEBUG ((DEBUG_INFO, "InstallPchSpi() End\n")); return EFI_SUCCESS; }