/** Allocate a block of memory to be used by the buffer pool. @param Pages How many pages to allocate. @return The allocated memory block or NULL if failed. **/ SD_PEIM_MEM_BLOCK * SdPeimAllocMemBlock ( IN UINTN Pages ) { SD_PEIM_MEM_BLOCK *Block; VOID *BufHost; VOID *Mapping; EFI_PHYSICAL_ADDRESS MappedAddr; EFI_STATUS Status; VOID *TempPtr; TempPtr = NULL; Block = NULL; Status = PeiServicesAllocatePool (sizeof(SD_PEIM_MEM_BLOCK), &TempPtr); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)TempPtr, sizeof(SD_PEIM_MEM_BLOCK)); // // each bit in the bit array represents SD_PEIM_MEM_UNIT // bytes of memory in the memory block. // ASSERT (SD_PEIM_MEM_UNIT * 8 <= EFI_PAGE_SIZE); Block = (SD_PEIM_MEM_BLOCK*)(UINTN)TempPtr; Block->BufLen = EFI_PAGES_TO_SIZE (Pages); Block->BitsLen = Block->BufLen / (SD_PEIM_MEM_UNIT * 8); Status = PeiServicesAllocatePool (Block->BitsLen, &TempPtr); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)TempPtr, Block->BitsLen); Block->Bits = (UINT8*)(UINTN)TempPtr; Status = IoMmuAllocateBuffer ( Pages, &BufHost, &MappedAddr, &Mapping ); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)BufHost, EFI_PAGES_TO_SIZE (Pages)); Block->BufHost = (UINT8 *) (UINTN) BufHost; Block->Buf = (UINT8 *) (UINTN) MappedAddr; Block->Mapping = Mapping; Block->Next = NULL; return Block; }
/** Allocate a block of memory to be used by the buffer pool. @param Pages How many pages to allocate. @return The allocated memory block or NULL if failed. **/ UFS_PEIM_MEM_BLOCK * UfsPeimAllocMemBlock ( IN UINTN Pages ) { UFS_PEIM_MEM_BLOCK *Block; EFI_STATUS Status; VOID *TempPtr; EFI_PHYSICAL_ADDRESS Address; TempPtr = NULL; Block = NULL; Status = PeiServicesAllocatePool (sizeof(UFS_PEIM_MEM_BLOCK), &TempPtr); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)TempPtr, sizeof(UFS_PEIM_MEM_BLOCK)); // // each bit in the bit array represents UFS_PEIM_MEM_UNIT // bytes of memory in the memory block. // ASSERT (UFS_PEIM_MEM_UNIT * 8 <= EFI_PAGE_SIZE); Block = (UFS_PEIM_MEM_BLOCK*)(UINTN)TempPtr; Block->BufLen = EFI_PAGES_TO_SIZE (Pages); Block->BitsLen = Block->BufLen / (UFS_PEIM_MEM_UNIT * 8); Status = PeiServicesAllocatePool (Block->BitsLen, &TempPtr); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)TempPtr, Block->BitsLen); Block->Bits = (UINT8*)(UINTN)TempPtr; Status = PeiServicesAllocatePages ( EfiBootServicesCode, Pages, &Address ); if (EFI_ERROR (Status)) { return NULL; } ZeroMem ((VOID*)(UINTN)Address, EFI_PAGES_TO_SIZE (Pages)); Block->Buf = (UINT8*)((UINTN)Address); Block->Next = NULL; return Block; }
/** Initialize the memory management pool for the host controller. @param Private The Sd Peim driver private data. @retval EFI_SUCCESS The memory pool is initialized. @retval Others Fail to init the memory pool. **/ EFI_STATUS SdPeimInitMemPool ( IN SD_PEIM_HC_PRIVATE_DATA *Private ) { SD_PEIM_MEM_POOL *Pool; EFI_STATUS Status; VOID *TempPtr; TempPtr = NULL; Pool = NULL; Status = PeiServicesAllocatePool (sizeof (SD_PEIM_MEM_POOL), &TempPtr); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } ZeroMem ((VOID*)(UINTN)TempPtr, sizeof (SD_PEIM_MEM_POOL)); Pool = (SD_PEIM_MEM_POOL *)((UINTN)TempPtr); Pool->Head = SdPeimAllocMemBlock (SD_PEIM_MEM_DEFAULT_PAGES); if (Pool->Head == NULL) { return EFI_OUT_OF_RESOURCES; } Private->Pool = Pool; return EFI_SUCCESS; }
/** Worker function to get CPUs' BIST by calling SecPlatformInformationPpi or SecPlatformInformation2Ppi. @param PeiServices Pointer to PEI Services Table @param Guid PPI Guid @param PpiDescriptor Return a pointer to instance of the EFI_PEI_PPI_DESCRIPTOR @param BistInformationData Pointer to BIST information data @retval EFI_SUCCESS Retrieve of the BIST data successfully @retval EFI_NOT_FOUND No sec platform information(2) ppi export @retval EFI_DEVICE_ERROR Failed to get CPU Information **/ EFI_STATUS GetBistInfoFromPpi ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, OUT VOID **BistInformationData ) { EFI_STATUS Status; EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi; EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; UINT64 InformationSize; Status = PeiServicesLocatePpi ( Guid, // GUID 0, // INSTANCE PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&SecPlatformInformation2Ppi // PPI ); if (Status == EFI_NOT_FOUND) { return EFI_NOT_FOUND; } if (Status == EFI_SUCCESS) { // // Get the size of the sec platform information2(BSP/APs' BIST data) // InformationSize = 0; SecPlatformInformation2 = NULL; Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_BUFFER_TOO_SMALL) { Status = PeiServicesAllocatePool ( (UINTN) InformationSize, (VOID **) &SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { // // Retrieve BIST data // Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { *BistInformationData = SecPlatformInformation2; return EFI_SUCCESS; } } } } return EFI_DEVICE_ERROR; }
EFIAPI AllocatePool ( IN UINTN AllocationSize ) { EFI_STATUS Status; VOID *Buffer; Status = PeiServicesAllocatePool (AllocationSize, &Buffer); if (EFI_ERROR (Status)) { Buffer = NULL; } return Buffer; }
/** The function is provided by PCD PEIM and PCD DXE driver to do the work of reading a HII variable from variable service. @param VariableGuid The Variable GUID. @param VariableName The Variable Name. @param VariableData The output data. @param VariableSize The size of the variable. @retval EFI_SUCCESS Operation successful. @retval EFI_NOT_FOUND Variablel not found. **/ EFI_STATUS GetHiiVariable ( IN CONST EFI_GUID *VariableGuid, IN UINT16 *VariableName, OUT VOID **VariableData, OUT UINTN *VariableSize ) { UINTN Size; EFI_STATUS Status; VOID *Buffer; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); ASSERT_EFI_ERROR (Status); Size = 0; Status = VariablePpi->GetVariable ( VariablePpi, VariableName, (EFI_GUID *) VariableGuid, NULL, &Size, NULL ); if (Status == EFI_BUFFER_TOO_SMALL) { Status = PeiServicesAllocatePool (Size, &Buffer); ASSERT_EFI_ERROR (Status); Status = VariablePpi->GetVariable ( VariablePpi, (UINT16 *) VariableName, (EFI_GUID *) VariableGuid, NULL, &Size, Buffer ); ASSERT_EFI_ERROR (Status); *VariableSize = Size; *VariableData = Buffer; return EFI_SUCCESS; } return EFI_NOT_FOUND; }
/** Submits bulk transfer to a bulk endpoint of a USB device. Calls underlying OhciBulkTransfer to do work. This wrapper routine required on Quark so that USB DMA transfers do not cause an IMR violation. @param PeiServices The pointer of EFI_PEI_SERVICES. @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. @param DeviceAddress Target device address. @param EndPointAddress Endpoint number and its direction in bit 7. @param MaxiPacketLength Maximum packet size the endpoint is capable of sending or receiving. @param Data A pointers to the buffers of data to transmit from or receive into. @param DataLength The lenght of the data buffer. @param DataToggle On input, the initial data toggle for the transfer; On output, it is updated to to next data toggle to use of the subsequent bulk transfer. @param TimeOut Indicates the maximum time, in millisecond, which the transfer is allowed to complete. @param TransferResult A pointer to the detailed result information of the bulk transfer. @retval EFI_SUCCESS The transfer was completed successfully. @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. @retval EFI_INVALID_PARAMETER Parameters are invalid. @retval EFI_TIMEOUT The transfer failed due to timeout. @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. **/ EFI_STATUS EFIAPI RedirectOhciBulkTransfer ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_HOST_CONTROLLER_PPI *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 MaxPacketLength, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, OUT UINT32 *TransferResult ) { EFI_STATUS Status; UINT8 *NewData; // // Allocate memory external to IMR protected region for transfer data. // Status = PeiServicesAllocatePool ( *DataLength, (VOID **) &NewData ); ASSERT_EFI_ERROR (Status); // // Copy callers data into transfer buffer. // if (Data != NULL) { if (DataLength > 0) { CopyMem (NewData,Data,*DataLength); } } else { NewData = NULL; } // // Call underlying OhciBulkTransfer to do work. // Status = OhciBulkTransfer ( PeiServices, This, DeviceAddress, EndPointAddress, MaxPacketLength, NewData, DataLength, DataToggle, TimeOut, TransferResult ); // // Copy transfer buffer back into callers buffer. // if (Data != NULL && *DataLength > 0) { CopyMem (Data, NewData, *DataLength); } return Status; }
/** Submits control transfer to a target USB device. Calls underlying OhciControlTransfer to do work. This wrapper routine required on Quark so that USB DMA transfers do not cause an IMR violation. @param PeiServices The pointer of EFI_PEI_SERVICES. @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. @param DeviceAddress The target device address. @param DeviceSpeed Target device speed. @param MaximumPacketLength Maximum packet size the default control transfer endpoint is capable of sending or receiving. @param Request USB device request to send. @param TransferDirection Specifies the data direction for the data stage. @param Data Data buffer to be transmitted or received from USB device. @param DataLength The size (in bytes) of the data buffer. @param TimeOut Indicates the maximum timeout, in millisecond. @param TransferResult Return the result of this control transfer. @retval EFI_SUCCESS Transfer was completed successfully. @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_TIMEOUT Transfer failed due to timeout. @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. **/ EFI_STATUS EFIAPI RedirectOhciControlTransfer ( IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_HOST_CONTROLLER_PPI *This, IN UINT8 DeviceAddress, IN UINT8 DeviceSpeed, IN UINT8 MaxPacketLength, IN EFI_USB_DEVICE_REQUEST *Request, IN EFI_USB_DATA_DIRECTION TransferDirection, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN UINTN TimeOut, OUT UINT32 *TransferResult ) { EFI_STATUS Status; EFI_USB_DEVICE_REQUEST *NewRequest; VOID *NewData; UINT8 *Alloc; // // Allocate memory external to IMR protected region for transfer data. // Status = PeiServicesAllocatePool ( sizeof(EFI_USB_DEVICE_REQUEST) + *DataLength, (VOID **) &Alloc ); ASSERT_EFI_ERROR (Status); // // Setup pointers to transfer buffers. // NewRequest = (EFI_USB_DEVICE_REQUEST *) Alloc; Alloc += sizeof(EFI_USB_DEVICE_REQUEST); NewData = (VOID *) Alloc; // // Copy callers request packet into transfer request packet. // if (Request != NULL) { CopyMem (NewRequest,Request,sizeof(EFI_USB_DEVICE_REQUEST)); } else { NewRequest = NULL; } // // Copy callers data into transfer data buffer. // if (Data != NULL) { if (DataLength > 0) { CopyMem (NewData,Data,*DataLength); } } else { NewData = NULL; } // // Call underlying OhciControlTransfer to do work. // Status = OhciControlTransfer ( PeiServices, This, DeviceAddress, DeviceSpeed, MaxPacketLength, NewRequest, TransferDirection, NewData, DataLength, TimeOut, TransferResult ); // // Copy transfer buffer back into callers buffer. // if (Data != NULL && *DataLength > 0) { CopyMem (Data, NewData, *DataLength); } return Status; }