Commit 06f53eed authored by Dean Camera's avatar Dean Camera
Browse files

Fixed bootloaders not disabling global interrupts during erase and write...

Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan).
parent 544c4dc9
......@@ -37,16 +37,22 @@
void BootloaderAPI_ErasePage(const uint32_t Address)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_WritePage(const uint32_t Address)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
......@@ -71,5 +77,8 @@ uint8_t BootloaderAPI_ReadLock(void)
void BootloaderAPI_WriteLock(const uint8_t LockBits)
{
boot_lock_bits_set_safe(LockBits);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_lock_bits_set_safe(LockBits);
}
}
......@@ -39,6 +39,7 @@
/* Includes: */
#include <avr/io.h>
#include <avr/boot.h>
#include <util/atomic.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
......
......@@ -97,7 +97,7 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#else
/* Check if the device's BOOTRST fuse is set */
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
if (BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
{
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
......@@ -297,9 +297,6 @@ static void ReadWriteMemoryBlock(const uint8_t Command)
/* Check if command is to read a memory block */
if (Command == AVR109_COMMAND_BlockRead)
{
/* Re-enable RWW section */
boot_rww_enable();
while (BlockSize--)
{
if (MemoryType == MEMORY_TYPE_FLASH)
......@@ -332,10 +329,7 @@ static void ReadWriteMemoryBlock(const uint8_t Command)
uint32_t PageStartAddress = CurrAddress;
if (MemoryType == MEMORY_TYPE_FLASH)
{
boot_page_erase(PageStartAddress);
boot_spm_busy_wait();
}
BootloaderAPI_ErasePage(PageStartAddress);
while (BlockSize--)
{
......@@ -345,7 +339,7 @@ static void ReadWriteMemoryBlock(const uint8_t Command)
if (HighByte)
{
/* Write the next FLASH word to the current FLASH page */
boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
BootloaderAPI_FillWord(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
/* Increment the address counter after use */
CurrAddress += 2;
......@@ -371,10 +365,7 @@ static void ReadWriteMemoryBlock(const uint8_t Command)
if (MemoryType == MEMORY_TYPE_FLASH)
{
/* Commit the flash page to memory */
boot_page_write(PageStartAddress);
/* Wait until write operation has completed */
boot_spm_busy_wait();
BootloaderAPI_WritePage(PageStartAddress);
}
/* Send response byte back to the host */
......@@ -516,12 +507,7 @@ static void CDC_Task(void)
{
/* Clear the application section of flash */
for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
{
boot_page_erase(CurrFlashAddress);
boot_spm_busy_wait();
boot_page_write(CurrFlashAddress);
boot_spm_busy_wait();
}
BootloaderAPI_ErasePage(CurrFlashAddress);
/* Send confirmation byte back to the host */
WriteNextResponseByte('\r');
......@@ -530,7 +516,7 @@ static void CDC_Task(void)
else if (Command == AVR109_COMMAND_WriteLockbits)
{
/* Set the lock bits to those given by the host */
boot_lock_bits_set(FetchNextCommandByte());
BootloaderAPI_WriteLock(FetchNextCommandByte());
/* Send confirmation byte back to the host */
WriteNextResponseByte('\r');
......@@ -538,19 +524,19 @@ static void CDC_Task(void)
#endif
else if (Command == AVR109_COMMAND_ReadLockbits)
{
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS));
WriteNextResponseByte(BootloaderAPI_ReadLock());
}
else if (Command == AVR109_COMMAND_ReadLowFuses)
{
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS));
WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_LOW_FUSE_BITS));
}
else if (Command == AVR109_COMMAND_ReadHighFuses)
{
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS));
WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS));
}
else if (Command == AVR109_COMMAND_ReadExtendedFuses)
{
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS));
WriteNextResponseByte(BootloaderAPI_ReadFuse(GET_EXTENDED_FUSE_BITS));
}
#if !defined(NO_BLOCK_SUPPORT)
else if (Command == AVR109_COMMAND_GetBlockWriteSupport)
......@@ -571,7 +557,7 @@ static void CDC_Task(void)
else if (Command == AVR109_COMMAND_FillFlashPageWordHigh)
{
/* Write the high byte to the current flash page */
boot_page_fill(CurrAddress, FetchNextCommandByte());
BootloaderAPI_FillWord(CurrAddress, FetchNextCommandByte());
/* Send confirmation byte back to the host */
WriteNextResponseByte('\r');
......@@ -579,7 +565,7 @@ static void CDC_Task(void)
else if (Command == AVR109_COMMAND_FillFlashPageWordLow)
{
/* Write the low byte to the current flash page */
boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
BootloaderAPI_FillWord(CurrAddress | 0x01, FetchNextCommandByte());
/* Increment the address */
CurrAddress += 2;
......@@ -590,10 +576,7 @@ static void CDC_Task(void)
else if (Command == AVR109_COMMAND_WriteFlashPage)
{
/* Commit the flash page to memory */
boot_page_write(CurrAddress);
/* Wait until write operation has completed */
boot_spm_busy_wait();
BootloaderAPI_WritePage(CurrAddress);
/* Send confirmation byte back to the host */
WriteNextResponseByte('\r');
......
......@@ -37,16 +37,22 @@
void BootloaderAPI_ErasePage(const uint32_t Address)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_WritePage(const uint32_t Address)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
......@@ -71,6 +77,8 @@ uint8_t BootloaderAPI_ReadLock(void)
void BootloaderAPI_WriteLock(const uint8_t LockBits)
{
boot_lock_bits_set_safe(LockBits);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_lock_bits_set_safe(LockBits);
}
}
......@@ -39,6 +39,7 @@
/* Includes: */
#include <avr/io.h>
#include <avr/boot.h>
#include <util/atomic.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
......
......@@ -133,7 +133,7 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#else
/* Check if the device's BOOTRST fuse is set */
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
if (BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
{
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
......@@ -351,7 +351,7 @@ void EVENT_USB_Device_ControlRequest(void)
}
/* Write the next word into the current flash page */
boot_page_fill(CurrFlashAddress.Long, Endpoint_Read_16_LE());
BootloaderAPI_FillWord(CurrFlashAddress.Long, Endpoint_Read_16_LE());
/* Adjust counters */
WordsInFlashPage += 1;
......@@ -361,8 +361,7 @@ void EVENT_USB_Device_ControlRequest(void)
if ((WordsInFlashPage == (SPM_PAGESIZE >> 1)) || !(WordsRemaining))
{
/* Commit the flash page to memory */
boot_page_write(CurrFlashPageStartAddress);
boot_spm_busy_wait();
BootloaderAPI_WritePage(CurrFlashPageStartAddress);
/* Check if programming incomplete */
if (WordsRemaining)
......@@ -371,17 +370,13 @@ void EVENT_USB_Device_ControlRequest(void)
WordsInFlashPage = 0;
/* Erase next page's temp buffer */
boot_page_erase(CurrFlashAddress.Long);
boot_spm_busy_wait();
BootloaderAPI_ErasePage(CurrFlashAddress.Long);
}
}
}
/* Once programming complete, start address equals the end address */
StartAddr = EndAddr;
/* Re-enable the RWW section of flash */
boot_rww_enable();
}
else // Write EEPROM
{
......@@ -691,8 +686,7 @@ static void ProcessMemProgCommand(void)
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
/* Erase the current page's temp buffer */
boot_page_erase(CurrFlashAddress.Long);
boot_spm_busy_wait();
BootloaderAPI_ErasePage(CurrFlashAddress.Long);
}
/* Set the state so that the next DNLOAD requests reads in the firmware */
......@@ -789,21 +783,9 @@ static void ProcessWriteCommand(void)
}
else if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) // Erase flash
{
uint32_t CurrFlashAddress = 0;
/* Clear the application section of flash */
while (CurrFlashAddress < (uint32_t)BOOT_START_ADDR)
{
boot_page_erase(CurrFlashAddress);
boot_spm_busy_wait();
boot_page_write(CurrFlashAddress);
boot_spm_busy_wait();
CurrFlashAddress += SPM_PAGESIZE;
}
/* Re-enable the RWW section of flash as writing to the flash locks it out */
boot_rww_enable();
for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
BootloaderAPI_ErasePage(CurrFlashAddress);
/* Memory has been erased, reset the security bit so that programming/reading is allowed */
IsSecure = false;
......
......@@ -164,8 +164,11 @@ void EVENT_USB_Device_ControlRequest(void)
else if (PageAddress < BOOT_START_ADDR)
{
/* Erase the given FLASH page, ready to be programmed */
boot_page_erase(PageAddress);
boot_spm_busy_wait();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_erase(PageAddress);
boot_spm_busy_wait();
}
/* Write each of the FLASH page's bytes in sequence */
for (uint8_t PageWord = 0; PageWord < (SPM_PAGESIZE / 2); PageWord++)
......@@ -182,8 +185,11 @@ void EVENT_USB_Device_ControlRequest(void)
}
/* Write the filled FLASH page to memory */
boot_page_write(PageAddress);
boot_spm_busy_wait();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_write(PageAddress);
boot_spm_busy_wait();
}
/* Re-enable RWW section */
boot_rww_enable();
......
......@@ -42,6 +42,7 @@
#include <avr/boot.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
#include <stdbool.h>
#include "Descriptors.h"
......
......@@ -37,16 +37,22 @@
void BootloaderAPI_ErasePage(const uint32_t Address)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_WritePage(const uint32_t Address)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
......@@ -71,6 +77,8 @@ uint8_t BootloaderAPI_ReadLock(void)
void BootloaderAPI_WriteLock(const uint8_t LockBits)
{
boot_lock_bits_set_safe(LockBits);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_lock_bits_set_safe(LockBits);
}
}
......@@ -39,6 +39,7 @@
/* Includes: */
#include <avr/io.h>
#include <avr/boot.h>
#include <util/atomic.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
......
......@@ -114,7 +114,7 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#else
/* Check if the device's BOOTRST fuse is set */
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
if (BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
{
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
......
......@@ -44,6 +44,7 @@
#include <string.h>
#include "Descriptors.h"
#include "BootloaderAPI.h"
#include "Config/AppConfig.h"
#include "Lib/SCSI.h"
......
......@@ -37,16 +37,22 @@
void BootloaderAPI_ErasePage(const uint32_t Address)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_erase_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_WritePage(const uint32_t Address)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_page_write_safe(Address);
boot_spm_busy_wait();
boot_rww_enable();
}
}
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
......@@ -71,5 +77,8 @@ uint8_t BootloaderAPI_ReadLock(void)
void BootloaderAPI_WriteLock(const uint8_t LockBits)
{
boot_lock_bits_set_safe(LockBits);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
boot_lock_bits_set_safe(LockBits);
}
}
......@@ -39,6 +39,7 @@
/* Includes: */
#include <avr/io.h>
#include <avr/boot.h>
#include <util/atomic.h>
#include <stdbool.h>
#include <LUFA/Common/Common.h>
......
......@@ -146,7 +146,7 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#else
/* Check if the device's BOOTRST fuse is set */
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
if (BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
{
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
......@@ -221,8 +221,7 @@ static void FlushPageIfRequired(void)
uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1));
if (HEXParser.PageStartAddress != NewPageStartAddress)
{
boot_page_write(HEXParser.PageStartAddress);
boot_spm_busy_wait();
BootloaderAPI_WritePage(HEXParser.PageStartAddress);
HEXParser.PageStartAddress = NewPageStartAddress;
......@@ -321,14 +320,13 @@ static void ParseIntelHEXByte(const char ReadCharacter)
/* If we are writing to a new page, we need to erase it first */
if (!(PageDirty))
{
boot_page_erase(HEXParser.PageStartAddress);
boot_spm_busy_wait();
BootloaderAPI_ErasePage(HEXParser.PageStartAddress);
PageDirty = true;
}
/* Fill the FLASH memory buffer with the new word of data */
boot_page_fill(HEXParser.CurrAddress, NewDataWord);
BootloaderAPI_FillWord(HEXParser.CurrAddress, NewDataWord);
HEXParser.CurrAddress += 2;
/* Flush the FLASH page to physical memory if we are crossing a page boundary */
......
......@@ -43,6 +43,7 @@
#include <avr/interrupt.h>
#include "Descriptors.h"
#include "BootloaderAPI.h"
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h>
......
......@@ -10,6 +10,8 @@
* <b>Fixed:</b>
* - Core:
* - Fixed DeviceUsesOUTPipe flag not being set correctly in the HID host class driver (thanks to Wolfgang Schnerring)
* - Library Applications:
* - Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan)
*
* \section Sec_ChangeLog170418 Version 170418
* <b>New:</b>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment