blob: f5a4c5f508fceab5f1917adc34b4c502216ad44e [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/**
2 * @file IxNpeDlNpeMgr.c
3 *
4 * @author Intel Corporation
5 * @date 09 January 2002
6 *
7 * @brief This file contains the implementation of the private API for the
8 * IXP425 NPE Downloader NpeMgr 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 user defined include files required.
53 */
54
55
56/*
57 * Put the user defined include files required.
58 */
59#include "IxOsal.h"
60#include "IxNpeDl.h"
61#include "IxNpeDlNpeMgr_p.h"
62#include "IxNpeDlNpeMgrUtils_p.h"
63#include "IxNpeDlNpeMgrEcRegisters_p.h"
64#include "IxNpeDlMacros_p.h"
65#include "IxFeatureCtrl.h"
66
67/*
68 * #defines and macros used in this file.
69 */
70#define IX_NPEDL_BYTES_PER_WORD 4
71
72/* used to read download map from version in microcode image */
73#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000
74#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001
75#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002
76#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F
77
78/*
79 * masks used to extract address info from State information context
80 * register addresses as read from microcode image
81 */
82#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F
83#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0
84
85/* LSB offset of Context Number field in State-Info Context Address */
86#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4
87
88/* size (in words) of single State Information entry (ctxt reg address|data) */
89#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2
90
91
92 #define IX_NPEDL_RESET_NPE_PARITY 0x0800
93 #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF
94 #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF
95
96
97/*
98 * Typedefs whose scope is limited to this file.
99 */
100
101typedef struct
102{
103 UINT32 type;
104 UINT32 offset;
105} IxNpeDlNpeMgrDownloadMapBlockEntry;
106
107typedef union
108{
109 IxNpeDlNpeMgrDownloadMapBlockEntry block;
110 UINT32 eodmMarker;
111} IxNpeDlNpeMgrDownloadMapEntry;
112
113typedef struct
114{
115 /* 1st entry in the download map (there may be more than one) */
116 IxNpeDlNpeMgrDownloadMapEntry entry[1];
117} IxNpeDlNpeMgrDownloadMap;
118
119
120/* used to access an instruction or data block in a microcode image */
121typedef struct
122{
123 UINT32 npeMemAddress;
124 UINT32 size;
125 UINT32 data[1];
126} IxNpeDlNpeMgrCodeBlock;
127
128/* used to access each Context Reg entry state-information block */
129typedef struct
130{
131 UINT32 addressInfo;
132 UINT32 value;
133} IxNpeDlNpeMgrStateInfoCtxtRegEntry;
134
135/* used to access a state-information block in a microcode image */
136typedef struct
137{
138 UINT32 size;
139 IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
140} IxNpeDlNpeMgrStateInfoBlock;
141
142/* used to store some useful NPE information for easy access */
143typedef struct
144{
145 UINT32 baseAddress;
146 UINT32 insMemSize;
147 UINT32 dataMemSize;
148} IxNpeDlNpeInfo;
149
150/* used to distinguish instruction and data memory operations */
151typedef enum
152{
153 IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
154 IX_NPEDL_MEM_TYPE_DATA
155} IxNpeDlNpeMemType;
156
157/* used to hold a reset value for a particular ECS register */
158typedef struct
159{
160 UINT32 regAddr;
161 UINT32 regResetVal;
162} IxNpeDlEcsRegResetValue;
163
164/* prototype of function to write either Instruction or Data memory */
165typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
166 UINT32 npeMemAddress,
167 UINT32 npeMemData,
168 BOOL verify);
169
170/* module statistics counters */
171typedef struct
172{
173 UINT32 instructionBlocksLoaded;
174 UINT32 dataBlocksLoaded;
175 UINT32 stateInfoBlocksLoaded;
176 UINT32 criticalNpeErrors;
177 UINT32 criticalMicrocodeErrors;
178 UINT32 npeStarts;
179 UINT32 npeStops;
180 UINT32 npeResets;
181} IxNpeDlNpeMgrStats;
182
183
184/*
185 * Variable declarations global to this file only. Externs are followed by
186 * static variables.
187 */
188static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
189{
190 {
191 0,
192 IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
193 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
194 },
195 {
196 0,
197 IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
198 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
199 },
200 {
201 0,
202 IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
203 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
204 }
205};
206
207/* contains Reset values for Context Store Registers */
208static UINT32 ixNpeDlCtxtRegResetValues[] =
209{
210 IX_NPEDL_CTXT_REG_RESET_STEVT,
211 IX_NPEDL_CTXT_REG_RESET_STARTPC,
212 IX_NPEDL_CTXT_REG_RESET_REGMAP,
213 IX_NPEDL_CTXT_REG_RESET_CINDEX,
214};
215
216/* contains Reset values for Context Store Registers */
217static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
218{
219 {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
220 {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
221 {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
222 {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
223 {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
224 {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
225 {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
226 {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
227 {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
228 {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
229 {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
230 {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
231 {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET}
232};
233
234static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
235
236/* Set when NPE register memory has been mapped */
237static BOOL ixNpeDlMemInitialised = FALSE;
238
239
240/*
241 * static function prototypes.
242 */
243PRIVATE IX_STATUS
244ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
245 IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
246 BOOL verify, IxNpeDlNpeMemType npeMemType);
247PRIVATE IX_STATUS
248ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
249 IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
250 BOOL verify);
251PRIVATE BOOL
252ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
253 UINT32 expectedBitsSet);
254
255PRIVATE UINT32
256ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
257
258/*
259 * Function definition: ixNpeDlNpeMgrBaseAddressGet
260 */
261PRIVATE UINT32
262ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
263{
264 IX_OSAL_ASSERT (ixNpeDlMemInitialised);
265 return ixNpeDlNpeInfo[npeId].baseAddress;
266}
267
268
269/*
270 * Function definition: ixNpeDlNpeMgrInit
271 */
272void
273ixNpeDlNpeMgrInit (void)
274{
275 /* Only map the memory once */
276 if (!ixNpeDlMemInitialised)
277 {
278 UINT32 virtAddr;
279
280 /* map the register memory for NPE-A */
281 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
282 IX_OSAL_IXP400_NPEA_MAP_SIZE);
283 IX_OSAL_ASSERT(virtAddr);
284 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
285
286 /* map the register memory for NPE-B */
287 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
288 IX_OSAL_IXP400_NPEB_MAP_SIZE);
289 IX_OSAL_ASSERT(virtAddr);
290 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
291
292 /* map the register memory for NPE-C */
293 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
294 IX_OSAL_IXP400_NPEC_MAP_SIZE);
295 IX_OSAL_ASSERT(virtAddr);
296 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
297
298 ixNpeDlMemInitialised = TRUE;
299 }
300}
301
302
303/*
304 * Function definition: ixNpeDlNpeMgrUninit
305 */
306IX_STATUS
307ixNpeDlNpeMgrUninit (void)
308{
309 if (!ixNpeDlMemInitialised)
310 {
311 return IX_FAIL;
312 }
313
314 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
315 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
316 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
317
318 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
319 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
320 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
321
322 ixNpeDlMemInitialised = FALSE;
323
324 return IX_SUCCESS;
325}
326
327/*
328 * Function definition: ixNpeDlNpeMgrImageLoad
329 */
330IX_STATUS
331ixNpeDlNpeMgrImageLoad (
332 IxNpeDlNpeId npeId,
333 UINT32 *imageCodePtr,
334 BOOL verify)
335{
336 UINT32 npeBaseAddress;
337 IxNpeDlNpeMgrDownloadMap *downloadMap;
338 UINT32 *blockPtr;
339 UINT32 mapIndex = 0;
340 IX_STATUS status = IX_SUCCESS;
341
342 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
343 "Entering ixNpeDlNpeMgrImageLoad\n");
344
345 /* get base memory address of NPE from npeId */
346 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
347
348 /* check execution status of NPE to verify NPE Stop was successful */
349 if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
350 IX_NPEDL_EXCTL_STATUS_STOP))
351 {
352 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
353 "NPE was not stopped before download\n");
354 status = IX_FAIL;
355 }
356 else
357 {
358 /*
359 * Read Download Map, checking each block type and calling
360 * appropriate function to perform download
361 */
362 downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
363 while ((downloadMap->entry[mapIndex].eodmMarker !=
364 IX_NPEDL_END_OF_DOWNLOAD_MAP)
365 && (status == IX_SUCCESS))
366 {
367 /* calculate pointer to block to be downloaded */
368 blockPtr = imageCodePtr +
369 downloadMap->entry[mapIndex].block.offset;
370
371 switch (downloadMap->entry[mapIndex].block.type)
372 {
373 case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
374 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
375 (IxNpeDlNpeMgrCodeBlock *)blockPtr,
376 verify,
377 IX_NPEDL_MEM_TYPE_INSTRUCTION);
378 break;
379 case IX_NPEDL_BLOCK_TYPE_DATA:
380 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
381 (IxNpeDlNpeMgrCodeBlock *)blockPtr,
382 verify, IX_NPEDL_MEM_TYPE_DATA);
383 break;
384 case IX_NPEDL_BLOCK_TYPE_STATE:
385 status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
386 (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
387 verify);
388 break;
389 default:
390 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
391 "unknown block type in download map\n");
392 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
393 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
394 break;
395 }
396 mapIndex++;
397 }/* loop: for each entry in download map, while status == SUCCESS */
398 }/* condition: NPE stopped before attempting download */
399
400 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
401 "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
402 status);
403 return status;
404}
405
406
407/*
408 * Function definition: ixNpeDlNpeMgrMemLoad
409 */
410PRIVATE IX_STATUS
411ixNpeDlNpeMgrMemLoad (
412 IxNpeDlNpeId npeId,
413 UINT32 npeBaseAddress,
414 IxNpeDlNpeMgrCodeBlock *blockPtr,
415 BOOL verify,
416 IxNpeDlNpeMemType npeMemType)
417{
418 UINT32 npeMemAddress;
419 UINT32 blockSize;
420 UINT32 memSize = 0;
421 IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
422 UINT32 localIndex = 0;
423 IX_STATUS status = IX_SUCCESS;
424
425 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
426 "Entering ixNpeDlNpeMgrMemLoad\n");
427
428 /*
429 * select NPE EXCTL reg read/write commands depending on memory
430 * type (instruction/data) to be accessed
431 */
432 if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
433 {
434 memSize = ixNpeDlNpeInfo[npeId].insMemSize;
435 memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
436 }
437 else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
438 {
439 memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
440 memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
441 }
442
443 /*
444 * NPE memory is loaded contiguously from each block, so only address
445 * of 1st word in block is needed
446 */
447 npeMemAddress = blockPtr->npeMemAddress;
448 /* number of words of instruction/data microcode in block to download */
449 blockSize = blockPtr->size;
450 if ((npeMemAddress + blockSize) > memSize)
451 {
452 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
453 "Block size too big for NPE memory\n");
454 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
455 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
456 }
457 else
458 {
459 for (localIndex = 0; localIndex < blockSize; localIndex++)
460 {
461 status = memWriteFunc (npeBaseAddress, npeMemAddress,
462 blockPtr->data[localIndex], verify);
463
464 if (status != IX_SUCCESS)
465 {
466 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
467 "write to NPE memory failed\n");
468 status = IX_NPEDL_CRITICAL_NPE_ERR;
469 ixNpeDlNpeMgrStats.criticalNpeErrors++;
470 break; /* abort download */
471 }
472 /* increment target (word)address in NPE memory */
473 npeMemAddress++;
474 }
475 }/* condition: block size will fit in NPE memory */
476
477 if (status == IX_SUCCESS)
478 {
479 if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
480 {
481 ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
482 }
483 else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
484 {
485 ixNpeDlNpeMgrStats.dataBlocksLoaded++;
486 }
487 }
488
489 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
490 "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
491 return status;
492}
493
494
495/*
496 * Function definition: ixNpeDlNpeMgrStateInfoLoad
497 */
498PRIVATE IX_STATUS
499ixNpeDlNpeMgrStateInfoLoad (
500 UINT32 npeBaseAddress,
501 IxNpeDlNpeMgrStateInfoBlock *blockPtr,
502 BOOL verify)
503{
504 UINT32 blockSize;
505 UINT32 ctxtRegAddrInfo;
506 UINT32 ctxtRegVal;
507 IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
508 UINT32 ctxtNum; /* identifies Context number (0-16) */
509 UINT32 i;
510 IX_STATUS status = IX_SUCCESS;
511
512 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
513 "Entering ixNpeDlNpeMgrStateInfoLoad\n");
514
515 /* block size contains number of words of state-info in block */
516 blockSize = blockPtr->size;
517
518 ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
519
520 /* for each state-info context register entry in block */
521 for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
522 {
523 /* each state-info entry is 2 words (address, value) in length */
524 ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
525 ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value;
526
527 ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
528 ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >>
529 IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
530
531 /* error-check Context Register No. and Context Number values */
532 /* NOTE that there is no STEVT register for Context 0 */
533 if ((ctxtReg < 0) ||
534 (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
535 (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
536 ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
537 {
538 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
539 "invalid Context Register Address\n");
540 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
541 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
542 break; /* abort download */
543 }
544
545 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
546 ctxtRegVal, verify);
547 if (status != IX_SUCCESS)
548 {
549 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
550 "write of state-info to NPE failed\n");
551 status = IX_NPEDL_CRITICAL_NPE_ERR;
552 ixNpeDlNpeMgrStats.criticalNpeErrors++;
553 break; /* abort download */
554 }
555 }/* loop: for each context reg entry in State Info block */
556
557 ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
558
559 if (status == IX_SUCCESS)
560 {
561 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
562 }
563
564 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
565 "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
566 status);
567 return status;
568}
569
570
571/*
572 * Function definition: ixNpeDlNpeMgrNpeReset
573 */
574IX_STATUS
575ixNpeDlNpeMgrNpeReset (
576 IxNpeDlNpeId npeId)
577{
578 UINT32 npeBaseAddress;
579 IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
580 UINT32 ctxtNum; /* identifies Context number (0-16) */
581 UINT32 regAddr;
582 UINT32 regVal;
583 UINT32 localIndex;
584 UINT32 indexMax;
585 IX_STATUS status = IX_SUCCESS;
586 IxFeatureCtrlReg unitFuseReg;
587 UINT32 ixNpeConfigCtrlRegVal;
588
589 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
590 "Entering ixNpeDlNpeMgrNpeReset\n");
591
592 /* get base memory address of NPE from npeId */
593 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
594
595 /* pre-store the NPE Config Control Register Value */
596 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
597
598 ixNpeConfigCtrlRegVal |= 0x3F000000;
599
600 /* disable the parity interrupt */
601 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
602
603 ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
604
605 /*
606 * clear the FIFOs
607 */
608 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
609 IX_NPEDL_REG_OFFSET_WFIFO,
610 IX_NPEDL_MASK_WFIFO_VALID))
611 {
612 /* read from the Watch-point FIFO until empty */
613 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
614 &regVal);
615 }
616
617 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
618 IX_NPEDL_REG_OFFSET_STAT,
619 IX_NPEDL_MASK_STAT_OFNE))
620 {
621 /* read from the outFIFO until empty */
622 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
623 &regVal);
624 }
625
626 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
627 IX_NPEDL_REG_OFFSET_STAT,
628 IX_NPEDL_MASK_STAT_IFNE))
629 {
630 /*
631 * step execution of the NPE intruction to read inFIFO using
632 * the Debug Executing Context stack
633 */
634 status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
635 IX_NPEDL_INSTR_RD_FIFO, 0, 0);
636
637 if (IX_SUCCESS != status)
638 {
639 return status;
640 }
641
642 }
643
644 /*
645 * Reset the mailbox reg
646 */
647 /* ...from XScale side */
648 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
649 IX_NPEDL_REG_RESET_MBST);
650 /* ...from NPE side */
651 status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
652 IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
653
654 if (IX_SUCCESS != status)
655 {
656 return status;
657 }
658
659 /*
660 * Reset the physical registers in the NPE register file:
661 * Note: no need to save/restore REGMAP for Context 0 here
662 * since all Context Store regs are reset in subsequent code
663 */
664 for (regAddr = 0;
665 (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
666 regAddr++)
667 {
668 /* for each physical register in the NPE reg file, write 0 : */
669 status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
670 0, TRUE);
671 if (status != IX_SUCCESS)
672 {
673 return status; /* abort reset */
674 }
675 }
676
677
678 /*
679 * Reset the context store:
680 */
681 for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
682 ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
683 {
684 /* set each context's Context Store registers to reset values: */
685 for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
686 {
687 /* NOTE that there is no STEVT register for Context 0 */
688 if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
689 {
690 regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
691 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
692 ctxtReg, regVal, TRUE);
693 if (status != IX_SUCCESS)
694 {
695 return status; /* abort reset */
696 }
697 }
698 }
699 }
700
701 ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
702
703 /* write Reset values to Execution Context Stack registers */
704 indexMax = sizeof (ixNpeDlEcsRegResetValues) /
705 sizeof (IxNpeDlEcsRegResetValue);
706 for (localIndex = 0; localIndex < indexMax; localIndex++)
707 {
708 regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
709 regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
710 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
711 }
712
713 /* clear the profile counter */
714 ixNpeDlNpeMgrCommandIssue (npeBaseAddress,
715 IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
716
717 /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
718 for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
719 regAddr <= IX_NPEDL_REG_OFFSET_AP3;
720 regAddr += IX_NPEDL_BYTES_PER_WORD)
721 {
722 IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
723 }
724
725 /* Reset the Watch-count register */
726 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
727
728 /*
729 * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
730 */
731
732 /*
733 * Call the feature control API to fused out and reset the NPE and its
734 * coprocessor - to reset internal states and remove parity error
735 */
736 unitFuseReg = ixFeatureCtrlRead ();
737 unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
738 ixFeatureCtrlWrite (unitFuseReg);
739
740 /* call the feature control API to un-fused and un-reset the NPE & COP */
741 unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
742 ixFeatureCtrlWrite (unitFuseReg);
743
744 /*
745 * Call NpeMgr function to stop the NPE again after the Feature Control
746 * has unfused and Un-Reset the NPE and its associated Coprocessors
747 */
748 status = ixNpeDlNpeMgrNpeStop (npeId);
749
750 /* restore NPE configuration bus Control Register - Parity Settings */
751 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL,
752 (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
753
754 ixNpeDlNpeMgrStats.npeResets++;
755
756 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
757 "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
758 return status;
759}
760
761
762/*
763 * Function definition: ixNpeDlNpeMgrNpeStart
764 */
765IX_STATUS
766ixNpeDlNpeMgrNpeStart (
767 IxNpeDlNpeId npeId)
768{
769 UINT32 npeBaseAddress;
770 UINT32 ecsRegVal;
771 BOOL npeRunning;
772 IX_STATUS status = IX_SUCCESS;
773
774 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
775 "Entering ixNpeDlNpeMgrNpeStart\n");
776
777 /* get base memory address of NPE from npeId */
778 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
779
780 /*
781 * ensure only Background Context Stack Level is Active by turning off
782 * the Active bit in each of the other Executing Context Stack levels
783 */
784 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
785 IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
786 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
787 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
788 ecsRegVal);
789
790 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
791 IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
792 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
793 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
794 ecsRegVal);
795
796 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
797 IX_NPEDL_ECS_DBG_CTXT_REG_0);
798 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
799 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
800 ecsRegVal);
801
802 /* clear the pipeline */
803 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
804
805 /* start NPE execution by issuing command through EXCTL register on NPE */
806 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
807
808 /*
809 * check execution status of NPE to verify NPE Start operation was
810 * successful
811 */
812 npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
813 IX_NPEDL_REG_OFFSET_EXCTL,
814 IX_NPEDL_EXCTL_STATUS_RUN);
815 if (npeRunning)
816 {
817 ixNpeDlNpeMgrStats.npeStarts++;
818 }
819 else
820 {
821 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
822 "failed to start NPE execution\n");
823 status = IX_FAIL;
824 }
825
826
827 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
828 "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
829 return status;
830}
831
832
833/*
834 * Function definition: ixNpeDlNpeMgrNpeStop
835 */
836IX_STATUS
837ixNpeDlNpeMgrNpeStop (
838 IxNpeDlNpeId npeId)
839{
840 UINT32 npeBaseAddress;
841 IX_STATUS status = IX_SUCCESS;
842
843 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
844 "Entering ixNpeDlNpeMgrNpeStop\n");
845
846 /* get base memory address of NPE from npeId */
847 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
848
849 /* stop NPE execution by issuing command through EXCTL register on NPE */
850 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
851
852 /* verify that NPE Stop was successful */
853 if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
854 IX_NPEDL_EXCTL_STATUS_STOP))
855 {
856 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
857 "failed to stop NPE execution\n");
858 status = IX_FAIL;
859 }
860
861 ixNpeDlNpeMgrStats.npeStops++;
862
863 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
864 "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
865 return status;
866}
867
868
869/*
870 * Function definition: ixNpeDlNpeMgrBitsSetCheck
871 */
872PRIVATE BOOL
873ixNpeDlNpeMgrBitsSetCheck (
874 UINT32 npeBaseAddress,
875 UINT32 regOffset,
876 UINT32 expectedBitsSet)
877{
878 UINT32 regVal;
879 IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
880
881 return expectedBitsSet == (expectedBitsSet & regVal);
882}
883
884
885/*
886 * Function definition: ixNpeDlNpeMgrStatsShow
887 */
888void
889ixNpeDlNpeMgrStatsShow (void)
890{
891 ixOsalLog (IX_OSAL_LOG_LVL_USER,
892 IX_OSAL_LOG_DEV_STDOUT,
893 "\nixNpeDlNpeMgrStatsShow:\n"
894 "\tInstruction Blocks loaded: %u\n"
895 "\tData Blocks loaded: %u\n"
896 "\tState Information Blocks loaded: %u\n"
897 "\tCritical NPE errors: %u\n"
898 "\tCritical Microcode errors: %u\n",
899 ixNpeDlNpeMgrStats.instructionBlocksLoaded,
900 ixNpeDlNpeMgrStats.dataBlocksLoaded,
901 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
902 ixNpeDlNpeMgrStats.criticalNpeErrors,
903 ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
904 0);
905
906 ixOsalLog (IX_OSAL_LOG_LVL_USER,
907 IX_OSAL_LOG_DEV_STDOUT,
908 "\tSuccessful NPE Starts: %u\n"
909 "\tSuccessful NPE Stops: %u\n"
910 "\tSuccessful NPE Resets: %u\n\n",
911 ixNpeDlNpeMgrStats.npeStarts,
912 ixNpeDlNpeMgrStats.npeStops,
913 ixNpeDlNpeMgrStats.npeResets,
914 0,0,0);
915
916 ixNpeDlNpeMgrUtilsStatsShow ();
917}
918
919
920/*
921 * Function definition: ixNpeDlNpeMgrStatsReset
922 */
923void
924ixNpeDlNpeMgrStatsReset (void)
925{
926 ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
927 ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
928 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
929 ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
930 ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
931 ixNpeDlNpeMgrStats.npeStarts = 0;
932 ixNpeDlNpeMgrStats.npeStops = 0;
933 ixNpeDlNpeMgrStats.npeResets = 0;
934
935 ixNpeDlNpeMgrUtilsStatsReset ();
936}