]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/ixp/npe/IxNpeDlNpeMgrUtils.c
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / cpu / ixp / 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  * 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }