1 /*\r
2 * Copyright ( C ) 2022 Texas Instruments Incorporated\r
3 *\r
4 * Redistribution and use in source and binary forms, with or without\r
5 * modification, are permitted provided that the following conditions\r
6 * are met:\r
7 *\r
8 * Redistributions of source code must retain the above copyright\r
9 * notice, this list of conditions and the following disclaimer.\r
10 *\r
11 * Redistributions in binary form must reproduce the above copyright\r
12 * notice, this list of conditions and the following disclaimer in the\r
13 * documentation and/or other materials provided with the\r
14 * distribution.\r
15 *\r
16 * Neither the name of Texas Instruments Incorporated nor the names of\r
17 * its contributors may be used to endorse or promote products derived\r
18 * from this software without specific prior written permission.\r
19 *\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT\r
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY\r
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
29 * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE\r
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31 */\r
32 \r
33 /* Generic headers */\r
34 #include <stdlib.h>\r
35 \r
36 /* SafeRTOS includes */\r
37 #include "SafeRTOS_API.h"\r
38 #include "SafeRTOSConfig.h"\r
39 \r
40 #include "SafeRTOS_priv.h"\r
41 \r
42 #include "Mmu.h"\r
43 #include "Exception.h"\r
44 \r
45 #include <ti/csl/csl_clec.h>\r
46 #include <ti/osal/src/nonos/Nonos_config.h>\r
47 #include <ti/osal/DebugP.h>\r
48 \r
49 /* Function declaration */\r
50 static void prvMmuInit( Bool isSecure );\r
51 static void prvCfgClecAccessCtrl ( Bool onlyInSecure );\r
52 static void vPortInitTimerCLECCfg( uint32_t timerId, uint32_t timerIntNum );\r
53 \r
54 \r
55 /* Hook function handlers targeting the TI PDK libraries. */\r
56 \r
57 /*-----------------------------------------------------------------------------\r
58 * Public function definitions.\r
59 *---------------------------------------------------------------------------*/\r
60 /* Hardware setup using the TI PDK libraries. */\r
61 __attribute__((weak)) portBaseType prvSetupHardware( void )\r
62 {\r
63 portBaseType xStatus = pdPASS;\r
64 Safertos_OSTimerParams xOSTimerParams;\r
65 \r
66 prvGetOSTimerParams( &xOSTimerParams );\r
67 \r
68 vPortInitTimerCLECCfg( xOSTimerParams.timerId, \r
69 xOSTimerParams.intNum );\r
70 \r
71 return xStatus;\r
72 }\r
73 /*-------------------------------------------------------------------------*/\r
74 \r
75 /*-----------------------------------------------------------------------------\r
76 * Override functions for TI PDK library startup code.\r
77 *---------------------------------------------------------------------------*/\r
78 \r
79 \r
80 /* Override the startup code mpu initialisation - not used in this demo. */\r
81 /*\r
82 void __mpu_init( void )\r
83 {\r
84 }\r
85 */\r
86 /*-------------------------------------------------------------------------*/\r
87 \r
88 /*****************************************************************************/\r
89 /* _SYSTEM_PRE_INIT() - _system_pre_init() is called in the C/C++ startup */\r
90 /* routine (_c_int00()) and provides a mechanism for the user to */\r
91 /* insert application specific low level initialization instructions prior */\r
92 /* to calling main(). The return value of _system_pre_init() is used to */\r
93 /* determine whether or not C/C++ global data initialization will be */\r
94 /* performed (return value of 0 to bypass C/C++ auto-initialization). */\r
95 /* */\r
96 /* PLEASE NOTE THAT BYPASSING THE C/C++ AUTO-INITIALIZATION ROUTINE MAY */\r
97 /* RESULT IN PROGRAM FAILURE. */\r
98 /* */\r
99 /* The version of _system_pre_init() below is skeletal and is provided to */\r
100 /* illustrate the interface and provide default behavior. To replace this */\r
101 /* version rewrite the routine and include it as part of the current project.*/\r
102 /* The linker will include the updated version if it is linked in prior to */\r
103 /* linking with the C/C++ runtime library. */\r
104 /*****************************************************************************/\r
105 __attribute__((weak)) portBaseType _system_pre_init( void )\r
106 {\r
107 return 1;\r
108 }\r
109 /*---------------------------------------------------------------------------*/\r
110 \r
111 /*****************************************************************************/\r
112 /* _SYSTEM_POST_CINIT() - _system_post_cinit() is a hook function called in */\r
113 /* the C/C++ auto-initialization function after cinit() and before pinit(). */\r
114 /* */\r
115 /* The version of _system_post_cinit() below is skeletal and is provided to */\r
116 /* illustrate the interface and provide default behavior. To replace this */\r
117 /* version rewrite the routine and include it as part of the current project.*/\r
118 /* The linker will include the updated version if it is linked in prior to */\r
119 /* linking with the C/C++ runtime library. */\r
120 /*****************************************************************************/\r
121 __attribute__((weak)) void _system_post_cinit( void )\r
122 {\r
123 extern void c7x_startup_init(void);\r
124 c7x_startup_init();\r
125 }\r
126 /*---------------------------------------------------------------------------*/\r
127 \r
128 void Osal_initMmuDefault( void )\r
129 {\r
130 prvMmuInit( false );\r
131 prvMmuInit( true );\r
132 \r
133 /* Setup CLEC access/configure in non-secure mode */\r
134 prvCfgClecAccessCtrl( false );\r
135 }\r
136 \r
137 /*---------------------------------------------------------------------------*/\r
138 \r
139 __attribute__((weak)) void vInitMmu( void )\r
140 {\r
141 /* Invoke application defined InitMmu() */\r
142 extern void InitMmu(void);\r
143 \r
144 InitMmu();\r
145 }\r
146 \r
147 /*---------------------------------------------------------------------------*/\r
148 \r
149 void OsalCfgClecAccessCtrl (bool onlyInSecure)\r
150 {\r
151 prvCfgClecAccessCtrl( onlyInSecure );\r
152 }\r
153 \r
154 /*---------------------------------------------------------------------------*/\r
155 \r
156 /* Dispatch handler for TI PDK style exceptions. */\r
157 void vApplicationExceptionHandlerHook( portBaseType xAbortFlag, portBaseType xVectorType )\r
158 {\r
159 Exception_handler( xAbortFlag, xVectorType );\r
160 }\r
161 \r
162 /*---------------------------------------------------------------------------*/\r
163 \r
164 /* Dispatch handler for TI PDK style interrupts. */\r
165 portBaseType xApplicationInterruptHandlerHook( portUInt32Type ulInterruptVectorNum )\r
166 {\r
167 return Hwi_dispatchC( ulInterruptVectorNum );\r
168 }\r
169 \r
170 /*-----------------------------------------------------------------------------\r
171 * End of Override functions for TI PDK library startup code.\r
172 *---------------------------------------------------------------------------*/\r
173 \r
174 /*-----------------------------------------------------------------------------\r
175 * Private function definitions.\r
176 *---------------------------------------------------------------------------*/\r
177 \r
178 static void prvMmuInit( Bool isSecure )\r
179 {\r
180 Mmu_MapAttrs attrs;\r
181 \r
182 Mmu_initMapAttrs( &attrs );\r
183 attrs.attrIndx = Mmu_AttrIndx_MAIR0;\r
184 \r
185 if( TRUE == isSecure )\r
186 {\r
187 attrs.ns = 0;\r
188 }\r
189 else\r
190 {\r
191 attrs.ns = 1;\r
192 }\r
193 \r
194 /* Register region */\r
195 ( void )Mmu_map( 0x00000000U, 0x00000000U, 0x20000000U, &attrs, isSecure );\r
196 ( void )Mmu_map( 0x20000000U, 0x20000000U, 0x20000000U, &attrs, isSecure );\r
197 ( void )Mmu_map( 0x40000000U, 0x40000000U, 0x20000000U, &attrs, isSecure );\r
198 ( void )Mmu_map( 0x60000000U, 0x60000000U, 0x10000000U, &attrs, isSecure );\r
199 ( void )Mmu_map( 0x78000000U, 0x78000000U, 0x08000000U, &attrs, isSecure ); /* CLEC */\r
200 \r
201 attrs.attrIndx = Mmu_AttrIndx_MAIR7;\r
202 ( void )Mmu_map( 0x80000000U, 0x80000000U, 0x20000000U, &attrs, isSecure ); /* DDR */\r
203 ( void )Mmu_map( 0xA0000000U, 0xA0000000U, 0x20000000U, &attrs, isSecure ); /* DDR */\r
204 ( void )Mmu_map( 0x70000000U, 0x70000000U, 0x00800000U, &attrs, isSecure ); /* MSMC - 8MB */\r
205 ( void )Mmu_map( 0x41C00000U, 0x41C00000U, 0x00080000U, &attrs, isSecure ); /* OCMC - 512KB */\r
206 \r
207 /*\r
208 * DDR range 0xA0000000 - 0xAA000000 : Used as RAM by multiple\r
209 * remote cores, no need to mmp_map this range.\r
210 * IPC VRing Buffer - uncached\r
211 */\r
212 attrs.attrIndx = Mmu_AttrIndx_MAIR4;\r
213 ( void )Mmu_map( 0xAA000000U, 0xAA000000U, 0x02000000U, &attrs, isSecure );\r
214 \r
215 return;\r
216 }\r
217 /*-------------------------------------------------------------------------*/\r
218 \r
219 static void prvCfgClecAccessCtrl ( Bool onlyInSecure )\r
220 {\r
221 CSL_ClecEventConfig cfgClec;\r
222 CSL_CLEC_EVTRegs *clecBaseAddr = ( CSL_CLEC_EVTRegs* ) CSL_COMPUTE_CLUSTER0_CLEC_REGS_BASE;\r
223 uint32_t i, maxInputs = 2048U;\r
224 \r
225 cfgClec.secureClaimEnable = onlyInSecure;\r
226 cfgClec.evtSendEnable = FALSE;\r
227 cfgClec.rtMap = CSL_CLEC_RTMAP_DISABLE;\r
228 cfgClec.extEvtNum = 0U;\r
229 cfgClec.c7xEvtNum = 0U;\r
230 for(i = 0U; i < maxInputs; i++)\r
231 {\r
232 CSL_clecConfigEvent( clecBaseAddr, i, &cfgClec );\r
233 }\r
234 }\r
235 /*-------------------------------------------------------------------------*/\r
236 \r
237 \r
238 static void vPortInitTimerCLECCfg( uint32_t timerId, uint32_t timerIntNum )\r
239 {\r
240 CSL_ClecEventConfig cfgClec;\r
241 CSL_CLEC_EVTRegs *clecBaseAddr = (CSL_CLEC_EVTRegs*)CSL_COMPUTE_CLUSTER0_CLEC_REGS_BASE;\r
242 uint32_t input = gDmTimerPInfoTbl[timerId].eventId;\r
243 uint32_t corepackEvent = timerIntNum;\r
244 \r
245 /* Configure CLEC */\r
246 cfgClec.secureClaimEnable = FALSE;\r
247 cfgClec.evtSendEnable = TRUE;\r
248 cfgClec.rtMap = CSL_CLEC_RTMAP_CPU_ALL;\r
249 cfgClec.extEvtNum = 0;\r
250 cfgClec.c7xEvtNum = corepackEvent;\r
251 CSL_clecClearEvent(clecBaseAddr, input);\r
252 CSL_clecConfigEventLevel(clecBaseAddr, input, 0); /* configure interrupt as pulse */\r
253 CSL_clecConfigEvent(clecBaseAddr, input, &cfgClec);\r
254 }\r
255 \r
256 /*-------------------------------------------------------------------------*/\r