-\r
-EFI_STATUS\r
-NorFlashWriteSingleWord (\r
- IN NOR_FLASH_INSTANCE *Instance,\r
- IN UINTN WordAddress,\r
- IN UINT32 WriteData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 StatusRegister;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- // Request a write single word command\r
- SEND_NOR_COMMAND(WordAddress, 0, P30_CMD_WORD_PROGRAM_SETUP);\r
-\r
- // Store the word into NOR Flash;\r
- MmioWrite32 (WordAddress, WriteData);\r
-\r
- // Wait for the write to complete and then check for any errors; i.e. check the Status Register\r
- do {\r
- // Prepare to read the status register\r
- StatusRegister = NorFlashReadStatusRegister (Instance, WordAddress);\r
- // The chip is busy while the WRITE bit is not asserted\r
- } while ((StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);\r
-\r
-\r
- // Perform a full status check:\r
- // Mask the relevant bits of Status Register.\r
- // Everything should be zero, if not, we have a problem\r
-\r
- if (StatusRegister & P30_SR_BIT_VPP) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): VPP Range Error\n",WordAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (StatusRegister & P30_SR_BIT_PROGRAM) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): Program Error\n",WordAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (StatusRegister & P30_SR_BIT_BLOCK_LOCKED) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteSingleWord(WordAddress:0x%X): Device Protect Error\n",WordAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (!EFI_ERROR(Status)) {\r
- // Clear the Status Register\r
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);\r
- }\r
-\r
- // Put device back into Read Array mode\r
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
-\r
- return Status;\r
-}\r
-\r
-/*\r
- * Writes data to the NOR Flash using the Buffered Programming method.\r
- *\r
- * The maximum size of the on-chip buffer is 32-words, because of hardware restrictions.\r
- * Therefore this function will only handle buffers up to 32 words or 128 bytes.\r
- * To deal with larger buffers, call this function again.\r
- *\r
- * This function presumes that both the TargetAddress and the TargetAddress+BufferSize\r
- * exist entirely within the NOR Flash. Therefore these conditions will not be checked here.\r
- *\r
- * In buffered programming, if the target address not at the beginning of a 32-bit word boundary,\r
- * then programming time is doubled and power consumption is increased.\r
- * Therefore, it is a requirement to align buffer writes to 32-bit word boundaries.\r
- * i.e. the last 4 bits of the target start address must be zero: 0x......00\r
- */\r
-EFI_STATUS\r
-NorFlashWriteBuffer (\r
- IN NOR_FLASH_INSTANCE *Instance,\r
- IN UINTN TargetAddress,\r
- IN UINTN BufferSizeInBytes,\r
- IN UINT32 *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSizeInWords;\r
- UINTN Count;\r
- volatile UINT32 *Data;\r
- UINTN WaitForBuffer;\r
- BOOLEAN BufferAvailable;\r
- UINT32 StatusRegister;\r
-\r
- WaitForBuffer = MAX_BUFFERED_PROG_ITERATIONS;\r
- BufferAvailable = FALSE;\r
-\r
- // Check that the target address does not cross a 32-word boundary.\r
- if ((TargetAddress & BOUNDARY_OF_32_WORDS) != 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Check there are some data to program\r
- if (BufferSizeInBytes == 0) {\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- // Check that the buffer size does not exceed the maximum hardware buffer size on chip.\r
- if (BufferSizeInBytes > P30_MAX_BUFFER_SIZE_IN_BYTES) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- // Check that the buffer size is a multiple of 32-bit words\r
- if ((BufferSizeInBytes % 4) != 0) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- // Pre-programming conditions checked, now start the algorithm.\r
-\r
- // Prepare the data destination address\r
- Data = (UINT32 *)TargetAddress;\r
-\r
- // Check the availability of the buffer\r
- do {\r
- // Issue the Buffered Program Setup command\r
- SEND_NOR_COMMAND(TargetAddress, 0, P30_CMD_BUFFERED_PROGRAM_SETUP);\r
-\r
- // Read back the status register bit#7 from the same address\r
- if (((*Data) & P30_SR_BIT_WRITE) == P30_SR_BIT_WRITE) {\r
- BufferAvailable = TRUE;\r
- }\r
-\r
- // Update the loop counter\r
- WaitForBuffer--;\r
-\r
- } while ((WaitForBuffer > 0) && (BufferAvailable == FALSE));\r
-\r
- // The buffer was not available for writing\r
- if (WaitForBuffer == 0) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto EXIT;\r
- }\r
-\r
- // From now on we work in 32-bit words\r
- BufferSizeInWords = BufferSizeInBytes / (UINTN)4;\r
-\r
- // Write the word count, which is (buffer_size_in_words - 1),\r
- // because word count 0 means one word.\r
- SEND_NOR_COMMAND(TargetAddress, 0, (BufferSizeInWords - 1));\r
-\r
- // Write the data to the NOR Flash, advancing each address by 4 bytes\r
- for(Count=0; Count < BufferSizeInWords; Count++, Data++, Buffer++) {\r
- *Data = *Buffer;\r
- }\r
-\r
- // Issue the Buffered Program Confirm command, to start the programming operation\r
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_BUFFERED_PROGRAM_CONFIRM);\r
-\r
- // Wait for the write to complete and then check for any errors; i.e. check the Status Register\r
- do {\r
- StatusRegister = NorFlashReadStatusRegister (Instance, TargetAddress);\r
- // The chip is busy while the WRITE bit is not asserted\r
- } while ((StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE);\r
-\r
-\r
- // Perform a full status check:\r
- // Mask the relevant bits of Status Register.\r
- // Everything should be zero, if not, we have a problem\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if (StatusRegister & P30_SR_BIT_VPP) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteBuffer(TargetAddress:0x%X): VPP Range Error\n", TargetAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (StatusRegister & P30_SR_BIT_PROGRAM) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteBuffer(TargetAddress:0x%X): Program Error\n", TargetAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (StatusRegister & P30_SR_BIT_BLOCK_LOCKED) {\r
- DEBUG((EFI_D_ERROR,"NorFlashWriteBuffer(TargetAddress:0x%X): Device Protect Error\n",TargetAddress));\r
- Status = EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (!EFI_ERROR(Status)) {\r
- // Clear the Status Register\r
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_CLEAR_STATUS_REGISTER);\r
- }\r
-\r
-EXIT:\r
- // Put device back into Read Array mode\r
- SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
-\r
- return Status;\r
-}\r
-\r