nanokernel: move dataCopy() and bssZero() to common code

Used by ARC, ARM, Nios II. x86 has alternate code done in assembly.

Linker scripts had some alarming comments about data/BSS overlap,
but the beginning of BSS is aligned so this can't happen even if
the end of data isn't.

The common code doesn't use fake pointer values for the number of
words in these sections, don't compute or export them.

Change-Id: I4291c2a6d0222d0a3e95c140deae7539ebab3cc3
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-07-06 11:06:24 -07:00 committed by Inaky Perez-Gonzalez
commit 5b9378ab7e
10 changed files with 81 additions and 193 deletions

View file

@ -30,51 +30,7 @@
#include <toolchain.h>
#include <linker-defs.h>
#include <arch/arc/v2/aux_regs.h>
/**
*
* @brief Clear BSS
*
* This routine clears the BSS region, so all bytes are 0.
*
* @return N/A
*/
static void bssZero(void)
{
volatile uint32_t *pBSS = (uint32_t *)&__bss_start;
unsigned int n;
for (n = 0; n < (unsigned int)&__bss_num_words; n++) {
pBSS[n] = 0;
}
}
/**
*
* @brief Copy the data section from ROM to RAM
*
* This routine copies the data section from ROM to RAM.
*
* @return N/A
*/
#ifdef CONFIG_XIP
static void dataCopy(void)
{
volatile uint32_t *pROM = (uint32_t *)&__data_rom_start;
volatile uint32_t *pRAM = (uint32_t *)&__data_ram_start;
unsigned int n;
for (n = 0; n < (unsigned int)&__data_num_words; n++) {
pRAM[n] = pROM[n];
}
}
#else
static void dataCopy(void)
{
}
#endif
#include <nano_internal.h>
/**
@ -167,8 +123,8 @@ void _PrepC(void)
disable_icache();
invalidate_dcache();
adjust_vector_table_base();
bssZero();
dataCopy();
_bss_zero();
_data_copy();
_Cstart();
CODE_UNREACHABLE;
}

View file

@ -1,5 +1,6 @@
ccflags-y +=-I$(srctree)/include/drivers
ccflags-y +=-I$(srctree)/arch/arm/soc/$(SOC_PATH)
ccflags-y +=-I$(srctree)/kernel/nanokernel/include
asflags-y = $(ccflags-y)

View file

@ -30,53 +30,11 @@
#include <stdint.h>
#include <toolchain.h>
#include <linker-defs.h>
/**
*
* @brief Clear BSS
*
* This routine clears the BSS region, so all bytes are 0.
*
* @return N/A
*/
static void bssZero(void)
{
volatile uint32_t *pBSS = (uint32_t *)&__bss_start;
unsigned int n;
for (n = 0; n < (unsigned int)&__bss_num_words; n++) {
pBSS[n] = 0;
}
}
/**
*
* @brief Copy the data section from ROM to RAM
*
* This routine copies the data section from ROM to RAM.
*
* @return N/A
*/
#include <nano_internal.h>
#ifdef CONFIG_XIP
static void dataCopy(void)
{
volatile uint32_t *pROM = (uint32_t *)&__data_rom_start;
volatile uint32_t *pRAM = (uint32_t *)&__data_ram_start;
unsigned int n;
for (n = 0; n < (unsigned int)&__data_num_words; n++) {
pRAM[n] = pROM[n];
}
}
static inline void relocate_vector_table(void) { /* do nothing */ }
#else
static void dataCopy(void)
{
}
static inline void relocate_vector_table(void)
{
/* vector table is already in SRAM, just point to it */
@ -136,8 +94,8 @@ void _PrepC(void)
{
relocate_vector_table();
enable_floating_point();
bssZero();
dataCopy();
_bss_zero();
_data_copy();
_Cstart();
CODE_UNREACHABLE;
}

View file

@ -30,65 +30,8 @@
#include <toolchain.h>
#include <linker-defs.h>
#include <nano_private.h>
#include <nano_internal.h>
/**
*
* @brief Clear BSS
*
* This routine clears the BSS region, so all bytes are 0.
*
* @return N/A
*/
static void bssZero(void)
{
uint32_t *pos = (uint32_t *)&__bss_start;
for ( ; pos < (uint32_t *)&__bss_end; pos++) {
*pos = 0;
}
}
/**
*
* @brief Copy the data section from ROM to RAM
*
* This routine copies the data section from ROM to RAM.
*
* @return N/A
*/
#ifdef CONFIG_XIP
static void dataCopy(void)
{
uint32_t *pROM, *pRAM;
pROM = (uint32_t *)&__data_rom_start;
pRAM = (uint32_t *)&__data_ram_start;
for ( ; pRAM < (uint32_t *)&__data_ram_end; pROM++, pRAM++) {
*pRAM = *pROM;
}
/* In most XIP scenarios we copy the exception code into RAM, so need
* to flush instruction cache.
*/
_nios2_icache_flush_all();
#if NIOS2_ICACHE_SIZE > 0
/* Only need to flush the data cache here if there actually is an
* instruction cache, so that the cached instruction data written is
* actually committed.
*/
_nios2_dcache_flush_all();
#endif
}
#else
static void dataCopy(void)
{
}
#endif
extern FUNC_NORETURN void _Cstart(void);
/**
*
* @brief Prepare to and run C code
@ -100,8 +43,21 @@ extern FUNC_NORETURN void _Cstart(void);
void _PrepC(void)
{
bssZero();
dataCopy();
_bss_zero();
#ifdef CONFIG_XIP
_data_copy();
/* In most XIP scenarios we copy the exception code into RAM, so need
* to flush instruction cache.
*/
_nios2_icache_flush_all();
#if NIOS2_ICACHE_SIZE > 0
/* Only need to flush the data cache here if there actually is an
* instruction cache, so that the cached instruction data written is
* actually committed.
*/
_nios2_dcache_flush_all();
#endif
#endif
_Cstart();
CODE_UNREACHABLE;
}

