i2o.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:24k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* i2o.c - Drivers for the I2O */
  2. /* Copyright - Galileo technology. */
  3. /*includes*/
  4. #include <linux/module.h>
  5. #ifdef __linux__
  6. #include <asm/galileo-boards/evb64120A/core.h>
  7. #include <asm/galileo-boards/evb64120A/i2o.h>
  8. #else
  9. #include "Core.h"
  10. #include "i2o.h"
  11. #endif
  12. /********************************************************************
  13. * getInBoundMessage - When the GT is configured for I2O support
  14. *                     it can receive a message from an agent on the pci bus.
  15. *                     This message is a 32 bit wide and can be read by
  16. *                     the CPU.
  17. *                     The messaging unit contains two sets of registers
  18. *                     so, actually it can receive a 64 bit message.
  19. *
  20. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  21. * OUTPUT: N/A.
  22. * RETURNS: Data received from the remote agent.
  23. *********************************************************************/
  24. unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum)
  25. {
  26. unsigned int regValue;
  27. GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum,
  28.     &regValue);
  29. return (regValue);
  30. }
  31. /********************************************************************
  32. * checkInboundIntAndClear - When a message is received an interrupt is
  33. *                           generated, to enable polling instead the use of
  34. *                           an interrupt handler the user can use this fuction.
  35. *                           You will need to mask the incomming interrupt for
  36. *                           proper use.
  37. *
  38. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  39. * OUTPUT: N/A.
  40. * RETURNS: true if the corresponding bit in the cause register is set otherwise
  41. *          false.
  42. *********************************************************************/
  43. bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum)
  44. {
  45. unsigned int regValue;
  46. GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
  47. /* clears bit 0 for message register 0 or bit 1 for message register 1 */
  48. GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE,
  49.      BIT1 * messageRegNum);
  50. switch (messageRegNum) {
  51. case MESSAGE_REG_0:
  52. if (regValue & BIT0)
  53. return true;
  54. break;
  55. case MESSAGE_REG_1:
  56. if (regValue & BIT1)
  57. return true;
  58. break;
  59. }
  60. return false;
  61. }
  62. /********************************************************************
  63. * sendOutBoundMessage - When the GT is configured for I2O support
  64. *                     it can send a message to an agent on the pci bus.
  65. *                     This message is a 32 bit wide and can be read by
  66. *                     the PCI agent.
  67. *                     The messaging unit contains two sets of registers
  68. *                     so, actually it can send a 64 bit message.
  69. *
  70. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  71. *         unsigned int message - Message to be sent.
  72. * OUTPUT: N/A.
  73. * RETURNS: true.
  74. *********************************************************************/
  75. bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum,
  76.  unsigned int message)
  77. {
  78. GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE +
  79.      4 * messageRegNum, message);
  80. return true;
  81. }
  82. /********************************************************************
  83. * checkOutboundInt - When the CPU sends a message to the Outbound
  84. *                    register it generates an interrupt which is refelcted on
  85. *                    the Outbound Interrupt cause register, the interrupt can
  86. *                    be cleard only by the PCI agent which read the message.
  87. *                    After sending the message you can acknowledge it by
  88. *                    monitoring the corresponding bit in the cause register.
  89. *
  90. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  91. * OUTPUT: N/A.
  92. * RETURNS: true if the corresponding bit in the cause register is set otherwise
  93. *          false.
  94. *********************************************************************/
  95. bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum)
  96. {
  97. unsigned int regValue;
  98. GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
  99. switch (messageRegNum) {
  100. case MESSAGE_REG_0:
  101. if (regValue & BIT0)
  102. return true;
  103. break;
  104. case MESSAGE_REG_1:
  105. if (regValue & BIT1)
  106. return true;
  107. break;
  108. }
  109. return false;
  110. }
  111. /********************************************************************
  112. * maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking
  113. *                               the interrupt you can work in polling mode
  114. *                               using the checkInboundIntAndClear function.
  115. *
  116. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  117. * OUTPUT: N/A.
  118. * RETURNS: true.
  119. *********************************************************************/
  120. bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
  121. {
  122. switch (messageRegNum) {
  123. case MESSAGE_REG_0:
  124. SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  125.      BIT0);
  126. break;
  127. case MESSAGE_REG_1:
  128. SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  129.      BIT1);
  130. break;
  131. }
  132. return true;
  133. }
  134. /********************************************************************
  135. * enableInBoundMessageInterrupt - unMask the inbound interrupt.
  136. *
  137. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  138. * OUTPUT: N/A.
  139. * RETURNS: true.
  140. *********************************************************************/
  141. bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
  142. {
  143. switch (messageRegNum) {
  144. case MESSAGE_REG_0:
  145. RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  146.        BIT0);
  147. break;
  148. case MESSAGE_REG_1:
  149. RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  150.        BIT1);
  151. break;
  152. }
  153. return true;
  154. }
  155. /********************************************************************
  156. * maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
  157. *                           the PCI agent needs to poll on the interrupt
  158. *                           cause register to monitor an incoming message.
  159. *
  160. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  161. * OUTPUT: N/A.
  162. * RETURNS: true.
  163. *********************************************************************/
  164. bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
  165. {
  166. switch (messageRegNum) {
  167. case MESSAGE_REG_0:
  168. SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  169.      BIT0);
  170. break;
  171. case MESSAGE_REG_1:
  172. SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  173.      BIT1);
  174. break;
  175. }
  176. return true;
  177. }
  178. /********************************************************************
  179. * enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
  180. *                           the PCI agent needs to poll on the interrupt
  181. *                           cause register to monitor an incoming message.
  182. *
  183. * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
  184. * OUTPUT: N/A.
  185. * RETURNS: true.
  186. *********************************************************************/
  187. bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
  188. {
  189. switch (messageRegNum) {
  190. case MESSAGE_REG_0:
  191. RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  192.        BIT0);
  193. break;
  194. case MESSAGE_REG_1:
  195. RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  196.        BIT1);
  197. break;
  198. }
  199. return true;
  200. }
  201. /********************************************************************
  202. * initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the
  203. *                       CPU generates a PCI interrupt (if it is not masked by
  204. *                       the Outbound interrupt Mask register)
  205. *                       Only the PCI agent which recieved the interrupt can
  206. *                       clear it, only after clearing all the bits the
  207. *                       interrupt will be de-asserted.
  208. *
  209. * INPUTS: unsigned int data - Requested interrupt bits.
  210. * OUTPUT: N/A.
  211. * RETURNS: true.
  212. *********************************************************************/
  213. bool initiateOutBoundDoorBellInt(unsigned int data)
  214. {
  215. GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
  216. return true;
  217. }
  218. /********************************************************************
  219. * readInBoundDoorBellInt - Read the in bound door bell interrupt cause
  220. *                          register.
  221. *
  222. * OUTPUT:  N/A.
  223. * RETURNS: The 32 bit interrupt cause register.
  224. *********************************************************************/
  225. unsigned int readInBoundDoorBellInt()
  226. {
  227. unsigned int regData;
  228. GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, &regData);
  229. return regData;
  230. }
  231. /********************************************************************
  232. * clearInBoundDoorBellInt - An interrupt generated by a PCI agent through
  233. *                           the in bound door bell mechanisem can be cleared
  234. *                           only by the CPU. The interrupt will be de-asserted
  235. *                           only if all the bits which where set by the PCI
  236. *                           agent are cleared.
  237. *
  238. * INPUTS:  unsigned int data - Bits to be cleared.
  239. * OUTPUT:  N/A.
  240. * RETURNS: true.
  241. *********************************************************************/
  242. bool clearInBoundDoorBellInt(unsigned int data)
  243. {
  244. GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
  245. return true;
  246. }
  247. /********************************************************************
  248. * isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set,
  249. *                                 can be used for polling mode.
  250. *
  251. * INPUTS:  N/A.
  252. * OUTPUT:  N/A.
  253. * RETURNS: true if the corresponding bit in the cause register is set otherwise
  254. *          false.
  255. *********************************************************************/
  256. bool isInBoundDoorBellInterruptSet()
  257. {
  258. unsigned int regData;
  259. GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
  260. return (regData & BIT2);
  261. }
  262. /********************************************************************
  263. * isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is
  264. *                                  set, can be used for acknowledging interrupt
  265. *                                  handling by the agent who recieived the
  266. *                                  interrupt.
  267. *
  268. * INPUTS:  N/A.
  269. * OUTPUT:  N/A.
  270. * RETURNS: true if the corresponding bit in the cause register is set otherwise
  271. *          false.
  272. *********************************************************************/
  273. bool isOutBoundDoorBellInterruptSet()
  274. {
  275. unsigned int regData;
  276. GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
  277. return (regData & BIT2);
  278. }
  279. /********************************************************************
  280. * maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt.
  281. *
  282. * INPUTS:  N/A.
  283. * OUTPUT:  N/A.
  284. * RETURNS: true.
  285. *********************************************************************/
  286. bool maskInBoundDoorBellInterrupt()
  287. {
  288. SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
  289. return true;
  290. }
  291. /********************************************************************
  292. * enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt.
  293. *
  294. * INPUTS:  N/A.
  295. * OUTPUT:  N/A.
  296. * RETURNS: true.
  297. *********************************************************************/
  298. bool enableInBoundDoorBellInterrupt()
  299. {
  300. RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
  301. return true;
  302. }
  303. /********************************************************************
  304. * maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt.
  305. *
  306. * INPUTS:  N/A.
  307. * OUTPUT:  N/A.
  308. * RETURNS: true.
  309. *********************************************************************/
  310. bool maskOutBoundDoorBellInterrupt()
  311. {
  312. SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
  313. return true;
  314. }
  315. /********************************************************************
  316. * enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt.
  317. *
  318. * INPUTS:  N/A.
  319. * OUTPUT:  N/A.
  320. * RETURNS: true.
  321. *********************************************************************/
  322. bool enableOutBoundDoorBellInterrupt()
  323. {
  324. RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
  325. return true;
  326. }
  327. /********************************************************************
  328. * circularQueueEnable - Initialize the I2O messaging mechanism.
  329. *
  330. * INPUTS:   CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the:
  331. *           Queue Control Register, Offset 0x50 (0x1c50).
  332. *           Defines the queues size (refer to the data sheet
  333. *           for more information)
  334. *          unsigned int queueBaseAddr - The base address for the first queue.
  335. *           The other queues base Address will be determined as follows:
  336. *           Inbound Free = queueBaseAddr
  337. *           Inbound Post = queueBaseAddr + cirQueSize
  338. *           Outbound Post = queueBaseAddr + cirQueSize
  339. *
  340. * OUTPUT:  N/A.
  341. * RETURNS: true.
  342. *
  343. *  The Circular Queue Starting Addresses as written in the spec:
  344. *  ----------------------------------------
  345. *  |    Queue       |  Starting Address   |
  346. *  |----------------|---------------------|
  347. *  | Inbound Free   |       QBAR          |
  348. *  | Inbound Post   | QBAR + Queue Size   |
  349. *  | Outbound Post  | QBAR + 2*Queue Size |
  350. *  | Outbound Free  | QBAR + 3*Queue Size |
  351. *  ----------------------------------------
  352. *********************************************************************/
  353. bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize,
  354.  unsigned int queueBaseAddr)
  355. {
  356. unsigned int regData;
  357. regData = BIT0 | (cirQueSize << 1);
  358. /* Enable Queue Operation */
  359. GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData);
  360. /* Writing The base Address for the 4 Queues */
  361. GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr);
  362. /* Update The Inbound Free Queue Base Address, offset=0 */
  363. GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0);
  364. GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0);
  365. /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */
  366. GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
  367.      _16K * cirQueSize);
  368. GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
  369.      _16K * cirQueSize);
  370. /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */
  371. GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
  372.      2 * _16K * cirQueSize);
  373. GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
  374.      2 * _16K * cirQueSize);
  375. /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */
  376. GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
  377.      3 * _16K * cirQueSize);
  378. GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
  379.      3 * _16K * cirQueSize);
  380. return true;
  381. }
  382. /********************************************************************
  383. * inBoundPostQueuePop - Two actions are being taken upon pop:
  384. *           1) Getting out the data from the Queue`s head.
  385. *           2) Increment the tail pointer in a cyclic way (The HEAD is
  386. *              incremented automaticaly by the GT)
  387. *
  388. * INPUTS:  N/A.
  389. * OUTPUT:  N/A.
  390. * RETURNS: Data pointed by tail.
  391. *********************************************************************/
  392. unsigned int inBoundPostQueuePop()
  393. {
  394. unsigned int tailAddrPointer;
  395. unsigned int data;
  396. unsigned int cirQueSize;
  397. unsigned int qBar;
  398. unsigned int inBoundPostQbase;
  399. /* Gets the Inbound Post TAIL pointer */
  400. GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
  401.     &tailAddrPointer);
  402. /* Gets the Data From the pointer Address */
  403. READ_WORD(tailAddrPointer, &data);
  404. /* incrementing head process: */
  405. /* Gets the fifo's base Address */
  406. GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
  407. qBar = qBar & 0xfff00000;
  408. /* Gets the fifo's size */
  409. GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
  410. cirQueSize = 0x1f && (cirQueSize >> 1);
  411. /* calculating The Inbound Post Queue Base Address */
  412. inBoundPostQbase = qBar + 1 * cirQueSize * _16K;
  413. /* incrementing Inbound Post queue TAIL in a cyclic loop */
  414. tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) %
  415.       (_16K * cirQueSize));
  416. /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */
  417. GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
  418.      tailAddrPointer);
  419. return data;
  420. }
  421. /********************************************************************
  422. * isInBoundPostQueueInterruptSet - Check if in bound interrupt is set.
  423. *                                  can be used for polling mode.
  424. *
  425. * INPUTS:  N/A.
  426. * OUTPUT:  N/A.
  427. * RETURNS: true if the corresponding bit in the cause register is set otherwise
  428. *          false.
  429. *********************************************************************/
  430. bool isInBoundPostQueueInterruptSet()
  431. {
  432. unsigned int regData;
  433. GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
  434. return (regData & BIT4); /* if set return '1' (true), else '0' (false) */
  435. }
  436. /********************************************************************
  437. * clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.
  438. *
  439. * INPUTS:  N/A.
  440. * OUTPUT:  N/A.
  441. * RETURNS: true.
  442. *********************************************************************/
  443. bool clearInBoundPostQueueInterrupt()
  444. {
  445. GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4);
  446. return true;
  447. }
  448. /********************************************************************
  449. * maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking
  450. *                                 the interrupt you can work in polling mode.
  451. *
  452. * INPUTS:  N/A.
  453. * OUTPUT:  N/A.
  454. * RETURNS:
  455. *********************************************************************/
  456. void maskInBoundPostQueueInterrupt()
  457. {
  458. unsigned int regData;
  459. GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
  460. GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  461.      regData | BIT4);
  462. }
  463. /********************************************************************
  464. * enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new
  465. *                                   message from the PCI agent.
  466. *
  467. * INPUTS:  N/A.
  468. * OUTPUT:  N/A.
  469. * RETURNS:
  470. *********************************************************************/
  471. void enableInBoundPostQueueInterrupt()
  472. {
  473. unsigned int regData;
  474. GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
  475. GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
  476.      regData & 0xfffffffb);
  477. }
  478. /********************************************************************
  479. * inBoundFreeQueuePush - Two actions are being taken upon push:
  480. *           1) Place the user`s data on the Queue`s head.
  481. *           2) Increment the haed pointer in a cyclic way (The tail is
  482. *              decremented automaticaly by the GT)
  483. *
  484. * INPUTS:  unsigned int data - Data to be placed in the queue.
  485. * OUTPUT:  N/A.
  486. * RETURNS: true.
  487. *********************************************************************/
  488. bool inBoundFreeQueuePush(unsigned int data)
  489. {
  490. unsigned int headPointer;
  491. unsigned int cirQueSize;
  492. unsigned int qBar;
  493. unsigned int inBoundFreeQbase;
  494. GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
  495.     &headPointer);
  496. /* placing the data in the queue */
  497. WRITE_WORD(headPointer, data);
  498. /* incrementing head process: */
  499. /* Gets the fifo's base Address */
  500. GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
  501. qBar = qBar & 0xfff00000;
  502. /* Gets the fifo's size */
  503. GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
  504. cirQueSize = 0x1f && (cirQueSize >> 1);
  505. /* calculating The Inbound Free Queue Base Address */
  506. inBoundFreeQbase = qBar;
  507. /* incrementing Inbound Free queue HEAD in a cyclic loop */
  508. headPointer =
  509.     inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize));
  510. /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
  511. GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
  512.      headPointer);
  513. return true;
  514. }
  515. /********************************************************************
  516. * isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty.
  517. *                           Can be used for acknowledging the messages
  518. *                           being sent by us to the PCI agent.
  519. *
  520. * INPUTS:  N/A.
  521. * OUTPUT:  N/A.
  522. * RETURNS: true if the queue is empty , otherwise false.
  523. *********************************************************************/
  524. bool isInBoundFreeQueueEmpty()
  525. {
  526. unsigned int inBoundFreeQueHead;
  527. unsigned int inBoundFreeQueTail;
  528. GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
  529.     &inBoundFreeQueHead);
  530. GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
  531.     &inBoundFreeQueTail);
  532. if (inBoundFreeQueHead == inBoundFreeQueTail) {
  533. return true;
  534. } else
  535. return false;
  536. }
  537. /********************************************************************
  538. * outBoundPostQueuePush  - Two actions are being taken upon push:
  539. *           1) Place the user`s data on the Queue`s head.
  540. *           2) Increment the haed pointer in a cyclic way (The tail is
  541. *              decremented automaticaly by the GT when the Agent on the
  542. *              PCI have read data from the Outbound Port).
  543. *
  544. * INPUTS:  unsigned int data - Data to be placed in the queue`s head.
  545. * OUTPUT:  N/A.
  546. * RETURNS: true.
  547. *********************************************************************/
  548. bool outBoundPostQueuePush(unsigned int data)
  549. {
  550. unsigned int headPointer;
  551. unsigned int cirQueSize;
  552. unsigned int qBar;
  553. unsigned int outBoundPostQbase;
  554. GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
  555.     &headPointer);
  556. /* placing the data in the queue (where the head point to..) */
  557. WRITE_WORD(headPointer, data);
  558. /* incrementing head process: */
  559. /* Gets the fifo's base Address */
  560. GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
  561. qBar = qBar & 0xfff00000;
  562. /* Gets the fifo's size */
  563. GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
  564. cirQueSize = 0x1f && (cirQueSize >> 1);
  565. /* calculating The Outbound Post Queue Base Address */
  566. outBoundPostQbase = qBar + 2 * cirQueSize * _16K;
  567. /* incrementing Outbound Post queue in a cyclic loop */
  568. headPointer =
  569.     outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize));
  570. /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
  571. GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
  572.      headPointer);
  573. return true;
  574. }
  575. /********************************************************************
  576. * isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty.
  577. *                            Can be used for acknowledging the messages
  578. *                            being sent by us to the PCI agent.
  579. *
  580. * INPUTS:  N/A.
  581. * OUTPUT:  N/A.
  582. * RETURNS: true if the queue is empty , otherwise false.
  583. *********************************************************************/
  584. bool isOutBoundPostQueueEmpty()
  585. {
  586. unsigned int outBoundPostQueHead;
  587. unsigned int outBoundPostQueTail;
  588. GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
  589.     &outBoundPostQueHead);
  590. GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
  591.     &outBoundPostQueTail);
  592. if (outBoundPostQueHead == outBoundPostQueTail) {
  593. return true;
  594. } else
  595. return false;
  596. }
  597. /********************************************************************
  598. * outBoundFreeQueuePop - Two actions are being taken upon pop:
  599. *           1) Getting out the data from the Queue`s head.
  600. *           2) Increment the tail pointer in a cyclic way (The HEAD is
  601. *              incremented automaticaly by the GT)
  602. *
  603. * INPUTS:  N/A.
  604. * OUTPUT:  N/A.
  605. * RETURNS: Data pointed by tail.
  606. *********************************************************************/
  607. unsigned int outBoundFreeQueuePop()
  608. {
  609. unsigned int tailAddrPointer;
  610. unsigned int data;
  611. unsigned int cirQueSize;
  612. unsigned int qBar;
  613. unsigned int outBoundFreeQbase;
  614. /* Gets the Inbound Post TAIL pointer */
  615. GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
  616.     &tailAddrPointer);
  617. /* Gets the Data From the pointer Address */
  618. READ_WORD(tailAddrPointer, &data);
  619. /* incrementing head process: */
  620. /* Gets the fifo's base Address */
  621. GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
  622. qBar = qBar & 0xfff00000;
  623. /* Gets the fifo's size */
  624. GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
  625. cirQueSize = 0x1f && (cirQueSize >> 1);
  626. /* calculating The Inbound Post Queue Base Address */
  627. outBoundFreeQbase = qBar + 3 * cirQueSize * _16K;
  628. /* incrementing Outbound Free queue TAlL in a cyclic loop */
  629. tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) %
  630.        (_16K * cirQueSize));
  631. /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */
  632. GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
  633.      tailAddrPointer);
  634. return data;
  635. }
  636. EXPORT_SYMBOL(isInBoundDoorBellInterruptSet);
  637. EXPORT_SYMBOL(initiateOutBoundDoorBellInt);
  638. EXPORT_SYMBOL(clearInBoundDoorBellInt);