1 /**
2  * @file IxNpeDlNpeMgrUtils.c
3  *
4  * @author Intel Corporation
5  * @date 18 February 2002
6  *
7  * @brief This file contains the implementation of the private API for the
8  *        IXP425 NPE Downloader NpeMgr Utils module
9  *
10  *
11  * @par
12  * IXP400 SW Release version 2.0
13  *
14  * -- Copyright Notice --
15  *
16  * @par
17  * Copyright 2001-2005, Intel Corporation.
18  * All rights reserved.
19  *
20  * @par
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions
23  * are met:
24  * 1. Redistributions of source code must retain the above copyright
25  *    notice, this list of conditions and the following disclaimer.
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in the
28  *    documentation and/or other materials provided with the distribution.
29  * 3. Neither the name of the Intel Corporation nor the names of its contributors
30  *    may be used to endorse or promote products derived from this software
31  *    without specific prior written permission.
32  *
33  * @par
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  *
46  * @par
47  * -- End of Copyright Notice --
48 */
49 
50 
51 /*
52  * Put the system defined include files required.
53  */
54 #define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
55                                               * retries before
56                                               * timeout
57 					                          */
58 
59 /*
60  * Put the user defined include files required.
61  */
62 #include "IxOsal.h"
63 #include "IxNpeDl.h"
64 #include "IxNpeDlNpeMgrUtils_p.h"
65 #include "IxNpeDlNpeMgrEcRegisters_p.h"
66 #include "IxNpeDlMacros_p.h"
67 
68 /*
69  * #defines and macros used in this file.
70  */
71 
72 /* used to bit-mask a number of bytes */
73 #define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD  0x000000FF
74 #define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
75 #define IX_NPEDL_MASK_FULL_WORD           0xFFFFFFFF
76 
77 #define IX_NPEDL_BYTES_PER_WORD           4
78 #define IX_NPEDL_BYTES_PER_SHORT          2
79 
80 #define IX_NPEDL_REG_SIZE_BYTE            8
81 #define IX_NPEDL_REG_SIZE_SHORT           16
82 #define IX_NPEDL_REG_SIZE_WORD            32
83 
84 /*
85  * Introduce extra read cycles after issuing read command to NPE
86  * so that we read the register after the NPE has updated it
87  * This is to overcome race condition between XScale and NPE
88  */
89 #define IX_NPEDL_DELAY_READ_CYCLES        2
90 /*
91  * To mask top three MSBs of 32bit word to download into NPE IMEM
92  */
93 #define IX_NPEDL_MASK_UNUSED_IMEM_BITS    0x1FFFFFFF;
94 
95 
96 /*
97  * typedefs
98  */
99 typedef struct
100 {
101     UINT32 regAddress;
102     UINT32 regSize;
103 } IxNpeDlCtxtRegAccessInfo;
104 
105 /* module statistics counters */
106 typedef struct
107 {
108     UINT32 insMemWrites;
109     UINT32 insMemWriteFails;
110     UINT32 dataMemWrites;
111     UINT32 dataMemWriteFails;
112     UINT32 ecsRegWrites;
113     UINT32 ecsRegReads;
114     UINT32 dbgInstructionExecs;
115     UINT32 contextRegWrites;
116     UINT32 physicalRegWrites;
117     UINT32 nextPcWrites;
118 } IxNpeDlNpeMgrUtilsStats;
119 
120 
121 /*
122  * Variable declarations global to this file only.  Externs are followed by
123  * static variables.
124  */
125 
126 /*
127  * contains useful address and function pointers to read/write Context Regs,
128  * eliminating some switch or if-else statements in places
129  */
130 static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
131 {
132     {
133 	IX_NPEDL_CTXT_REG_ADDR_STEVT,
134 	IX_NPEDL_REG_SIZE_BYTE
135     },
136     {
137 	IX_NPEDL_CTXT_REG_ADDR_STARTPC,
138 	IX_NPEDL_REG_SIZE_SHORT
139     },
140     {
141 	IX_NPEDL_CTXT_REG_ADDR_REGMAP,
142 	IX_NPEDL_REG_SIZE_SHORT
143     },
144     {
145 	IX_NPEDL_CTXT_REG_ADDR_CINDEX,
146 	IX_NPEDL_REG_SIZE_BYTE
147     }
148 };
149 
150 static UINT32 ixNpeDlSavedExecCount = 0;
151 static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
152 
153 static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
154 
155 
156 /*
157  * static function prototypes.
158  */
159 PRIVATE __inline__ void
160 ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
161 				UINT32 addr, UINT32 data);
162 
163 PRIVATE __inline__ UINT32
164 ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
165 
166 PRIVATE IX_STATUS
167 ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
168 			     UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
169 
170 PRIVATE IX_STATUS
171 ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
172 			      UINT32 regVal, UINT32 regSize,
173 			      UINT32 ctxtNum, BOOL verify);
174 
175 /*
176  * Function definition: ixNpeDlNpeMgrWriteCommandIssue
177  */
178 PRIVATE __inline__ void
ixNpeDlNpeMgrWriteCommandIssue(UINT32 npeBaseAddress,UINT32 cmd,UINT32 addr,UINT32 data)179 ixNpeDlNpeMgrWriteCommandIssue (
180     UINT32 npeBaseAddress,
181     UINT32 cmd,
182     UINT32 addr,
183     UINT32 data)
184 {
185     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
186     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
187     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
188 }
189 
190 
191 /*
192  * Function definition: ixNpeDlNpeMgrReadCommandIssue
193  */
194 PRIVATE __inline__ UINT32
ixNpeDlNpeMgrReadCommandIssue(UINT32 npeBaseAddress,UINT32 cmd,UINT32 addr)195 ixNpeDlNpeMgrReadCommandIssue (
196     UINT32 npeBaseAddress,
197     UINT32 cmd,
198     UINT32 addr)
199 {
200     UINT32 data = 0;
201     int i;
202 
203     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
204     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
205     for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
206     {
207 	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
208     }
209 
210     return data;
211 }
212 
213 /*
214  * Function definition: ixNpeDlNpeMgrInsMemWrite
215  */
216 IX_STATUS
ixNpeDlNpeMgrInsMemWrite(UINT32 npeBaseAddress,UINT32 insMemAddress,UINT32 insMemData,BOOL verify)217 ixNpeDlNpeMgrInsMemWrite (
218     UINT32 npeBaseAddress,
219     UINT32 insMemAddress,
220     UINT32 insMemData,
221     BOOL verify)
222 {
223     UINT32 insMemDataRtn;
224 
225     ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
226 				    IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
227 				    insMemAddress, insMemData);
228     if (verify)
229     {
230         /* write invalid data to this reg, so we can see if we're reading
231 	   the EXDATA register too early */
232 	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
233 			    ~insMemData);
234 
235         /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
236         insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
237 
238         insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
239                                            IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
240                                            insMemAddress);
241 
242         insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
243 
244 	if (insMemData != insMemDataRtn)
245 	{
246 	    ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
247 	    return IX_FAIL;
248 	}
249     }
250 
251     ixNpeDlNpeMgrUtilsStats.insMemWrites++;
252     return IX_SUCCESS;
253 }
254 
255 
256 /*
257  * Function definition: ixNpeDlNpeMgrDataMemWrite
258  */
259 IX_STATUS
ixNpeDlNpeMgrDataMemWrite(UINT32 npeBaseAddress,UINT32 dataMemAddress,UINT32 dataMemData,BOOL verify)260 ixNpeDlNpeMgrDataMemWrite (
261     UINT32 npeBaseAddress,
262     UINT32 dataMemAddress,
263     UINT32 dataMemData,
264     BOOL verify)
265 {
266     ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
267 				    IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
268 				    dataMemAddress, dataMemData);
269     if (verify)
270     {
271         /* write invalid data to this reg, so we can see if we're reading
272 	   the EXDATA register too early */
273 	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);
274 
275 	if (dataMemData !=
276 	    ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
277 					   IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
278 					   dataMemAddress))
279 	{
280 	    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
281 	    return IX_FAIL;
282 	}
283     }
284 
285     ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
286     return IX_SUCCESS;
287 }
288 
289 
290 /*
291  * Function definition: ixNpeDlNpeMgrExecAccRegWrite
292  */
293 void
ixNpeDlNpeMgrExecAccRegWrite(UINT32 npeBaseAddress,UINT32 regAddress,UINT32 regData)294 ixNpeDlNpeMgrExecAccRegWrite (
295     UINT32 npeBaseAddress,
296     UINT32 regAddress,
297     UINT32 regData)
298 {
299     ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
300 				    IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
301 				    regAddress, regData);
302     ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
303 }
304 
305 
306 /*
307  * Function definition: ixNpeDlNpeMgrExecAccRegRead
308  */
309 UINT32
ixNpeDlNpeMgrExecAccRegRead(UINT32 npeBaseAddress,UINT32 regAddress)310 ixNpeDlNpeMgrExecAccRegRead (
311     UINT32 npeBaseAddress,
312     UINT32 regAddress)
313 {
314     ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
315     return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
316 					  IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
317 					  regAddress);
318 }
319 
320 
321 /*
322  * Function definition: ixNpeDlNpeMgrCommandIssue
323  */
324 void
ixNpeDlNpeMgrCommandIssue(UINT32 npeBaseAddress,UINT32 command)325 ixNpeDlNpeMgrCommandIssue (
326     UINT32 npeBaseAddress,
327     UINT32 command)
328 {
329     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
330 		     "Entering ixNpeDlNpeMgrCommandIssue\n");
331 
332     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);
333 
334     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
335 		     "Exiting ixNpeDlNpeMgrCommandIssue\n");
336 }
337 
338 
339 /*
340  * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
341  */
342 void
ixNpeDlNpeMgrDebugInstructionPreExec(UINT32 npeBaseAddress)343 ixNpeDlNpeMgrDebugInstructionPreExec(
344     UINT32 npeBaseAddress)
345 {
346     /* turn off the halt bit by clearing Execution Count register. */
347     /* save reg contents 1st and restore later */
348     IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
349 		       &ixNpeDlSavedExecCount);
350     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);
351 
352     /* ensure that IF and IE are on (temporarily), so that we don't end up
353      * stepping forever */
354     ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
355 				                   IX_NPEDL_ECS_DBG_CTXT_REG_2);
356 
357     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
358 				  (ixNpeDlSavedEcsDbgCtxtReg2 |
359 				   IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
360 				   IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
361 }
362 
363 
364 /*
365  * Function definition: ixNpeDlNpeMgrDebugInstructionExec
366  */
367 IX_STATUS
ixNpeDlNpeMgrDebugInstructionExec(UINT32 npeBaseAddress,UINT32 npeInstruction,UINT32 ctxtNum,UINT32 ldur)368 ixNpeDlNpeMgrDebugInstructionExec(
369     UINT32 npeBaseAddress,
370     UINT32 npeInstruction,
371     UINT32 ctxtNum,
372     UINT32 ldur)
373 {
374     UINT32 ecsDbgRegVal;
375     UINT32 oldWatchcount, newWatchcount;
376     UINT32 retriesCount = 0;
377     IX_STATUS status = IX_SUCCESS;
378 
379     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
380 		     "Entering ixNpeDlNpeMgrDebugInstructionExec\n");
381 
382     /* set the Active bit, and the LDUR, in the debug level */
383     ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
384 	(ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
385 
386     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
387 				  ecsDbgRegVal);
388 
389     /*
390      * set CCTXT at ECS DEBUG L3 to specify in which context to execute the
391      * instruction, and set SELCTXT at ECS DEBUG Level to specify which context
392      * store to access.
393      * Debug ECS Level Reg 1 has form  0x000n000n, where n = context number
394      */
395     ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
396 	(ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
397 
398     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
399 				  ecsDbgRegVal);
400 
401     /* clear the pipeline */
402     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
403 
404     /* load NPE instruction into the instruction register */
405     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
406 				  npeInstruction);
407 
408     /* we need this value later to wait for completion of NPE execution step */
409     IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);
410 
411     /* issue a Step One command via the Execution Control register */
412     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);
413 
414 	/* Watch Count register increments when NPE completes an instruction */
415 	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
416         &newWatchcount);
417 
418     /*
419      * force the XScale to wait until the NPE has finished execution step
420      * NOTE that this delay will be very small, just long enough to allow a
421      * single NPE instruction to complete execution; if instruction execution
422      * is not completed before timeout retries, exit the while loop
423      */
424     while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
425         && (newWatchcount == oldWatchcount))
426     {
427 	    /* Watch Count register increments when NPE completes an instruction */
428 	    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
429 		    &newWatchcount);
430 
431         retriesCount++;
432     }
433 
434     if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
435     {
436         ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
437     }
438     else
439     {
440         /* Return timeout status as the instruction has not been executed
441          * after maximum retries */
442         status = IX_NPEDL_CRITICAL_NPE_ERR;
443     }
444 
445     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
446 		     "Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
447 
448     return status;
449 }
450 
451 
452 /*
453  * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
454  */
455 void
ixNpeDlNpeMgrDebugInstructionPostExec(UINT32 npeBaseAddress)456 ixNpeDlNpeMgrDebugInstructionPostExec(
457     UINT32 npeBaseAddress)
458 {
459     /* clear active bit in debug level */
460     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
461 				  0);
462 
463     /* clear the pipeline */
464     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
465 
466     /* restore Execution Count register contents. */
467     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
468 			ixNpeDlSavedExecCount);
469 
470     /* restore IF and IE bits to original values */
471     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
472 				  ixNpeDlSavedEcsDbgCtxtReg2);
473 }
474 
475 
476 /*
477  * Function definition: ixNpeDlNpeMgrLogicalRegRead
478  */
479 PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegRead(UINT32 npeBaseAddress,UINT32 regAddr,UINT32 regSize,UINT32 ctxtNum,UINT32 * regVal)480 ixNpeDlNpeMgrLogicalRegRead (
481     UINT32 npeBaseAddress,
482     UINT32 regAddr,
483     UINT32 regSize,
484     UINT32 ctxtNum,
485     UINT32 *regVal)
486 {
487     IX_STATUS status = IX_SUCCESS;
488     UINT32 npeInstruction = 0;
489     UINT32 mask = 0;
490 
491     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
492 		     "Entering ixNpeDlNpeMgrLogicalRegRead\n");
493 
494     switch (regSize)
495     {
496     case IX_NPEDL_REG_SIZE_BYTE:
497       npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
498       mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
499     case IX_NPEDL_REG_SIZE_SHORT:
500       npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
501       mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
502     case IX_NPEDL_REG_SIZE_WORD:
503       npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
504       mask = IX_NPEDL_MASK_FULL_WORD;  break;
505     }
506 
507     /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
508     npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
509 	(regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
510 
511     /* step execution of NPE intruction using Debug Executing Context stack */
512     status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
513 				       ctxtNum, IX_NPEDL_RD_INSTR_LDUR);
514 
515     if (IX_SUCCESS != status)
516     {
517         return status;
518     }
519 
520     /* read value of register from Execution Data register */
521     IX_NPEDL_REG_READ (npeBaseAddress,	IX_NPEDL_REG_OFFSET_EXDATA, regVal);
522 
523    /* align value from left to right */
524     *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
525 
526     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
527 		     "Exiting ixNpeDlNpeMgrLogicalRegRead\n");
528 
529     return IX_SUCCESS;
530 }
531 
532 
533 /*
534  * Function definition: ixNpeDlNpeMgrLogicalRegWrite
535  */
536 PRIVATE IX_STATUS
ixNpeDlNpeMgrLogicalRegWrite(UINT32 npeBaseAddress,UINT32 regAddr,UINT32 regVal,UINT32 regSize,UINT32 ctxtNum,BOOL verify)537 ixNpeDlNpeMgrLogicalRegWrite (
538     UINT32 npeBaseAddress,
539     UINT32 regAddr,
540     UINT32 regVal,
541     UINT32 regSize,
542     UINT32 ctxtNum,
543     BOOL verify)
544 {
545     UINT32 npeInstruction = 0;
546     UINT32 mask = 0;
547     IX_STATUS status = IX_SUCCESS;
548     UINT32 retRegVal;
549 
550     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
551 		     "Entering ixNpeDlNpeMgrLogicalRegWrite\n");
552 
553     if (regSize == IX_NPEDL_REG_SIZE_WORD)
554     {
555 	/* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
556 	/* Write upper half-word (short) to |d0|d1| */
557 	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
558 				      regVal >> IX_NPEDL_REG_SIZE_SHORT,
559 				      IX_NPEDL_REG_SIZE_SHORT,
560 				      ctxtNum, verify);
561 
562 	if (IX_SUCCESS != status)
563 	{
564 	    return status;
565 	}
566 
567 	/* Write lower half-word (short) to |d2|d3| */
568 	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
569 				      regAddr + IX_NPEDL_BYTES_PER_SHORT,
570                                     regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
571 				      IX_NPEDL_REG_SIZE_SHORT,
572 				      ctxtNum, verify);
573 
574     if (IX_SUCCESS != status)
575 	{
576 	    return status;
577 	}
578 	}
579     else
580     {
581         switch (regSize)
582 	{
583 	case IX_NPEDL_REG_SIZE_BYTE:
584 	    npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
585 	    mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
586 	case IX_NPEDL_REG_SIZE_SHORT:
587             npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
588 	    mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
589 	}
590 	/* mask out any redundant bits, so verify will work later */
591 	regVal &= mask;
592 
593 	/* fill dest operand field of  instruction with destination reg addr */
594 	npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
595 
596 	/* fill src operand field of instruction with least-sig 5 bits of val*/
597 	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
598 			   IX_NPEDL_OFFSET_INSTR_SRC);
599 
600 	/* fill coprocessor field of instruction with most-sig 11 bits of val*/
601 	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
602 			   IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
603 
604 	/* step execution of NPE intruction using Debug ECS */
605 	status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
606 					  ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
607 
608 	if (IX_SUCCESS != status)
609 	{
610 	    return status;
611 	}
612     }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */
613 
614     if (verify)
615     {
616 	status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
617 						   regSize, ctxtNum, &retRegVal);
618 
619         if (IX_SUCCESS == status)
620         {
621             if (regVal != retRegVal)
622             {
623                 status = IX_FAIL;
624             }
625         }
626     }
627 
628     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
629 		     "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
630 		     status);
631 
632     return status;
633 }
634 
635 
636 /*
637  * Function definition: ixNpeDlNpeMgrPhysicalRegWrite
638  */
639 IX_STATUS
ixNpeDlNpeMgrPhysicalRegWrite(UINT32 npeBaseAddress,UINT32 regAddr,UINT32 regValue,BOOL verify)640 ixNpeDlNpeMgrPhysicalRegWrite (
641     UINT32 npeBaseAddress,
642     UINT32 regAddr,
643     UINT32 regValue,
644     BOOL verify)
645 {
646     IX_STATUS status;
647 
648     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
649 		     "Entering ixNpeDlNpeMgrPhysicalRegWrite\n");
650 
651 /*
652  * There are 32 physical registers used in an NPE.  These are
653  * treated as 16 pairs of 32-bit registers.  To write one of the pair,
654  * write the pair number (0-16) to the REGMAP for Context 0.  Then write
655  * the value to register  0 or 4 in the regfile, depending on which
656  * register of the pair is to be written
657  */
658 
659     /*
660      * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
661      * of physical registers to write
662      */
663     status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
664 					   IX_NPEDL_CTXT_REG_ADDR_REGMAP,
665 					   (regAddr >>
666 					  IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
667 					   IX_NPEDL_REG_SIZE_SHORT, 0, verify);
668     if (status == IX_SUCCESS)
669     {
670 	/* regAddr = 0 or 4  */
671 	regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
672 	    IX_NPEDL_BYTES_PER_WORD;
673 
674     status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue,
675 					   IX_NPEDL_REG_SIZE_WORD, 0, verify);
676     }
677 
678     if (status != IX_SUCCESS)
679     {
680 	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
681 			       "error writing to physical register\n");
682     }
683 
684     ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;
685 
686     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
687 		     "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
688 		     status);
689     return status;
690 }
691 
692 
693 /*
694  * Function definition: ixNpeDlNpeMgrCtxtRegWrite
695  */
696 IX_STATUS
ixNpeDlNpeMgrCtxtRegWrite(UINT32 npeBaseAddress,UINT32 ctxtNum,IxNpeDlCtxtRegNum ctxtReg,UINT32 ctxtRegVal,BOOL verify)697 ixNpeDlNpeMgrCtxtRegWrite (
698     UINT32 npeBaseAddress,
699     UINT32 ctxtNum,
700     IxNpeDlCtxtRegNum ctxtReg,
701     UINT32 ctxtRegVal,
702     BOOL verify)
703 {
704     UINT32 tempRegVal;
705     UINT32 ctxtRegAddr;
706     UINT32 ctxtRegSize;
707     IX_STATUS status = IX_SUCCESS;
708 
709     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
710 		     "Entering ixNpeDlNpeMgrCtxtRegWrite\n");
711 
712     /*
713      * Context 0 has no STARTPC. Instead, this value is used to set
714      * NextPC for Background ECS, to set where NPE starts executing code
715      */
716     if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
717     {
718 	/* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
719 	tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
720 						  IX_NPEDL_ECS_BG_CTXT_REG_0);
721 	tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
722 	tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
723 	    IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
724 
725 	ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
726 				      IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);
727 
728 	ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
729     }
730     else
731     {
732 	ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
733 	ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
734 	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
735 					       ctxtRegVal, ctxtRegSize,
736 					       ctxtNum, verify);
737 	if (status != IX_SUCCESS)
738 	{
739 	    IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
740 				   "error writing to context store register\n");
741 	}
742 
743 	ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
744     }
745 
746     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
747 		     "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
748 		     status);
749 
750     return status;
751 }
752 
753 
754 /*
755  * Function definition: ixNpeDlNpeMgrUtilsStatsShow
756  */
757 void
ixNpeDlNpeMgrUtilsStatsShow(void)758 ixNpeDlNpeMgrUtilsStatsShow (void)
759 {
760     ixOsalLog (IX_OSAL_LOG_LVL_USER,
761                IX_OSAL_LOG_DEV_STDOUT,
762                "\nixNpeDlNpeMgrUtilsStatsShow:\n"
763                "\tInstruction Memory writes: %u\n"
764                "\tInstruction Memory writes failed: %u\n"
765                "\tData Memory writes: %u\n"
766                "\tData Memory writes failed: %u\n",
767                ixNpeDlNpeMgrUtilsStats.insMemWrites,
768                ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
769                ixNpeDlNpeMgrUtilsStats.dataMemWrites,
770                ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
771                0,0);
772 
773     ixOsalLog (IX_OSAL_LOG_LVL_USER,
774                IX_OSAL_LOG_DEV_STDOUT,
775                "\tExecuting Context Stack Register writes: %u\n"
776                "\tExecuting Context Stack Register reads: %u\n"
777                "\tPhysical Register writes: %u\n"
778                "\tContext Store Register writes: %u\n"
779                "\tExecution Backgound Context NextPC writes: %u\n"
780                "\tDebug Instructions Executed: %u\n\n",
781                ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
782                ixNpeDlNpeMgrUtilsStats.ecsRegReads,
783                ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
784                ixNpeDlNpeMgrUtilsStats.contextRegWrites,
785                ixNpeDlNpeMgrUtilsStats.nextPcWrites,
786                ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
787 }
788 
789 
790 /*
791  * Function definition: ixNpeDlNpeMgrUtilsStatsReset
792  */
793 void
ixNpeDlNpeMgrUtilsStatsReset(void)794 ixNpeDlNpeMgrUtilsStatsReset (void)
795 {
796     ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
797     ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
798     ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
799     ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
800     ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
801     ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
802     ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
803     ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
804     ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
805     ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
806 }
807