View file

@ -279,7 +279,6 @@ SECTION_PROLOGUE (_k_task_list, (OPTIONAL),)
/* Define linker symbols */
_image_ram_end = .;
_end = .; /* end of image */
__bss_num_words = (__bss_end - __bss_start) >> 2;
GROUP_END(RAMABLE_REGION)
@ -294,15 +293,3 @@ SECTION_PROLOGUE (_k_task_list, (OPTIONAL),)
ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")
}
#ifdef CONFIG_XIP
/*
* Round up number of words for DATA section to ensure that XIP copies the
* entire data section. XIP copy is done in words only, so there may be up
* to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
* is done first followed by clearing the BSS section.
*/
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif

View file

@ -268,7 +268,6 @@ SECTION_PROLOGUE (_k_task_list, (OPTIONAL),)
/* Define linker symbols */
_image_ram_end = .;
_end = .; /* end of image */
__bss_num_words = (__bss_end - __bss_start) >> 2;
GROUP_END(RAMABLE_REGION)
@ -283,15 +282,3 @@ SECTION_PROLOGUE (_k_task_list, (OPTIONAL),)
ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")
}
#ifdef CONFIG_XIP
/*
* Round up number of words for DATA section to ensure that XIP copies the
* entire data section. XIP copy is done in words only, so there may be up
* to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
* is done first followed by clearing the BSS section.
*/
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif

View file

@ -302,7 +302,6 @@ SECTIONS
_image_ram_end = .;
_end = .; /* end of image */
__bss_num_words = (__bss_end - __bss_start) >> 2;
GROUP_END(RAMABLE_REGION)
@ -340,15 +339,3 @@ SECTIONS
ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.")
}
#ifdef CONFIG_XIP
/*
* Round up number of words for DATA section to ensure that XIP copies the
* entire data section. XIP copy is done in words only, so there may be up
* to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
* is done first followed by clearing the BSS section.
*/
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#endif

View file

@ -133,12 +133,10 @@ GDATA(__data_num_words)
#include <stdint.h>
extern char __bss_start[];
extern char __bss_end[];
extern int __bss_num_words[];
#ifdef CONFIG_XIP
extern char __data_rom_start[];
extern char __data_ram_start[];
extern char __data_ram_end[];
extern int __data_num_words[];
#endif
extern char _image_rom_start[];

View file

@ -31,6 +31,21 @@
extern "C" {
#endif
#include <nanokernel.h>
/* Early boot functions */
void _bss_zero(void);
#ifdef CONFIG_XIP
void _data_copy(void);
#else
static inline void _data_copy(void)
{
/* Do nothing */
}
#endif
FUNC_NORETURN void _Cstart(void);
/* helper type alias for thread control structure */
typedef struct tcs tTCS;

View file

@ -30,6 +30,7 @@
#include <nano_private.h>
#include <device.h>
#include <init.h>
#include <linker-defs.h>
/* kernel build timestamp items */
@ -135,6 +136,48 @@ extern ktask_t _k_task_ptr_idle _GENERIC_SECTION(_k_task_list);
extern void _main(void);
#endif
/**
*
* @brief Clear BSS
*
* This routine clears the BSS region, so all bytes are 0.
*
* @return N/A
*/
void _bss_zero(void)
{
uint32_t *pos = (uint32_t *)&__bss_start;
for ( ; pos < (uint32_t *)&__bss_end; pos++) {
*pos = 0;
}
}
#ifdef CONFIG_XIP
/**
*
* @brief Copy the data section from ROM to RAM
*
* This routine copies the data section from ROM to RAM.
*
* @return N/A
*/
void _data_copy(void)
{
uint32_t *pROM, *pRAM;
pROM = (uint32_t *)&__data_rom_start;
pRAM = (uint32_t *)&__data_ram_start;
for ( ; pRAM < (uint32_t *)&__data_ram_end; pROM++, pRAM++) {
*pRAM = *pROM;
}
}
#endif
/**
*
* @brief Initializes nanokernel data structures