/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _STARTUP_H_
#define _STARTUP_H_

#include <stdint.h>

/*! \brief Contains public interface to various functions related
 *         to the startup of this chip
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*! \brief define symbols that specific start and end addres of some basic sections.
 */
#if(defined(__ICCARM__))
#define INTERRUPTS_SECTION_START    __section_begin(".intvec")
#define INTERRUPTS_SECTION_END      __section_end(".intvec")
#define BSS_SECTION_START           __section_begin(".bss")
#define BSS_SECTION_END             __section_end(".bss")
#define DATA_SECTION_START          __section_begin(".data")
#define DATA_SECTION_END            __section_end(".data")
#define CUSTOMSECTION_SECTION_START __section_begin(".customSection")
#define CUSTOMSECTION_SECTION_END   __section_end(".customSection")
#define CODE_RAM_SECTION_START      __section_begin("__CODE_RAM")
#define CODE_RAM_SECTION_END        __section_end("__CODE_RAM")
#define DATA_INIT_SECTION_START     __section_begin(".data_init")
#define DATA_INIT_SECTION_END       __section_end(".data_init")
#define CODE_ROM_SECTION_START      __section_begin("__CODE_ROM")
#define CODE_ROM_SECTION_END        __section_end("__CODE_ROM")

#elif(defined(__ARMCC_VERSION))
#define INTERRUPTS_SECTION_START    (uint8_t *)__VECTOR_ROM_START
#define INTERRUPTS_SECTION_END      (uint8_t *)__VECTOR_ROM_END
#define BSS_SECTION_START           (uint8_t *)__BSS_START
#define BSS_SECTION_END             (uint8_t *)__BSS_END
#define DATA_SECTION_START          (uint8_t *)__DATA_RAM_START
#define DATA_SECTION_END            (uint8_t *)__DATA_RAM_END
#define CUSTOMSECTION_SECTION_START (uint8_t *)__CUSTOM_SECTION_START
#define CUSTOMSECTION_SECTION_END   (uint8_t *)__CUSTOM_SECTION_END
#define CODE_RAM_SECTION_START      (uint8_t *)__CODE_RAM_START
#define CODE_RAM_SECTION_END        (uint8_t *)__CODE_RAM_END

extern uint32_t __VECTOR_ROM_START;
extern uint32_t __VECTOR_ROM_END;
extern uint32_t __BSS_START;
extern uint32_t __BSS_END;
extern uint32_t __DATA_RAM_START;
extern uint32_t __DATA_RAM_END;
extern uint32_t __CUSTOM_SECTION_START;
extern uint32_t __CUSTOM_SECTION_END;
extern uint32_t __CODE_RAM_START;
extern uint32_t __CODE_RAM_END;
#else
#define INTERRUPTS_SECTION_START    (uint8_t *)&__interrupts_start__
#define INTERRUPTS_SECTION_END      (uint8_t *)&__interrupts_end__
#define BSS_SECTION_START           (uint8_t *)&__bss_start__
#define BSS_SECTION_END             (uint8_t *)&__bss_end__
#define DATA_SECTION_START          (uint8_t *)&__data_start__
#define DATA_SECTION_END            (uint8_t *)&__data_end__
#define CUSTOMSECTION_SECTION_START (uint8_t *)&__customSection_start__
#define CUSTOMSECTION_SECTION_END   (uint8_t *)&__customSection_end__
#define CODE_RAM_SECTION_START      (uint8_t *)&__code_ram_start__
#define CODE_RAM_SECTION_END        (uint8_t *)&__code_ram_end__

extern uint32_t __interrupts_start__;
extern uint32_t __interrupts_end__;
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
extern uint32_t __data_start__;
extern uint32_t __data_end__;
extern uint32_t __customSection_start__;
extern uint32_t __customSection_end__;
extern uint32_t __code_ram_start__;
extern uint32_t __code_ram_end__;
#endif

#if(defined(__ICCARM__))
#pragma section = ".data"
#pragma section = ".data_init"
#pragma section = ".bss"
#pragma section = ".intvec"
#pragma section = ".customSection"
#pragma section = ".customSection_init"
#pragma section = "__CODE_RAM"
#pragma section = "__CODE_ROM"
#endif

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief Make necessary initializations for RAM.
 *
 * - Copy initialized data from ROM to RAM.
 * - Clear the zero-initialized data section.
 * - Copy the vector table from ROM to RAM. This could be an option.
 */
void init_data_bss(void);

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif /* _STARTUP_H_ */
