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