1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of Freescale Semiconductor nor the
12  *       names of its contributors may be used to endorse or promote products
13  *       derived from this software without specific prior written permission.
14  *
15  *
16  * ALTERNATIVELY, this software may be distributed under the terms of the
17  * GNU General Public License ("GPL") as published by the Free Software
18  * Foundation, either version 2 of that License or (at your option) any
19  * later version.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /******************************************************************************
34  @File          fm_pcd.c
35 
36  @Description   FM PCD ...
37 *//***************************************************************************/
38 #include "std_ext.h"
39 #include "error_ext.h"
40 #include "string_ext.h"
41 #include "debug_ext.h"
42 #include "net_ext.h"
43 
44 #include "fm_common.h"
45 #include "fm_pcd.h"
46 #include "fm_pcd_ipc.h"
47 
48 
49 t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
50 {
51     t_FmPcdPrs  *p_FmPcdPrs;
52     uintptr_t   baseAddr;
53 
54     UNUSED(p_FmPcd);
55     UNUSED(p_FmPcdParams);
56 
57     p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
58     if (!p_FmPcdPrs)
59     {
60         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
61         return NULL;
62     }
63     memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
64 
65     if (p_FmPcd->guestId == NCSW_MASTER_ID)
66     {
67         baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
68         p_FmPcdPrs->p_SwPrsCode  = (uint32_t *)UINT_TO_PTR(baseAddr);
69         p_FmPcdPrs->p_FmPcdPrsRegs  = (t_FmPcdPrsRegs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
70     }
71 
72     p_FmPcdPrs->fmPcdPrsPortIdStatistics             = 0;
73     p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit   = DEFAULT_prsMaxParseCycleLimit;
74     p_FmPcd->exceptions |= (DEFAULT_fmPcdPrsErrorExceptions | DEFAULT_fmPcdPrsExceptions);
75 
76     return p_FmPcdPrs;
77 }
78 
79 static void PcdPrsErrorException(t_Handle h_FmPcd)
80 {
81     t_FmPcd                 *p_FmPcd = (t_FmPcd *)h_FmPcd;
82     uint32_t                event, mask, force;
83 
84     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
85     event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr);
86     mask = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer);
87 
88     event &= mask;
89 
90     /* clear the forced events */
91     force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr);
92     if(force & event)
93         WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, force & ~event);
94 
95     WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr, event);
96 
97     DBG(TRACE, ("parser error - 0x%08x\n",event));
98 
99     if(event & FM_PCD_PRS_DOUBLE_ECC)
100         p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
101 }
102 
103 static void PcdPrsException(t_Handle h_FmPcd)
104 {
105     t_FmPcd             *p_FmPcd = (t_FmPcd *)h_FmPcd;
106     uint32_t            event, force;
107 
108     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
109     event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr);
110     event &= GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever);
111 
112     ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
113 
114     DBG(TRACE, ("parser event - 0x%08x\n",event));
115 
116     /* clear the forced events */
117     force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr);
118     if(force & event)
119         WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, force & ~event);
120 
121     WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr, event);
122 
123     p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
124 }
125 
126 static uint32_t GetSwPrsOffset(t_Handle h_FmPcd,  e_NetHeaderType hdr, uint8_t  indexPerHdr)
127 {
128     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
129     int                     i;
130     t_FmPcdPrsLabelParams   *p_Label;
131 
132     SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
133     SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
134 
135     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
136     ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
137 
138     for (i=0; i < p_FmPcd->p_FmPcdPrs->currLabel; i++)
139     {
140         p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
141 
142         if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
143             return p_Label->instructionOffset;
144     }
145 
146     REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
147     return (uint32_t)ILLEGAL_BASE;
148 }
149 
150 t_Error PrsInit(t_FmPcd *p_FmPcd)
151 {
152     t_FmPcdDriverParam  *p_Param = p_FmPcd->p_FmPcdDriverParam;
153     t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
154     uint32_t            tmpReg;
155 
156     if(p_FmPcd->guestId != NCSW_MASTER_ID)
157         return E_OK;
158 
159     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
160 
161 #ifdef FM_PRS_MEM_ERRATA_FMAN_SW003
162     {
163         uint32_t            i;
164         uint32_t            regsToGlobalOffset = 0x840;
165         uint32_t            firstPortToGlobalOffset = 0x45800;
166         uint64_t            globalAddr = PTR_TO_UINT(p_Regs) - regsToGlobalOffset;
167         uint32_t            firstPortAddr = (uint32_t)(globalAddr - (uint64_t)firstPortToGlobalOffset);
168         uint32_t            portSize = 0x1000;
169         t_FmRevisionInfo    revInfo;
170 
171         FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
172         if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
173         {
174             /* clear all parser memory */
175             IOMemSet32(UINT_TO_PTR(globalAddr), 0x00000000, 0x800);
176             for(i = 0;i<16;i++)
177                 IOMemSet32(UINT_TO_PTR(firstPortAddr+i*portSize), (uint8_t)0x00000000, (uint32_t)0x80);
178         }
179     }
180 #endif /* FM_PRS_MEM_ERRATA_FMAN_SW003 */
181 
182     /**********************RPCLIM******************/
183     WRITE_UINT32(p_Regs->rpclim, (uint32_t)p_Param->prsMaxParseCycleLimit);
184     /**********************FMPL_RPCLIM******************/
185 
186     /* register even if no interrupts enabled, to allow future enablement */
187     FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
188 
189     /* register even if no interrupts enabled, to allow future enablement */
190     FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
191 
192     /**********************PEVR******************/
193     WRITE_UINT32(p_Regs->pevr, (FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS) );
194     /**********************PEVR******************/
195 
196     /**********************PEVER******************/
197     if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
198     {
199         FmEnableRamsEcc(p_FmPcd->h_Fm);
200         WRITE_UINT32(p_Regs->pever, FM_PCD_PRS_SINGLE_ECC);
201     }
202     else
203         WRITE_UINT32(p_Regs->pever, 0);
204     /**********************PEVER******************/
205 
206     /**********************PERR******************/
207     WRITE_UINT32(p_Regs->perr, FM_PCD_PRS_DOUBLE_ECC);
208 
209     /**********************PERR******************/
210 
211     /**********************PERER******************/
212     tmpReg = 0;
213     if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
214     {
215         FmEnableRamsEcc(p_FmPcd->h_Fm);
216         tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
217     }
218     WRITE_UINT32(p_Regs->perer, tmpReg);
219     /**********************PERER******************/
220 
221     /**********************PPCS******************/
222     WRITE_UINT32(p_Regs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
223     /**********************PPCS******************/
224 
225 #ifdef FM_PRS_L4_SHELL_ERRATA_FMANb
226     {
227         uint32_t            i, j;
228         t_FmRevisionInfo    revInfo;
229         uint8_t             swPrsL4Patch[] = SW_PRS_L4_PATCH;
230 
231         FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
232         if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
233         {
234             /* load sw parser L4 patch */
235             for(i=0;i<sizeof(swPrsL4Patch)/4;i++)
236             {
237                tmpReg = 0;
238                for(j =0;j<4;j++)
239                {
240                   tmpReg <<= 8;
241                   tmpReg |= swPrsL4Patch[i*4+j];
242 
243                }
244                 WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+ FM_PCD_PRS_SW_OFFSET/4 + i), tmpReg);
245             }
246             p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = FM_PCD_PRS_SW_OFFSET/4 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode+sizeof(swPrsL4Patch)/4;
247         }
248     }
249 #endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */
250 
251     return E_OK;
252 }
253 
254 void PrsFree(t_FmPcd *p_FmPcd )
255 {
256     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
257     FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
258     /* register even if no interrupts enabled, to allow future enablement */
259     FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
260 }
261 
262 void PrsEnable(t_FmPcd *p_FmPcd )
263 {
264     t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
265 
266     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
267     WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) | FM_PCD_PRS_RPIMAC_EN);
268 }
269 
270 void PrsDisable(t_FmPcd *p_FmPcd )
271 {
272     t_FmPcdPrsRegs      *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
273 
274     ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
275     WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) & ~FM_PCD_PRS_RPIMAC_EN);
276 }
277 
278 t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
279 {
280     uint32_t    bitMask = 0;
281     uint8_t     prsPortId;
282 
283     SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
284     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
285     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
286 
287     GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
288     GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
289 
290     if(include)
291         p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
292     else
293         p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
294 
295     WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
296 
297     return E_OK;
298 }
299 
300 t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
301 {
302     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
303     t_FmPcdIpcPrsIncludePort    prsIncludePortParams;
304     t_FmPcdIpcMsg               msg;
305     t_Error                     err;
306 
307     SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
308     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
309     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
310 
311     if(p_FmPcd->guestId != NCSW_MASTER_ID)
312     {
313         prsIncludePortParams.hardwarePortId = hardwarePortId;
314         prsIncludePortParams.include = include;
315         memset(&msg, 0, sizeof(msg));
316         msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
317         memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
318         if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
319                                      (uint8_t*)&msg,
320                                      sizeof(msg.msgId) +sizeof(prsIncludePortParams),
321                                      NULL,
322                                      NULL,
323                                      NULL,
324                                      NULL)) != E_OK)
325             RETURN_ERROR(MAJOR, err, NO_MSG);
326         return E_OK;
327     }
328     return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
329 }
330 
331 uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
332 {
333     t_FmPcd                 *p_FmPcd = (t_FmPcd *)h_FmPcd;
334     t_Error                 err = E_OK;
335     t_FmPcdIpcSwPrsLable    labelParams;
336     t_FmPcdIpcMsg           msg;
337     uint32_t                prsOffset = 0;
338     t_FmPcdIpcReply         reply;
339     uint32_t                replyLength;
340 
341     if(p_FmPcd->guestId != NCSW_MASTER_ID)
342     {
343         memset(&reply, 0, sizeof(reply));
344         memset(&msg, 0, sizeof(msg));
345         labelParams.enumHdr = (uint32_t)hdr;
346         labelParams.indexPerHdr = indexPerHdr;
347         msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
348         memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
349         replyLength = sizeof(uint32_t) + sizeof(uint32_t);
350         if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
351                                      (uint8_t*)&msg,
352                                      sizeof(msg.msgId) +sizeof(labelParams),
353                                      (uint8_t*)&reply,
354                                      &replyLength,
355                                      NULL,
356                                      NULL)) != E_OK)
357             RETURN_ERROR(MAJOR, err, NO_MSG);
358         if(replyLength != sizeof(uint32_t) + sizeof(uint32_t))
359             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
360 
361         memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
362         return prsOffset;
363     }
364 
365     return GetSwPrsOffset(h_FmPcd, hdr, indexPerHdr);
366 }
367 
368 void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
369 {
370     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
371 
372     SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
373     SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
374 
375     if(p_FmPcd->guestId != NCSW_MASTER_ID)
376     {
377         REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
378         return;
379     }
380     if(enable)
381         WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, FM_PCD_PRS_PPSC_ALL_PORTS);
382     else
383         WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, 0);
384 
385 }
386 
387 t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
388 {
389     t_FmPcd                 *p_FmPcd = (t_FmPcd*)h_FmPcd;
390     uint32_t                *p_LoadTarget, tmpReg;
391     int                     i, j;
392 
393     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
394     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
395     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
396     SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
397     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
398 
399     if(p_FmPcd->guestId != NCSW_MASTER_ID)
400         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_PrsLoadSw - guest mode!"));
401 
402     if(!p_SwPrs->override)
403     {
404         if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
405             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
406     }
407     if(p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
408         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
409     if(p_SwPrs->size % 4)
410         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size must be divisible by 4"));
411 
412     /* save sw parser labels */
413     if(p_SwPrs->override)
414         p_FmPcd->p_FmPcdPrs->currLabel = 0;
415     if(p_FmPcd->p_FmPcdPrs->currLabel+ p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
416         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
417     memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], p_SwPrs->labelsTable, p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
418     p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
419     /* load sw parser code */
420     p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
421     for(i=0;i<p_SwPrs->size/4;i++)
422     {
423         tmpReg = 0;
424         for(j =0;j<4;j++)
425         {
426             tmpReg <<= 8;
427             tmpReg |= *(p_SwPrs->p_Code+i*4+j);
428         }
429         WRITE_UINT32(*(p_LoadTarget + i), tmpReg);
430     }
431     p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + p_SwPrs->size/4;
432 
433     /* copy data parameters */
434     for(i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
435         WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
436 
437 
438     /* Clear last 4 bytes */
439     WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
440 
441     return E_OK;
442 }
443 
444 t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
445 {
446     t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
447 
448     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
449     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
450 
451     if(p_FmPcd->guestId != NCSW_MASTER_ID)
452         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
453 
454     p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
455 
456     return E_OK;
457 }
458 
459 
460 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
461 t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd)
462 {
463     t_FmPcd             *p_FmPcd = (t_FmPcd*)h_FmPcd;
464     t_FmPcdIpcMsg       msg;
465 
466     DECLARE_DUMP;
467 
468     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
469     SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
470     SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
471 
472     if(p_FmPcd->guestId != NCSW_MASTER_ID)
473     {
474         memset(&msg, 0, sizeof(msg));
475         msg.msgId = FM_PCD_PRS_DUMP_REGS;
476         return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
477                                     (uint8_t*)&msg,
478                                     sizeof(msg.msgId),
479                                     NULL,
480                                     NULL,
481                                     NULL,
482                                     NULL);
483     }
484     DUMP_SUBTITLE(("\n"));
485     DUMP_TITLE(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs, ("FmPcdPrsRegs Regs"));
486 
487     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpclim);
488     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpimac);
489     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pmeec);
490     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevr);
491     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pever);
492     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevfr);
493     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perr);
494     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perer);
495     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perfr);
496     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,ppsc);
497     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pds);
498     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rrs);
499     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rrs);
500     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rrs);
501     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srrs);
502     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rres);
503     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rres);
504     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rres);
505     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srres);
506     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spcs);
507     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spscs);
508     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,hxscs);
509     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrcs);
510     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwcs);
511     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrscs);
512     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwscs);
513     DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fcscs);
514 
515     return E_OK;
516 }
517 #endif /* (defined(DEBUG_ERRORS) && ... */
518