nes-proj/cpu/stm32w108/hal/micro/cortexm3/mfg-token.c
Benoît Thébaudeau 19fd7a3551 Use additive offsets
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.

Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.

Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.

Here are the results for the cc2538-demo example:
 - Compilation of uart_init():
    * before:
        REG(regs->base | UART_CC) = 0;
        200b78:	f446 637c 	orr.w	r3, r6, #4032	; 0xfc0
        200b7c:	f043 0308 	orr.w	r3, r3, #8
        200b80:	2200      	movs	r2, #0
        200b82:	601a      	str	r2, [r3, #0]

    * now:
        REG(regs->base + UART_CC) = 0;
        200b7a:	2300      	movs	r3, #0
        200b7c:	f8c4 3fc8 	str.w	r3, [r4, #4040]	; 0xfc8

 - Size of the .text section:
    * before:	0x4c7c
    * now:	0x4c28
    * saved:	84 bytes

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
2015-03-28 17:28:15 +01:00

105 lines
3.0 KiB
C

/** @file hal/micro/cortexm3/mfg-token.c
* @brief Cortex-M3 Manufacturing-Token system
*
* <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved. -->
*/
#include PLATFORM_HEADER
#include "error.h"
#include "hal/micro/cortexm3/flash.h"
#include "mfg-token.h"
#define DEFINETOKENS
#define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \
const uint16_t TOKEN_##name = TOKEN_##name##_ADDRESS;
#include "hal/micro/cortexm3/token-manufacturing.h"
#undef TOKEN_DEF
#undef TOKEN_MFG
#undef DEFINETOKENS
static const uint8_t nullEui[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };
void halInternalGetMfgTokenData(void *data, uint16_t ID, uint8_t index, uint8_t len)
{
uint8_t *ram = (uint8_t*)data;
//0x7F is a non-indexed token. Remap to 0 for the address calculation
index = (index==0x7F) ? 0 : index;
if(ID == MFG_EUI_64_LOCATION) {
//There are two EUI64's stored in the Info Blocks, St and Custom.
//0x0A00 is the address used by the generic EUI64 token, and it is
//token.c's responbility to pick the returned EUI64 from either St
//or Custom. Return the Custom EUI64 if it is not all FF's, otherwise
//return the St EUI64.
tokTypeMfgEui64 eui64;
halCommonGetMfgToken(&eui64, TOKEN_MFG_CUSTOM_EUI_64);
if(MEMCOMPARE(eui64,nullEui, 8 /*EUI64_SIZE*/) == 0) {
halCommonGetMfgToken(&eui64, TOKEN_MFG_ST_EUI_64);
}
MEMCOPY(ram, eui64, 8 /*EUI64_SIZE*/);
} else {
//read from the Information Blocks. The token ID is only the
//DATA_BIG_INFO_BASE-relative 16-bit offset of the token. Since the
//info blocks exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END,
//we need to add the ID to DATA_BIG_INFO_BASE to get the real address.
uint32_t realAddress = (DATA_BIG_INFO_BASE+ID) + (len*index);
uint8_t *flash = (uint8_t *)realAddress;
MEMCOPY(ram, flash, len);
}
}
void halInternalSetMfgTokenData(uint16_t token, void *data, uint8_t len)
{
StStatus flashStatus;
uint32_t realAddress = (DATA_BIG_INFO_BASE+token);
uint8_t * flash = (uint8_t *)realAddress;
uint32_t i;
//The flash library (and hardware) requires the address and length to both
//be multiples of 16bits. Since this API is only valid for writing to
//the CIB, verify that the token+len falls within the CIB.
assert((token&1) != 1);
assert((len&1) != 1);
assert((realAddress>=CIB_BOTTOM) && ((realAddress+len-1)<=CIB_TOP));
//CIB manufacturing tokens can only be written by on-chip code if the token
//is currently unprogrammed. Verify the entire token is unwritten. The
//flash library performs a similar check, but verifying here ensures that
//the entire token is unprogrammed and will prevent partial writes.
for(i=0;i<len;i++) {
assert(flash[i] == 0xFF);
}
//Remember, the flash library operates in 16bit quantities, but the
//token system operates in 8bit quantities. Hence the divide by 2.
flashStatus = halInternalFlashWrite(realAddress, data, (len/2));
assert(flashStatus == ST_SUCCESS);
}