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