From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c0c::231; helo=mail-wr0-x231.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr0-x231.google.com (mail-wr0-x231.google.com [IPv6:2a00:1450:400c:c0c::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2163D22684786 for ; Wed, 18 Apr 2018 12:26:13 -0700 (PDT) Received: by mail-wr0-x231.google.com with SMTP id q13-v6so7775641wre.3 for ; Wed, 18 Apr 2018 12:26:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=2FAZDyRN1hgP4DtjhMoZDZkMVlWwRPlvBfLcMELAWRQ=; b=GSXFvZkCM3OubtULXTloLORR9fpbjpSTNezZZYz5h6wlRKOBz1wsOONpu5HRnDpzvW GfUO1+54cPC7+HkCeE9TfcARsxwt6/p+PZDCYX//0DeAZhFlxNYkxyUUjRgR79YwzGj6 OGhoFU/Ngb048JE0W8ZIpdgSuDcB7U9VQRi7k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=2FAZDyRN1hgP4DtjhMoZDZkMVlWwRPlvBfLcMELAWRQ=; b=m4pSfOj+KAXpnKdUmyh03dl7Ss/WkBKHs/FwsHZc2MhDlPGeaMye4H7juSGLf4Choz bh/y17Jw7SywsxCs6PeorvD0mCKZebZHzl9KOd4yPWTVeQUCI3qVkKjTdNb/FnNE/5gh l+WrUIvIewHzpf+PYjgFujs3/6ev4pIkkW0MVp6wQ4BbQOyxcUUJWlbOMFsFE/gbIgwn xweSeu/d/T7P4HAHxJ0p2DHRN86AMUiHnaprG+J2ozOKkODA3UYuQ3NzJKtADctGE10B h5K5jTmVJsJcUsXmPb8FQDJOhrbhUlo3OXqhOQ8kp5vk+U9exjSVdSE+mYyJ0AD9D9te qSJA== X-Gm-Message-State: ALQs6tC037lM86C0bHw7denHQ5oyQ5Bc5bgSvrQJy5gaIS7XT32iC+Um UNAq2D9GZJAG0Gj2+v7LF6wCUg== X-Google-Smtp-Source: AIpwx49ch1h/gJ1AaTR08YQY2lOQ2V+5ViDn7LxCmLQ6D3Q1R+B72H4eDOEI9AhUBpIDHv4yo35CXw== X-Received: by 2002:adf:a453:: with SMTP id e19-v6mr2606486wra.121.1524079571846; Wed, 18 Apr 2018 12:26:11 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id z12-v6sm2034705wrg.20.2018.04.18.12.26.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 18 Apr 2018 12:26:10 -0700 (PDT) Date: Wed, 18 Apr 2018 20:26:09 +0100 From: Leif Lindholm To: Meenakshi Cc: ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, udit.kumar@nxp.com, v.sethi@nxp.com Message-ID: <20180418192609.zbfcjfc62v24secn@bivouac.eciton.net> References: <1518771035-6733-1-git-send-email-meenakshi.aggarwal@nxp.com> <1518771035-6733-16-git-send-email-meenakshi.aggarwal@nxp.com> MIME-Version: 1.0 In-Reply-To: <1518771035-6733-16-git-send-email-meenakshi.aggarwal@nxp.com> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [PATCH edk2-platforms 15/39] Silicon/NXP : Add support of NorFlashLib X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Apr 2018 19:26:14 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Feb 16, 2018 at 02:20:11PM +0530, Meenakshi wrote: > From: Meenakshi Aggarwal > > NorFlashLib interacts with the underlying IFC NOR controller. > This will be used by NOR driver for any information > exchange with NOR controller. Some of this looks generic CFI which should at some point be broken out in its own library. Let's not worray about that for now, but I wanted to mention it :) > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Meenakshi Aggarwal > --- > Silicon/NXP/Include/Library/NorFlashLib.h | 77 +++ > Silicon/NXP/Include/NorFlash.h | 48 ++ > Silicon/NXP/Library/NorFlashLib/CfiCommand.h | 99 ++++ > Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.c | 233 ++++++++ > Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.h | 68 +++ > Silicon/NXP/Library/NorFlashLib/NorFlashLib.c | 660 +++++++++++++++++++++++ > Silicon/NXP/Library/NorFlashLib/NorFlashLib.inf | 41 ++ > 7 files changed, 1226 insertions(+) > create mode 100644 Silicon/NXP/Include/Library/NorFlashLib.h > create mode 100644 Silicon/NXP/Include/NorFlash.h > create mode 100644 Silicon/NXP/Library/NorFlashLib/CfiCommand.h > create mode 100644 Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.c > create mode 100644 Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.h > create mode 100644 Silicon/NXP/Library/NorFlashLib/NorFlashLib.c > create mode 100644 Silicon/NXP/Library/NorFlashLib/NorFlashLib.inf > > diff --git a/Silicon/NXP/Include/Library/NorFlashLib.h b/Silicon/NXP/Include/Library/NorFlashLib.h > new file mode 100644 > index 0000000..defdc61 > --- /dev/null > +++ b/Silicon/NXP/Include/Library/NorFlashLib.h > @@ -0,0 +1,77 @@ > +/** @file > + > + Copyright (c) 2011-2012, ARM Ltd. All rights reserved. > + Copyright (c) 2016, Freescale Semiconductor. All rights reserved. > + Copyright 2017 NXP > + > +This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > + **/ > + > +#ifndef _NOR_FLASH_LIB_H_ > +#define _NOR_FLASH_LIB_H_ > + > +#include > + > +#define NOR_FLASH_DEVICE_COUNT 1 > + > +typedef struct { > + UINTN DeviceBaseAddress; // Start address of the Device Base Address (DBA) > + UINTN RegionBaseAddress; // Start address of one single region > + UINTN Size; > + UINTN BlockSize; > + UINTN MultiByteWordCount; // Maximum Word count that can be written to Nor Flash in multi byte write > + UINTN WordWriteTimeOut; // single byte/word timeout usec > + UINTN BufferWriteTimeOut; // buffer write timeout usec > + UINTN BlockEraseTimeOut; // block erase timeout usec > + UINTN ChipEraseTimeOut; // chip erase timeout usec > +} NorFlashDescription; > + > +EFI_STATUS > +NorFlashPlatformGetDevices ( > + OUT NorFlashDescription **NorFlashDevices, > + OUT UINT32 *Count > + ); > + > +EFI_STATUS > +NorFlashPlatformFlashGetAttributes ( > + OUT NorFlashDescription *NorFlashDevices, > + IN UINT32 Count > + ); > + > +EFI_STATUS > +NorFlashPlatformWriteBuffer ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ); > + > +EFI_STATUS > +NorFlashPlatformEraseSector ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN UINTN SectorAddress > + ); > + > +EFI_STATUS > +NorFlashPlatformRead ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN UINTN BufferSizeInBytes, > + OUT UINT8 *Buffer > + ); > + > +EFI_STATUS > +NorFlashPlatformReset ( > + IN UINTN Instance > + ); > + > +#endif /* _NOR_FLASH_LIB_H_ */ > diff --git a/Silicon/NXP/Include/NorFlash.h b/Silicon/NXP/Include/NorFlash.h > new file mode 100644 > index 0000000..888f5c1 > --- /dev/null > +++ b/Silicon/NXP/Include/NorFlash.h > @@ -0,0 +1,48 @@ > +/** @NorFlash.h > + > + Contains data structure shared by both NOR Library and Driver. > + Copyright 2017 NXP > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef __NOR_FLASH_H__ > +#define __NOR_FLASH_H__ > + > +#include > +#include > + > +typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE; > +typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance); > + > +typedef struct { > + VENDOR_DEVICE_PATH Vendor; > + EFI_DEVICE_PATH_PROTOCOL End; > +} NOR_FLASH_DEVICE_PATH; > + > +struct _NOR_FLASH_INSTANCE { > + UINT32 Signature; > + EFI_HANDLE Handle; > + BOOLEAN Initialized; > + NOR_FLASH_INITIALIZE Initialize; > + UINTN DeviceBaseAddress; > + UINTN RegionBaseAddress; > + UINTN Size; > + EFI_LBA StartLba; > + EFI_BLOCK_IO_PROTOCOL BlockIoProtocol; > + EFI_BLOCK_IO_MEDIA Media; > + BOOLEAN SupportFvb; > + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; > + VOID* ShadowBuffer; > + NOR_FLASH_DEVICE_PATH DevicePath; > +}; > + > + > +#endif /* __NOR_FLASH_H__ */ > diff --git a/Silicon/NXP/Library/NorFlashLib/CfiCommand.h b/Silicon/NXP/Library/NorFlashLib/CfiCommand.h > new file mode 100644 > index 0000000..8543227 > --- /dev/null > +++ b/Silicon/NXP/Library/NorFlashLib/CfiCommand.h > @@ -0,0 +1,99 @@ > +/** @CfiCommand.h > + > + Copyright 2017 NXP > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef __CFI_COMMAND_H__ > +#define __CFI_COMMAND_H__ > + > +// CFI Data "QRY" > +#define CFI_QRY_Q 0x51 > +#define CFI_QRY_R 0x52 > +#define CFI_QRY_Y 0x59 > +#define CFI_QRY 0x515259 > + > +#define ENTER_CFI_QUERY_MODE_ADDR 0x0055 > +#define ENTER_CFI_QUERY_MODE_CMD 0x0098 > + > +#define CFI_QUERY_UNIQUE_QRY_STRING 0x10 > + > +// Offsets for CFI queries > +#define CFI_QUERY_TYP_TIMEOUT_WORD_WRITE 0x1F > +#define CFI_QUERY_TYP_TIMEOUT_MAX_BUFFER_WRITE 0x20 > +#define CFI_QUERY_TYP_TIMEOUT_BLOCK_ERASE 0x21 > +#define CFI_QUERY_TYP_TIMEOUT_CHIP_ERASE 0x22 > +#define CFI_QUERY_MAX_TIMEOUT_WORD_WRITE 0x23 > +#define CFI_QUERY_MAX_TIMEOUT_MAX_BUFFER_WRITE 0x24 > +#define CFI_QUERY_MAX_TIMEOUT_BLOCK_ERASE 0x25 > +#define CFI_QUERY_MAX_TIMEOUT_CHIP_ERASE 0x26 > +#define CFI_QUERY_DEVICE_SIZE 0x27 > +#define CFI_QUERY_MAX_NUM_BYTES_WRITE 0x2A > +#define CFI_QUERY_BLOCK_SIZE 0x2F > + > +// Unlock Address > +#define CMD_UNLOCK_1_ADDR 0x555 > +#define CMD_UNLOCK_2_ADDR 0x2AA > + > +// RESET Command > +#define CMD_RESET_FIRST 0xAA > +#define CMD_RESET_SECOND 0x55 > +#define CMD_RESET 0xF0 > + > +// READ Command > + > +// Manufacturer ID > +#define CMD_READ_M_ID_FIRST 0xAA > +#define CMD_READ_M_ID_SECOND 0x55 > +#define CMD_READ_M_ID_THIRD 0x90 > +#define CMD_READ_M_ID_FOURTH 0x01 > + > +// Device ID > +#define CMD_READ_D_ID_FIRST 0xAA > +#define CMD_READ_D_ID_SECOND 0x55 > +#define CMD_READ_D_ID_THIRD 0x90 > +#define CMD_READ_D_ID_FOURTH 0x7E > +#define CMD_READ_D_ID_FIFTH 0x13 > +#define CMD_READ_D_ID_SIXTH 0x00 > + > +// WRITE Command > + > +// PROGRAM Command > +#define CMD_PROGRAM_FIRST 0xAA > +#define CMD_PROGRAM_SECOND 0x55 > +#define CMD_PROGRAM_THIRD 0xA0 > + > +// Write Buffer Command > +#define CMD_WRITE_TO_BUFFER_FIRST 0xAA > +#define CMD_WRITE_TO_BUFFER_SECOND 0x55 > +#define CMD_WRITE_TO_BUFFER_THIRD 0x25 > +#define CMD_WRITE_TO_BUFFER_CONFIRM 0x29 > + > +// ERASE Command > + > +// UNLOCK COMMANDS FOR ERASE > +#define CMD_ERASE_FIRST 0xAA > +#define CMD_ERASE_SECOND 0x55 > +#define CMD_ERASE_THIRD 0x80 > +#define CMD_ERASE_FOURTH 0xAA > +#define CMD_ERASE_FIFTH 0x55 > + > +// Chip Erase Command > +#define CMD_CHIP_ERASE_SIXTH 0x10 > + > +// Sector Erase Command > +#define CMD_SECTOR_ERASE_SIXTH 0x30 > + > +// SUSPEND Command > +#define CMD_PROGRAM_OR_ERASE_SUSPEND 0xB0 > +#define CMD_PROGRAM_OR_ERASE_RESUME 0x30 > + > +#endif // __CFI_COMMAND_H__ > diff --git a/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.c b/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.c > new file mode 100644 > index 0000000..632e943 > --- /dev/null > +++ b/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.c > @@ -0,0 +1,233 @@ > +/** @CfiNorFlashLib.c > + > + Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. > + Copyright 2017 NXP > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > + **/ > + > +#include > +#include > +#include > + > +#include "CfiCommand.h" > +#include "CfiNorFlashLib.h" > + > +FLASH_DATA > +IfcNorFlashData ( > + IN OUT FLASH_DATA Value > + ) > +{ > + if (FixedPcdGetBool (PcdIfcBigEndian)) { > + return SwapBytes16 (Value); > + } else { > + return Value; > + } > +} > + > +/** > + Write Val at given address. > + > + @param Val Data to be written. > + @param Addr Address where data is to be written. > + > +**/ > +VOID > +FlashWriteData ( > + IN FLASH_DATA Val, > + IN UINTN Addr > + ) > +{ > + *(volatile FLASH_DATA *)(Addr) = (Val); > +} > + > +/** > + Check endianness of IFC Controller and depending on swap > + the data and write on given address. > + > + @param Val Data to be written. > + @param Addr Address where data is to be written. > + > +**/ > +VOID > +FlashWrite ( > + IN FLASH_DATA Val, > + IN UINTN Addr > + ) > +{ > + FLASH_DATA ShiftVal; > + > + ShiftVal = IfcNorFlashData (Val); > + > + *(volatile FLASH_DATA *)(Addr) = (ShiftVal); > +} > + > +/** > + Read data from given address. > + > + @param Addr Address from where data is to be read. > + > + @return Read Data > +**/ > +FLASH_DATA > +FlashReadData ( > + IN UINTN Addr > + ) > +{ > + FLASH_DATA Val; > + > + Val = *(volatile FLASH_DATA *)(Addr); > + > + return (Val); > +} > + > +/** > + Read data from given address and depending on endianness of IFC Controller > + swap the read data. > + > + @param Addr Address from where data is to be read. > + > + @return Read Data > +**/ > +FLASH_DATA > +FlashRead ( > + IN UINTN Addr > + ) > +{ > + FLASH_DATA Val; > + FLASH_DATA ShiftVal; > + > + Val = *(volatile FLASH_DATA *)(Addr); > + ShiftVal = IfcNorFlashData (Val); > + > + return (ShiftVal); > +} Instead of the above, please use same mechanisms as watchdog, gur(?), ifc. > + > +STATIC > +VOID > +NorFlashReadCfiData ( > + IN UINTN DeviceBaseAddress, > + IN UINTN CfiOffset, > + IN UINT32 NumberOfShorts, > + OUT VOID *Data > + ) > +{ > + UINT32 Count; > + FLASH_DATA *TmpData = (FLASH_DATA *)Data; > + > + for (Count = 0; Count < NumberOfShorts; Count++, TmpData++) { > + *TmpData = FLASH_READ ((UINTN)((FLASH_DATA*)DeviceBaseAddress + CfiOffset)); > + CfiOffset++; > + } > +} > + > +/* > + Currently we support only CFI flash devices; Bail-out otherwise > +*/ > +EFI_STATUS > +CfiNorFlashFlashGetAttributes ( > + OUT NorFlashDescription *NorFlashDevices, > + IN UINT32 Index > + ) > +{ > + UINT32 Count; > + FLASH_DATA QryData[3]; > + FLASH_DATA BlockSize[2]; > + UINTN DeviceBaseAddress; > + FLASH_DATA MaxNumBytes[2]; > + FLASH_DATA Size; > + FLASH_DATA HighByteMask; // Masks High byte in a UIN16 word > + FLASH_DATA HighByteShift; // Bitshifts needed to make a byte High Byte in a UIN16 word > + FLASH_DATA Temp1; > + FLASH_DATA Temp2; > + > + HighByteMask = 0xFF; > + HighByteShift = 8; > + > + for (Count = 0; Count < Index; Count++) { > + > + NorFlashDevices[Count].DeviceBaseAddress = DeviceBaseAddress = PcdGet64 (PcdFlashDeviceBase64); > + > + // Reset flash first > + NorFlashPlatformReset (DeviceBaseAddress); > + > + // Enter the CFI Query Mode > + SEND_NOR_COMMAND (DeviceBaseAddress, ENTER_CFI_QUERY_MODE_ADDR, > + ENTER_CFI_QUERY_MODE_CMD); Indentation. > + > + ArmDataSynchronizationBarrier (); I would prefer the use of a MemoryFence() here. In fact, ArmDataSynchronizationBarrier () is inappropriate in this location anyway. > + > + // Query the unique QRY > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_UNIQUE_QRY_STRING, > + 3, What's 3 here? Could it be replaced by a macro or define? > + &QryData); Indentation. Please have a look throughout this file. > + if (QryData[0] != (FLASH_DATA)CFI_QRY_Q || QryData[1] != > + (FLASH_DATA)CFI_QRY_R || QryData[2] != (FLASH_DATA)CFI_QRY_Y ) { Some added parentheses please. > + DEBUG ((DEBUG_ERROR, "Not a CFI flash (QRY not recvd): " > + "Got = 0x%04x, 0x%04x, 0x%04x\n", > + QryData[0], QryData[1], QryData[2])); > + return EFI_DEVICE_ERROR; > + } > + > + NorFlashReadCfiData (DeviceBaseAddress, CFI_QUERY_DEVICE_SIZE, > + 1, &Size); What's 1 here? Could it be replaced by a macro or define? > + // Refer CFI Specification > + NorFlashDevices[Count].Size = 1 << Size; > + > + NorFlashReadCfiData (DeviceBaseAddress, CFI_QUERY_BLOCK_SIZE, > + 2, &BlockSize); What's 2 here? Could it be replaced by a macro or define? > + // Refer CFI Specification > + NorFlashDevices[Count].BlockSize = 256 * ((FLASH_DATA) ((BlockSize[1] << What's 256 here? Could it be replaced by a macro or define? > + HighByteShift) | (BlockSize[0] & HighByteMask))); > + > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_MAX_NUM_BYTES_WRITE, 2, &MaxNumBytes); > + // Refer CFI Specification > + /* from CFI query we get the Max. number of BYTE in multi-byte write = 2^N. > + But our Flash Library is able to read/write in WORD size (2 bytes) which > + is why we need to CONVERT MAX BYTES TO MAX WORDS by diving it by > + width of word size */ > + NorFlashDevices[Count].MultiByteWordCount =\ > + (1 << ((FLASH_DATA)((MaxNumBytes[1] << HighByteShift) | > + (MaxNumBytes[0] & HighByteMask))))/sizeof(FLASH_DATA); > + > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_TYP_TIMEOUT_WORD_WRITE, 1, &Temp1); > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_MAX_TIMEOUT_WORD_WRITE, 1, &Temp2); What's 1 here? Could it be replaced by a macro or define? (Same question repeated throughout.) > + NorFlashDevices[Count].WordWriteTimeOut = (1U << Temp1) * (1U << Temp2); > + > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_TYP_TIMEOUT_MAX_BUFFER_WRITE, 1, &Temp1); > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_MAX_TIMEOUT_MAX_BUFFER_WRITE, 1, &Temp2); > + NorFlashDevices[Count].BufferWriteTimeOut = (1U << Temp1) * (1U << Temp2); > + > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_TYP_TIMEOUT_BLOCK_ERASE, 1, &Temp1); > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_MAX_TIMEOUT_BLOCK_ERASE, 1, &Temp2); > + NorFlashDevices[Count].BlockEraseTimeOut = > + (1U << Temp1) * (1U << Temp2) * 1000; * 1000 - microseconds to milliseconds? > + > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_TYP_TIMEOUT_CHIP_ERASE, 1, &Temp1); > + NorFlashReadCfiData (DeviceBaseAddress, > + CFI_QUERY_MAX_TIMEOUT_CHIP_ERASE, 1, &Temp2); > + NorFlashDevices[Count].ChipEraseTimeOut = > + (1U << Temp1) * (1U << Temp2) * 1000; > + > + // Put device back into Read Array mode (via Reset) > + NorFlashPlatformReset (DeviceBaseAddress); > + } > + > + return EFI_SUCCESS; > +} > diff --git a/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.h b/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.h > new file mode 100644 > index 0000000..91d50f0 > --- /dev/null > +++ b/Silicon/NXP/Library/NorFlashLib/CfiNorFlashLib.h > @@ -0,0 +1,68 @@ > +/** @CfiNorFlashLib.h > + > + Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. > + Copyright 2017 NXP > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef __CFI_NOR_FLASH_LIB_H__ > +#define __CFI_NOR_FLASH_LIB_H__ > + > +#include > +#include > + > +/* > + * Values for the width of the port > + */ > +#define FLASH_CFI_8BIT 0x01 > +#define FLASH_CFI_16BIT 0x02 > +#define FLASH_CFI_32BIT 0x04 > +#define FLASH_CFI_64BIT 0x08 > + > +#define CREATE_BYTE_OFFSET(OffsetAddr) ((sizeof (FLASH_DATA)) * (OffsetAddr)) > +#define CREATE_NOR_ADDRESS(BaseAddr, OffsetAddr) ((BaseAddr) + (OffsetAddr)) > +#define FLASH_READ(Addr) FlashRead ((Addr)) > +#define FLASH_WRITE(Addr, Val) FlashWrite ((Val), (Addr)) > +#define FLASH_READ_DATA(Addr) FlashReadData ((Addr)) > +#define FLASH_WRITE_DATA(Addr, Val) FlashWriteData ((Val), (Addr)) > +#define SEND_NOR_COMMAND(BaseAddr, Offset, Cmd) FLASH_WRITE (CREATE_NOR_ADDRESS (BaseAddr, CREATE_BYTE_OFFSET (Offset)), (Cmd)) > + > +typedef UINT16 FLASH_DATA; > + > +VOID > +FlashWrite ( > + IN FLASH_DATA Val, > + IN UINTN Addr > + ); > + > +FLASH_DATA > +FlashRead ( > + IN UINTN Addr > + ); > + > +VOID > +FlashWriteData ( > + IN FLASH_DATA Val, > + IN UINTN Addr > + ); > + > +FLASH_DATA > +FlashReadData ( > + IN UINTN Addr > + ); > + > +EFI_STATUS > +CfiNorFlashFlashGetAttributes ( > + OUT NorFlashDescription *NorFlashDevices, > + IN UINT32 Index > + ); > + > +#endif //__CFI_NOR_FLASH_LIB_H__ > diff --git a/Silicon/NXP/Library/NorFlashLib/NorFlashLib.c b/Silicon/NXP/Library/NorFlashLib/NorFlashLib.c > new file mode 100644 > index 0000000..b74e9eb > --- /dev/null > +++ b/Silicon/NXP/Library/NorFlashLib/NorFlashLib.c > @@ -0,0 +1,660 @@ > +/** @NorFlashLib.c > + > + Based on NorFlash implementation available in NorFlashDxe.c > + > + Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved. > + Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. > + Copyright 2017 NXP > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD License > + which accompanies this distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > +**/ > + > +#include > +#include > +#include > + > +#include "CfiCommand.h" > +#include "CfiNorFlashLib.h" > + > +#define GET_BLOCK_OFFSET(Lba) ((Instance->RegionBaseAddress)-\ > + (Instance->DeviceBaseAddress)+((UINTN)((Lba) * Instance->Media.BlockSize))) > + > +NorFlashDescription mNorFlashDevices[NOR_FLASH_DEVICE_COUNT]; > + > +STATIC VOID > +UnlockEraseAddress ( > + IN UINTN DeviceBaseAddress > + ) > +{ // Issue the Unlock cmds > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_ERASE_FIRST); Indentation. > + > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_2_ADDR, > + CMD_ERASE_SECOND); > + > + // Issue a setup command > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_ERASE_THIRD); > + > + // Issue the Unlock cmds > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_ERASE_FOURTH); > + > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_2_ADDR, > + CMD_ERASE_FIFTH); > + > + return; > +} > + > +STATIC > +UINT64 > +ConvertMicroSecondsToTicks ( > + IN UINTN MicroSeconds > + ) > +{ > + UINT64 TimerTicks64; > + > + TimerTicks64 = 0; > + > + // Calculate counter ticks that represent requested delay: > + // = MicroSeconds x TICKS_PER_MICRO_SEC > + // = MicroSeconds x Timer Frequency(in Hz) x 10^-6 > + // GetPerformanceCounterProperties = Get Arm Timer Frequency in Hz > + TimerTicks64 = DivU64x32 ( > + MultU64x64 ( > + MicroSeconds, > + GetPerformanceCounterProperties (NULL, NULL) > + ), > + 1000000U > + ); > + return TimerTicks64; > +} > + > +/** > + * The following function erases a NOR flash sector. > + **/ > +EFI_STATUS > +NorFlashPlatformEraseSector ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN UINTN SectorAddress > + ) > +{ > + FLASH_DATA EraseStatus1; > + FLASH_DATA EraseStatus2; > + UINT64 Timeout; > + UINT64 SystemCounterVal; > + > + EraseStatus1 = 0; > + EraseStatus2 = 0; > + Timeout = 0; > + > + Timeout = ConvertMicroSecondsToTicks ( > + mNorFlashDevices[Instance->Media.MediaId].BlockEraseTimeOut); Indentation. > + // Request a sector erase by writing two unlock cycles, followed by a > + // setup command and two additional unlock cycles > + > + UnlockEraseAddress (Instance->DeviceBaseAddress); > + > + // Now send the address of the sector to be erased > + SEND_NOR_COMMAND (SectorAddress, 0, CMD_SECTOR_ERASE_SIXTH); > + > + // Wait for erase to complete > + // Read Sector start address twice to detect bit toggle and to > + // determine ERASE DONE (all bits are 1) > + // Get the maximum timer ticks needed to complete the operation > + // Check if operation is complete or not in continous loop? > + // if complete, exit from loop > + // if not check the ticks that have been passed from the begining of loop > + // if Maximum Ticks allocated for operation has passed exit from loop > + > + SystemCounterVal = GetPerformanceCounter (); > + Timeout += SystemCounterVal; > + while (SystemCounterVal < Timeout) { > + if ((EraseStatus1 = FLASH_READ (SectorAddress)) == > + (EraseStatus2 = FLASH_READ (SectorAddress))) { Indentation. > + if (0xFFFF == FLASH_READ (SectorAddress)) { No jeopardy compares, please. if (FLASH_READ (SectorAddress) == 0xFFFF) { > + break; > + } > + } > + SystemCounterVal = GetPerformanceCounter (); > + } > + > + if (SystemCounterVal >= Timeout) { > + DEBUG ((DEBUG_ERROR, "%a :Failed to Erase @ SectorAddress 0x%p, Timeout\n", > + __FUNCTION__, SectorAddress)); > + return EFI_DEVICE_ERROR; > + } else { > + return EFI_SUCCESS; > + } > +} > + > +EFI_STATUS > +NorFlashPlatformWriteWord ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN UINTN WordOffset, > + IN FLASH_DATA Word > + ) > +{ > + UINT64 Timeout; > + UINTN TargetAddress; > + UINT64 SystemCounterVal; > + FLASH_DATA Read1; > + FLASH_DATA Read2; > + > + Timeout = 0; > + > + Timeout = ConvertMicroSecondsToTicks ( > + mNorFlashDevices[Instance->Media.MediaId].WordWriteTimeOut); > + > + TargetAddress = CREATE_NOR_ADDRESS (Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET (WordOffset)); > + > + // Issue the Unlock cmds > + SEND_NOR_COMMAND (Instance->DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_PROGRAM_FIRST); > + > + SEND_NOR_COMMAND (Instance->DeviceBaseAddress, CMD_UNLOCK_2_ADDR, > + CMD_PROGRAM_SECOND); > + > + SEND_NOR_COMMAND (Instance->DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_PROGRAM_THIRD); > + > + FLASH_WRITE_DATA (TargetAddress, Word); > + > + // Wait for Write to Complete > + // Read the last written address twice to detect bit toggle and > + // to determine if date is wriiten successfully or not ? > + // Get the maximum timer ticks needed to complete the operation > + // Check if operation is complete or not in continous loop? > + // if complete, exit from loop > + // if not check the ticks that have been passed from the begining of loop > + // if Maximum Ticks allocated for operation has passed, then exit from loop > + > + SystemCounterVal = GetPerformanceCounter (); > + Timeout += SystemCounterVal; > + while (SystemCounterVal < Timeout) { > + if ((Read1 = FLASH_READ_DATA (TargetAddress)) == > + (Read2 = FLASH_READ_DATA (TargetAddress))) { Indentation. > + if (Word == FLASH_READ_DATA (TargetAddress)) { > + break; > + } > + } > + SystemCounterVal = GetPerformanceCounter (); > + } > + > + if (SystemCounterVal >= Timeout) { > + DEBUG ((DEBUG_ERROR, "%a: Failed to Write @ TargetAddress 0x%p, Timeout\n", > + __FUNCTION__, TargetAddress)); > + return EFI_DEVICE_ERROR; > + } else { > + return EFI_SUCCESS; > + } > +} > + > +EFI_STATUS > +NorFlashPlatformWritePageBuffer ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN UINTN PageBufferOffset, > + IN UINTN NumWords, > + IN FLASH_DATA *Buffer > + ) > +{ > + UINT64 Timeout; > + UINTN LastWrittenAddress; > + FLASH_DATA LastWritenData; > + UINTN CurrentOffset; > + UINTN EndOffset; > + UINTN TargetAddress; > + UINT64 SystemCounterVal; > + FLASH_DATA Read1; > + FLASH_DATA Read2; > + > + // Initialize variables > + Timeout = 0; > + LastWrittenAddress = 0; > + LastWritenData = 0; > + CurrentOffset = PageBufferOffset; > + EndOffset = PageBufferOffset + NumWords - 1; > + Timeout = ConvertMicroSecondsToTicks ( > + mNorFlashDevices[Instance->Media.MediaId].BufferWriteTimeOut); > + TargetAddress = CREATE_NOR_ADDRESS (Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET (CurrentOffset)); > + > + // don't try with a count of zero > + if (!NumWords) { > + return EFI_SUCCESS; > + } > + else if (NumWords == 1) { else on same line as } > + return NorFlashPlatformWriteWord (Instance, PageBufferOffset, *Buffer); > + } > + > + // Issue the Unlock cmds > + SEND_NOR_COMMAND (Instance->DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_WRITE_TO_BUFFER_FIRST); > + > + SEND_NOR_COMMAND (Instance->DeviceBaseAddress, CMD_UNLOCK_2_ADDR, > + CMD_WRITE_TO_BUFFER_SECOND); > + > + // Write the buffer load > + SEND_NOR_COMMAND (TargetAddress, 0, CMD_WRITE_TO_BUFFER_THIRD); > + > + // Write # of locations to program > + SEND_NOR_COMMAND (TargetAddress, 0, (NumWords - 1)); > + > + // Load Data into Buffer > + while (CurrentOffset <= EndOffset) { > + LastWrittenAddress = CREATE_NOR_ADDRESS (Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET (CurrentOffset++)); > + LastWritenData = *Buffer++; > + > + // Write Data > + FLASH_WRITE_DATA (LastWrittenAddress,LastWritenData); > + } > + > + // Issue the Buffered Program Confirm command > + SEND_NOR_COMMAND (TargetAddress, 0, CMD_WRITE_TO_BUFFER_CONFIRM); > + > + /* Wait for Write to Complete > + Read the last written address twice to detect bit toggle and > + to determine if date is wriiten successfully or not ? > + Get the maximum timer ticks needed to complete the operation > + Check if operation is complete or not in continous loop? > + if complete, exit from loop > + if not check the ticks that have been passed from the begining of loop > + if Maximum Ticks allocated for operation has passed, then exit from loop **/ > + SystemCounterVal = GetPerformanceCounter(); > + Timeout += SystemCounterVal; > + while (SystemCounterVal < Timeout) { > + if ((Read1 = FLASH_READ_DATA (LastWrittenAddress)) == > + (Read2 = FLASH_READ_DATA (LastWrittenAddress))) { Indentation. > + if (LastWritenData == FLASH_READ_DATA (LastWrittenAddress)) { > + break; > + } > + } > + SystemCounterVal = GetPerformanceCounter (); > + } > + > + if (SystemCounterVal >= Timeout) { > + DEBUG ((DEBUG_ERROR, "%a: Failed to Write @LastWrittenAddress 0x%p, Timeout\n", > + __FUNCTION__, LastWrittenAddress)); > + return EFI_DEVICE_ERROR; > + } else { > + return EFI_SUCCESS; > + } > +} > + > +EFI_STATUS > +NorFlashPlatformWriteWordAlignedAddressBuffer ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN UINTN Offset, > + IN UINTN NumWords, > + IN FLASH_DATA *Buffer > + ) > +{ > + EFI_STATUS Status; > + UINTN MultiByteWordCount; > + UINTN Mask; > + UINTN IntWords; > + > + MultiByteWordCount = mNorFlashDevices[Instance->Media.MediaId].MultiByteWordCount; > + Mask = MultiByteWordCount - 1; > + IntWords = NumWords; > + Status = EFI_SUCCESS; > + > + if (Offset & Mask) { > + // program only as much as necessary, so pick the lower of the two numbers > + if (NumWords < (MultiByteWordCount - (Offset & Mask))) { > + IntWords = NumWords; > + } else { > + IntWords = MultiByteWordCount - (Offset & Mask); > + } > + > + // program the first few to get write buffer aligned > + Status = NorFlashPlatformWritePageBuffer (Instance, Offset, IntWords, Buffer); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Offset += IntWords; // adjust pointers and counter > + NumWords -= IntWords; > + Buffer += IntWords; > + > + if (NumWords == 0) { > + return Status; > + } > + } > + > + while (NumWords >= MultiByteWordCount) {// while big chunks to do > + Status = NorFlashPlatformWritePageBuffer (Instance, Offset, > + MultiByteWordCount, Buffer); > + if (EFI_ERROR (Status)) { > + return (Status); > + } > + > + Offset += MultiByteWordCount; // adjust pointers and counter > + NumWords -= MultiByteWordCount; > + Buffer += MultiByteWordCount; > + } > + if (NumWords == 0) { > + return (Status); > + } > + > + Status = NorFlashPlatformWritePageBuffer (Instance, Offset, NumWords, Buffer); > + return (Status); > +} > + > +/** > + Writes data to the NOR Flash using the Buffered Programming method. > + > + Write Buffer Programming allows the system to write a maximum of 32 bytes > + in one programming operation. Therefore this function will only handle > + buffers up to 32 bytes. > + To deal with larger buffers, call this function again. > +**/ > +EFI_STATUS > +NorFlashPlatformWriteBuffer ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ) > +{ > + EFI_STATUS Status; > + FLASH_DATA *SrcBuffer; > + UINTN TargetOffsetinBytes; > + UINTN WordsToWrite; > + UINTN Mask; > + UINTN BufferSizeInBytes; > + UINTN IntBytes; > + UINT8 *CopyFrom; > + UINT8 *CopyTo; VOID* (x2) > + FLASH_DATA TempWrite; > + > + SrcBuffer = (FLASH_DATA *)Buffer; > + TargetOffsetinBytes = 0; > + WordsToWrite = 0; > + Mask = sizeof (FLASH_DATA) - 1; > + BufferSizeInBytes = *NumBytes; > + IntBytes = BufferSizeInBytes; // Intermediate Bytes needed to copy for alignment > + TempWrite = 0; > + > + DEBUG ((DEBUG_BLKIO, "%a(Parameters: Lba=%ld, Offset=0x%x, " > + "*NumBytes=0x%x, Buffer @ 0x%08x)\n", > + __FUNCTION__, Lba, Offset, *NumBytes, Buffer)); > + > + TargetOffsetinBytes = GET_BLOCK_OFFSET (Lba) + (UINTN)(Offset); > + > + if (TargetOffsetinBytes & Mask) { > + // Write only as much as necessary, so pick the lower of the two numbers > + // and call it Intermediate bytes to write to make alignment proper > + if (BufferSizeInBytes < (sizeof (FLASH_DATA) - (TargetOffsetinBytes & Mask))) { > + IntBytes = BufferSizeInBytes; > + } else { > + IntBytes = sizeof (FLASH_DATA) - (TargetOffsetinBytes & Mask); > + } > + > + // Read the first few to get Read buffer aligned > + NorFlashPlatformRead (Instance, Lba, (TargetOffsetinBytes & ~Mask) - > + GET_BLOCK_OFFSET (Lba), sizeof (TempWrite), (UINT8*)&TempWrite); > + > + CopyTo = (UINT8*)&TempWrite; > + CopyTo += (TargetOffsetinBytes & Mask); > + CopyFrom = (UINT8*)Buffer; > + > + InternalMemCopyMem (CopyTo, CopyFrom, IntBytes); Please use CopyMem instead. > + > + Status = NorFlashPlatformWriteWordAlignedAddressBuffer ( > + Instance, > + (UINTN)((TargetOffsetinBytes & ~Mask) / sizeof (FLASH_DATA)), > + 1, > + &TempWrite); > + if (EFI_ERROR (Status)) { > + DEBUG((DEBUG_ERROR, "%a : Failed to Write @TargetOffset 0x%x (0x%x)\n", > + __FUNCTION__, TargetOffsetinBytes, Status)); > + goto EXIT; > + } > + > + TargetOffsetinBytes += IntBytes; /* adjust pointers and counter */ > + BufferSizeInBytes -= IntBytes; > + Buffer += IntBytes; > + > + if (BufferSizeInBytes == 0) { > + goto EXIT; > + } > + } > + > + // Write the bytes to CFI width aligned address. > + // Note we can Write number of bytes=CFI width in one operation > + WordsToWrite = BufferSizeInBytes/sizeof (FLASH_DATA); > + SrcBuffer = (FLASH_DATA*)Buffer; > + > + Status = NorFlashPlatformWriteWordAlignedAddressBuffer ( > + Instance, > + (UINTN)(TargetOffsetinBytes/sizeof (FLASH_DATA)), > + WordsToWrite, > + SrcBuffer); > + if (EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "%a : Failed to Write @ TargetOffset 0x%x (0x%x)\n", > + __FUNCTION__, TargetOffsetinBytes, Status)); > + goto EXIT; > + } > + > + BufferSizeInBytes -= (WordsToWrite * sizeof (FLASH_DATA)); > + Buffer += (WordsToWrite*sizeof (FLASH_DATA)); > + TargetOffsetinBytes += (WordsToWrite * sizeof (FLASH_DATA)); > + > + if (BufferSizeInBytes == 0) { > + goto EXIT; > + } > + > + // Now Write bytes that are remaining and are less than CFI width. > + // Read the first few to get Read buffer aligned > + NorFlashPlatformRead ( > + Instance, > + Lba, > + TargetOffsetinBytes - GET_BLOCK_OFFSET (Lba), > + sizeof (TempWrite), > + (UINT8*)&TempWrite); > + > + CopyFrom = (UINT8*)Buffer; > + CopyTo = (UINT8*)&TempWrite; > + > + InternalMemCopyMem (CopyTo, CopyFrom, BufferSizeInBytes); Please use CopyMem instead. > + > + Status = NorFlashPlatformWriteWordAlignedAddressBuffer (Instance, > + (UINTN)(TargetOffsetinBytes/sizeof (FLASH_DATA)), > + 1, > + &TempWrite); > + if (EFI_ERROR(Status)) { > + DEBUG((DEBUG_ERROR, "%a: Failed to Write @TargetOffset 0x%x Status=%d\n", > + __FUNCTION__, TargetOffsetinBytes, Status)); > + goto EXIT; > + } > + > +EXIT: > + // Put device back into Read Array mode (via Reset) > + NorFlashPlatformReset (Instance->DeviceBaseAddress); > + return (Status); > +} > + > +EFI_STATUS > +NorFlashPlatformRead ( > + IN NOR_FLASH_INSTANCE *Instance, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN UINTN BufferSizeInBytes, > + OUT UINT8 *Buffer > + ) > +{ > + UINTN IntBytes; > + UINTN Mask; > + FLASH_DATA TempRead; > + UINT8 *CopyFrom; > + UINT8 *CopyTo; Don't use UINT8* where VOID* is intended. > + UINTN TargetOffsetinBytes; > + FLASH_DATA *ReadData; > + UINTN BlockSize; > + > + IntBytes = BufferSizeInBytes; //Intermediate Bytes needed to copy for alignment > + Mask = sizeof (FLASH_DATA) - 1; > + TempRead = 0; > + TargetOffsetinBytes = (UINTN)(GET_BLOCK_OFFSET (Lba) + Offset); > + BlockSize = Instance->Media.BlockSize; > + > + DEBUG ((DEBUG_BLKIO, "%a(Parameters: Lba=%ld, Offset=0x%x," > + " BufferSizeInBytes=0x%x, Buffer @ 0x%p)\n", > + __FUNCTION__, Lba, Offset, BufferSizeInBytes, Buffer)); > + > + // The buffer must be valid > + if (Buffer == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Return if we have not any byte to read > + if (BufferSizeInBytes == 0) { > + return EFI_SUCCESS; > + } > + > + if (((Lba * BlockSize) + BufferSizeInBytes) > Instance->Size) { > + DEBUG ((DEBUG_ERROR, "%a : Read will exceed device size.\n", __FUNCTION__)); > + return EFI_INVALID_PARAMETER; > + } > + > + // Put device back into Read Array mode (via Reset) > + NorFlashPlatformReset (Instance->DeviceBaseAddress); > + > + // First Read bytes to make buffer aligned to CFI width > + if (TargetOffsetinBytes & Mask) { > + // Read only as much as necessary, so pick the lower of the two numbers > + if (BufferSizeInBytes < (sizeof (FLASH_DATA) - (TargetOffsetinBytes & Mask))) { > + IntBytes = BufferSizeInBytes; > + } else { > + IntBytes = sizeof (FLASH_DATA) - (TargetOffsetinBytes & Mask); > + } > + > + // Read the first few to get Read buffer aligned > + TempRead = FLASH_READ_DATA (CREATE_NOR_ADDRESS ( > + Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET ((TargetOffsetinBytes & ~Mask)/sizeof (FLASH_DATA)))); > + > + CopyFrom = (UINT8*)&TempRead; > + CopyFrom += (TargetOffsetinBytes & Mask); > + CopyTo = (UINT8*)Buffer; That way you can also get rid of these casts. > + > + InternalMemCopyMem (CopyTo, CopyFrom, IntBytes); Please use CopyMem instead. > + > + TargetOffsetinBytes += IntBytes; // adjust pointers and counter > + BufferSizeInBytes -= IntBytes; > + Buffer += IntBytes; > + if (BufferSizeInBytes == 0) { > + return EFI_SUCCESS; > + } > + } > + > + ReadData = (FLASH_DATA*)Buffer; > + > + // Readout the bytes from CFI width aligned address. > + // Note we can read number of bytes=CFI width in one operation > + while (BufferSizeInBytes >= sizeof (FLASH_DATA)) { > + *ReadData = FLASH_READ_DATA (CREATE_NOR_ADDRESS ( > + Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET (TargetOffsetinBytes/sizeof (FLASH_DATA)))); > + ReadData += 1; > + BufferSizeInBytes -= sizeof (FLASH_DATA); > + TargetOffsetinBytes += sizeof (FLASH_DATA); > + } > + > + if (BufferSizeInBytes == 0) { > + return EFI_SUCCESS; > + } > + > + // Now read bytes that are remaining and are less than CFI width. > + CopyTo = (UINT8*)ReadData; > + // Read the first few to get Read buffer aligned > + TempRead = FLASH_READ_DATA (CREATE_NOR_ADDRESS ( > + Instance->DeviceBaseAddress, > + CREATE_BYTE_OFFSET (TargetOffsetinBytes/sizeof (FLASH_DATA)))); > + CopyFrom = (UINT8*)&TempRead; And these. > + > + InternalMemCopyMem (CopyTo, CopyFrom, BufferSizeInBytes); Please use CopyMem instead. > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +NorFlashPlatformReset ( > + IN UINTN DeviceBaseAddress > + ) > +{ > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_1_ADDR, > + CMD_RESET_FIRST); > + > + SEND_NOR_COMMAND (DeviceBaseAddress, CMD_UNLOCK_2_ADDR, > + CMD_RESET_SECOND); > + > + SEND_NOR_COMMAND (DeviceBaseAddress, 0, CMD_RESET); > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +NorFlashPlatformGetDevices ( > + OUT NorFlashDescription **NorFlashDevices, > + OUT UINT32 *Count > + ) > +{ > + if ((NorFlashDevices == NULL) || (Count == NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Get the number of NOR flash devices supported > + *NorFlashDevices = mNorFlashDevices; > + *Count = NOR_FLASH_DEVICE_COUNT; > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +NorFlashPlatformFlashGetAttributes ( > + OUT NorFlashDescription *NorFlashDevices, > + IN UINT32 Count > + ) > +{ > + EFI_STATUS Status; > + UINT32 Index; > + > + if ((NorFlashDevices == NULL) || (Count == 0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Check the attributes of the NOR flash slave we are connected to. > + // Currently we support only CFI flash devices. Bail-out otherwise. > + Status = CfiNorFlashFlashGetAttributes (NorFlashDevices, Count); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // Limit the Size of Nor Flash that can be programmed > + for (Index = 0; Index < Count; Index++) { > + NorFlashDevices[Index].RegionBaseAddress = PcdGet64 (PcdFlashReservedRegionBase64); > + NorFlashDevices[Index].Size -= (NorFlashDevices[Index].RegionBaseAddress - > + NorFlashDevices[Index].DeviceBaseAddress); > + if((NorFlashDevices[Index].RegionBaseAddress - NorFlashDevices[Index].DeviceBaseAddress) % > + NorFlashDevices[Index].BlockSize) { > + DEBUG ((DEBUG_ERROR, "%a : Reserved Region(0x%p) doesn't start " > + "from block boundry(0x%08x)\n", __FUNCTION__, > + (UINTN)NorFlashDevices[Index].RegionBaseAddress, > + (UINT32)NorFlashDevices[Index].BlockSize)); > + return EFI_DEVICE_ERROR; > + } > + } > + return Status; > +} > diff --git a/Silicon/NXP/Library/NorFlashLib/NorFlashLib.inf b/Silicon/NXP/Library/NorFlashLib/NorFlashLib.inf > new file mode 100644 > index 0000000..403766a > --- /dev/null > +++ b/Silicon/NXP/Library/NorFlashLib/NorFlashLib.inf > @@ -0,0 +1,41 @@ > +# @NorFlashLib.inf > +# > +# Component description file for NorFlashLib module > +# > +# Copyright 2017 NXP > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the BSD License > +# which accompanies this distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +# > + > +[Defines] > + INF_VERSION = 0x0001001A > + BASE_NAME = NorFlashLib > + FILE_GUID = f3176a49-dde1-450d-a909-8580c03b9ba8 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = NorFlashLib > + > +[Sources.common] > + NorFlashLib.c > + CfiNorFlashLib.c Please sort alphabetically. > + > +[LibraryClasses] > + ArmLib > + TimerLib > + > +[Packages] > + ArmPkg/ArmPkg.dec > + MdePkg/MdePkg.dec > + Silicon/NXP/NxpQoriqLs.dec > + > +[Pcd.common] > + gNxpQoriqLsTokenSpaceGuid.PcdFlashDeviceBase64 > + gNxpQoriqLsTokenSpaceGuid.PcdFlashReservedRegionBase64 > + gNxpQoriqLsTokenSpaceGuid.PcdIfcBigEndian > + gNxpQoriqLsTokenSpaceGuid.PcdIfcNandReservedSize > -- > 1.9.1 >