IxNpeDlNpeMgrUtils.c 23 KB

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