diff --git a/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c
new file mode 100644
index 00000000..a1822bf0
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.c
@@ -0,0 +1,127 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\GCC\cpu_comp.c
+* \brief Bootloader compiler specific cpu module source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+/****************************************************************************************
+* Local function prototypes
+****************************************************************************************/
+static void CpuWriteWDTCON0(blt_int32u uwValue);
+
+
+/************************************************************************************//**
+** \brief This macro clears the EndInit bit, which controls access to system critical
+** registers. Clearing the EndInit bit unlocks all EndInit protectedd
+** registers. Modifications of the EndInit bit are monitored by the watchdog
+** timer such that after clearing the EndInit, the watchdog timer enters a
+** defined time-out mode; EndInit must be set again before the time-out
+** expires.
+** \return none.
+**
+****************************************************************************************/
+void CpuEnterInitMode(void)
+{
+ /* request clearing of the EndInit bit */
+ CpuWriteWDTCON0(WDT_CON0.reg & ~0x00000001);
+ /* wait for hardware handshake */
+ while (WDT_CON0.bits.ENDINIT != 0)
+ {
+ /* keep the watchdog happy */
+ CopService();
+ }
+} /*** end of CpuEnterInitMode ***/
+
+
+/************************************************************************************//**
+** \brief This macro sets the EndInit bit, which controls access to system critical
+** registers. Setting the EndInit bit locks all EndInit protected registers.
+** \return none.
+**
+****************************************************************************************/
+void CpuLeaveInitMode(void)
+{
+ /* set the EndInit bit */
+ CpuWriteWDTCON0(WDT_CON0.reg | 0x00000001);
+} /*** end of CpuLeaveInitMode ***/
+
+
+/************************************************************************************//**
+** \brief Write a new value to the WDTCON0 register.
+** \param value New value for the WDTCON0 register.
+** \return none.
+**
+****************************************************************************************/
+static void CpuWriteWDTCON0(blt_int32u value)
+{
+ blt_int32u dummy;
+
+ /* load current value of the WDTCON0 register */
+ dummy = WDT_CON0.reg;
+ /* set HWPW1 = 1111b */
+ dummy |= 0x000000F0;
+ /* set HWPW0 = WDTDR */
+ if(WDT_CON1.bits.DR)
+ {
+ dummy |= 0x00000008;
+ }
+ else
+ {
+ dummy &= ~0x00000008;
+ }
+ /* set HWPW0 = WDTIR */
+ if(WDT_CON1.bits.IR)
+ {
+ dummy |= 0x00000004;
+ }
+ else
+ {
+ dummy &= ~0x00000004;
+ }
+ /* set WDTLCK = 0 */
+ dummy &= ~0x00000002;
+ /* unlock access */
+ WDT_CON0.reg = dummy;
+ /* set HWPW1 = 1111b and WDTLCK = 1 */
+ value |= 0x000000F2;
+ /* set HWPW0 = 00b */
+ value &= ~0x0000000C;
+ /* write access and lock */
+ WDT_CON0.reg = value;
+} /*** end of CpuWriteWDTCON0 ***/
+
+
+/*********************************** end of cpu_comp.c *********************************/
diff --git a/Target/Source/TRICORE_TC1798/GCC/cpu_comp.h b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.h
new file mode 100644
index 00000000..4e8a53f2
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/GCC/cpu_comp.h
@@ -0,0 +1,62 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\GCC\cpu_comp.h
+* \brief Bootloader compiler specific cpu module header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef CPU_COMP_H
+#define CPU_COMP_H
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include
+#include
+#include
+#include
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/** \brief Macro for performing a processor specific desync. This part is located in the
+ * compiler specific part because it uses an inline assembly call.
+ */
+#define CpuSetDSYNC() asm("DSYNC")
+
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void CpuEnterInitMode(void);
+void CpuLeaveInitMode(void);
+
+
+#endif /* CPU_COMP_H */
+/*********************************** end of cpu_comp.h *********************************/
diff --git a/Target/Source/TRICORE_TC1798/GCC/crt0-tc1x.S b/Target/Source/TRICORE_TC1798/GCC/crt0-tc1x.S
new file mode 100644
index 00000000..f5db123d
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/GCC/crt0-tc1x.S
@@ -0,0 +1,540 @@
+/*
+ * crt0-tc1x.S -- Startup code for GNU/TriCore applications.
+ *
+ * Copyright (C) 1998-2012 HighTec EDV-Systeme GmbH.
+ *
+ * This file is part of GCC.
+ *
+ * GCC is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GCC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Under Section 7 of GPL version 3, you are granted additional
+ * permissions described in the GCC Runtime Library Exception, version
+ * 3.1, as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License and
+ * a copy of the GCC Runtime Library Exception along with this program;
+ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ * . */
+
+#ifndef __TRICORE_NAME__
+#error Please define __TRICOR_NAME__
+#endif
+
+/* define the Derivate Name as a hexvalue
+ * this name is defined in tricore.specs for specific derivate to
+ * the derivate number as a hexvalue (e.g. TC1796 => 0x1796
+ * This name will be used in the memory.x Memory description to
+ * to confirm that the crt0.o and the memory.x will be get from
+ * same directory
+ */
+.global __TRICORE_DERIVATE_NAME__
+.type __TRICORE_DERIVATE_NAME__,@object
+.set __TRICORE_DERIVATE_NAME__,__TRICORE_NAME__
+
+ .section ".startup_code", "awx", @progbits
+ .global _start
+ .type _start,@function
+_start:
+ .code32
+ j 0f
+
+ /*
+ * external boot memory configuration word
+ */
+ .word __EBMCFG
+ .word __EBMCFG
+ .word __EBMCFG
+ .word __EBMCFG
+
+ /*
+ * default value for this configuration word
+ */
+ .global __EBMCFG
+ .weak __EBMCFG
+ __EBMCFG = 0x0000808c
+0:
+
+#; check whether WDTCON0.ENDINIT is set
+#; clear it if necessary
+#; initialization code must write ENDINIT protected registers
+
+ ld.w %d1,$wdtcon0 # %d1 = *WDTCON0
+ jz.t %d1,0,endinit_done
+ jl asm_clear_endinit
+endinit_done:
+
+ /*
+ * initialize user and interrupt stack pointers
+ */
+
+ movh.a %sp,hi:__USTACK # load %sp
+ lea %sp,[%sp]lo:__USTACK
+ movh %d0,hi:__ISTACK # load $isp
+ addi %d0,%d0,lo:__ISTACK
+ mtcr $isp,%d0
+ isync
+
+#; install trap handlers
+
+ movh %d0,hi:first_trap_table #; load $btv
+ addi %d0,%d0,lo:first_trap_table
+ mtcr $btv,%d0
+ isync
+
+ /*
+ * initialize call depth counter
+ */
+
+ mfcr %d0,$psw
+#ifdef MAX_CALLDEPTH_64
+ andn %d0,%d0,0x7f # reset call depth counter
+ or %d0,%d0,0x80 # set CDE bit
+#else
+ or %d0,%d0,0x7f # disable call depth counting
+ andn %d0,%d0,0x80 # clear CDE bit
+#endif
+ mtcr $psw,%d0
+ isync
+
+ /*
+ * initialize access to system global registers
+ */
+
+ mfcr %d0,$psw
+ or %d0,%d0,0x100 # set GW bit
+ mtcr $psw,%d0
+ isync
+
+ /*
+ * initialize SDA base pointers
+ */
+ .global _SMALL_DATA_,_SMALL_DATA2_,_SMALL_DATA3_,_SMALL_DATA4_
+ .weak _SMALL_DATA_,_SMALL_DATA2_,_SMALL_DATA3_,_SMALL_DATA4_
+
+ movh.a %a0,hi:_SMALL_DATA_ # %a0 addresses .sdata/.sbss
+ lea %a0,[%a0]lo:_SMALL_DATA_
+ movh.a %a1,hi:_SMALL_DATA2_ # %a1 addresses .sdata2/.sbss2
+ lea %a1,[%a1]lo:_SMALL_DATA2_
+ movh.a %a8,hi:_SMALL_DATA3_ # %a8 addresses .sdata3/.sbss3
+ lea %a8,[%a8]lo:_SMALL_DATA3_
+ movh.a %a9,hi:_SMALL_DATA4_ # %a9 addresses .sdata4/.sbss4
+ lea %a9,[%a9]lo:_SMALL_DATA4_
+
+
+#ifdef READONLY_SYSREGS
+ mfcr %d0,$psw
+ andn %d0,%d0,0x100 # clear GW bit
+ mtcr $psw,%d0
+ isync
+#endif
+
+
+/*
+ * initialize target environment (PLLCLC, BUSCONx, ADDSELx etc)
+ *
+ * This is done by a user supplied assembler function __board_init
+ */
+#; force PC to remapped ROM address
+ movh.a %a15,hi:__remapped
+ lea %a15,[%a15]lo:__remapped
+ nop
+ ji %a15
+
+__remapped:
+ # call _board_init
+ jl __board_init
+
+__no_board_init:
+
+ /*
+ * disable code and data protection
+ */
+
+#ifdef DISABLE_CODE_PROTECTION
+ mfcr %d0,$cpm0_0 # disable code protection
+ andn %d0,%d0,0xff
+ mtcr $cpm0_0,%d0
+ isync
+#endif
+#ifdef DISABLE_DATA_PROTECTION
+ mfcr %d0,$dpm0_0 # disable data protection
+ andn %d0,%d0,0xff
+ mtcr $dpm0_0,%d0
+ isync
+#endif
+
+ /*
+ * initialize software break service (OCDS)
+ */
+
+#ifdef INIT_SBS
+ SRCSB0 = 0xfffeffbc
+ SWBIPL = 31
+
+ mov.u %d0,lo:(SWBIPL + 0x00001000)
+ addih %d0,%d0,hi:(SWBIPL + 0x00001000)
+ movh.a %a5,hi:SRCSB0
+ lea %a5,[%a5]lo:SRCSB0
+ st.w [%a5],%d0
+#endif
+
+ /*
+ * disable watchdog timer and set ENDINIT bit
+ */
+
+ jl _disable_wdt
+
+
+
+ /*
+ * initialize context save areas
+ */
+
+ jl __init_csa
+
+
+
+ /*
+ * handle clear table (i.e., fill BSS with zeros)
+ */
+
+ jl __clear_table_func
+
+
+ /*
+ * handle copy table (support for romable code)
+ */
+
+ jl __copy_table_func
+
+
+ /*
+ * call the initializer, constructors etc.
+ */
+ call _init
+
+ /*
+ * _exit (main (0, NULL));
+ */
+ mov %d4,0 # argc = 0
+ sub.a %sp,8
+ st.w [%sp]0, %d4
+ st.w [%sp]4, %d4
+ mov.aa %a4, %sp # argv
+
+ call main # int retval = main (0, NULL);
+ mov %d4,%d2
+ lea %sp,[%sp]8 # remove argv[0]
+ mov.u %d1, 0x900d # set exit code i(A14) for the simulator to
+ mov %d15, %d2 # 0x900d if the exit status is 0
+ movh %d3, 0xffff
+ or %d2, %d2, %d3
+ cmov %d1,%d15,%d2
+ mov.a %a14, %d1
+ j _exit # _exit (retval);
+
+ debug # should never come here
+
+
+
+ /*
+ * disable watchdog timer and set ENDINIT bit
+ */
+
+ WDTMASK = 0xffffff03
+ WDTMASKA= 0xffffff01
+ WDTMASK2= 0xfffffff0
+
+ .globl _disable_wdt
+ .type _disable_wdt,function
+
+_disable_wdt: # lock WDT via passwd access
+ movh %d2,hi:WDTMASK
+ addi %d2,%d2,lo:WDTMASK # %d2 = 0xffffff03
+ movh %d5,hi:WDTMASK2 # %d5 = 0xfffffff0
+ addi %d5,%d5,lo:WDTMASK2
+ mov %d6,0x8 # %d6 = "disable WDT"
+ st.w $wdtcon1,%d6 # WDTCON1.WDTDR = 1
+
+ ld.w %d0,$wdtcon0 # %d0 = *WDTCON0
+ ld.w %d1,$wdtcon1 # %d1 = *WDTCON1
+
+ and %d3,%d2,%d0 # %d3 = WDTCON0 & 0xffffff03
+ or %d3,%d3,0xf0 # %d3 |= 0xf0
+ and %d4,%d1,0xc
+ or %d3,%d3,%d4 # %d3 |= (WDTCON1 & 0xc)
+ xor %d3,%d3,0x2 # %d3 ^= 0x2
+ st.w $wdtcon0,%d3 # WDTCON = %d3
+ and %d3,%d3,%d5 # %d3 &= 0xfffffff0
+ or %d3,%d3,0x3 # WDTCON0.{WDTLCK,ENDINIT} = 1
+ st.w $wdtcon0,%d3 # write back new value
+ ld.w %d0,$wdtcon0 # ensure that value is written
+
+ ji %a11
+
+
+
+ /*
+ * initialize context save areas (CSAs), PCXI, LCX and FCX
+ */
+
+ .globl __init_csa
+ .type __init_csa,function
+
+__init_csa:
+ movh %d0,0
+ mtcr $pcxi,%d0
+ isync
+ movh %d0,hi:__CSA_BEGIN #; %d0 = begin of CSA
+ addi %d0,%d0,lo:__CSA_BEGIN
+ addi %d0,%d0,63 #; force alignment (2^6)
+ andn %d0,%d0,63
+ movh %d2,hi:__CSA_END #; %d2 = end of CSA
+ addi %d2,%d2,lo:__CSA_END
+ andn %d2,%d2,63 #; force alignment (2^6)
+ sub %d2,%d2,%d0
+ sh %d2,%d2,-6 #; %d2 = number of CSAs
+ mov.a %a3,%d0 #; %a3 = address of first CSA
+ extr.u %d0,%d0,28,4 #; %d0 = segment << 16
+ sh %d0,%d0,16
+ lea %a4,0 #; %a4 = previous CSA = 0
+ st.a [%a3], %a4 #; store it in 1st CSA
+ mov.aa %a4,%a3 #; %a4 = current CSA
+ lea %a3,[%a3]64 #; %a3 = %a3->nextCSA
+ mov.d %d1,%a3
+ extr.u %d1,%d1,6,16 #; get CSA index
+ or %d1,%d1,%d0 #; add segment number
+ mtcr $lcx,%d1 #; initialize LCX
+ add %d2,%d2,-2 #; CSAs to initialize -= 2
+ mov.a %a5, %d2 #; %a5 = loop counter
+csa_loop:
+ mov.d %d1,%a4 #; %d1 = current CSA address
+ extr.u %d1,%d1,6,16 #; get CSA index
+ or %d1,%d1,%d0 #; add segment number
+ st.w [%a3],%d1 #; store "nextCSA" pointer
+ mov.aa %a4,%a3 #; %a4 = current CSA address
+ lea %a3,[%a3]64 #; %a3 = %a3->nextCSA
+ loop %a5, csa_loop #; repeat until done
+
+ mov.d %d1,%a4 #; %d1 = current CSA address
+ extr.u %d1,%d1,6,16 #; get CSA index
+ or %d1,%d1,%d0 #; add segment number
+ mtcr $fcx,%d1 #; initialize FCX
+ isync
+ ji %a11
+
+
+
+ .global asm_clear_endinit
+ .type asm_clear_endinit,@function
+
+asm_clear_endinit:
+ ld.w %d0,$wdtcon0 # %d0 = *WDTCON0
+ ld.w %d1,$wdtcon1 # %d1 = *WDTCON1
+
+ movh %d2,hi:WDTMASKA
+ addi %d2,%d2,lo:WDTMASKA # %d2 = 0xffffff01
+
+ and %d0,%d2,%d0
+ or %d0,%d0,240
+ and %d4,%d1,12
+ or %d0,%d4,%d0
+ st.w $wdtcon0,%d0
+
+ movh %d4,hi:WDTMASK2 # %d4 = 0xfffffff0
+ addi %d4,%d4,lo:WDTMASK2
+ and %d0,%d4,%d0
+ or %d0,%d0,2 # ENDINIT = 0
+ isync
+ st.w $wdtcon0,%d0
+ ld.w %d0,$wdtcon0 # ensure that value is written
+
+ ji %a11
+
+
+
+ /*
+ * handle clear table (i.e., fill BSS with zeros)
+ */
+ .global __clear_table_func
+ .type __clear_table_func,@function
+
+__clear_table_func:
+ mov %d14,0 # %e14 = 0
+ mov %d15,0
+ movh.a %a13,hi:__clear_table # %a13 = &first table entry
+ lea %a13,[%a13]lo:__clear_table
+
+__clear_table_next:
+ ld.a %a15,[%a13+]4 # %a15 = current block base
+ ld.w %d3,[%a13+]4 # %d3 = current block length
+ jeq %d3,-1,__clear_table_done # length == -1 => end of table
+ sh %d0,%d3,-3 # %d0 = length / 8 (doublewords)
+ and %d1,%d3,7 # %d1 = length % 8 (rem. bytes)
+ jz %d0,__clear_word # block size < 8 => clear word
+ addi %d0,%d0,-1 # else doublewords -= 1
+ mov.a %a2,%d0 # %a2 = loop counter
+__clear_dword:
+ st.d [%a15+]8,%e14 # clear one doubleword
+ loop %a2,__clear_dword
+__clear_word:
+ jz %d1,__clear_table_next
+ sh %d0,%d1,-2 # %d0 = length / 4 (words)
+ and %d1,%d1,3 # %d1 = length % 4 (rem. bytes)
+ jz %d0,__clear_hword # block size < 4 => clear hword
+ st.w [%a15+]4,%d15 # clear one word
+__clear_hword:
+ jz %d1,__clear_table_next
+ sh %d0,%d1,-1 # %d0 = length / 2 (halfwords)
+ and %d1,%d1,1 # %d1 = length % 2 (rem. bytes)
+ jz %d0,__clear_byte # block size < 2 => clear byte
+ st.h [%a15+]2,%d15 # clear one halfword
+__clear_byte:
+ jz %d1,__clear_table_next
+ st.b [%a15],%d15 # clear one byte
+ j __clear_table_next # handle next clear table entry
+__clear_table_done:
+
+ ji %a11
+
+
+
+ /*
+ * handle copy table (support for romable code)
+ */
+ .global __copy_table_func
+ .type __copy_table_func,@function
+
+__copy_table_func:
+ movh.a %a13,hi:__copy_table # %a13 = &first table entry
+ lea %a13,[%a13]lo:__copy_table
+
+__copy_table_next:
+ ld.a %a15,[%a13+]4 # %a15 = src address
+ ld.a %a14,[%a13+]4 # %a14 = dst address
+ ld.w %d3,[%a13+]4 # %d3 = block length
+ jeq %d3,-1,__copy_table_done # length == -1 => end of table
+ sh %d0,%d3,-3 # %d0 = length / 8 (doublewords)
+ and %d1,%d3,7 # %d1 = lenght % 8 (rem. bytes)
+ jz %d0,__copy_word # block size < 8 => copy word
+ addi %d0,%d0,-1 # else doublewords -= 1
+ mov.a %a2,%d0 # %a2 = loop counter
+__copy_dword:
+ ld.d %e14,[%a15+]8 # copy one doubleword
+ st.d [%a14+]8,%e14
+ loop %a2,__copy_dword
+__copy_word:
+ jz %d1,__copy_table_next
+ sh %d0,%d1,-2 # %d0 = length / 4 (words)
+ and %d1,%d1,3 # %d1 = lenght % 4 (rem. bytes)
+ jz %d0,__copy_hword # block size < 4 => copy hword
+ ld.w %d14,[%a15+]4 # copy one word
+ st.w [%a14+]4,%d14
+__copy_hword:
+ jz %d1,__copy_table_next
+ sh %d0,%d1,-1 # %d0 = length / 2 (halfwords)
+ and %d1,%d1,1 # %d1 = lenght % 2 (rem. bytes)
+ jz %d0,__copy_byte # block size < 2 => copy byte
+ ld.h %d14,[%a15+]2 # copy one halfword
+ st.h [%a14+]2,%d14
+__copy_byte:
+ jz %d1,__copy_table_next
+ ld.b %d14,[%a15]0 # copy one byte
+ st.b [%a14],%d14
+ j __copy_table_next # handle next copy table entry
+__copy_table_done:
+
+ ji %a11
+
+
+/*
+ * dummy board initilization function
+ .global __board_init
+ .weak __board_init
+
+__board_init:
+ ji %a11
+ */
+
+ .global boardSetupTabSize
+ .weak boardSetupTabSize
+ .global boardSetupTab
+ .weak boardSetupTab
+boardSetupTab:
+boardSetupTabSize:
+
+
+ .global __board_init
+ .type __board_init,@function
+__board_init:
+ .code32
+
+#;
+#; initialize target environment (PLLCLC, BUSCONx, ADDSELx)
+#;
+#; this is done by board specific setup table (address/value - pairs)
+#;
+
+ movh.a %a15,hi:boardSetupTabSize
+ lea %a15,[%a15]lo:boardSetupTabSize # %a14 address of table size
+ movh.a %a14,hi:boardSetupTab
+ lea %a14,[%a14]lo:boardSetupTab # %a14 address of setup table
+ jeq.a %a14, %a15, no_setup
+
+ ld.a %a15,[%a15]0 # %a15 = table size
+ jz.a %a15,no_setup
+ add.a %a15,-1 # correction for loop
+setup_loop:
+ ld.a %a2,[%a14+] # %a2 = boardSetupTab.addr
+ ld.w %d2,[%a14+] # %d2 = boardSetupTab.val
+ st.w [%a2],%d2
+ loop %a15,setup_loop
+
+ isync
+ nop
+ nop
+
+no_setup:
+
+ ji %a11
+
+/*============================================================================*
+ * Exception handlers (exceptions in startup code)
+ *
+ * This is a minimal trap vector table, which consists of eight
+ * entries, each consisting of eight words (32 bytes).
+ *============================================================================*/
+
+
+#; .section .traptab, "awx", @progbits
+
+.macro trapentry from=0, to=7
+ debug
+ mov.u %d14, \from << 8
+ add %d14, %d14, %d15
+ mov.a %a14, %d14
+ addih.a %a14, %a14,0xdead
+ j _exit
+ 0: j 0b
+ nop
+ rfe
+ .align 5
+ .if \to-\from
+ trapentry "(\from+1)",\to
+ .endif
+ .endm
+
+ .align 8
+ .globl first_trap_table
+first_trap_table:
+ trapentry 0, 7
+
+
diff --git a/Target/Source/TRICORE_TC1798/GCC/crtn.S b/Target/Source/TRICORE_TC1798/GCC/crtn.S
new file mode 100644
index 00000000..eb882608
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/GCC/crtn.S
@@ -0,0 +1,40 @@
+# Copyright (C) 1998-2012 HighTec EDV-Systeme GmbH.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# Under Section 7 of GPL version 3, you are granted additional
+# permissions described in the GCC Runtime Library Exception, version
+# 3.1, as published by the Free Software Foundation.
+#
+# You should have received a copy of the GNU General Public License and
+# a copy of the GCC Runtime Library Exception along with this program;
+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+# . */
+
+# This file just makes sure that the .fini and .init sections do in
+# fact return. Users may put any desired instructions in those sections.
+# This file is the last thing linked into any executable.
+
+# On the tricore we have just to return
+
+ .file "crtn.S"
+
+ .section ".init"
+ ;;
+ ret
+
+ .section ".fini"
+ ;;
+ ret
+
+# end of crtn.asm
diff --git a/Target/Source/TRICORE_TC1798/GCC/memory.x b/Target/Source/TRICORE_TC1798/GCC/memory.x
new file mode 100644
index 00000000..17d977eb
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/GCC/memory.x
@@ -0,0 +1,656 @@
+
+/*
+ * Name: memory.x
+ *
+ * Generated Linker Description File
+ * Copyright (C) 2010 HighTec EDV-Systeme GmbH.
+ * (!Do not edit outsite of the protection areas!)
+ *
+ * Description:
+ * internal flash configuration
+ */
+
+/*
+ * Define Entrypoint of Executable
+ */
+ENTRY(_start)
+
+/*
+ * Global
+ */
+/*Program Flash Memory (PFLASH0)*/
+__PMU_PFLASH0_BEGIN = 0x80000000;
+__PMU_PFLASH0_SIZE = 2M;
+/*Program Flash Memory (PFLASH1)*/
+__PMU_PFLASH1_BEGIN = 0x80800000;
+__PMU_PFLASH1_SIZE = 2M;
+/*Data Flash Memory (DFLASH0)*/
+__PMU_DFLASH0_BEGIN = 0xAF000000;
+__PMU_DFLASH0_SIZE = 96K;
+/*Data Flash Memory (DFLASH1)*/
+__PMU_DFLASH1_BEGIN = 0xAF080000;
+__PMU_DFLASH1_SIZE = 96K;
+/*Boot ROM (BROM)*/
+__BROM_BEGIN = 0xAFFFC000;
+__BROM_SIZE = 16K;
+/*Scratch-Pad RAM (PSPR)*/
+__PMI_PSPR_BEGIN = 0xC0000000;
+__PMI_PSPR_SIZE = 32K;
+/*Local Data RAM (DSPR)*/
+__DMI_DSPR_BEGIN = 0xD0000000;
+__DMI_DSPR_SIZE = 128K;
+/*PCP Code Memory (CMEM)*/
+__PCP_CMEM_BEGIN = 0xF0060000;
+__PCP_CMEM_SIZE = 32K;
+/*PCP Data Memory (PRAM)*/
+__PCP_PRAM_BEGIN = 0xF0050000;
+__PCP_PRAM_SIZE = 16K;
+/*External Code Memory*/
+__EXT_FLASH_BEGIN = 0x84000000;
+__EXT_FLASH_SIZE = 4M;
+/*External Data Memory*/
+__EXT_RAM_BEGIN = 0x83000000;
+__EXT_RAM_SIZE = 1M;
+
+
+__USTACK_SIZE = DEFINED (__USTACK_SIZE) ? __USTACK_SIZE : 1K; /* Section for ustack*/
+__ISTACK_SIZE = DEFINED (__ISTACK_SIZE) ? __ISTACK_SIZE : 256; /* Section for istack*/
+__HEAP_SIZE = DEFINED (__HEAP_SIZE) ? __HEAP_SIZE : 4K; /* Section for heap*/
+__CSA_SIZE = DEFINED (__CSA_SIZE) ? __CSA_SIZE : 16K; /* Section for CSA*/
+
+/**
+ * User defined global region
+ */
+/*PROTECTED REGION ID(Protection:iROM-Global) ENABLED START*/
+/*Protection-Area for your own LDF-Code*/
+/*PROTECTED REGION END*/
+
+/*
+ * internal flash configuration
+ */
+MEMORY
+{
+ PMU_PFLASH0 (rx!p): org = 0x80000000, len = 2M /*Program Flash Memory (PFLASH0)*/
+ PMU_PFLASH1 (rx!p): org = 0x80800000, len = 2M /*Program Flash Memory (PFLASH1)*/
+ PMU_DFLASH0 (r!xp): org = 0xAF000000, len = 96K /*Data Flash Memory (DFLASH0)*/
+ PMU_DFLASH1 (r!xp): org = 0xAF080000, len = 96K /*Data Flash Memory (DFLASH1)*/
+ BROM (rx!p): org = 0xAFFFC000, len = 16K /*Boot ROM (BROM)*/
+ PMI_PSPR (wx!p): org = 0xC0000000, len = 32K /*Scratch-Pad RAM (PSPR)*/
+ DMI_DSPR (w!xp): org = 0xD0000000, len = 128K /*Local Data RAM (DSPR)*/
+ PCP_CMEM (rxp): org = 0xF0060000, len = 32K /*PCP Code Memory (CMEM)*/
+ PCP_PRAM (wp!x): org = 0xF0050000, len = 16K /*PCP Data Memory (PRAM)*/
+ EXT_FLASH (rx): org = 0x84000000, len = 4M /*External Code Memory*/
+ EXT_RAM (w!x): org = 0x83000000, len = 1M /*External Data Memory*/
+
+}
+
+SECTIONS
+{
+ /*Code-Sections*/
+
+ /*
+ * Startup code for TriCore
+ */
+ .startup_code :
+ {
+ PROVIDE(__startup_code_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .startup_code.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.startup_code) /*Startup code for TriCore*/
+ *(.startup_code*)
+
+ /*PROTECTED REGION ID(Protection: iROM .startup_code) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__startup_code_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Code section
+ */
+ .text :
+ {
+ PROVIDE(__text_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .text.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.text) /*Code section*/
+ *(.text*)
+ *(.gnu.linkonce.t.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .text) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__text_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Code executed before calling main
+ */
+ .init :
+ {
+ PROVIDE(__init_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .init.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ KEEP(*(.init)) /*Code executed before calling main*/
+ KEEP(*(.init*))
+
+ /*PROTECTED REGION ID(Protection: iROM .init) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__init_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Code executed before exiting program
+ */
+ .fini :
+ {
+ PROVIDE(__fini_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .fini.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ KEEP(*(.fini)) /*Code executed before exiting program*/
+ KEEP(*(.fini*))
+
+ /*PROTECTED REGION ID(Protection: iROM .fini) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__fini_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Section for trap table
+ */
+ .traptab :
+ {
+ PROVIDE(__traptab_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .traptab.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.traptab) /*Section for trap table*/
+ *(.traptab*)
+
+ /*PROTECTED REGION ID(Protection: iROM .traptab) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__traptab_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Section for interrupt table
+ */
+ .inttab :
+ {
+ PROVIDE(__inttab_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .inttab.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.inttab) /*Section for interrupt table*/
+ *(.inttab*)
+
+ /*PROTECTED REGION ID(Protection: iROM .inttab) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__inttab_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Exception handling frame for C++ exceptions
+ */
+ .eh_frame :
+ {
+ PROVIDE(__eh_frame_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .eh_frame.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.eh_frame) /*Exception handling frame for C++ exceptions*/
+ *(.eh_frame*)
+
+ /*PROTECTED REGION ID(Protection: iROM .eh_frame) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__eh_frame_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+
+
+
+ /*Absolute Data-Sections*/
+
+ /*
+ * Initialised data addressed as absolute
+ */
+ .zdata :
+ {
+ PROVIDE(__zdata_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .zdata.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.zdata) /*Initialised data addressed as absolute*/
+ *(.zdata*)
+ *(.zdata.rodata) /*.zdata.rodata*/
+ *(.zdata.rodata*)
+ *(.zrodata) /*.zrodata*/
+ *(.zrodata*)
+ *(.gnu.linkonce.z.*)
+ *(.gnu.linkonce.zr.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .zdata) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__zdata_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR AT > PMU_PFLASH0 /* DMI_DSPR: Local Data RAM (DSPR) */ /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Not initialised data addressed as absolute
+ */
+ .zbss (NOLOAD) :
+ {
+ PROVIDE(__zbss_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .zbss.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.zbss) /*Not Initialised data addressed as absolute*/
+ *(.zbss*)
+ *(.gnu.linkonce.zb.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .zbss) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__zbss_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR /* DMI_DSPR: Local Data RAM (DSPR) */
+
+ /*
+ * Not initialised bit data
+ */
+ .bbss (NOLOAD) :
+ {
+ PROVIDE(__bbss_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .bbss.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.bbss) /*Not initialised bit data*/
+ *(.bbss*)
+
+ /*PROTECTED REGION ID(Protection: iROM .bbss) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__bbss_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR /* DMI_DSPR: Local Data RAM (DSPR) */
+
+ /*
+ * Bit variables
+ */
+ .bdata :
+ {
+ PROVIDE(__bdata_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .bdata.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.bdata) /*Bit variables*/
+ *(.bdata*)
+
+ /*PROTECTED REGION ID(Protection: iROM .bdata) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__bdata_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR AT > PMU_PFLASH0 /* DMI_DSPR: Local Data RAM (DSPR) */ /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+
+
+ /*Small Data-Sections*/
+
+ /*
+ * Storage of write-protected data addressed as small
+ */
+ .sdata2 :
+ {
+ PROVIDE(__sdata2_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .sdata2.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.sdata.rodata) /*Storage of write-protected data addressed as small*/
+ *(.sdata.rodata*)
+ *(.gnu.linkonce.sr.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .sdata2) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__sdata2_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Section stores initialised data which is addressable by small data area pointer (%a0)
+ */
+ .sdata :
+ {
+ PROVIDE(__sdata_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .sdata.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.sdata) /*Section stores initialised data which is addressable by small data area pointer (%a0)*/
+ *(.sdata*)
+ *(.gnu.linkonce.s.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .sdata) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__sdata_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR AT > PMU_PFLASH0 /* DMI_DSPR: Local Data RAM (DSPR) */ /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Not initialised data in section ’.sbss’, addressable by small data area pointer (%a0)
+ */
+ .sbss (NOLOAD) :
+ {
+ PROVIDE(__sbss_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .sbss.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.sbss) /*Not initialised data in section ’.sbss’, addressable by small data area pointer (%a0)*/
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .sbss) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__sbss_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR /* DMI_DSPR: Local Data RAM (DSPR) */
+
+
+
+ /*Normal Data-Sections*/
+
+ /*
+ * Storage of write-protected data
+ */
+ .rodata :
+ {
+ PROVIDE(__rodata_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .rodata.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.rodata) /*Storage of write-protected data*/
+ *(.rodata*)
+ *(.gnu.linkonce.r.*)
+ *(.jcr.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .rodata) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__rodata_end = .);
+ . = ALIGN(8);
+
+ } > PMU_PFLASH0 /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Initialised data
+ */
+ .data :
+ {
+ PROVIDE(__data_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .data.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.data) /*Initialised data*/
+ *(.data*)
+ *(.gnu.linkonce.d.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .data) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__data_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR AT > PMU_PFLASH0 /* DMI_DSPR: Local Data RAM (DSPR) */ /* PMU_PFLASH0: Program Flash Memory (PFLASH0) */
+
+ /*
+ * Not Initialised data
+ */
+ .bss (NOLOAD) :
+ {
+ PROVIDE(__bss_start = .);
+
+ /*PROTECTED REGION ID(Protection: iROM .bss.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ *(.bss) /*Not Initialised data*/
+ *(.bss*)
+ *(.gnu.linkonce.b.*)
+
+ /*PROTECTED REGION ID(Protection: iROM .bss) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+ PROVIDE(__bss_end = .);
+ . = ALIGN(8);
+
+ } > DMI_DSPR /* DMI_DSPR: Local Data RAM (DSPR) */
+
+
+
+
+
+ /*
+ * Section for constructors
+ */
+ .ctors :
+ {
+ __CTOR_LIST__ = . ;
+
+ /*PROTECTED REGION ID(Protection: iROMconstructor.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2);
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ LONG(0) ;
+ /*PROTECTED REGION ID(Protection: iROMconstructor) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ __CTOR_END__ = . ;
+ . = ALIGN(8);
+ } > PMU_PFLASH0
+
+
+ /*
+ * Section for destructors
+ */
+ .dtors :
+ {
+ __DTOR_LIST__ = . ;
+ /*PROTECTED REGION ID(Protection: iROM destructor.begin) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2);
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ LONG(0) ;
+ /*PROTECTED REGION ID(Protection: iROM destructor) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ __DTOR_END__ = . ;
+ . = ALIGN(8);
+ } > PMU_PFLASH0
+
+
+ /*
+ * Section for clear table
+ */
+ .clear_sec :
+ {
+ . = ALIGN(8);
+ PROVIDE(__clear_table = .) ;
+ LONG(0 + ADDR(.bss)); LONG(SIZEOF(.bss));
+ LONG(0 + ADDR(.sbss)); LONG(SIZEOF(.sbss));
+ LONG(0 + ADDR(.zbss)); LONG(SIZEOF(.zbss));
+ LONG(0 + ADDR(.bbss)); LONG(SIZEOF(.bbss));
+ /*PROTECTED REGION ID(Protection: iROM clear section) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ LONG(-1); LONG(-1);
+ } > PMU_PFLASH0
+
+ /*
+ * Section for copy table
+ */
+ .copy_sec :
+ {
+ . = ALIGN(8);
+ PROVIDE(__copy_table = .) ;
+ LONG(LOADADDR(.data)); LONG(0 + ADDR(.data)); LONG(SIZEOF(.data));
+ LONG(LOADADDR(.sdata)); LONG(0 + ADDR(.sdata)); LONG(SIZEOF(.sdata));
+ LONG(LOADADDR(.zdata)); LONG(0 + ADDR(.zdata)); LONG(SIZEOF(.zdata));
+ LONG(LOADADDR(.bdata)); LONG(0 + ADDR(.bdata)); LONG(SIZEOF(.bdata));
+ /*PROTECTED REGION ID(Protection: iROM copy section) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+ LONG(-1); LONG(-1); LONG(-1);
+ } > PMU_PFLASH0
+
+
+ /*
+ * Section for ustack
+ */
+ .ustack :
+ {
+ . = ALIGN(8);
+ __USTACK_BEGIN = . ;
+ . += __USTACK_SIZE ;
+ . = ALIGN(8);
+ __USTACK = . ;
+ __USTACK_END = . ;
+ } > DMI_DSPR
+
+ /*
+ * Section for istack
+ */
+ .istack :
+ {
+ . = ALIGN(8);
+ __ISTACK_BEGIN = . ;
+ . += __ISTACK_SIZE ;
+ . = ALIGN(8);
+ __ISTACK = . ;
+ __ISTACK_END = . ;
+ } > DMI_DSPR
+
+ /*
+ * Section for heap
+ */
+ .heap :
+ {
+ . = ALIGN(8);
+ __HEAP_BEGIN = . ;
+ __HEAP = . ;
+ . += __HEAP_SIZE ;
+ . = ALIGN(8);
+ __HEAP_END = . ;
+ } > DMI_DSPR
+
+ /*
+ * Section for CSA
+ */
+ .csa :
+ {
+ . = ALIGN(64);
+ __CSA_BEGIN = . ;
+ __CSA = . ;
+ . += __CSA_SIZE ;
+ . = ALIGN(64);
+ __CSA_END = . ;
+ } > DMI_DSPR
+
+
+
+
+ /*PROTECTED REGION ID(Protection:iROM-User-Sections) ENABLED START*/
+ /*Protection-Area for your own LDF-Code*/
+ /*PROTECTED REGION END*/
+
+}
+
diff --git a/Target/Source/TRICORE_TC1798/cpu.c b/Target/Source/TRICORE_TC1798/cpu.c
new file mode 100644
index 00000000..9cb76457
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/cpu.c
@@ -0,0 +1,140 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\cpu.c
+* \brief Bootloader cpu module source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/** \brief Pointer to the user program's reset vector. */
+#define CPU_USER_PROGRAM_STARTADDR_PTR ((blt_addr)(FlashGetUserProgBaseAddress()))
+
+
+/****************************************************************************************
+* Hook functions
+****************************************************************************************/
+#if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0)
+extern blt_bool CpuUserProgramStartHook(void);
+#endif
+
+
+/****************************************************************************************
+* External functions
+****************************************************************************************/
+extern void _start(void); /* implemented in crt0-tc1x.S */
+
+
+/************************************************************************************//**
+** \brief Starts the user program, if one is present. In this case this function
+** does not return.
+** \return none.
+**
+****************************************************************************************/
+void CpuStartUserProgram(void)
+{
+ void (*pProgResetHandler)(void);
+
+ /* check if a user program is present by verifying the checksum */
+ if (NvmVerifyChecksum() == BLT_FALSE)
+ {
+ /* not a valid user program so it cannot be started */
+ return;
+ }
+ #if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0)
+ /* invoke callback */
+ if (CpuUserProgramStartHook() == BLT_FALSE)
+ {
+ /* callback requests the user program to not be started */
+ return;
+ }
+ #endif
+ #if (BOOT_COM_ENABLE > 0)
+ /* release the communication interface */
+ ComFree();
+ #endif
+ /* reset the timer */
+ TimerReset();
+ /* set the address where the bootloader needs to jump to. the user program entry,
+ * typically called _start, is expected to be located at the start of the user program
+ * flash.
+ */
+ pProgResetHandler = (void(*)(void))((blt_addr*)CPU_USER_PROGRAM_STARTADDR_PTR);
+ /* start the user program by activating its reset interrupt service routine */
+ pProgResetHandler();
+} /*** end of CpuStartUserProgram ***/
+
+
+/************************************************************************************//**
+** \brief Copies data from the source to the destination address.
+** \param dest Destination address for the data.
+** \param src Source address of the data.
+** \param len length of the data in bytes.
+** \return none.
+**
+****************************************************************************************/
+void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len)
+{
+ blt_int8u *from, *to;
+
+ /* set casted pointers */
+ from = (blt_int8u *)src;
+ to = (blt_int8u *)dest;
+
+ /* copy all bytes from source address to destination address */
+ while(len-- > 0)
+ {
+ /* store byte value from source to destination */
+ *to++ = *from++;
+ /* keep the watchdog happy */
+ CopService();
+ }
+} /*** end of CpuMemCopy ***/
+
+
+/************************************************************************************//**
+** \brief Perform a soft reset of the microcontroller by starting from the reset ISR.
+** \return none.
+**
+****************************************************************************************/
+void CpuReset(void)
+{
+ /* perform a software reset by calling the reset ISR routine */
+ _start();
+} /*** end of CpuReset ***/
+
+
+/*********************************** end of cpu.c **************************************/
diff --git a/Target/Source/TRICORE_TC1798/cpu.h b/Target/Source/TRICORE_TC1798/cpu.h
new file mode 100644
index 00000000..9d3953d8
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/cpu.h
@@ -0,0 +1,51 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\cpu.h
+* \brief Bootloader cpu module header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef CPU_H
+#define CPU_H
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "cpu_comp.h" /* compiler specific CPU definitions */
+
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void CpuStartUserProgram(void);
+void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len);
+void CpuReset(void);
+
+
+#endif /* CPU_H */
+/*********************************** end of cpu.h **************************************/
diff --git a/Target/Source/TRICORE_TC1798/flash.c b/Target/Source/TRICORE_TC1798/flash.c
new file mode 100644
index 00000000..31511243
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/flash.c
@@ -0,0 +1,967 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\flash.c
+* \brief Bootloader flash driver source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/** \brief Value for an invalid flash sector. */
+#define FLASH_INVALID_SECTOR (0xffu)
+
+/** \brief Value for an invalid flash address. */
+#define FLASH_INVALID_ADDRESS (0xffffffffu)
+
+/** \brief Standard size of a flash block for writing. */
+#define FLASH_WRITE_BLOCK_SIZE (256u)
+
+/** \brief Total numbers of sectors in array flashLayout[]. */
+#define FLASH_TOTAL_SECTORS (sizeof(flashLayout)/sizeof(flashLayout[0]))
+
+/** \brief The flash driver is setup to operate on the cached PFLASH addresses, whereas
+ * the actual PFLASH commands should operate on non-cached addresses. This
+ * macro defines the offset between cached (80xxxxxxh) and non-cached
+ * (A0xxxxxxh) addresses.
+ */
+#define FLASH_NON_CACHED_OFFSET (0x20000000u)
+
+/** \brief Base address of the PFLASH0 module. */
+#define FLASH_PFLASH0_BASE (0x80000000u)
+
+/** \brief Base address of the PFLASH1 module. */
+#define FLASH_PFLASH1_BASE (0x80800000u)
+
+/** \brief Base address of the PFLASH0 flash status register. */
+#define FLASH_PFLASH0_FSR_ADDR (0xF8002010u)
+
+/** \brief Base address of the PFLASH0 flash status register. */
+#define FLASH_PFLASH1_FSR_ADDR (0xF8004010u)
+
+/** \brief Macro that returns the PFLASHx modules base address, giving any address
+ * in PFLASH.
+ */
+#define FLASH_GET_PFLASH_BASE(addr) ((addr < FLASH_PFLASH1_BASE) ? \
+ FLASH_PFLASH0_BASE : FLASH_PFLASH1_BASE)
+
+/** \brief Macro that converts are 32 bit address into a pointer to a 32-bit unsigned
+ * value and writes a value to this pointer.
+ */
+#define FLASH_WRITE_TO_U32_PTR_BY_ADDR(addr, val) ((*((volatile blt_int32u *) (addr+FLASH_NON_CACHED_OFFSET))) = val)
+
+/** \brief The FLASHx_FSR register is the only register used in this driver. Its address
+ * depends on the PFLASH module that is being operated on. This macro gets the
+ * correct base address for the FSR register.
+ */
+#define FLASH_GET_FSR_REG_ADDR(addr) ((addr < FLASH_PFLASH1_BASE) ? \
+ FLASH_PFLASH0_FSR_ADDR : FLASH_PFLASH1_FSR_ADDR)
+
+/** \brief Offset in bytes from the bootblock's base address where the checksum is
+ * located.
+ */
+#define FLASH_CS_OFFSET (0x04u)
+
+/** \brief Offset in bytes from the bootblock's base address where the checksum area
+ * starts.
+ */
+#define FLASH_CS_RANGE_START_OFFSET (0x08u)
+
+/** \brief The total number of 32-bit words that are in the checksum address range. */
+#define FLASH_CS_RANGE_TOTAL_WORDS ((FLASH_WRITE_BLOCK_SIZE/4u) - \
+ (FLASH_CS_RANGE_START_OFFSET/4u))
+
+
+/****************************************************************************************
+* Type definitions
+****************************************************************************************/
+/** \brief Flash sector descriptor type. */
+typedef struct
+{
+ blt_addr sector_start; /**< sector start address */
+ blt_int32u sector_size; /**< sector size in bytes */
+ blt_int8u sector_num; /**< sector number */
+} tFlashSector;
+
+/** \brief Structure type for grouping flash block information.
+ * \details Programming is done per block of max FLASH_WRITE_BLOCK_SIZE. for this a
+ * flash block manager is implemented in this driver. this flash block manager
+ * depends on this flash block info structure. It holds the base address of
+ * the flash block and the data that should be programmed into the flash
+ * block. The .base_addr must be a multiple of FLASH_WRITE_BLOCK_SIZE.
+ */
+typedef struct
+{
+ blt_addr base_addr;
+ blt_int8u data[FLASH_WRITE_BLOCK_SIZE];
+} tFlashBlockInfo;
+
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+static blt_bool FlashInitBlock(tFlashBlockInfo *block, blt_addr address);
+static tFlashBlockInfo *FlashSwitchBlock(tFlashBlockInfo *block, blt_addr base_addr);
+static blt_bool FlashAddToBlock(tFlashBlockInfo *block, blt_addr address,
+ blt_int8u *data, blt_int32u len);
+static blt_bool FlashWriteBlock(tFlashBlockInfo *block);
+static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector);
+static blt_int8u FlashGetSector(blt_addr address);
+static blt_addr FlashGetSectorBaseAddr(blt_int8u sector);
+static blt_int32u FlashGetSectorSize(blt_int8u sector);
+static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data);
+static blt_bool FlashTricoreEraseSector(blt_addr start_addr);
+
+
+/****************************************************************************************
+* Local constant declarations
+****************************************************************************************/
+/** \brief Array wit the layout of the flash memory.
+ * \details The current implementation assumes that the bootloader is in the 2Mbyte
+ * PFLASH0 and supports flash operations only on the 2Mbyte PFLASH1. The reason
+ * for this is that a flash module cannot be in read mode and command mode at
+ * the same time. A future improvement is one where the actual flash command
+ * code is copied and run from RAM, to bypass this restriction.
+ */
+static const tFlashSector flashLayout[] =
+{
+ { 0x80800000, 0x04000, 0}, /* flash sector 0 - 16kb */
+ { 0x80804000, 0x04000, 1}, /* flash sector 1 - 16kb */
+ { 0x80808000, 0x04000, 2}, /* flash sector 2 - 16kb */
+ { 0x8080C000, 0x04000, 3}, /* flash sector 3 - 16kb */
+ { 0x80810000, 0x04000, 4}, /* flash sector 4 - 16kb */
+ { 0x80814000, 0x04000, 5}, /* flash sector 5 - 16kb */
+ { 0x80818000, 0x04000, 6}, /* flash sector 6 - 16kb */
+ { 0x8081C000, 0x04000, 7}, /* flash sector 7 - 16kb */
+ { 0x80820000, 0x20000, 8}, /* flash sector 8 - 128kb */
+ { 0x80840000, 0x40000, 9}, /* flash sector 9 - 256kb */
+ { 0x80880000, 0x40000, 10}, /* flash sector 10 - 256kb */
+ { 0x808C0000, 0x40000, 11}, /* flash sector 11 - 256kb */
+ { 0x80900000, 0x40000, 12}, /* flash sector 12 - 256kb */
+ { 0x80940000, 0x40000, 13}, /* flash sector 13 - 256kb */
+ { 0x80980000, 0x40000, 14}, /* flash sector 14 - 256kb */
+ { 0x809C0000, 0x40000, 15}, /* flash sector 15 - 256kb */
+#if (BOOT_NVM_SIZE_KB > 2048)
+#error "BOOT_NVM_SIZE_KB > 2048 is currently not supported."
+#endif
+};
+
+
+/****************************************************************************************
+* Local data declarations
+****************************************************************************************/
+/** \brief Local variable with information about the flash block that is currently
+ * being operated on.
+ * \details The smallest amount of flash that can be programmed is
+ * FLASH_WRITE_BLOCK_SIZE. A flash block manager is implemented in this driver
+ * and stores info in this variable. Whenever new data should be flashed, it
+ * is first added to a RAM buffer, which is part of this variable. Whenever
+ * the RAM buffer, which has the size of a flash block, is full or data needs
+ * to be written to a different block, the contents of the RAM buffer are
+ * programmed to flash. The flash block manager requires some software
+ * overhead, yet results is faster flash programming because data is first
+ * harvested, ideally until there is enough to program an entire flash block,
+ * before the flash device is actually operated on.
+ */
+static tFlashBlockInfo blockInfo;
+
+/** \brief Local variable with information about the flash boot block.
+ * \details The first block of the user program holds the vector table, which on the
+ * STM32 is also the where the checksum is written to. Is it likely that
+ * the vector table is first flashed and then, at the end of the programming
+ * sequence, the checksum. This means that this flash block need to be written
+ * to twice. Normally this is not a problem with flash memory, as long as you
+ * write the same values to those bytes that are not supposed to be changed
+ * and the locations where you do write to are still in the erased 0xFF state.
+ * Unfortunately, writing twice to flash this way, does not work reliably on
+ * all micros. This is why we need to have an extra block, the bootblock,
+ * placed under the management of the block manager. This way is it possible
+ * to implement functionality so that the bootblock is only written to once
+ * at the end of the programming sequence.
+ */
+static tFlashBlockInfo bootBlockInfo;
+
+
+/************************************************************************************//**
+** \brief Initializes the flash driver.
+** \return none.
+**
+****************************************************************************************/
+void FlashInit(void)
+{
+ /* init the flash block info structs by setting the address to an invalid address */
+ blockInfo.base_addr = FLASH_INVALID_ADDRESS;
+ bootBlockInfo.base_addr = FLASH_INVALID_ADDRESS;
+} /*** end of FlashInit ***/
+
+
+/************************************************************************************//**
+** \brief Writes the data to flash through a flash block manager. Note that this
+** function also checks that no data is programmed outside the flash
+** memory region, so the bootloader can never be overwritten.
+** \param addr Start address.
+** \param len Length in bytes.
+** \param data Pointer to the data buffer.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data)
+{
+ blt_addr base_addr;
+
+ /* make sure the addresses are within the flash device */
+ if ( (FlashGetSector(addr) == FLASH_INVALID_SECTOR) || \
+ (FlashGetSector(addr+len-1) == FLASH_INVALID_SECTOR) )
+ {
+ return BLT_FALSE;
+ }
+
+ /* if this is the bootblock, then let the boot block manager handle it */
+ base_addr = (addr/FLASH_WRITE_BLOCK_SIZE)*FLASH_WRITE_BLOCK_SIZE;
+ if (base_addr == flashLayout[0].sector_start)
+ {
+ /* let the boot block manager handle it */
+ return FlashAddToBlock(&bootBlockInfo, addr, data, len);
+ }
+ /* let the block manager handle it */
+ return FlashAddToBlock(&blockInfo, addr, data, len);
+} /*** end of FlashWrite ***/
+
+
+/************************************************************************************//**
+** \brief Erases the flash memory. Note that this function also checks that no
+** data is erased outside the flash memory region, so the bootloader can
+** never be erased.
+** \param addr Start address.
+** \param len Length in bytes.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool FlashErase(blt_addr addr, blt_int32u len)
+{
+ blt_int8u first_sector;
+ blt_int8u last_sector;
+
+ /* obtain the first and last sector number */
+ first_sector = FlashGetSector(addr);
+ last_sector = FlashGetSector(addr+len-1);
+ /* check them */
+ if ( (first_sector == FLASH_INVALID_SECTOR) || (last_sector == FLASH_INVALID_SECTOR) )
+ {
+ return BLT_FALSE;
+ }
+ /* erase the sectors */
+ return FlashEraseSectors(first_sector, last_sector);
+} /*** end of FlashErase ***/
+
+
+/************************************************************************************//**
+** \brief Writes a checksum of the user program to non-volatile memory. This is
+** performed once the entire user program has been programmed. Through
+** the checksum, the bootloader can check if the programming session
+** was completed, which indicates that a valid user programming is
+** present and can be started.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool FlashWriteChecksum(void)
+{
+ blt_int32u signature_checksum = 0;
+ blt_int8u wordIdx;
+
+ /* for the Tricore TC1798 target, the bootlblock is FLASH_WRITE_BLOCK_SIZE in size.
+ * the actual 32-bit checksum value in this bootblock is located at:
+ * + 4.
+ * for this reason the checksum is defined as the one's complement value of the sum
+ * of everything else in the bootblock, so starting at:
+ * + 8 and ending at:
+ * + FLASH_WRITE_BLOCK_SIZE - 1;
+ *
+ * note that the user program need to be modified to reserve 32-bit at
+ * + 4, because the bootload will write the checksum value
+ * here. refer to the port specific documentation for additional details.
+ *
+ * keep in mind that this checksum is just used as a user program signature, i.e. as
+ * a flag to figure out if a user program is present or not. the checksum is not
+ * calculated over the full user program size. such a checksum routine is typically
+ * application/customer specific and therefore not part of the standard bootloader.
+ * it can however be easily implemented by adding the following macro to blt_conf.h:
+ * #define BOOT_NVM_CHECKSUM_HOOKS_ENABLE (1).
+ * You can then implement your own checksum write/verify routines in the hook
+ * functions NvmWriteChecksumHook() and NvmVerifyChecksumHook().
+ */
+
+ /* first check that the bootblock contains valid data. if not, this means the
+ * bootblock is not part of the reprogramming this time and therefore no
+ * new checksum needs to be written
+ */
+ if (bootBlockInfo.base_addr == FLASH_INVALID_ADDRESS)
+ {
+ return BLT_TRUE;
+ }
+
+ /* compute the checksum. note that the data in the checksum range is not yet written
+ * to flash but is present in the bootblock data structure at this point.
+ */
+ for (wordIdx = 0; wordIdx < FLASH_CS_RANGE_TOTAL_WORDS; wordIdx++)
+ {
+ signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[(wordIdx*4)+FLASH_CS_RANGE_START_OFFSET]));
+ }
+ signature_checksum = ~signature_checksum; /* one's complement */
+
+ /* write the checksum */
+ return FlashWrite(flashLayout[0].sector_start+FLASH_CS_OFFSET,
+ sizeof(blt_addr), (blt_int8u*)&signature_checksum);
+} /*** end of FlashWriteChecksum ***/
+
+
+/************************************************************************************//**
+** \brief Verifies the checksum, which indicates that a valid user program is
+** present and can be started.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool FlashVerifyChecksum(void)
+{
+ blt_int32u signature_checksum = 0;
+ blt_int32u signature_checksum_rom;
+ blt_int8u wordIdx;
+
+ /* compute the checksum by reading it from flash */
+ for (wordIdx = 0; wordIdx < FLASH_CS_RANGE_TOTAL_WORDS; wordIdx++)
+ {
+ signature_checksum += *((blt_int32u*)(flashLayout[0].sector_start + (wordIdx*4) + FLASH_CS_RANGE_START_OFFSET));
+ }
+ signature_checksum = ~signature_checksum; /* one's complement */
+
+ /* read the checksum value from flash that was writtin by the bootloader at the end
+ * of the last firmware update
+ */
+ signature_checksum_rom = *((blt_int32u*)(flashLayout[0].sector_start + FLASH_CS_OFFSET));
+ /* verify that they are both the same */
+ if (signature_checksum == signature_checksum_rom)
+ {
+ /* checksum okay */
+ return BLT_TRUE;
+ }
+ /* checksum incorrect */
+ return BLT_FALSE;
+} /*** end of FlashVerifyChecksum ***/
+
+
+/************************************************************************************//**
+** \brief Finalizes the flash driver operations. There could still be data in
+** the currently active block that needs to be flashed.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool FlashDone(void)
+{
+ /* check if there is still data waiting to be programmed in the boot block */
+ if (bootBlockInfo.base_addr != FLASH_INVALID_ADDRESS)
+ {
+ if (FlashWriteBlock(&bootBlockInfo) == BLT_FALSE)
+ {
+ return BLT_FALSE;
+ }
+ }
+
+ /* check if there is still data waiting to be programmed */
+ if (blockInfo.base_addr != FLASH_INVALID_ADDRESS)
+ {
+ if (FlashWriteBlock(&blockInfo) == BLT_FALSE)
+ {
+ return BLT_FALSE;
+ }
+ }
+ /* still here so all is okay */
+ return BLT_TRUE;
+} /*** end of FlashDone ***/
+
+
+/************************************************************************************//**
+** \brief Obtains the base address of the flash memory available to the user program.
+** This is basically the first address in the flashLayout table.
+** \return Base address.
+**
+****************************************************************************************/
+blt_addr FlashGetUserProgBaseAddress(void)
+{
+ return flashLayout[0].sector_start;
+} /*** end of FlashGetUserProgBaseAddress ***/
+
+
+/************************************************************************************//**
+** \brief Copies data currently in flash to the block->data and sets the
+** base address.
+** \param block Pointer to flash block info structure to operate on.
+** \param address Base address of the block data.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool FlashInitBlock(tFlashBlockInfo *block, blt_addr address)
+{
+ /* check address alignment */
+ if ((address % FLASH_WRITE_BLOCK_SIZE) != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* make sure that we are initializing a new block and not the same one */
+ if (block->base_addr == address)
+ {
+ /* block already initialized, so nothing to do */
+ return BLT_TRUE;
+ }
+ /* set the base address and copies the current data from flash */
+ block->base_addr = address;
+ CpuMemCopy((blt_addr)block->data, address, FLASH_WRITE_BLOCK_SIZE);
+ return BLT_TRUE;
+} /*** end of FlashInitBlock ***/
+
+
+/************************************************************************************//**
+** \brief Switches blocks by programming the current one and initializing the
+** next.
+** \param block Pointer to flash block info structure to operate on.
+** \param base_addr Base address of the next block.
+** \return The pointer of the block info struct that is no being used, or a NULL
+** pointer in case of error.
+**
+****************************************************************************************/
+static tFlashBlockInfo *FlashSwitchBlock(tFlashBlockInfo *block, blt_addr base_addr)
+{
+ /* check if a switch needs to be made away from the boot block. in this case the boot
+ * block shouldn't be written yet, because this is done at the end of the programming
+ * session by FlashDone(), this is right after the checksum was written.
+ */
+ if (block == &bootBlockInfo)
+ {
+ /* switch from the boot block to the generic block info structure */
+ block = &blockInfo;
+ }
+ /* check if a switch back into the bootblock is needed. in this case the generic block
+ * doesn't need to be written here yet.
+ */
+ else if (base_addr == flashLayout[0].sector_start)
+ {
+ /* switch from the generic block to the boot block info structure */
+ block = &bootBlockInfo;
+ base_addr = flashLayout[0].sector_start;
+ }
+ else
+ {
+ /* need to switch to a new block, so program the current one and init the next */
+ if (FlashWriteBlock(block) == BLT_FALSE)
+ {
+ return BLT_NULL;
+ }
+ }
+
+ /* initialize tne new block when necessary */
+ if (FlashInitBlock(block, base_addr) == BLT_FALSE)
+ {
+ return BLT_NULL;
+ }
+
+ /* still here to all is okay */
+ return block;
+} /*** end of FlashSwitchBlock ***/
+
+
+/************************************************************************************//**
+** \brief Programming is done per block. This function adds data to the block
+** that is currently collecting data to be written to flash. If the
+** address is outside of the current block, the current block is written
+** to flash an a new block is initialized.
+** \param block Pointer to flash block info structure to operate on.
+** \param address Flash destination address.
+** \param data Pointer to the byte array with data.
+** \param len Number of bytes to add to the block.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool FlashAddToBlock(tFlashBlockInfo *block, blt_addr address,
+ blt_int8u *data, blt_int32u len)
+{
+ blt_addr current_base_addr;
+ blt_int8u *dst;
+ blt_int8u *src;
+
+ /* determine the current base address */
+ current_base_addr = (address/FLASH_WRITE_BLOCK_SIZE)*FLASH_WRITE_BLOCK_SIZE;
+
+ /* make sure the blockInfo is not uninitialized */
+ if (block->base_addr == FLASH_INVALID_ADDRESS)
+ {
+ /* initialize the blockInfo struct for the current block */
+ if (FlashInitBlock(block, current_base_addr) == BLT_FALSE)
+ {
+ return BLT_FALSE;
+ }
+ }
+
+ /* check if the new data fits in the current block */
+ if (block->base_addr != current_base_addr)
+ {
+ /* need to switch to a new block, so program the current one and init the next */
+ block = FlashSwitchBlock(block, current_base_addr);
+ if (block == BLT_NULL)
+ {
+ return BLT_FALSE;
+ }
+ }
+
+ /* add the data to the current block, but check for block overflow */
+ dst = &(block->data[address - block->base_addr]);
+ src = data;
+ do
+ {
+ /* keep the watchdog happy */
+ CopService();
+ /* buffer overflow? */
+ if ((blt_addr)(dst-&(block->data[0])) >= FLASH_WRITE_BLOCK_SIZE)
+ {
+ /* need to switch to a new block, so program the current one and init the next */
+ block = FlashSwitchBlock(block, current_base_addr+FLASH_WRITE_BLOCK_SIZE);
+ if (block == BLT_NULL)
+ {
+ return BLT_FALSE;
+ }
+ /* reset destination pointer */
+ dst = &(block->data[0]);
+ }
+ /* write the data to the buffer */
+ *dst = *src;
+ /* update pointers */
+ dst++;
+ src++;
+ /* decrement byte counter */
+ len--;
+ }
+ while (len > 0);
+ /* still here so all is good */
+ return BLT_TRUE;
+} /*** end of FlashAddToBlock ***/
+
+
+/************************************************************************************//**
+** \brief Programs FLASH_WRITE_BLOCK_SIZE bytes to flash from the block->data
+** array.
+** \param block Pointer to flash block info structure to operate on.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool FlashWriteBlock(tFlashBlockInfo *block)
+{
+ blt_int8u sector_num;
+
+ /* check that address is actually within flash */
+ sector_num = FlashGetSector(block->base_addr);
+ if (sector_num == FLASH_INVALID_SECTOR)
+ {
+ return BLT_FALSE;
+ }
+ /* the FLASH_WRITE_BLOCK_SIZE is configured to exactly match the size of a page in
+ * PFLASH. so here simply need to program one page in PFLASH.
+ */
+ return FlashTricoreProgramPage(block->base_addr, block->data);
+} /*** end of FlashWriteBlock ***/
+
+
+/************************************************************************************//**
+** \brief Erases the flash sectors from first_sector up until last_sector.
+** \param first_sector First flash sector number.
+** \param last_sector Last flash sector number.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool FlashEraseSectors(blt_int8u first_sector, blt_int8u last_sector)
+{
+ blt_int8u current_sector;
+ blt_bool result = BLT_TRUE;
+
+ /* validate the sector numbers */
+ if (first_sector > last_sector)
+ {
+ return BLT_FALSE;
+ }
+ if ( (first_sector < flashLayout[0].sector_num) || \
+ (last_sector > flashLayout[FLASH_TOTAL_SECTORS-1].sector_num) )
+ {
+ return BLT_FALSE;
+ }
+ /* the table flashLayout[] is implemented such that it exactly matches the sectors
+ * in PFLASH. this means that here we simply need to loop through the sectors one-
+ * by-one and erase them.
+ */
+ for (current_sector = first_sector; current_sector <= last_sector; current_sector++)
+ {
+ if (FlashTricoreEraseSector(FlashGetSectorBaseAddr(current_sector)) == BLT_FALSE)
+ {
+ /* flag error and stop the loop */
+ result = BLT_FALSE;
+ break;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* return the result */
+ return result;
+} /*** end of FlashEraseSectors ***/
+
+
+/************************************************************************************//**
+** \brief Determines the flash sector the address is in.
+** \param address Address in the flash sector.
+** \return Flash sector number or FLASH_INVALID_SECTOR.
+**
+****************************************************************************************/
+static blt_int8u FlashGetSector(blt_addr address)
+{
+ blt_int8u sectorIdx;
+
+ /* search through the sectors to find the right one */
+ for (sectorIdx = 0; sectorIdx < FLASH_TOTAL_SECTORS; sectorIdx++)
+ {
+ /* keep the watchdog happy */
+ CopService();
+ /* is the address in this sector? */
+ if ( (address >= flashLayout[sectorIdx].sector_start) && \
+ (address < (flashLayout[sectorIdx].sector_start + \
+ flashLayout[sectorIdx].sector_size)) )
+ {
+ /* return the sector number */
+ return flashLayout[sectorIdx].sector_num;
+ }
+ }
+ /* still here so no valid sector found */
+ return FLASH_INVALID_SECTOR;
+} /*** end of FlashGetSector ***/
+
+
+/************************************************************************************//**
+** \brief Determines the flash sector base address.
+** \param sector Sector to get the base address of.
+** \return Flash sector base address or FLASH_INVALID_ADDRESS.
+**
+****************************************************************************************/
+static blt_addr FlashGetSectorBaseAddr(blt_int8u sector)
+{
+ blt_int8u sectorIdx;
+
+ /* search through the sectors to find the right one */
+ for (sectorIdx = 0; sectorIdx < FLASH_TOTAL_SECTORS; sectorIdx++)
+ {
+ /* keep the watchdog happy */
+ CopService();
+ if (flashLayout[sectorIdx].sector_num == sector)
+ {
+ return flashLayout[sectorIdx].sector_start;
+ }
+ }
+ /* still here so no valid sector found */
+ return FLASH_INVALID_ADDRESS;
+} /*** end of FlashGetSectorBaseAddr ***/
+
+
+/************************************************************************************//**
+** \brief Determines the flash sector size.
+** \param sector Sector to get the size of.
+** \return Flash sector size or 0.
+**
+****************************************************************************************/
+static blt_int32u FlashGetSectorSize(blt_int8u sector)
+{
+ blt_int8u sectorIdx;
+
+ /* search through the sectors to find the right one */
+ for (sectorIdx = 0; sectorIdx < FLASH_TOTAL_SECTORS; sectorIdx++)
+ {
+ /* keep the watchdog happy */
+ CopService();
+ if (flashLayout[sectorIdx].sector_num == sector)
+ {
+ return flashLayout[sectorIdx].sector_size;
+ }
+ }
+ /* still here so no valid sector found */
+ return 0;
+} /*** end of FlashGetSectorSize ***/
+
+
+/************************************************************************************//**
+** \brief Programs FLASH_WRITE_BLOCK_SIZE bytes into flash starting at the page's base
+** address.
+** \param start_addr Starting address of the page where the bytes should be
+** programmed. Should be aligned to FLASH_WRITE_BLOCK_SIZE.
+** \param data Pointer to a byte array with the data to be programmed. The array
+** should have FLASH_WRITE_BLOCK_SIZE bytes.
+** \return BLT_TRUE is the page was programmed successfully, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool FlashTricoreProgramPage(blt_addr start_addr, blt_int8u *data)
+{
+ blt_addr baseAddr;
+ blt_int32u *dataPtr;
+ blt_int8u *readPtr;
+ blt_int32u idx;
+ FLASHn_FSR_t *pflashFSR;
+
+ /* check address alignment to a page in PFLASH */
+ if ((start_addr % FLASH_WRITE_BLOCK_SIZE) != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* determine base address of the PFLASH module */
+ baseAddr = FLASH_GET_PFLASH_BASE(start_addr);
+ /* set pointer for the PFLASH module's FSR register */
+ pflashFSR = (FLASHn_FSR_t *)FLASH_GET_FSR_REG_ADDR(start_addr);
+ /* use "clear status" command to clear flags */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x000000F5u);
+ /* execute "enter page mode" command to activate the PFLASH assembly buffer */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x00000050u);
+ /* perform DSYNC */
+ CpuSetDSYNC();
+ /* wait until FSR.xFPAGE = '1' */
+ while(pflashFSR->bits.PFPAGE != 1)
+ {
+ /* fail if FSR.SQER = '1' */
+ if (pflashFSR->bits.SQER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* fail if FSR.PROER = '1' */
+ if (pflashFSR->bits.PROER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* load FLASH_WRITE_BLOCK_SIZE bytes of program data into the assembly buffer */
+ dataPtr = (blt_int32u *)data;
+ for (idx = 0; idx <(FLASH_WRITE_BLOCK_SIZE/8u); idx++)
+ {
+ /* write first 32-bit value */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x55F0U, *dataPtr);
+ dataPtr++;
+ /* write second 32-bit value */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x55F4U, *dataPtr);
+ dataPtr++;
+ }
+ /* launch the "write page" command */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x000000AAu);
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0xAAA8u, 0x00000055u);
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x000000A0u);
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(start_addr, 0x000000AAu);
+ /* perform DSYNC */
+ CpuSetDSYNC();
+ /* wait until FSR.PROG = '1' */
+ while(pflashFSR->bits.PROG != 1)
+ {
+ /* fail if FSR.SQER = '1' */
+ if (pflashFSR->bits.SQER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* fail if FSR.PROER = '1' */
+ if (pflashFSR->bits.PROER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* wait until FSR.xBUSY = '0' */
+ while(pflashFSR->bits.PBUSY == 1)
+ {
+ /* check flag FSR.xFOPER for ‘1’ as abort criterion to protect against hardware
+ * failures causing BUSY to stay '1'
+ */
+ if (pflashFSR->bits.PFOPER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* check FSR.VER flag */
+ if (pflashFSR->bits.VER != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* fail if FSR.xFOPER = '1' */
+ if (pflashFSR->bits.PFOPER != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* evaluate FSR.xDBER */
+ if(pflashFSR->bits.PFDBER != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* use "clear status" command to clear flags */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x000000F5u);
+ /* perform verification by checking the written values. do this on a byte-per-byte
+ * basis to also check the code for byte swapping mistakes.
+ */
+ readPtr = (blt_int8u *)start_addr;
+ for (idx = 0; idx bits.ERASE != 1)
+ {
+ /* fail if FSR.SQER = '1' */
+ if (pflashFSR->bits.SQER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* fail if FSR.PROER = '1' */
+ if (pflashFSR->bits.PROER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* wait until FSR.xBUSY = '0' */
+ while(pflashFSR->bits.PBUSY == 1)
+ {
+ /* check flag FSR.xFOPER for ‘1’ as abort criterion to protect against hardware
+ * failures causing BUSY to stay '1'
+ */
+ if (pflashFSR->bits.PFOPER == 1)
+ {
+ return BLT_FALSE;
+ }
+ /* keep the watchdog happy */
+ CopService();
+ }
+ /* check FSR.VER flag */
+ if (pflashFSR->bits.VER != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* fail if FSR.xFOPER = '1' */
+ if (pflashFSR->bits.PFOPER != 0)
+ {
+ return BLT_FALSE;
+ }
+ /* use "clear status" command to clear flags */
+ FLASH_WRITE_TO_U32_PTR_BY_ADDR(baseAddr + 0x5554u, 0x000000F5u);
+
+ /* perform erase verification */
+ sectorNum = FlashGetSector(start_addr);
+ if (sectorNum == FLASH_INVALID_SECTOR)
+ {
+ /* should not happen */
+ return BLT_FALSE;
+ }
+ /* get sector size in words and set the read pointer to the first word in the sector */
+ sectorWords = FlashGetSectorSize(sectorNum) / sizeof(blt_int32u);
+ if (sectorWords == 0)
+ {
+ /* should not happen */
+ return BLT_FALSE;
+ }
+ readPtr = (blt_int32u *)(FlashGetSectorBaseAddr(sectorNum));
+ /* loop through all words in the sector and check that they are in the erase state.
+ * note that this is a 0 value for PFLASH.
+ */
+ for (idx=0; idx.
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef FLASH_H
+#define FLASH_H
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void FlashInit(void);
+blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data);
+blt_bool FlashErase(blt_addr addr, blt_int32u len);
+blt_bool FlashWriteChecksum(void);
+blt_bool FlashVerifyChecksum(void);
+blt_bool FlashDone(void);
+blt_addr FlashGetUserProgBaseAddress(void);
+
+
+#endif /* FLASH_H */
+/*********************************** end of flash.h ************************************/
diff --git a/Target/Source/TRICORE_TC1798/nvm.c b/Target/Source/TRICORE_TC1798/nvm.c
new file mode 100644
index 00000000..f4e0c22b
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/nvm.c
@@ -0,0 +1,216 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\nvm.c
+* \brief Bootloader non-volatile memory driver source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+/****************************************************************************************
+* Hook functions
+****************************************************************************************/
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+extern void NvmInitHook(void);
+extern blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data);
+extern blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len);
+extern blt_bool NvmDoneHook(void);
+#endif
+
+#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
+extern blt_bool NvmWriteChecksumHook(void);
+extern blt_bool NvmVerifyChecksumHook(void);
+#endif
+
+
+
+/************************************************************************************//**
+** \brief Initializes the NVM driver.
+** \return none.
+**
+****************************************************************************************/
+void NvmInit(void)
+{
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ /* give the application a chance to initialize a driver for operating on NVM
+ * that is not by default supported by this driver.
+ */
+ NvmInitHook();
+#endif
+
+ /* init the internal driver */
+ FlashInit();
+} /*** end of NvmInit ***/
+
+
+/************************************************************************************//**
+** \brief Programs the non-volatile memory.
+** \param addr Start address.
+** \param len Length in bytes.
+** \param data Pointer to the data buffer.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data)
+{
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ blt_int8u result = BLT_NVM_NOT_IN_RANGE;
+#endif
+
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ /* give the application a chance to operate on memory that is not by default supported
+ * by this driver.
+ */
+ result = NvmWriteHook(addr, len, data);
+
+ /* process the return code */
+ if (result == BLT_NVM_OKAY)
+ {
+ /* data was within range of the additionally supported memory and succesfully
+ * programmed, so we are all done.
+ */
+ return BLT_TRUE;
+ }
+ else if (result == BLT_NVM_ERROR)
+ {
+ /* data was within range of the additionally supported memory and attempted to be
+ * programmed, but an error occurred, so we can't continue.
+ */
+ return BLT_FALSE;
+ }
+#endif
+
+ /* still here so the internal driver should try and perform the program operation */
+ return FlashWrite(addr, len, data);
+} /*** end of NvmWrite ***/
+
+
+/************************************************************************************//**
+** \brief Erases the non-volatile memory.
+** \param addr Start address.
+** \param len Length in bytes.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool NvmErase(blt_addr addr, blt_int32u len)
+{
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ blt_int8u result = BLT_NVM_NOT_IN_RANGE;
+#endif
+
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ /* give the application a chance to operate on memory that is not by default supported
+ * by this driver.
+ */
+ result = NvmEraseHook(addr, len);
+
+ /* process the return code */
+ if (result == BLT_NVM_OKAY)
+ {
+ /* address was within range of the additionally supported memory and succesfully
+ * erased, so we are all done.
+ */
+ return BLT_TRUE;
+ }
+ else if (result == BLT_NVM_ERROR)
+ {
+ /* address was within range of the additionally supported memory and attempted to be
+ * erased, but an error occurred, so we can't continue.
+ */
+ return BLT_FALSE;
+ }
+#endif
+
+ /* still here so the internal driver should try and perform the erase operation */
+ return FlashErase(addr, len);
+} /*** end of NvmErase ***/
+
+
+/************************************************************************************//**
+** \brief Verifies the checksum, which indicates that a valid user program is
+** present and can be started.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool NvmVerifyChecksum(void)
+{
+#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
+ /* check checksum using the application specific method. */
+ return NvmVerifyChecksumHook();
+#else
+ /* check checksum using the interally supported method. */
+ return FlashVerifyChecksum();
+#endif
+} /*** end of NvmVerifyChecksum ***/
+
+
+/************************************************************************************//**
+** \brief Once all erase and programming operations are completed, this
+** function is called, so at the end of the programming session and
+** right before a software reset is performed. It is used to calculate
+** a checksum and program this into flash. This checksum is later used
+** to determine if a valid user program is present in flash.
+** \return BLT_TRUE if successful, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool NvmDone(void)
+{
+#if (BOOT_NVM_HOOKS_ENABLE > 0)
+ /* give the application's NVM driver a chance to finish up */
+ if (NvmDoneHook() == BLT_FALSE)
+ {
+ /* error so no need to continue */
+ return BLT_FALSE;
+ }
+#endif
+
+#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
+ /* compute and write checksum, using the application specific method. */
+ if (NvmWriteChecksumHook() == BLT_FALSE)
+ {
+ return BLT_FALSE;
+ }
+#else
+ /* compute and write checksum, which is programmed by the internal driver. */
+ if (FlashWriteChecksum() == BLT_FALSE)
+ {
+ return BLT_FALSE;
+ }
+#endif
+
+ /* finish up internal driver operations */
+ return FlashDone();
+} /*** end of NvmDone ***/
+
+
+/*********************************** end of nvm.c **************************************/
diff --git a/Target/Source/TRICORE_TC1798/nvm.h b/Target/Source/TRICORE_TC1798/nvm.h
new file mode 100644
index 00000000..70ba13fd
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/nvm.h
@@ -0,0 +1,65 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\nvm.h
+* \brief Bootloader non-volatile memory driver header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef NVM_H
+#define NVM_H
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "flash.h" /* LPC2xxx flash driver */
+
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void NvmInit(void);
+blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data);
+blt_bool NvmErase(blt_addr addr, blt_int32u len);
+blt_bool NvmVerifyChecksum(void);
+blt_bool NvmDone(void);
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/* return codes for hook function NvmWrite/Erase */
+/** \brief Return code for success. */
+#define BLT_NVM_ERROR (0x00)
+/** \brief Return code for error. */
+#define BLT_NVM_OKAY (0x01)
+/** \brief Return code for not in range. */
+#define BLT_NVM_NOT_IN_RANGE (0x02)
+
+
+#endif /* NVM_H */
+/*********************************** end of nvm.h **************************************/
diff --git a/Target/Source/TRICORE_TC1798/target.dox b/Target/Source/TRICORE_TC1798/target.dox
new file mode 100644
index 00000000..1374c50e
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/target.dox
@@ -0,0 +1,8 @@
+/**
+\defgroup Target_TRICORE_TC1798 Target Tricore TC1798
+\brief Target dependent code for the Tricore TC1798 microcontroller family.
+\details This module implements the bootloader's target dependent part for the
+ Tricore TC1798 microcontroller family.
+*/
+
+
diff --git a/Target/Source/TRICORE_TC1798/timer.c b/Target/Source/TRICORE_TC1798/timer.c
new file mode 100644
index 00000000..7afdb52c
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/timer.c
@@ -0,0 +1,148 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\timer.c
+* \brief Bootloader timer driver source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+/****************************************************************************************
+* Local data declarations
+****************************************************************************************/
+/** \brief Local variable for storing the number of milliseconds that have elapsed since
+ * startup.
+ */
+static blt_int32u millisecond_counter;
+
+/** \brief Holds the timer tick count for 1 millisecond. */
+static blt_int16u millisecond_ticks;
+
+
+/************************************************************************************//**
+** \brief Initializes the polling based millisecond timer driver.
+** \return none.
+**
+****************************************************************************************/
+void TimerInit(void)
+{
+ blt_int32u dummy;
+
+ /* reset the timer configuration */
+ TimerReset();
+ /* obtain "E" access rights */
+ CpuEnterInitMode();
+ /* enable the GPT12 timer module */
+ GPT120_CLC.reg = 0x00000000;
+ /* dummy read to avoid pipeline effects */
+ dummy = GPT120_CLC.reg;
+ /* release "E" access rights */
+ CpuLeaveInitMode();
+ /* core timer 3 is used for polling millisecond events. its configuration is:
+ * - timer 3 works in timer mode
+ * - external up/down control is disabled
+ * - prescaler factor is 128 (Ftimer3 = BOOT_CPU_SYSTEM_SPEED_KHZ / 128)
+ * - up/down control bit is reset
+ * - alternate output function T3OUT is disabled
+ * - timer 3 output toggle latch (T3OTL) is set to 0
+ * - timer 3 run bit is set
+ */
+ GPT120_T3CON.reg = 0x00000845;
+ /* reset the timer 3 register so that counter starts at 0 */
+ GPT120_T3.reg = 0x00000000;
+ /* calculate the number of timer ticks in 1 millisecond */
+ millisecond_ticks = ((blt_int32u)BOOT_CPU_SYSTEM_SPEED_KHZ / 128);
+ /* reset the millisecond counter value */
+ millisecond_counter = 0;
+} /*** end of TimerInit ***/
+
+
+/************************************************************************************//**
+** \brief Reset the timer by placing the timer back into it's default reset
+** configuration.
+** \return none.
+**
+****************************************************************************************/
+void TimerReset(void)
+{
+ blt_int32u dummy;
+ /* revert back to timer 3 configuration reset value */
+ GPT120_T3CON.reg = 0x00000000;
+ /* revert back to timer 3 reset value */
+ GPT120_T3.reg = 0x00000000;
+ /* obtain "E" access rights */
+ CpuEnterInitMode();
+ /* disable the GPT12 timer module */
+ GPT120_CLC.reg = 0x00000003;
+ /* dummy read to avoid pipeline effects */
+ dummy = GPT120_CLC.reg;
+ /* release "E" access rights */
+ CpuLeaveInitMode();
+} /* end of TimerReset */
+
+
+/************************************************************************************//**
+** \brief Updates the millisecond timer.
+** \return none.
+**
+****************************************************************************************/
+void TimerUpdate(void)
+{
+ /* check if the millisecond event occurred */
+ if (GPT120_T3.reg >= millisecond_ticks)
+ {
+ GPT120_T3.reg = 0;
+ /* reset timer 3 register for detecting the next millisecond */
+ /* increment the millisecond counter */
+ millisecond_counter++;
+ }
+} /*** end of TimerUpdate ***/
+
+
+/************************************************************************************//**
+** \brief Obtains the counter value of the millisecond timer.
+** \return Current value of the millisecond timer.
+**
+****************************************************************************************/
+blt_int32u TimerGet(void)
+{
+ /* updating timer here allows this function to be called in a loop with timeout
+ * detection.
+ */
+ TimerUpdate();
+ /* read and return the amount of milliseconds that passed since initialization */
+ return millisecond_counter;
+} /*** end of TimerGet ***/
+
+
+/*********************************** end of timer.c ************************************/
diff --git a/Target/Source/TRICORE_TC1798/timer.h b/Target/Source/TRICORE_TC1798/timer.h
new file mode 100644
index 00000000..bbb053da
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/timer.h
@@ -0,0 +1,46 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\timer.h
+* \brief Bootloader timer driver header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef TIMER_H
+#define TIMER_H
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void TimerInit(void);
+void TimerUpdate(void);
+blt_int32u TimerGet(void);
+void TimerReset(void);
+
+
+#endif /* TIMER_H */
+/*********************************** end of timer.h ************************************/
diff --git a/Target/Source/TRICORE_TC1798/types.h b/Target/Source/TRICORE_TC1798/types.h
new file mode 100644
index 00000000..0a6c2782
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/types.h
@@ -0,0 +1,63 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\types.h
+* \brief Bootloader types header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef TYPES_H
+#define TYPES_H
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/** \brief Boolean true value. */
+#define BLT_TRUE (1)
+/** \brief Boolean false value. */
+#define BLT_FALSE (0)
+/** \brief NULL pointer value. */
+#define BLT_NULL ((void *)0)
+
+
+/****************************************************************************************
+* Type definitions
+****************************************************************************************/
+typedef unsigned char blt_bool; /**< boolean type */
+typedef char blt_char; /**< character type */
+typedef unsigned long blt_addr; /**< memory address type */
+typedef unsigned char blt_int8u; /**< 8-bit unsigned integer */
+typedef signed char blt_int8s; /**< 8-bit signed integer */
+typedef unsigned short blt_int16u; /**< 16-bit unsigned integer */
+typedef signed short blt_int16s; /**< 16-bit signed integer */
+typedef unsigned int blt_int32u; /**< 32-bit unsigned integer */
+typedef signed int blt_int32s; /**< 32-bit signed integer */
+
+
+#endif /* TYPES_H */
+/*********************************** end of types.h ************************************/
diff --git a/Target/Source/TRICORE_TC1798/uart.c b/Target/Source/TRICORE_TC1798/uart.c
new file mode 100644
index 00000000..b8cedec8
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/uart.c
@@ -0,0 +1,282 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\uart.c
+* \brief Bootloader UART communication interface source file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+
+/****************************************************************************************
+* Include files
+****************************************************************************************/
+#include "boot.h" /* bootloader generic header */
+
+
+#if (BOOT_COM_UART_ENABLE > 0)
+/****************************************************************************************
+* Type definitions
+****************************************************************************************/
+typedef struct
+{
+ blt_int32u reserved0[0x1]; /* 0x0 */
+ ASCn_PISEL_t PISEL; /* 0x4 */
+ ASCn_ID_t ID; /* 0x8 */
+ blt_int32u reserved3[0x1]; /* 0xc */
+ ASCn_CON_t CON; /* 0x10 */
+ ASCn_BG_t BG; /* 0x14 */
+ ASCn_FDV_t FDV; /* 0x18 */
+ blt_int32u reserved7[0x1]; /* 0x1c */
+ ASCn_TBUF_t TBUF; /* 0x20 */
+ ASCn_RBUF_t RBUF; /* 0x24 */
+ blt_int32u reserved10[0xa]; /* 0x28 */
+ ASCn_WHBCON_t WHBCON; /* 0x50 */
+ blt_int32u reserved12[0x27]; /* 0x54 */
+ ASCn_TSRC_t TSRC; /* 0xf0 */
+ ASCn_RSRC_t RSRC; /* 0xf4 */
+ ASCn_ESRC_t ESRC; /* 0xf8 */
+ ASCn_TBSRC_t TBSRC; /* 0xfc */
+} tUartRegs;
+
+
+/****************************************************************************************
+* Macro definitions
+****************************************************************************************/
+/** \brief Timeout time for the reception of a CTO packet. The timer is started upon
+ * reception of the first packet byte.
+ */
+#define UART_CTO_RX_PACKET_TIMEOUT_MS (100u)
+
+
+/****************************************************************************************
+* Register definitions
+****************************************************************************************/
+#if (BOOT_COM_UART_CHANNEL_INDEX == 0)
+/** \brief Set UART base address to ASC0. */
+#define UARTx ((tUartRegs *) (blt_int32u)0xf0000a00)
+#elif (BOOT_COM_UART_CHANNEL_INDEX == 1)
+/** \brief Set UART base address to ASC1. */
+#define UARTx ((tUartRegs *) (blt_int32u)0xf0000b00)
+#else
+/** \brief Set UART base address to ASC0 by default. */
+#define UARTx ((tUartRegs *) (blt_int32u)0xf0000a00)
+#endif
+
+
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+static blt_bool UartReceiveByte(blt_int8u *data);
+static blt_bool UartTransmitByte(blt_int8u data);
+
+
+/************************************************************************************//**
+** \brief Initializes the UART communication interface.
+** \return none.
+**
+****************************************************************************************/
+void UartInit(void)
+{
+ blt_int32u frequency, reload_value, fdv, dfreq;
+
+ /* Compute system frequency and reload value for ASC */
+ frequency = BOOT_CPU_SYSTEM_SPEED_KHZ * 1000;
+
+ /* reload_value = fdv/512 * freq/16/baudrate -1 ==>
+ * reload_value = (512*freq)/(baudrate * 512*16) - 1
+ * fdv = (reload_value + 1) * (baudrate*512*16/freq)
+ * reload_value = (frequency / 32) / baudrate - 1;
+ */
+ reload_value = (frequency / ((blt_int32u)BOOT_COM_UART_BAUDRATE * 16)) - 1;
+ dfreq = frequency / (16*512);
+ fdv = (reload_value + 1) * (blt_int32u)BOOT_COM_UART_BAUDRATE / dfreq;
+
+ /* enable ASC module */
+ CpuEnterInitMode();
+ ASC0_CLC.bits.RMC = 1;
+ ASC0_CLC.bits.DISR = 0;
+ CpuLeaveInitMode();
+
+ /* configure the ASC module for 8,n,1 */
+ UARTx->CON.reg = 0;
+ UARTx->BG.reg = reload_value;
+ UARTx->FDV.reg = fdv;
+
+ UARTx->CON.bits.M = 0x01;
+ UARTx->CON.bits.R = 1;
+ UARTx->CON.bits.REN = 1;
+ UARTx->CON.bits.FDE = 1;
+} /*** end of UartInit ***/
+
+
+/************************************************************************************//**
+** \brief Transmits a packet formatted for the communication interface.
+** \param data Pointer to byte array with data that it to be transmitted.
+** \param len Number of bytes that are to be transmitted.
+** \return none.
+**
+****************************************************************************************/
+void UartTransmitPacket(blt_int8u *data, blt_int8u len)
+{
+ blt_int16u data_index;
+ blt_bool result;
+
+ /* verify validity of the len-paramenter */
+ ASSERT_RT(len <= BOOT_COM_UART_TX_MAX_DATA);
+
+ /* first transmit the length of the packet */
+ result = UartTransmitByte(len);
+ ASSERT_RT(result == BLT_TRUE);
+
+ /* transmit all the packet bytes one-by-one */
+ for (data_index = 0; data_index < len; data_index++)
+ {
+ /* keep the watchdog happy */
+ CopService();
+ /* write byte */
+ result = UartTransmitByte(data[data_index]);
+ ASSERT_RT(result == BLT_TRUE);
+ }
+} /*** end of UartTransmitPacket ***/
+
+
+/************************************************************************************//**
+** \brief Receives a communication interface packet if one is present.
+** \param data Pointer to byte array where the data is to be stored.
+** \return BLT_TRUE if a packet was received, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+blt_bool UartReceivePacket(blt_int8u *data)
+{
+ static blt_int8u xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1]; /* one extra for length */
+ static blt_int8u xcpCtoRxLength;
+ static blt_bool xcpCtoRxInProgress = BLT_FALSE;
+ static blt_int32u xcpCtoRxStartTime = 0;
+
+ /* start of cto packet received? */
+ if (xcpCtoRxInProgress == BLT_FALSE)
+ {
+ /* store the message length when received */
+ if (UartReceiveByte(&xcpCtoReqPacket[0]) == BLT_TRUE)
+ {
+ if (xcpCtoReqPacket[0] > 0)
+ {
+ /* store the start time */
+ xcpCtoRxStartTime = TimerGet();
+ /* reset packet data count */
+ xcpCtoRxLength = 0;
+ /* indicate that a cto packet is being received */
+ xcpCtoRxInProgress = BLT_TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* store the next packet byte */
+ if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == BLT_TRUE)
+ {
+ /* increment the packet data count */
+ xcpCtoRxLength++;
+
+ /* check to see if the entire packet was received */
+ if (xcpCtoRxLength == xcpCtoReqPacket[0])
+ {
+ /* copy the packet data */
+ CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);
+ /* done with cto packet reception */
+ xcpCtoRxInProgress = BLT_FALSE;
+ /* packet reception complete */
+ return BLT_TRUE;
+ }
+ }
+ else
+ {
+ /* check packet reception timeout */
+ if (TimerGet() > (xcpCtoRxStartTime + UART_CTO_RX_PACKET_TIMEOUT_MS))
+ {
+ /* cancel cto packet reception due to timeout. note that that automaticaly
+ * discards the already received packet bytes, allowing the host to retry.
+ */
+ xcpCtoRxInProgress = BLT_FALSE;
+ }
+ }
+ }
+ /* packet reception not yet complete */
+ return BLT_FALSE;
+} /*** end of UartReceivePacket ***/
+
+
+/************************************************************************************//**
+** \brief Receives a communication interface byte if one is present.
+** \param data Pointer to byte where the data is to be stored.
+** \return BLT_TRUE if a byte was received, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool UartReceiveByte(blt_int8u *data)
+{
+ blt_bool result = BLT_FALSE;
+
+ /* reception event pending? */
+ if (UARTx->RSRC.bits.SRR != 0)
+ {
+ /* read out the newly received byte */
+ *data = UARTx->RBUF.bits.RD_VALUE;
+ /* reset the reception event flag */
+ UARTx->RSRC.bits.CLRR = 1;
+ /* set result to indicate that a new byte was received */
+ result = BLT_TRUE;
+ }
+
+ /* inform caller about the result */
+ return result;
+} /*** end of UartReceiveByte ***/
+
+
+/************************************************************************************//**
+** \brief Transmits a communication interface byte.
+** \param data Value of byte that is to be transmitted.
+** \return BLT_TRUE if the byte was transmitted, BLT_FALSE otherwise.
+**
+****************************************************************************************/
+static blt_bool UartTransmitByte(blt_int8u data)
+{
+ /* reset transmit buffer interrupt request */
+ UARTx->TBSRC.bits.CLRR = 1;
+ /* write byte to transmit buffer register */
+ UARTx->TBUF.reg = data;
+ /* wait for transmit buffer register to be empty */
+ while(UARTx->TBSRC.bits.SRR == 0)
+ {
+ CopService();
+ }
+ /* byte transmitted */
+ return BLT_TRUE;
+} /*** end of UartTransmitByte ***/
+#endif /* BOOT_COM_UART_ENABLE > 0 */
+
+
+/*********************************** end of uart.c *************************************/
diff --git a/Target/Source/TRICORE_TC1798/uart.h b/Target/Source/TRICORE_TC1798/uart.h
new file mode 100644
index 00000000..02ba5751
--- /dev/null
+++ b/Target/Source/TRICORE_TC1798/uart.h
@@ -0,0 +1,47 @@
+/************************************************************************************//**
+* \file Source\TRICORE_TC1798\uart.h
+* \brief Bootloader UART communication interface header file.
+* \ingroup Target_TRICORE_TC1798
+* \internal
+*----------------------------------------------------------------------------------------
+* C O P Y R I G H T
+*----------------------------------------------------------------------------------------
+* Copyright (c) 2015 by Feaser http://www.feaser.com All rights reserved
+*
+*----------------------------------------------------------------------------------------
+* L I C E N S E
+*----------------------------------------------------------------------------------------
+* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as published by the Free
+* Software Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with OpenBLT.
+* If not, see .
+*
+* A special exception to the GPL is included to allow you to distribute a combined work
+* that includes OpenBLT without being obliged to provide the source code for any
+* proprietary components. The exception text is included at the bottom of the license
+* file .
+*
+* \endinternal
+****************************************************************************************/
+#ifndef UART_H
+#define UART_H
+
+#if (BOOT_COM_UART_ENABLE > 0)
+/****************************************************************************************
+* Function prototypes
+****************************************************************************************/
+void UartInit(void);
+void UartTransmitPacket(blt_int8u *data, blt_int8u len);
+blt_bool UartReceivePacket(blt_int8u *data);
+#endif /* BOOT_COM_UART_ENABLE > 0 */
+
+
+#endif /* UART_H */
+/*********************************** end of uart.h *************************************/