RIOT/cpu/arm7_common/arm7_init.c
Benjamin Valentin 32bbba2fc5 cpu/lpc2387: add support for backup RAM
lpc23xx has 2k of battery RAM that is retained in Deep Power Down mode.

To not overwrite that data it must only be initialized on Power On Reset.
However, RSIR looks the same when waking up from Deep Power Down as it does
on the power-on case.

So use 4 bytes of the backup RAM to keep a signature that is only valid if
memory was retained (no power-on Reset).

A small change to the linker script is required so two sections can be
placed into flash.
2019-11-28 11:33:03 +01:00

112 lines
2.4 KiB
C

/*
* Copyright 2008-2009, Freie Universitaet Berlin (FUB). All rights reserved.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_arm7_common
* @{
*
* @file
* @brief Common ARM7 boot up code
*
* @author Heiko Will <hwill@inf.fu-berlin.de>
* @author Michael Baar <michael.baar@fu-berlin.de>
*/
#include <stdio.h>
#include <stdlib.h>
#include "thread.h"
#ifdef MODULE_PUF_SRAM
#include "puf_sram.h"
#endif
#include "cpu.h"
#include "log.h"
static inline void
_init_data(void)
{
extern unsigned int _etext;
extern unsigned int _data;
extern unsigned int _edata;
extern unsigned int __bss_start;
extern unsigned int __bss_end;
/* Support for LPRAM. */
#ifdef CPU_HAS_BACKUP_RAM
extern unsigned int _sbackup_data_load[];
extern unsigned int _sbackup_data[];
extern unsigned int _ebackup_data[];
extern unsigned int _sbackup_bss[];
extern unsigned int _ebackup_bss[];
#endif /* CPU_HAS_BACKUP_RAM */
register unsigned int *p1;
register unsigned int *p2;
register unsigned int *p3;
// initialize data from flash
// (linker script ensures that data is 32-bit aligned)
p1 = &_etext;
p2 = &_data;
p3 = &_edata;
while (p2 < p3) {
*p2++ = *p1++;
}
// clear bss
// (linker script ensures that bss is 32-bit aligned)
p1 = &__bss_start;
p2 = &__bss_end;
while (p1 < p2) {
*p1++ = 0;
}
#ifdef CPU_HAS_BACKUP_RAM
if (cpu_woke_from_backup()) {
/* load low-power data section. */
for (p1 = _sbackup_data, p2 = _sbackup_data_load;
p1 < _ebackup_data;
p1++, p2++) {
*p1 = *p2;
}
/* zero-out low-power bss. */
for (p1 = _sbackup_bss; p1 < _ebackup_bss; p1++) {
*p1 = 0;
}
}
#endif /* CPU_HAS_BACKUP_RAM */
}
void bootloader(void)
{
extern void cpu_init(void);
/* initialize bss and data */
_init_data();
#ifdef MODULE_PUF_SRAM
/* uninitialized heap starts after bss section */
extern unsigned int __bss_end;
puf_sram_init((uint8_t *) __bss_end, SEED_RAM_LEN);
#endif
/* cpu specific setup of clocks, peripherals */
cpu_init();
#ifdef MODULE_NEWLIB
extern void __libc_init_array(void);
__libc_init_array();
#endif
}
/** @} */