• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 
19 #include "los_compiler.h"
20 
21 #include <nds_intrinsic.h>
22 #include <stdint.h>
23 
24 #include <B91/sys.h>
25 
26 #define MCACHE_CTL_ICACHE 1
27 #define MCACHE_CTL_DCACHE 2
28 
29 #define SWIRE_MAGIC_REG 0x100c01
30 #define SWIRE_MAGIC_VALUE 0x40
31 
32 typedef void (*InitFunc)(void);
33 
34 extern UINT32 _ITB_BASE_;
35 
36 extern UINT32 SEG_RETENTION_DATA_LMA_START[], SEG_RETENTION_DATA_VMA_START[], SEG_RETENTION_DATA_VMA_END[];
37 extern UINT32 SEG_RAMCODE_LMA_START[], SEG_RAMCODE_VMA_START[], SEG_RAMCODE_VMA_END[];
38 extern UINT32 SEG_DATA_LMA_START[], SEG_DATA_VMA_START[], SEG_DATA_VMA_END[];
39 extern UINT32 SEG_BSS_VMA_START[], SEG_BSS_VMA_END[];
40 extern UINT32 __int_stack_start[], __int_stack_end[];
41 
42 extern InitFunc __preinit_array_start[] __attribute__((weak));
43 extern InitFunc __preinit_array_end[] __attribute__((weak));
44 extern InitFunc __init_array_start[] __attribute__((weak));
45 extern InitFunc __init_array_end[] __attribute__((weak));
46 extern InitFunc __fini_array_start[] __attribute__((weak));
47 extern InitFunc __fini_array_end[] __attribute__((weak));
48 
49 #define STACK_MAGIC UINT32_C(0xDEADBEEF)
50 
51 STATIC VOID BoardConfigInnerSafe(VOID);
52 
53 #ifdef __GNUC__
54 #pragma GCC push_options
55 #pragma GCC optimize("-fno-stack-protector")
56 #endif /* __GNUC__ */
57 
CopyBuf32(UINT32 * dst,const UINT32 * dstEnd,const UINT32 * src)58 __attribute__((noinline)) STATIC VOID CopyBuf32(UINT32 *dst, const UINT32 *dstEnd, const UINT32 *src)
59 {
60     while (dst < dstEnd) {
61         *dst++ = *src++;
62     }
63 }
64 
65 #define COPY_SEGMENT(_SEGNAME_) CopyBuf32((_SEGNAME_##_VMA_START), (_SEGNAME_##_VMA_END), (_SEGNAME_##_LMA_START))
66 
BoardConfigInner(void)67 __attribute__((used)) static void BoardConfigInner(void)
68 {
69     for (UINT32 *p = SEG_BSS_VMA_START; p < SEG_BSS_VMA_END; ++p) {
70         *p = 0;
71     }
72 
73     COPY_SEGMENT(SEG_RETENTION_DATA);
74     COPY_SEGMENT(SEG_RAMCODE);
75     COPY_SEGMENT(SEG_DATA);
76 
77     BoardConfigInnerSafe();
78 }
79 
80 /*
81  * Use "naked" attribute to prevent stack usage before stack is initialized
82  */
BoardConfig(void)83 __attribute__((naked)) void BoardConfig(void)
84 {
85     write_reg8(SWIRE_MAGIC_REG, SWIRE_MAGIC_VALUE);
86 
87 #ifdef __nds_execit
88     /* Initialize EXEC.IT table */
89     __builtin_riscv_csrw((UINT32)&_ITB_BASE_, NDS_UITB);
90 #endif /* __nds_execit */
91 
92     /* Enable I/D-Cache */
93     UINT32 mcacheCtl = __builtin_riscv_csrr(NDS_MCACHE_CTL);
94     mcacheCtl |= MCACHE_CTL_ICACHE; /* I-Cache */
95     mcacheCtl |= MCACHE_CTL_DCACHE; /* D-Cache */
96     __builtin_riscv_csrw(mcacheCtl, NDS_MCACHE_CTL);
97     __asm__ volatile("fence.i");
98 
99     for (UINT32 *p = __int_stack_start; p < __int_stack_end; ++p) {
100         *p = STACK_MAGIC;
101     }
102 
103     __asm__ volatile("j BoardConfigInner");
104 }
105 
106 #ifdef __GNUC__
107 #pragma GCC pop_options
108 #endif /* __GNUC__ */
109 
110 /**
111  * @brief BoardConfigInnerSafe is safe part of BoardConfig without disabled stack protection
112  */
BoardConfigInnerSafe(VOID)113 STATIC VOID BoardConfigInnerSafe(VOID)
114 {
115     for (InitFunc *f = __preinit_array_start; f < __preinit_array_end; ++f) {
116         (*f)();
117     }
118 
119     for (InitFunc *f = __init_array_start; f < __init_array_end; ++f) {
120         (*f)();
121     }
122 
123     for (InitFunc *f = __fini_array_start; f < __fini_array_end; ++f) {
124         (*f)();
125     }
126 }
127