IxNpeMhConfig.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /**
  2. * @file IxNpeMhConfig.c
  3. *
  4. * @author Intel Corporation
  5. * @date 18 Jan 2002
  6. *
  7. * @brief This file contains the implementation of the private API for the
  8. * Configuration 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. /*
  29. * Put the user defined include files required.
  30. */
  31. #include "IxOsal.h"
  32. #include "IxNpeMhMacros_p.h"
  33. #include "IxNpeMhConfig_p.h"
  34. /*
  35. * #defines and macros used in this file.
  36. */
  37. #define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
  38. * retries before
  39. * timeout
  40. */
  41. /*
  42. * Typedefs whose scope is limited to this file.
  43. */
  44. /**
  45. * @struct IxNpeMhConfigStats
  46. *
  47. * @brief This structure is used to maintain statistics for the
  48. * Configuration module.
  49. */
  50. typedef struct
  51. {
  52. UINT32 outFifoReads; /**< outFifo reads */
  53. UINT32 inFifoWrites; /**< inFifo writes */
  54. UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */
  55. UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
  56. } IxNpeMhConfigStats;
  57. /*
  58. * Variable declarations global to this file only. Externs are followed by
  59. * static variables.
  60. */
  61. IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
  62. {
  63. {
  64. 0,
  65. IX_NPEMH_NPEA_INT,
  66. 0,
  67. 0,
  68. 0,
  69. 0,
  70. 0,
  71. NULL,
  72. false
  73. },
  74. {
  75. 0,
  76. IX_NPEMH_NPEB_INT,
  77. 0,
  78. 0,
  79. 0,
  80. 0,
  81. 0,
  82. NULL,
  83. false
  84. },
  85. {
  86. 0,
  87. IX_NPEMH_NPEC_INT,
  88. 0,
  89. 0,
  90. 0,
  91. 0,
  92. 0,
  93. NULL,
  94. false
  95. }
  96. };
  97. PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
  98. /*
  99. * Extern function prototypes.
  100. */
  101. /*
  102. * Static function prototypes.
  103. */
  104. PRIVATE
  105. void ixNpeMhConfigIsr (void *parameter);
  106. /*
  107. * Function definition: ixNpeMhConfigIsr
  108. */
  109. PRIVATE
  110. void ixNpeMhConfigIsr (void *parameter)
  111. {
  112. IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
  113. UINT32 ofint;
  114. volatile UINT32 *statusReg =
  115. (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
  116. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  117. "ixNpeMhConfigIsr\n");
  118. /* get the OFINT (OutFifo interrupt) bit of the status register */
  119. IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
  120. /* if the OFINT status bit is set */
  121. if (ofint)
  122. {
  123. /* if there is an ISR registered for this NPE */
  124. if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
  125. {
  126. /* invoke the ISR routine */
  127. ixNpeMhConfigNpeInfo[npeId].isr (npeId);
  128. }
  129. else
  130. {
  131. /* if we don't service the interrupt the NPE will continue */
  132. /* to trigger the interrupt indefinitely */
  133. IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
  134. "interrupt\n");
  135. }
  136. }
  137. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  138. "ixNpeMhConfigIsr\n");
  139. }
  140. /*
  141. * Function definition: ixNpeMhConfigInitialize
  142. */
  143. void ixNpeMhConfigInitialize (
  144. IxNpeMhNpeInterrupts npeInterrupts)
  145. {
  146. IxNpeMhNpeId npeId;
  147. UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
  148. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  149. "ixNpeMhConfigInitialize\n");
  150. /* Request a mapping for the NPE-A config register address space */
  151. virtualAddr[IX_NPEMH_NPEID_NPEA] =
  152. (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
  153. IX_OSAL_IXP400_NPEA_MAP_SIZE);
  154. IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
  155. /* Request a mapping for the NPE-B config register address space */
  156. virtualAddr[IX_NPEMH_NPEID_NPEB] =
  157. (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
  158. IX_OSAL_IXP400_NPEB_MAP_SIZE);
  159. IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
  160. /* Request a mapping for the NPE-C config register address space */
  161. virtualAddr[IX_NPEMH_NPEID_NPEC] =
  162. (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
  163. IX_OSAL_IXP400_NPEC_MAP_SIZE);
  164. IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
  165. /* for each NPE ... */
  166. for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
  167. {
  168. /* declare a convenience pointer */
  169. IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
  170. /* store the virtual addresses of the NPE registers for later use */
  171. npeInfo->virtualRegisterBase = virtualAddr[npeId];
  172. npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
  173. npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
  174. npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
  175. npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
  176. /* for test purposes - to verify the register addresses */
  177. IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = "
  178. "0x%08X\n", npeId, npeInfo->statusRegister);
  179. IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
  180. "0x%08X\n", npeId, npeInfo->controlRegister);
  181. IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = "
  182. "0x%08X\n", npeId, npeInfo->inFifoRegister);
  183. IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
  184. "0x%08X\n", npeId, npeInfo->outFifoRegister);
  185. /* connect our ISR to the NPE interrupt */
  186. (void) ixOsalIrqBind (
  187. npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
  188. /* initialise a mutex for this NPE */
  189. (void) ixOsalMutexInit (&npeInfo->mutex);
  190. /* if we should service the NPE's "outFIFO not empty" interrupt */
  191. if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
  192. {
  193. /* enable the NPE's "outFIFO not empty" interrupt */
  194. ixNpeMhConfigNpeInterruptEnable (npeId);
  195. }
  196. else
  197. {
  198. /* disable the NPE's "outFIFO not empty" interrupt */
  199. ixNpeMhConfigNpeInterruptDisable (npeId);
  200. }
  201. }
  202. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  203. "ixNpeMhConfigInitialize\n");
  204. }
  205. /*
  206. * Function definition: ixNpeMhConfigUninit
  207. */
  208. void ixNpeMhConfigUninit (void)
  209. {
  210. IxNpeMhNpeId npeId;
  211. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  212. "ixNpeMhConfigUninit\n");
  213. /* for each NPE ... */
  214. for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
  215. {
  216. /* declare a convenience pointer */
  217. IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
  218. /* disconnect ISR */
  219. ixOsalIrqUnbind(npeInfo->interruptId);
  220. /* destroy mutex associated with this NPE */
  221. ixOsalMutexDestroy(&npeInfo->mutex);
  222. IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
  223. npeInfo->virtualRegisterBase = 0;
  224. npeInfo->statusRegister = 0;
  225. npeInfo->controlRegister = 0;
  226. npeInfo->inFifoRegister = 0;
  227. npeInfo->outFifoRegister = 0;
  228. }
  229. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  230. "ixNpeMhConfigUninit\n");
  231. }
  232. /*
  233. * Function definition: ixNpeMhConfigIsrRegister
  234. */
  235. void ixNpeMhConfigIsrRegister (
  236. IxNpeMhNpeId npeId,
  237. IxNpeMhConfigIsr isr)
  238. {
  239. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  240. "ixNpeMhConfigIsrRegister\n");
  241. /* check if there is already an ISR registered for this NPE */
  242. if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
  243. {
  244. IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
  245. }
  246. /* save the ISR routine with the NPE info */
  247. ixNpeMhConfigNpeInfo[npeId].isr = isr;
  248. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  249. "ixNpeMhConfigIsrRegister\n");
  250. }
  251. /*
  252. * Function definition: ixNpeMhConfigNpeInterruptEnable
  253. */
  254. BOOL ixNpeMhConfigNpeInterruptEnable (
  255. IxNpeMhNpeId npeId)
  256. {
  257. UINT32 ofe;
  258. volatile UINT32 *controlReg =
  259. (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
  260. /* get the OFE (OutFifoEnable) bit of the control register */
  261. IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
  262. /* if the interrupt is disabled then we must enable it */
  263. if (!ofe)
  264. {
  265. /* set the OFE (OutFifoEnable) bit of the control register */
  266. /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
  267. /* time for the write to have effect */
  268. IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
  269. (IX_NPEMH_NPE_CTL_OFE |
  270. IX_NPEMH_NPE_CTL_OFEWE),
  271. (IX_NPEMH_NPE_CTL_OFE |
  272. IX_NPEMH_NPE_CTL_OFEWE));
  273. }
  274. /* return the previous state of the interrupt */
  275. return (ofe != 0);
  276. }
  277. /*
  278. * Function definition: ixNpeMhConfigNpeInterruptDisable
  279. */
  280. BOOL ixNpeMhConfigNpeInterruptDisable (
  281. IxNpeMhNpeId npeId)
  282. {
  283. UINT32 ofe;
  284. volatile UINT32 *controlReg =
  285. (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
  286. /* get the OFE (OutFifoEnable) bit of the control register */
  287. IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
  288. /* if the interrupt is enabled then we must disable it */
  289. if (ofe)
  290. {
  291. /* unset the OFE (OutFifoEnable) bit of the control register */
  292. /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
  293. /* time for the write to have effect */
  294. IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
  295. (0 |
  296. IX_NPEMH_NPE_CTL_OFEWE),
  297. (IX_NPEMH_NPE_CTL_OFE |
  298. IX_NPEMH_NPE_CTL_OFEWE));
  299. }
  300. /* return the previous state of the interrupt */
  301. return (ofe != 0);
  302. }
  303. /*
  304. * Function definition: ixNpeMhConfigMessageIdGet
  305. */
  306. IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
  307. IxNpeMhMessage message)
  308. {
  309. /* return the most-significant byte of the first word of the */
  310. /* message */
  311. return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
  312. }
  313. /*
  314. * Function definition: ixNpeMhConfigNpeIdIsValid
  315. */
  316. BOOL ixNpeMhConfigNpeIdIsValid (
  317. IxNpeMhNpeId npeId)
  318. {
  319. /* check that the npeId parameter is within the range of valid IDs */
  320. return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
  321. }
  322. /*
  323. * Function definition: ixNpeMhConfigLockGet
  324. */
  325. void ixNpeMhConfigLockGet (
  326. IxNpeMhNpeId npeId)
  327. {
  328. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  329. "ixNpeMhConfigLockGet\n");
  330. /* lock the mutex for this NPE */
  331. (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
  332. IX_OSAL_WAIT_FOREVER);
  333. /* disable the NPE's "outFIFO not empty" interrupt */
  334. ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
  335. ixNpeMhConfigNpeInterruptDisable (npeId);
  336. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  337. "ixNpeMhConfigLockGet\n");
  338. }
  339. /*
  340. * Function definition: ixNpeMhConfigLockRelease
  341. */
  342. void ixNpeMhConfigLockRelease (
  343. IxNpeMhNpeId npeId)
  344. {
  345. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  346. "ixNpeMhConfigLockRelease\n");
  347. /* if the interrupt was previously enabled */
  348. if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
  349. {
  350. /* enable the NPE's "outFIFO not empty" interrupt */
  351. ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
  352. ixNpeMhConfigNpeInterruptEnable (npeId);
  353. }
  354. /* unlock the mutex for this NPE */
  355. (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
  356. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  357. "ixNpeMhConfigLockRelease\n");
  358. }
  359. /*
  360. * Function definition: ixNpeMhConfigInFifoWrite
  361. */
  362. IX_STATUS ixNpeMhConfigInFifoWrite (
  363. IxNpeMhNpeId npeId,
  364. IxNpeMhMessage message)
  365. {
  366. volatile UINT32 *npeInFifo =
  367. (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
  368. UINT32 retriesCount = 0;
  369. /* write the first word of the message to the NPE's inFIFO */
  370. IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
  371. /* need to wait for room to write second word - see SCR #493,
  372. poll for maximum number of retries, if exceed maximum
  373. retries, exit from while loop */
  374. while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
  375. && ixNpeMhConfigInFifoIsFull (npeId))
  376. {
  377. retriesCount++;
  378. }
  379. /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
  380. if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
  381. {
  382. return IX_NPEMH_CRITICAL_NPE_ERR;
  383. }
  384. /* write the second word of the message to the NPE's inFIFO */
  385. IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
  386. /* record in the stats the maximum number of retries needed */
  387. if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
  388. {
  389. ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
  390. }
  391. /* update statistical info */
  392. ixNpeMhConfigStats[npeId].inFifoWrites++;
  393. return IX_SUCCESS;
  394. }
  395. /*
  396. * Function definition: ixNpeMhConfigOutFifoRead
  397. */
  398. IX_STATUS ixNpeMhConfigOutFifoRead (
  399. IxNpeMhNpeId npeId,
  400. IxNpeMhMessage *message)
  401. {
  402. volatile UINT32 *npeOutFifo =
  403. (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
  404. UINT32 retriesCount = 0;
  405. /* read the first word of the message from the NPE's outFIFO */
  406. IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
  407. /* need to wait for NPE to write second word - see SCR #493
  408. poll for maximum number of retries, if exceed maximum
  409. retries, exit from while loop */
  410. while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
  411. && ixNpeMhConfigOutFifoIsEmpty (npeId))
  412. {
  413. retriesCount++;
  414. }
  415. /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
  416. if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
  417. {
  418. return IX_NPEMH_CRITICAL_NPE_ERR;
  419. }
  420. /* read the second word of the message from the NPE's outFIFO */
  421. IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
  422. /* record in the stats the maximum number of retries needed */
  423. if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
  424. {
  425. ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
  426. }
  427. /* update statistical info */
  428. ixNpeMhConfigStats[npeId].outFifoReads++;
  429. return IX_SUCCESS;
  430. }
  431. /*
  432. * Function definition: ixNpeMhConfigShow
  433. */
  434. void ixNpeMhConfigShow (
  435. IxNpeMhNpeId npeId)
  436. {
  437. /* show the message fifo read counter */
  438. IX_NPEMH_SHOW ("Message FIFO reads",
  439. ixNpeMhConfigStats[npeId].outFifoReads);
  440. /* show the message fifo write counter */
  441. IX_NPEMH_SHOW ("Message FIFO writes",
  442. ixNpeMhConfigStats[npeId].inFifoWrites);
  443. /* show the max retries performed when inFIFO full */
  444. IX_NPEMH_SHOW ("Max inFIFO Full retries",
  445. ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
  446. /* show the max retries performed when outFIFO empty */
  447. IX_NPEMH_SHOW ("Max outFIFO Empty retries",
  448. ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
  449. /* show the current status of the inFifo */
  450. ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
  451. "InFifo is %s and %s\n",
  452. (ixNpeMhConfigInFifoIsEmpty (npeId) ?
  453. (int) "EMPTY" : (int) "NOT EMPTY"),
  454. (ixNpeMhConfigInFifoIsFull (npeId) ?
  455. (int) "FULL" : (int) "NOT FULL"),
  456. 0, 0, 0, 0);
  457. /* show the current status of the outFifo */
  458. ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
  459. "OutFifo is %s and %s\n",
  460. (ixNpeMhConfigOutFifoIsEmpty (npeId) ?
  461. (int) "EMPTY" : (int) "NOT EMPTY"),
  462. (ixNpeMhConfigOutFifoIsFull (npeId) ?
  463. (int) "FULL" : (int) "NOT FULL"),
  464. 0, 0, 0, 0);
  465. }
  466. /*
  467. * Function definition: ixNpeMhConfigShowReset
  468. */
  469. void ixNpeMhConfigShowReset (
  470. IxNpeMhNpeId npeId)
  471. {
  472. /* reset the message fifo read counter */
  473. ixNpeMhConfigStats[npeId].outFifoReads = 0;
  474. /* reset the message fifo write counter */
  475. ixNpeMhConfigStats[npeId].inFifoWrites = 0;
  476. /* reset the max inFIFO Full retries counter */
  477. ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
  478. /* reset the max outFIFO empty retries counter */
  479. ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
  480. }