blob: 18cac5020886a4c8e7c40e3f1c1f78cd17b729a0 [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/**
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 */
99typedef struct
100{
101 UINT32 regAddress;
102 UINT32 regSize;
103} IxNpeDlCtxtRegAccessInfo;
104
105/* module statistics counters */
106typedef 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 */
130static 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
150static UINT32 ixNpeDlSavedExecCount = 0;
151static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
152
153static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
154
155
156/*
157 * static function prototypes.
158 */
159PRIVATE __inline__ void
160ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
161 UINT32 addr, UINT32 data);
162
163PRIVATE __inline__ UINT32
164ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
165
166PRIVATE IX_STATUS
167ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
168 UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
169
170PRIVATE IX_STATUS
171ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
172 UINT32 regVal, UINT32 regSize,
173 UINT32 ctxtNum, BOOL verify);
174
175/*
176 * Function definition: ixNpeDlNpeMgrWriteCommandIssue
177 */
178PRIVATE __inline__ void
179ixNpeDlNpeMgrWriteCommandIssue (
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 */
194PRIVATE __inline__ UINT32
195ixNpeDlNpeMgrReadCommandIssue (
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 */
216IX_STATUS
217ixNpeDlNpeMgrInsMemWrite (
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 */
259IX_STATUS
260ixNpeDlNpeMgrDataMemWrite (
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 */
293void
294ixNpeDlNpeMgrExecAccRegWrite (
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 */
309UINT32
310ixNpeDlNpeMgrExecAccRegRead (
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 */
324void
325ixNpeDlNpeMgrCommandIssue (
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 */
342void
343ixNpeDlNpeMgrDebugInstructionPreExec(
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 */
367IX_STATUS
368ixNpeDlNpeMgrDebugInstructionExec(
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 */
455void
456ixNpeDlNpeMgrDebugInstructionPostExec(
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 */
479PRIVATE IX_STATUS
480ixNpeDlNpeMgrLogicalRegRead (
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 */
536PRIVATE IX_STATUS
537ixNpeDlNpeMgrLogicalRegWrite (
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 {
Wolfgang Denka1be4762008-05-20 16:00:29 +0200616 status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
617 regSize, ctxtNum, &retRegVal);
618
Wolfgang Denk4646d2a2006-05-30 15:56:48 +0200619 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 */
639IX_STATUS
640ixNpeDlNpeMgrPhysicalRegWrite (
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 */
696IX_STATUS
697ixNpeDlNpeMgrCtxtRegWrite (
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 */
757void
758ixNpeDlNpeMgrUtilsStatsShow (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 */
793void
794ixNpeDlNpeMgrUtilsStatsReset (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}