1 /**
2 * @file fault_mgmt.c
3 *
4 * @brief
5 * The file implements the Fault Management library.
6 *
7 * \par
8 * NOTE:
9 * (C) Copyright 2012-2015 Texas Instruments, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 */
42 /**************************************************************************
43 *************************** Include Files ********************************
44 **************************************************************************/
46 /* Standard Include Files. */
47 #include <string.h>
48 #include <stdio.h>
50 /* BIOS/XDC Include Files. */
51 #include <ti/sysbios/family/c64p/Exception.h>
53 /* CSL Include Files. */
54 #include <ti/csl/csl_chip.h>
55 #include <ti/csl/csl_cacheAux.h>
56 #include <ti/csl/csl_ipcAux.h>
57 #include <ti/csl/csl_cppi.h>
58 #include <ti/csl/csl_cpsgmiiAux.h>
59 #include <ti/csl/csl_edma3Aux.h>
60 #include <ti/csl/csl_pscAux.h>
62 /* LLD Includes */
63 #include <ti/drv/cppi/cppi_drv.h>
64 #include <ti/drv/aif2/aif2.h>
66 /* FM API Include */
67 #include <ti/instrumentation/fault_mgmt/fault_mgmt.h>
69 /* FM Internal Include */
70 #include <ti/instrumentation/fault_mgmt/include/fm_loc.h>
71 #include <ti/instrumentation/fault_mgmt/include/fm_exclusionloc.h>
72 #include <ti/instrumentation/fault_mgmt/include/fm_cleanloc.h>
74 /* Fault Management OSAL File. */
75 #include <fault_mgmt_osal.h>
77 /**************************************************************************
78 ********************** Internal Data Structures **************************
79 **************************************************************************/
81 /* Note section name length in bytes (chars). */
82 #define NOTE_NAME_LEN 32
84 /* Structure specifying the ELF program header Note section header.
85 * ELF Note Section:
86 *
87 * byte +0 +1 +2 +3
88 * +--------+--------+---------+--------+
89 * namesz | # bytes in name field excluding pad|
90 * +--------+--------+---------+--------+
91 * descsz | # bytes in desc field excluding pad|
92 * +--------+--------+---------+--------+
93 * type | Not Used (should be zero) |
94 * +--------+--------+---------+--------+
95 * name | char 0 | char 1 | char 2 | char 3 |
96 * +--------+--------+---------+--------+
97 * | char 4 | ... | char n | pad |
98 * +--------+--------+---------+--------+
99 * desc | word 0 |
100 * +--------+--------+---------+--------+
101 * | word 1 |
102 * +--------+--------+---------+--------+
103 */
104 typedef struct
105 {
106 uint32_t namesz;
107 uint32_t descsz;
108 uint32_t type;
109 } elfNoteHeader;
111 /**********************************************************************
112 ************************** Globals ***********************************
113 **********************************************************************/
115 #pragma DATA_ALIGN (fault_mgmt_data, CACHE_L2_LINESIZE)
116 #pragma DATA_SECTION (fault_mgmt_data, ".note");
117 uint8_t fault_mgmt_data[FAULT_MGMT_DATA_SIZE];
119 #if (!defined(DEVICE_K2H) && !defined(DEVICE_K2K) && \
120 !defined(DEVICE_K2L) && !defined(DEVICE_K2E))
121 /* Cache line aligned and padded */
122 #pragma DATA_ALIGN (fmCleanupStatus, CACHE_L2_LINESIZE)
123 #pragma DATA_SECTION (fmCleanupStatus, ".fm_cleanup_status");
124 int32_t fmCleanupStatus[32];
125 #endif /* !(K2H && K2K && K2L && K2E) */
127 /* Heap needed to initialize CPPI prior to IO halt execution */
128 uint8_t tempCppiHeap[32000];
130 /* AIF configuration object. Defined as global because it's a large object
131 * that may cause overflow in smaller stacks */
132 AIF_ConfigObj localAifObj;
134 /**********************************************************************
135 ******************** External Variables ******************************
136 **********************************************************************/
138 /* CPPI Global configuration parameters */
139 extern Cppi_GlobalConfigParams cppiGblCfgParams[];
141 /**********************************************************************
142 ************************ Local Functions *****************************
143 **********************************************************************/
145 /* FUNCTION PURPOSE: Disables a given CPDMA channel
146 ***********************************************************************
147 * DESCRIPTION: Opens then disables a specified CPDMA channel
148 */
149 static void disableDmaCh(Cppi_Handle cppiHandle, int32_t dmaNum,
150 int32_t chNum, uint32_t isRxCh)
151 {
152 Cppi_RxChInitCfg rxChCfg;
153 Cppi_TxChInitCfg txChCfg;
154 Cppi_ChHnd chHandle;
155 uint8_t isAllocated;
156 Cppi_Result cppiResult;
158 if (isRxCh) {
159 memset((void *) &rxChCfg, 0, sizeof(rxChCfg));
160 rxChCfg.channelNum = chNum;
162 if (chHandle = Cppi_rxChannelOpen(cppiHandle, &rxChCfg, &isAllocated)) {
163 if(cppiResult = Cppi_channelDisable(chHandle) != CPPI_SOK) {
164 Fault_Mgmt_osalLog("IO Halt: Failed to disable cppi rx ch %d "
165 "with err %d\n", chNum, cppiResult);
166 }
167 } else {
168 Fault_Mgmt_osalLog("IO Halt: "
169 "Failed to open DMA %d, RX channel %d\n",
170 dmaNum, chNum);
171 }
172 } else {
173 memset((void *) &txChCfg, 0, sizeof(txChCfg));
174 txChCfg.channelNum = chNum;
176 if (chHandle = Cppi_txChannelOpenWithHwCfg(cppiHandle, &txChCfg,
177 &isAllocated, 0)) {
178 if(cppiResult = Cppi_channelDisable(chHandle) != CPPI_SOK) {
179 Fault_Mgmt_osalLog("IO Halt: Failed to disable cppi tx ch %d "
180 "with err %d\n", chNum, cppiResult);
181 }
182 } else {
183 Fault_Mgmt_osalLog("IO Halt: "
184 "Failed to open DMA %d, TX channel %d\n",
185 dmaNum, chNum);
186 }
187 }
188 }
190 /* FUNCTION PURPOSE: Creates the note header
191 ***********************************************************************
192 * DESCRIPTION: Creates the note header. Only the fault data region
193 * size if calculated if NULL is provided for the
194 * fault data region pointer.
195 */
196 static uint32_t createNoteHeader(uint32_t **pFaultDataPtr)
197 {
198 elfNoteHeader noteHeader;
199 char elfNoteName[NOTE_NAME_LEN];
200 uint32_t totalBytes = 0;
201 uint32_t *locPtr = NULL;
203 if (pFaultDataPtr) {
204 locPtr = *pFaultDataPtr;
205 }
207 memset((void *)¬eHeader, 0, sizeof(noteHeader));
208 totalBytes = sizeof(noteHeader);
210 sprintf(elfNoteName, "Core%d", DNUM);
211 noteHeader.namesz = strlen(elfNoteName) + 1;
212 totalBytes += noteHeader.namesz;
213 if (locPtr) {
214 *locPtr++ = noteHeader.namesz;
215 }
217 /* Calculate size of desc section. Subtract out size of pointer to
218 * Exception_Context structure since that structure is added in entirety.
219 * Add an additional uint32_t for PC value that is added. The PC is not
220 * tracked by the Exception Status or Context*/
221 noteHeader.descsz = (sizeof(ti_sysbios_family_c64p_Exception_Status) -
222 sizeof(ti_sysbios_family_c64p_Exception_Context *)) +
223 sizeof (ti_sysbios_family_c64p_Exception_Context) +
224 sizeof (uint32_t);
225 totalBytes += noteHeader.descsz;
227 /* noteHeader type should always be 0 */
228 noteHeader.type = 0;
229 if (locPtr) {
230 *locPtr++ = noteHeader.descsz;
231 *locPtr++ = noteHeader.type;
232 }
234 if (locPtr) {
235 memcpy ((void *)locPtr, (void *)&elfNoteName[0], noteHeader.namesz);
236 locPtr += (noteHeader.namesz/sizeof(noteHeader.namesz));
237 }
239 /* Account for name padding */
240 if (noteHeader.namesz % sizeof(noteHeader.namesz)) {
241 totalBytes += (sizeof(noteHeader.namesz) -
242 (noteHeader.namesz % sizeof(noteHeader.namesz)));
243 if (locPtr) {
244 locPtr++;
245 }
246 }
248 if (locPtr) {
249 *pFaultDataPtr = locPtr;
250 }
251 return(totalBytes);
252 }
254 /**********************************************************************
255 ********************** FM-Visible Functions **************************
256 **********************************************************************/
258 /* FUNCTION PURPOSE: Checks if a wireless peripheral is powered on
259 ***********************************************************************
260 * DESCRIPTION: Checks if a wireless peripheral is powered on via the
261 * PSC registers
262 */
263 uint32_t fmIsWirelessPeriphPoweredOnForCpdma(Cppi_CpDma dmaNum)
264 {
265 #ifndef DEVICE_K2E
266 uint32_t pwrDmnNum;
267 uint32_t moduleNum;
269 switch (dmaNum) {
270 #if (defined(DEVICE_K2H) || defined(DEVICE_K2K))
271 /* K2 devices */
272 case Cppi_CpDma_AIF_CPDMA:
273 pwrDmnNum = CSL_PSC_PD_AIF;
274 moduleNum = CSL_PSC_LPSC_AIF;
275 break;
276 case Cppi_CpDma_FFTC_A_CPDMA:
277 pwrDmnNum = CSL_PSC_PD_FFTC_01;
278 moduleNum = CSL_PSC_LPSC_FFTC_0;
279 break;
280 case Cppi_CpDma_FFTC_B_CPDMA:
281 pwrDmnNum = CSL_PSC_PD_FFTC_01;
282 moduleNum = CSL_PSC_LPSC_FFTC_1;
283 break;
284 case Cppi_CpDma_FFTC_C_CPDMA:
285 pwrDmnNum = CSL_PSC_PD_FFTC_2345;
286 moduleNum = CSL_PSC_LPSC_FFTC_2;
287 break;
288 case Cppi_CpDma_FFTC_D_CPDMA:
289 pwrDmnNum = CSL_PSC_PD_FFTC_2345;
290 moduleNum = CSL_PSC_LPSC_FFTC_3;
291 break;
292 case Cppi_CpDma_FFTC_E_CPDMA:
293 pwrDmnNum = CSL_PSC_PD_FFTC_2345;
294 moduleNum = CSL_PSC_LPSC_FFTC_4;
295 break;
296 case Cppi_CpDma_FFTC_F_CPDMA:
297 pwrDmnNum = CSL_PSC_PD_FFTC_2345;
298 moduleNum = CSL_PSC_LPSC_FFTC_5;
299 break;
300 #elif (defined(DEVICE_K2L))
301 case Cppi_CpDma_FFTC_A_CPDMA:
302 pwrDmnNum = CSL_PSC_PD_FFTC_0;
303 moduleNum = CSL_PSC_LPSC_FFTC_0;
304 break;
305 #elif (!defined(DEVICE_K2E))
306 /* Appleton */
307 case Cppi_CpDma_AIF_CPDMA:
308 pwrDmnNum = CSL_PSC_PD_AI;
309 moduleNum = CSL_PSC_LPSC_AI;
310 break;
311 case Cppi_CpDma_FFTC_A_CPDMA:
312 case Cppi_CpDma_FFTC_B_CPDMA:
313 pwrDmnNum = CSL_PSC_PD_FFTC_AB;
314 moduleNum = CSL_PSC_LPSC_FFTC_AB;
315 break;
316 #endif
317 case Cppi_CpDma_BCP_CPDMA:
318 pwrDmnNum = CSL_PSC_PD_BCP;
319 moduleNum = CSL_PSC_LPSC_BCP;
320 break;
321 default:
322 return (FM_TRUE);
323 }
325 /* Get peripheral PSC status */
326 if ((CSL_PSC_getPowerDomainState(pwrDmnNum) == PSC_PDSTATE_ON) &&
327 (CSL_PSC_getModuleState (moduleNum) == PSC_MODSTATE_ENABLE)) {
328 /* On */
329 return (FM_TRUE);
330 } else {
331 /* Off */
332 return (FM_FALSE);
333 }
334 #else
335 return (FM_TRUE);
336 #endif
337 }
339 /**********************************************************************
340 ********************** Application Visible APIs **********************
341 **********************************************************************/
343 #if (!defined(DEVICE_K2H) && !defined(DEVICE_K2K) && \
344 !defined(DEVICE_K2L) && !defined(DEVICE_K2E))
345 /* FUNCTION PURPOSE: Resets system peripherals to their power on reset state
346 ***********************************************************************
347 * DESCRIPTION: Can be called to reset system peripherals to their power on
348 * reset state. After a DSP local reset an application that
349 * uses system peripherals can be loaded without fear of a
350 * corrupted peripheral state.
351 */
352 Fm_Result Fault_Mgmt_faultCleanup(Fm_GlobalConfigParams *fmGblCfgParams,
353 Fm_CleanupCfg *cleanupCfg)
354 {
355 uint32_t numEntries;
356 int32_t validateStatus;
357 uint32_t fullInit = FM_TRUE;
358 Fm_Result retVal = FM_FAULT_CLEANUP_OK;
360 /* Writeback status so that Host can view it */
361 fmCleanupStatus[0] = FM_OK;
362 Fault_Mgmt_osalEndMemAccess(&fmCleanupStatus[0], sizeof(fmCleanupStatus));
364 /* Validate exclusion entries and return number of entries */
365 numEntries = fmExclusionValidateList(fmGblCfgParams,
366 cleanupCfg->excludedResources,
367 &validateStatus);
368 if (validateStatus < 0) {
369 Fault_Mgmt_osalLog("Fault Cleanup: Failed because entry %d (base 0) "
370 "of exclusion list has invalid exResInfo field\n",
371 numEntries);
372 retVal = validateStatus;
373 goto errorExit;
374 }
376 /* Do not do full initializtion of peripherals if there are excluded
377 * resources. This means the peripherals have already been configured */
378 if (numEntries) {
379 fullInit = FM_FALSE;
380 }
382 /* Clean sems first since they may be used in LLD OSAL layers */
383 if ((retVal = fmCleanSemaphores(cleanupCfg->excludedResources,
384 numEntries)) != FM_FAULT_CLEANUP_OK) {
385 goto errorExit;
386 }
387 /* Stop all timers */
388 if ((retVal = fmCleanTimers(fmGblCfgParams, cleanupCfg->excludedResources,
389 numEntries)) != FM_FAULT_CLEANUP_OK) {
390 goto errorExit;
391 }
393 /* Init CPPI, QMSS, etc data structures for cleanup */
394 if ((retVal = fmCleanupInit(fullInit)) != FM_FAULT_CLEANUP_OK) {
395 goto errorExit;
396 }
398 /* Shut down all the wireless peripherals first (Expectation is any app
399 * using them will power them on at init) AIF gets cleaned first since it
400 * is the heartbeat for all wireless peripherals. The wireless peripherals
401 * will be in an "idle" state after the AIF is cleaned */
402 if (cleanupCfg->cleanAif2) {
403 if ((retVal = fmCleanAif2()) != FM_FAULT_CLEANUP_OK) {
404 goto errorExit;
405 }
406 }
407 if (cleanupCfg->cleanTcp3d) {
408 if ((retVal = fmCleanTcp3d()) != FM_FAULT_CLEANUP_OK) {
409 goto errorExit;
410 }
411 }
412 if (cleanupCfg->cleanBcp) {
413 if ((retVal = fmCleanBcp()) != FM_FAULT_CLEANUP_OK) {
414 goto errorExit;
415 }
416 }
417 if (cleanupCfg->cleanFftc) {
418 if ((retVal = fmCleanFftc()) != FM_FAULT_CLEANUP_OK) {
419 goto errorExit;
420 }
421 }
422 if (cleanupCfg->cleanVcp) {
423 if ((retVal = fmCleanVcp()) != FM_FAULT_CLEANUP_OK) {
424 goto errorExit;
425 }
426 }
428 if (cleanupCfg->cleanCpdma) {
429 if ((retVal = fmCleanCppi(cleanupCfg->excludedResources,
430 numEntries)) != FM_FAULT_CLEANUP_OK) {
431 goto errorExit;
432 }
433 }
434 if (cleanupCfg->cleanEdma3) {
435 if ((retVal = fmCleanEdma3(fmGblCfgParams,
436 cleanupCfg->excludedResources,
437 numEntries,
438 FM_TRUE)) != FM_FAULT_CLEANUP_OK) {
439 goto errorExit;
440 }
441 }
442 if (cleanupCfg->cleanQmss) {
443 if ((retVal = fmCleanQmssQueue(fmGblCfgParams,
444 cleanupCfg->excludedResources,
445 numEntries)) != FM_FAULT_CLEANUP_OK) {
446 goto errorExit;
447 }
448 }
449 if (cleanupCfg->cleanPa) {
450 if ((retVal = fmCleanPa(fmGblCfgParams,
451 cleanupCfg->excludedResources,
452 numEntries)) != FM_FAULT_CLEANUP_OK) {
453 goto errorExit;
454 }
455 }
456 if (cleanupCfg->cleanSa) {
457 if ((retVal = fmCleanSa(cleanupCfg->excludedResources,
458 numEntries)) != FM_FAULT_CLEANUP_OK) {
459 goto errorExit;
460 }
461 }
462 /* Clean QMSS again in case of descriptor leakage during PA and SA
463 * cleanup */
464 if (cleanupCfg->cleanQmss) {
465 if ((retVal = fmCleanQmssQueue(fmGblCfgParams,
466 cleanupCfg->excludedResources,
467 numEntries)) != FM_FAULT_CLEANUP_OK) {
468 goto errorExit;
469 }
470 }
471 if (cleanupCfg->cleanQmss) {
472 if ((retVal = fmCleanQmssAccum(fmGblCfgParams,
473 cleanupCfg->excludedResources,
474 numEntries)) != FM_FAULT_CLEANUP_OK) {
475 goto errorExit;
476 }
477 }
478 /* Clean out all the CIC mappings after everything has been disabled */
479 if ((retVal = fmCleanCics(fmGblCfgParams, cleanupCfg->excludedResources,
480 numEntries)) != FM_FAULT_CLEANUP_OK) {
481 goto errorExit;
482 }
483 /* Clean sems again at end to wipe fresh for application restart */
484 if ((retVal = fmCleanSemaphores(cleanupCfg->excludedResources,
485 numEntries)) != FM_FAULT_CLEANUP_OK) {
486 goto errorExit;
487 }
489 errorExit:
490 /* Writeback status so that Host can view it */
491 fmCleanupStatus[0] = retVal;
492 Fault_Mgmt_osalEndMemAccess(&fmCleanupStatus[0], sizeof(fmCleanupStatus));
494 return(retVal);
495 }
496 #endif /* !(K2H && K2K && K2L && K2E) */
498 /* FUNCTION PURPOSE: Halts certain IO processing mechanisms
499 ***********************************************************************
500 * DESCRIPTION: Stops hardware processing in the following IO:
501 * - EMDA3 DMA, QDMA, and INT channels
502 * - AIF PE/PD channels
503 * - SGMII switch
504 * - CPDMA tx/rx channels
505 */
506 Fm_Result Fault_Mgmt_haltIoProcessing(Fm_GlobalConfigParams *fmGblCfgParams,
507 Fm_HaltCfg *haltCfg)
508 {
509 uint32_t numEntries;
510 int32_t validateStatus;
511 Fm_ExclusionParams exclusionParams;
512 int32_t i, j;
513 Cppi_Result cppiResult;
514 uint32_t heapSize;
515 Cppi_InitCfg cppiInitCfg;
516 Cppi_CpDmaInitCfg dmaCfg;
517 Cppi_Handle cppiHandle;
519 /* Validate exclusion entries and return number of entries */
520 numEntries = fmExclusionValidateList(fmGblCfgParams,
521 haltCfg->excludedResources,
522 &validateStatus);
523 if (validateStatus < 0) {
524 Fault_Mgmt_osalLog("IO Halt: Failed because entry %d (base 0) of "
525 "exclusion list has invalid exResInfo field\n",
526 numEntries);
527 return(validateStatus);
528 }
530 memset(&exclusionParams, 0, sizeof(exclusionParams));
531 exclusionParams.exclusionList = haltCfg->excludedResources;
532 exclusionParams.numListEntries = numEntries;
534 if (haltCfg->haltEdma3) {
535 /* Reuse recovery function */
536 fmCleanEdma3(fmGblCfgParams, haltCfg->excludedResources, numEntries,
537 FM_FALSE);
538 }
540 if (haltCfg->haltAif2) {
541 #if (!defined(DEVICE_K2L) && !defined(DEVICE_K2E))
542 /* Halts AIF2 peripheral resources. Resources in the exclusion
543 * list will not be reset */
545 /* Disable all the AIF2 PE (TX) and PD (RX) channels. */
546 exclusionParams.resType = Fm_res_AifPeCh;
547 for (i = 0; i < fmGblCfgParams->maxAifPeCh; i++) {
548 exclusionParams.resourceNum = i;
549 if (!fmExclusionIsExcluded(&exclusionParams)) {
550 AIF_disablePeCh(&localAifObj, i);
551 }
552 }
553 exclusionParams.resType = Fm_res_AifPdCh;
554 for (i = 0; i < fmGblCfgParams->maxAifPdCh; i++) {
555 exclusionParams.resourceNum = i;
556 if (!fmExclusionIsExcluded(&exclusionParams)) {
557 AIF_disablePdCh(&localAifObj, i);
558 }
559 }
561 /* Reset the AIF2 timers */
562 AIF_resetFsync(&localAifObj);
563 #endif /* !(K2L && K2E) */
564 }
566 if (haltCfg->haltSGMII) {
567 /* Halt the RX/TX transmit logic by starting soft reset but not
568 * completing it */
569 CSL_SGMII_startRxTxSoftReset(0);
570 CSL_SGMII_startRxTxSoftReset(1);
571 }
573 if (haltCfg->haltCpdma) {
574 /* Setup CPPI */
575 cppiResult = Cppi_getHeapReq(cppiGblCfgParams, &heapSize);
576 if (sizeof(tempCppiHeap) < heapSize) {
577 Fault_Mgmt_osalLog("IO Halt: Temp heap needed to initalize CPPI is "
578 "too small");
579 }
580 cppiInitCfg.heapParams.staticHeapBase = &tempCppiHeap[0];
581 cppiInitCfg.heapParams.staticHeapSize = heapSize;
582 cppiInitCfg.heapParams.heapAlignPow2 = 8;
583 cppiInitCfg.heapParams.dynamicHeapBlockSize = -1;
585 cppiResult = Cppi_initCfg(cppiGblCfgParams, &cppiInitCfg);
586 if (cppiResult != CPPI_SOK) {
587 Fault_Mgmt_osalLog("IO Halt: Failed CPPI init\n");
588 return(FM_ERROR_CPPI_INIT_FAILED);
589 }
591 memset(&exclusionParams, 0, sizeof(exclusionParams));
592 exclusionParams.exclusionList = haltCfg->excludedResources;
593 exclusionParams.numListEntries = numEntries;
595 /* Disable CPPI channels */
596 for (i = 0; i < CPPI_MAX_CPDMA; i++) {
597 if (fmIsWirelessPeriphPoweredOnForCpdma((Cppi_CpDma) i)) {
598 memset ((void *) &dmaCfg, 0, sizeof(dmaCfg));
599 dmaCfg.dmaNum = (Cppi_CpDma) i;
601 if (cppiHandle = Cppi_open(&dmaCfg)) {
602 exclusionParams.u.cpdmaParams.dma = dmaCfg.dmaNum;
603 exclusionParams.resType = Fm_res_CpdmaRxCh;
604 for (j = 0; j < fmGetDmaMaxRxCh(dmaCfg.dmaNum); j++) {
605 exclusionParams.resourceNum = j;
606 if (!fmExclusionIsExcluded(&exclusionParams)) {
607 disableDmaCh(cppiHandle, i, j, 1);
608 }
609 }
611 exclusionParams.resType = Fm_res_CpdmaTxCh;
612 for (j = 0; j < fmGetDmaMaxTxCh(dmaCfg.dmaNum); j++) {
613 exclusionParams.resourceNum = j;
614 if (!fmExclusionIsExcluded(&exclusionParams)) {
615 disableDmaCh(cppiHandle, i, j, 0);
616 }
617 }
618 }
619 }
620 }
621 }
623 return(FM_OK);
624 }
626 /* FUNCTION PURPOSE: Gets and stores the system register status
627 ***********************************************************************
628 * DESCRIPTION: Gets the system register status and stores it in the
629 * fault management data region.
630 */
631 void Fault_Mgmt_getLastRegStatus(void)
632 {
633 Exception_Status status;
634 uint32_t *faultDataPtr = (uint32_t *)&fault_mgmt_data[0];
636 /* Make sure note section fits within the provided fault data region */
637 if (Fault_Mgmt_getSizes() > FAULT_MGMT_DATA_SIZE) {
638 Fault_Mgmt_osalLog("Get Last Reg Status: Failed - ELF Note data "
639 "section is %d bytes. Need %d bytes.\n",
640 FAULT_MGMT_DATA_SIZE, Fault_Mgmt_getSizes());
641 return;
642 }
644 memset((void *)faultDataPtr, 0, FAULT_MGMT_DATA_SIZE);
646 createNoteHeader(&faultDataPtr);
648 /* Get the register status for the core dump. */
649 Exception_getLastStatus (&status);
651 /* Copy the execution context to fault management data memory and update
652 * number of bytes in the Note section. */
654 /* The very first data value in the "desc" field is the PC for the crash
655 * dump. The PC value should correspond to the NMI return pointer that was
656 * stored in the NRP register when the DSP exception triggered the
657 * exception handler which runs in the NMI context */
658 *faultDataPtr++ = status.nrp;
660 *faultDataPtr++ = status.efr;
661 *faultDataPtr++ = status.nrp;
662 *faultDataPtr++ = status.ntsr;
663 /* Copy IERR from exception context to the status value. According to the
664 * exception module it's tracked in two places. However, it is only
665 * updated in one of them. To avoid confusion on the host side when the
666 * fault is reported the valid value in the exception context is copied to
667 * the invalid value in the status context */
668 status.ierr = (uint32_t) status.excContext->IERR;
669 *faultDataPtr++ = status.ierr;
670 memcpy((void *)faultDataPtr, (void *)status.excContext,
671 sizeof(ti_sysbios_family_c64p_Exception_Context));
673 Fault_Mgmt_osalEndMemAccess(&fault_mgmt_data[0], FAULT_MGMT_DATA_SIZE);
675 return;
676 }
678 /* FUNCTION PURPOSE: Notifies Host of DSP fault
679 ***********************************************************************
680 * DESCRIPTION: Sends a notification to the Host via the IPC registers
681 * that a certain DSP has encountered an exception.
682 */
683 void Fault_Mgmt_notify(void)
684 {
685 CSL_IPC_genHostInterrupt(FM_HOST_IPCGR_OFFSET + DNUM);
686 return;
687 }
689 /* FUNCTION PURPOSE: Notifies remote DSP core of DSP fault
690 ***********************************************************************
691 * DESCRIPTION: Sends a notification to a remote DSP core via the IPC
692 * registers that a certain DSP has encountered an exception.
693 */
694 void Fault_Mgmt_notify_remote_core(uint32_t core_id)
695 {
696 CSL_IPC_genNMIEvent(core_id);
697 return;
698 }
700 /* FUNCTION PURPOSE: Returns the required fault management data region size
701 ***********************************************************************
702 * DESCRIPTION: Returns the required size of the fault management data
703 * region containing the crash dump data.
704 */
705 uint32_t Fault_Mgmt_getSizes(void)
706 {
707 return(createNoteHeader(NULL));
708 }
710 /**
711 @}
712 */