/** @file Wrap EFI_SPI_PROTOCOL to provide some library level interfaces for module use. Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include PCH_SPI_PROTOCOL *mSpiProtocol; // // FlashAreaBaseAddress and Size for boottime and runtime usage. // UINTN mFlashAreaBaseAddress = 0; UINTN mFlashAreaSize = 0; /** Enable block protection on the Serial Flash device. @retval EFI_SUCCESS Opertion is successful. @retval EFI_DEVICE_ERROR If there is any device errors. **/ EFI_STATUS EFIAPI SpiFlashLock ( VOID ) { return EFI_SUCCESS; } /** Read NumBytes bytes of data from the address specified by PAddress into Buffer. @param[in] Address The starting physical address of the read. @param[in,out] NumBytes On input, the number of bytes to read. On output, the number of bytes actually read. @param[out] Buffer The destination data buffer for the read. @retval EFI_SUCCESS Opertion is successful. @retval EFI_DEVICE_ERROR If there is any device errors. **/ EFI_STATUS EFIAPI SpiFlashRead ( IN UINTN Address, IN OUT UINT32 *NumBytes, OUT UINT8 *Buffer ) { ASSERT ((NumBytes != NULL) && (Buffer != NULL)); if ((NumBytes == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } // // This function is implemented specifically for those platforms // at which the SPI device is memory mapped for read. So this // function just do a memory copy for Spi Flash Read. // CopyMem (Buffer, (VOID *) Address, *NumBytes); return EFI_SUCCESS; } /** Write NumBytes bytes of data from Buffer to the address specified by PAddresss. @param[in] Address The starting physical address of the write. @param[in,out] NumBytes On input, the number of bytes to write. On output, the actual number of bytes written. @param[in] Buffer The source data buffer for the write. @retval EFI_SUCCESS Opertion is successful. @retval EFI_DEVICE_ERROR If there is any device errors. **/ EFI_STATUS EFIAPI SpiFlashWrite ( IN UINTN Address, IN OUT UINT32 *NumBytes, IN UINT8 *Buffer ) { EFI_STATUS Status; UINTN Offset; UINT32 Length; UINT32 RemainingBytes; ASSERT ((NumBytes != NULL) && (Buffer != NULL)); if ((NumBytes == NULL) || (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } ASSERT (Address >= mFlashAreaBaseAddress); Offset = Address - mFlashAreaBaseAddress; ASSERT ((*NumBytes + Offset) <= mFlashAreaSize); Status = EFI_SUCCESS; RemainingBytes = *NumBytes; while (RemainingBytes > 0) { if (RemainingBytes > SECTOR_SIZE_4KB) { Length = SECTOR_SIZE_4KB; } else { Length = RemainingBytes; } Status = mSpiProtocol->FlashWrite ( mSpiProtocol, FlashRegionBios, (UINT32) Offset, Length, Buffer ); if (EFI_ERROR (Status)) { break; } RemainingBytes -= Length; Offset += Length; Buffer += Length; } // // Actual number of bytes written // *NumBytes -= RemainingBytes; return Status; } /** Erase the block starting at Address. @param[in] Address The starting physical address of the block to be erased. This library assume that caller garantee that the PAddress is at the starting address of this block. @param[in] NumBytes On input, the number of bytes of the logical block to be erased. On output, the actual number of bytes erased. @retval EFI_SUCCESS. Opertion is successful. @retval EFI_DEVICE_ERROR If there is any device errors. **/ EFI_STATUS EFIAPI SpiFlashBlockErase ( IN UINTN Address, IN UINTN *NumBytes ) { EFI_STATUS Status; UINTN Offset; UINTN RemainingBytes; ASSERT (NumBytes != NULL); if (NumBytes == NULL) { return EFI_INVALID_PARAMETER; } ASSERT (Address >= mFlashAreaBaseAddress); Offset = Address - mFlashAreaBaseAddress; ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0); ASSERT ((*NumBytes + Offset) <= mFlashAreaSize); Status = EFI_SUCCESS; RemainingBytes = *NumBytes; Status = mSpiProtocol->FlashErase ( mSpiProtocol, FlashRegionBios, (UINT32) Offset, (UINT32) RemainingBytes ); return Status; }