mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-07-19 22:22:03 +00:00
Add ATTR_NEVER_INLINE attribute. Add EEPROM byte read/write proxy functions to the Mass Storage bootloader to prevent link errors due to linker relaxations.
This commit is contained in:
parent
7251da6581
commit
85343a436d
@ -186,15 +186,50 @@ static FATDirectoryEntry_t FirmwareFileEntries[] =
|
|||||||
* systems files are usually replaced using the original file's disk clusters,
|
* systems files are usually replaced using the original file's disk clusters,
|
||||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||||
*/
|
*/
|
||||||
static uint16_t* FLASHFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_FLASH_MSDOS].MSDOS_File.StartingCluster;
|
static const uint16_t* FLASHFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_FLASH_MSDOS].MSDOS_File.StartingCluster;
|
||||||
|
|
||||||
/** Starting cluster of the virtual EEPROM.BIN file on disk, tracked so that the
|
/** Starting cluster of the virtual EEPROM.BIN file on disk, tracked so that the
|
||||||
* offset from the start of the data sector can be determined. On Windows
|
* offset from the start of the data sector can be determined. On Windows
|
||||||
* systems files are usually replaced using the original file's disk clusters,
|
* systems files are usually replaced using the original file's disk clusters,
|
||||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||||
*/
|
*/
|
||||||
static uint16_t* EEPROMFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_EEPROM_MSDOS].MSDOS_File.StartingCluster;
|
static const uint16_t* EEPROMFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_EEPROM_MSDOS].MSDOS_File.StartingCluster;
|
||||||
|
|
||||||
|
/** Reads a byte of EEPROM out from the EEPROM memory space.
|
||||||
|
*
|
||||||
|
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||||
|
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||||
|
* larger USB AVRs will break the linker. This function is marked as
|
||||||
|
* never inlinable and placed into the normal text segment so that the
|
||||||
|
* call to the EEPROM function will be short even if the AUX boot section
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
|
* \param[in] Address Address of the EEPROM location to read from
|
||||||
|
*
|
||||||
|
* \return Read byte of EEPROM data.
|
||||||
|
*/
|
||||||
|
static uint8_t ReadEEPROMByte(const uint8_t* const Address)
|
||||||
|
{
|
||||||
|
return eeprom_read_byte(Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Writes a byte of EEPROM out to the EEPROM memory space.
|
||||||
|
*
|
||||||
|
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||||
|
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||||
|
* larger USB AVRs will break the linker. This function is marked as
|
||||||
|
* never inlinable and placed into the normal text segment so that the
|
||||||
|
* call to the EEPROM function will be short even if the AUX boot section
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
|
* \param[in] Address Address of the EEPROM location to write to
|
||||||
|
* \param[in] Data New data to write to the EEPROM location
|
||||||
|
*/
|
||||||
|
static void WriteEEPROMByte(uint8_t* const Address,
|
||||||
|
const uint8_t Data)
|
||||||
|
{
|
||||||
|
eeprom_update_byte(Address, Data);
|
||||||
|
}
|
||||||
|
|
||||||
/** Updates a FAT12 cluster entry in the FAT file table with the specified next
|
/** Updates a FAT12 cluster entry in the FAT file table with the specified next
|
||||||
* chain index. If the cluster is the last in the file chain, the magic value
|
* chain index. If the cluster is the last in the file chain, the magic value
|
||||||
@ -241,9 +276,9 @@ static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
|||||||
*/
|
*/
|
||||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||||
const uint16_t Index,
|
const uint16_t Index,
|
||||||
const uint16_t ChainLength)
|
const uint8_t ChainLength)
|
||||||
{
|
{
|
||||||
for (uint16_t i = 0; i < ChainLength; i++)
|
for (uint8_t i = 0; i < ChainLength; i++)
|
||||||
{
|
{
|
||||||
uint16_t CurrentCluster = Index + i;
|
uint16_t CurrentCluster = Index + i;
|
||||||
uint16_t NextCluster = CurrentCluster + 1;
|
uint16_t NextCluster = CurrentCluster + 1;
|
||||||
@ -346,13 +381,13 @@ static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber,
|
|||||||
{
|
{
|
||||||
/* Read out the mapped block of data from the device's EEPROM */
|
/* Read out the mapped block of data from the device's EEPROM */
|
||||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||||
BlockBuffer[i] = eeprom_read_byte((void*)EEPROMAddress++);
|
BlockBuffer[i] = ReadEEPROMByte((uint8_t*)EEPROMAddress++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Write out the mapped block of data to the device's EEPROM */
|
/* Write out the mapped block of data to the device's EEPROM */
|
||||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||||
eeprom_update_byte((void*)EEPROMAddress++, BlockBuffer[i]);
|
WriteEEPROMByte((uint8_t*)EEPROMAddress++, BlockBuffer[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,13 +274,18 @@
|
|||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C)
|
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C)
|
||||||
|
static uint8_t ReadEEPROMByte(const uint8_t* const Address) ATTR_NEVER_INLINE;
|
||||||
|
|
||||||
|
static void WriteEEPROMByte(uint8_t* const Address,
|
||||||
|
const uint8_t Data) ATTR_NEVER_INLINE;
|
||||||
|
|
||||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||||
const uint16_t Index,
|
const uint16_t Index,
|
||||||
const uint16_t ChainEntry) AUX_BOOT_SECTION;
|
const uint16_t ChainEntry) AUX_BOOT_SECTION;
|
||||||
|
|
||||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||||
const uint16_t StartIndex,
|
const uint16_t StartIndex,
|
||||||
const uint16_t ChainLength) AUX_BOOT_SECTION;
|
const uint8_t ChainLength) AUX_BOOT_SECTION;
|
||||||
|
|
||||||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
||||||
uint8_t* BlockBuffer,
|
uint8_t* BlockBuffer,
|
||||||
|
@ -90,6 +90,11 @@
|
|||||||
*/
|
*/
|
||||||
#define ATTR_NO_INLINE __attribute__ ((noinline))
|
#define ATTR_NO_INLINE __attribute__ ((noinline))
|
||||||
|
|
||||||
|
/** Forces the compiler to never inline the specified function. When applied, the given function will be
|
||||||
|
* always be called explicitly under all circumstances.
|
||||||
|
*/
|
||||||
|
#define ATTR_NEVER_INLINE __attribute__ ((noinline))
|
||||||
|
|
||||||
/** Forces the compiler to inline the specified function. When applied, the given function will be
|
/** Forces the compiler to inline the specified function. When applied, the given function will be
|
||||||
* in-lined under all circumstances.
|
* in-lined under all circumstances.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user