IxNpeDlNpeMgrUtils.c 22 KB

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