blob: db50d22d1be4e9ed767dc3e5bfbaf0bc6964d569 [file] [log] [blame]
Wolfgang Denkba94a1b2006-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
Wolfgang Denkcb3761e2013-07-28 22:12:47 +020021 * SPDX-License-Identifier: BSD-3-Clause
Wolfgang Denkba94a1b2006-05-30 15:56:48 +020022 * @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 */
75typedef struct
76{
77 UINT32 regAddress;
78 UINT32 regSize;
79} IxNpeDlCtxtRegAccessInfo;
80
81/* module statistics counters */
82typedef 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 */
106static 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
126static UINT32 ixNpeDlSavedExecCount = 0;
127static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
128
129static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
130
131
132/*
133 * static function prototypes.
134 */
135PRIVATE __inline__ void
136ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
137 UINT32 addr, UINT32 data);
138
139PRIVATE __inline__ UINT32
140ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
141
142PRIVATE IX_STATUS
143ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
144 UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
145
146PRIVATE IX_STATUS
147ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
148 UINT32 regVal, UINT32 regSize,
149 UINT32 ctxtNum, BOOL verify);
150
151/*
152 * Function definition: ixNpeDlNpeMgrWriteCommandIssue
153 */
154PRIVATE __inline__ void
155ixNpeDlNpeMgrWriteCommandIssue (
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 */
170PRIVATE __inline__ UINT32
171ixNpeDlNpeMgrReadCommandIssue (
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 */
192IX_STATUS
193ixNpeDlNpeMgrInsMemWrite (
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 */
235IX_STATUS
236ixNpeDlNpeMgrDataMemWrite (
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 */
269void
270ixNpeDlNpeMgrExecAccRegWrite (
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 */
285UINT32
286ixNpeDlNpeMgrExecAccRegRead (
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 */
300void
301ixNpeDlNpeMgrCommandIssue (
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 */
318void
319ixNpeDlNpeMgrDebugInstructionPreExec(
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 */
343IX_STATUS
344ixNpeDlNpeMgrDebugInstructionExec(
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 */
431void
432ixNpeDlNpeMgrDebugInstructionPostExec(
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 */
455PRIVATE IX_STATUS
456ixNpeDlNpeMgrLogicalRegRead (
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 */
512PRIVATE IX_STATUS
513ixNpeDlNpeMgrLogicalRegWrite (
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 {
Wolfgang Denk53677ef2008-05-20 16:00:29 +0200592 status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
593 regSize, ctxtNum, &retRegVal);
594
Wolfgang Denkba94a1b2006-05-30 15:56:48 +0200595 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 */
615IX_STATUS
616ixNpeDlNpeMgrPhysicalRegWrite (
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 */
672IX_STATUS
673ixNpeDlNpeMgrCtxtRegWrite (
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 */
733void
734ixNpeDlNpeMgrUtilsStatsShow (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 */
769void
770ixNpeDlNpeMgrUtilsStatsReset (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}