1 /*
2 * Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2023 NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 */
9
10 #include <stdio.h>
11 #include "mcmgr.h"
12 #include "mcmgr_internal_core_api.h"
13
14 mcmgr_event_t MCMGR_eventTable[kMCMGR_EventTableLength] = {0};
15
MCMGR_RegisterEvent(mcmgr_event_type_t type,mcmgr_event_callback_t callback,void * callbackData)16 mcmgr_status_t MCMGR_RegisterEvent(mcmgr_event_type_t type, mcmgr_event_callback_t callback, void *callbackData)
17 {
18 if (type >= kMCMGR_EventTableLength)
19 {
20 return kStatus_MCMGR_Error;
21 }
22 /* Make sure any old handler is inactive */
23 MCMGR_eventTable[type].callback = ((void *)0);
24 /* Install callback data first */
25 MCMGR_eventTable[type].callbackData = callbackData;
26 /* Install the callback */
27 MCMGR_eventTable[type].callback = callback;
28
29 return kStatus_MCMGR_Success;
30 }
31
MCMGR_TriggerEventCommon(mcmgr_event_type_t type,uint16_t eventData,bool forcedWrite)32 static mcmgr_status_t MCMGR_TriggerEventCommon(mcmgr_event_type_t type, uint16_t eventData, bool forcedWrite)
33 {
34 uint32_t remoteData;
35 if (type >= kMCMGR_EventTableLength)
36 {
37 return kStatus_MCMGR_Error;
38 }
39
40 mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
41 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
42 {
43 remoteData = (((uint32_t)type) << 16) | eventData;
44 return mcmgr_trigger_event_internal(remoteData, forcedWrite);
45 }
46 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_GetCurrentCore() returns coreNum from
47 register and g_mcmgrSystem is defined as const */
48 }
49
MCMGR_TriggerEvent(mcmgr_event_type_t type,uint16_t eventData)50 mcmgr_status_t MCMGR_TriggerEvent(mcmgr_event_type_t type, uint16_t eventData)
51 {
52 return MCMGR_TriggerEventCommon(type, eventData, false);
53 }
54
MCMGR_TriggerEventForce(mcmgr_event_type_t type,uint16_t eventData)55 mcmgr_status_t MCMGR_TriggerEventForce(mcmgr_event_type_t type, uint16_t eventData)
56 {
57 return MCMGR_TriggerEventCommon(type, eventData, true);
58 }
59
MCMGR_StartupDataEventHandler(uint16_t startupDataChunk,void * context)60 static void MCMGR_StartupDataEventHandler(uint16_t startupDataChunk, void *context)
61 {
62 mcmgr_core_context_t *coreContext = (mcmgr_core_context_t *)context;
63
64 switch (coreContext->state)
65 {
66 case kMCMGR_StartupGettingLowCoreState:
67 coreContext->startupData = startupDataChunk; /* Receive the low part */
68 coreContext->state = kMCMGR_StartupGettingHighCoreState;
69 (void)MCMGR_TriggerEvent(kMCMGR_FeedStartupDataEvent, (uint16_t)kMCMGR_StartupGettingHighCoreState);
70 break;
71
72 case kMCMGR_StartupGettingHighCoreState:
73 coreContext->startupData |= ((uint32_t)startupDataChunk) << 16;
74 coreContext->state = kMCMGR_RunningCoreState;
75 (void)MCMGR_TriggerEvent(kMCMGR_FeedStartupDataEvent, (uint16_t)kMCMGR_RunningCoreState);
76 break;
77 /* coco begin validated: not possible to get into this default case */
78 default:
79 /* All the cases have been listed above, the default clause should not be reached. */
80 break;
81 }
82 /* coco end */
83 }
84
MCMGR_FeedStartupDataEventHandler(uint16_t startupDataChunk,void * context)85 static void MCMGR_FeedStartupDataEventHandler(uint16_t startupDataChunk, void *context)
86 {
87 mcmgr_core_context_t *coreContext = (mcmgr_core_context_t *)context;
88
89 switch ((mcmgr_core_state_t)startupDataChunk)
90 {
91 case kMCMGR_StartupGettingLowCoreState:
92 (void)MCMGR_TriggerEvent(kMCMGR_StartupDataEvent, (uint16_t)(coreContext->startupData & 0xFFFFU));
93 coreContext->state = (mcmgr_core_state_t)startupDataChunk;
94 break;
95
96 case kMCMGR_StartupGettingHighCoreState:
97 (void)MCMGR_TriggerEvent(kMCMGR_StartupDataEvent, (uint16_t)((coreContext->startupData) >> 16));
98 coreContext->state = (mcmgr_core_state_t)startupDataChunk;
99 break;
100
101 case kMCMGR_RunningCoreState:
102 coreContext->state = (mcmgr_core_state_t)startupDataChunk;
103 break;
104
105 /* coco begin validated: not possible to get into this default case */
106 default:
107 /* All the cases have been listed above, the default clause should not be reached. */
108 break;
109 }
110 /* coco end */
111 }
112
MCMGR_EarlyInit(void)113 mcmgr_status_t MCMGR_EarlyInit(void)
114 {
115 /* This function is intended to be called as close to the reset entry as possible,
116 (within the startup sequence in SystemInitHook) to allow CoreUp event triggering.
117 Avoid using uninitialized data here. */
118
119 mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
120 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
121 {
122 return mcmgr_early_init_internal(coreNum);
123 }
124 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_GetCurrentCore() returns coreNum from
125 register and g_mcmgrSystem is defined as const */
126 }
127
MCMGR_Init(void)128 mcmgr_status_t MCMGR_Init(void)
129 {
130 mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
131 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
132 {
133 /* Register critical and generic event handlers */
134 if (kStatus_MCMGR_Success != MCMGR_RegisterEvent(kMCMGR_StartupDataEvent, MCMGR_StartupDataEventHandler,
135 (void *)&s_mcmgrCoresContext[coreNum]))
136 {
137 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_RegisterEvent() params are always
138 correct here */
139 }
140 if (kStatus_MCMGR_Success !=
141 MCMGR_RegisterEvent(kMCMGR_FeedStartupDataEvent, MCMGR_FeedStartupDataEventHandler,
142 (void *)&s_mcmgrCoresContext[(coreNum == kMCMGR_Core0) ? kMCMGR_Core1 : kMCMGR_Core0]))
143 {
144 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_RegisterEvent() params are always
145 correct here */
146 }
147 return mcmgr_late_init_internal(coreNum);
148 }
149 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_GetCurrentCore() returns coreNum from
150 register and g_mcmgrSystem is defined as const */
151 }
152
MCMGR_StartCore(mcmgr_core_t coreNum,void * bootAddress,uint32_t startupData,mcmgr_start_mode_t mode)153 mcmgr_status_t MCMGR_StartCore(mcmgr_core_t coreNum, void *bootAddress, uint32_t startupData, mcmgr_start_mode_t mode)
154 {
155 mcmgr_status_t ret;
156
157 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
158 {
159 /* Pass the startupData - LSB first */
160 s_mcmgrCoresContext[coreNum].startupData = startupData;
161 /* the startup data is sent asynchronously */
162 ret = mcmgr_start_core_internal(coreNum, bootAddress);
163
164 if (ret == kStatus_MCMGR_Success)
165 {
166 if (mode == kMCMGR_Start_Synchronous)
167 {
168 /* Wait until the second core reads and confirms the startup data */
169 while (s_mcmgrCoresContext[coreNum].state != kMCMGR_RunningCoreState)
170 {
171 }
172 }
173 return kStatus_MCMGR_Success;
174 }
175 }
176 return kStatus_MCMGR_Error;
177 }
178
MCMGR_GetStartupData(uint32_t * startupData)179 mcmgr_status_t MCMGR_GetStartupData(uint32_t *startupData)
180 {
181 mcmgr_core_t coreNum = MCMGR_GetCurrentCore();
182 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
183 {
184 if (s_mcmgrCoresContext[coreNum].state == kMCMGR_ResetCoreState)
185 {
186 s_mcmgrCoresContext[coreNum].state = kMCMGR_StartupGettingLowCoreState;
187 if (kStatus_MCMGR_Success !=
188 MCMGR_TriggerEvent(kMCMGR_FeedStartupDataEvent, (uint16_t)kMCMGR_StartupGettingLowCoreState))
189 {
190 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_TriggerEvent() params are
191 always correct here */
192 }
193 }
194 return mcmgr_get_startup_data_internal(coreNum, startupData);
195 }
196 return kStatus_MCMGR_Error; /* coco validated: line never reached, MCMGR_GetCurrentCore() returns coreNum from
197 register and g_mcmgrSystem is defined as const */
198 }
199
MCMGR_StopCore(mcmgr_core_t coreNum)200 mcmgr_status_t MCMGR_StopCore(mcmgr_core_t coreNum)
201 {
202 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
203 {
204 return mcmgr_stop_core_internal(coreNum);
205 }
206 return kStatus_MCMGR_Error;
207 }
208
MCMGR_GetVersion(void)209 int32_t MCMGR_GetVersion(void)
210 {
211 return (int32_t)kMCMGR_Version;
212 }
213
MCMGR_GetCoreProperty(mcmgr_core_t coreNum,mcmgr_core_property_t property,void * value,uint32_t * length)214 mcmgr_status_t MCMGR_GetCoreProperty(mcmgr_core_t coreNum,
215 mcmgr_core_property_t property,
216 void *value,
217 uint32_t *length)
218 {
219 if ((uint32_t)coreNum < g_mcmgrSystem.coreCount)
220 {
221 return mcmgr_get_core_property_internal(coreNum, property, value, length);
222 }
223 return kStatus_MCMGR_Error;
224 }
225
MCMGR_GetCoreCount(void)226 uint32_t MCMGR_GetCoreCount(void)
227 {
228 return g_mcmgrSystem.coreCount;
229 }
230
MCMGR_GetCurrentCore(void)231 mcmgr_core_t MCMGR_GetCurrentCore(void)
232 {
233 return mcmgr_get_current_core_internal();
234 }
235