📄 i2o.c
字号:
* OUTPUT: N/A.* RETURNS: true.*********************************************************************/bool enableOutBoundDoorBellInterrupt(){ RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); return true;}/********************************************************************* circularQueueEnable - Initialize the I2O messaging mechanism.** INPUTS: CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the:* Queue Control Register, Offset 0x50 (0x1c50).* Defines the queues size (refer to the data sheet* for more information)* unsigned int queueBaseAddr - The base address for the first queue.* The other queues base Address will be determined as follows:* Inbound Free = queueBaseAddr* Inbound Post = queueBaseAddr + cirQueSize* Outbound Post = queueBaseAddr + cirQueSize** OUTPUT: N/A.* RETURNS: true.** The Circular Queue Starting Addresses as written in the spec:* ----------------------------------------* | Queue | Starting Address |* |----------------|---------------------|* | Inbound Free | QBAR |* | Inbound Post | QBAR + Queue Size |* | Outbound Post | QBAR + 2*Queue Size |* | Outbound Free | QBAR + 3*Queue Size |* ----------------------------------------*********************************************************************/bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize, unsigned int queueBaseAddr){ unsigned int regData; regData = BIT0 | (cirQueSize << 1); /* Enable Queue Operation */ GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData); /* Writing The base Address for the 4 Queues */ GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr); /* Update The Inbound Free Queue Base Address, offset=0 */ GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0); GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0); /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */ GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, _16K * cirQueSize); GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, _16K * cirQueSize); /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */ GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, 2 * _16K * cirQueSize); GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, 2 * _16K * cirQueSize); /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */ GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 3 * _16K * cirQueSize); GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 3 * _16K * cirQueSize); return true;}/********************************************************************* inBoundPostQueuePop - Two actions are being taken upon pop:* 1) Getting out the data from the Queue`s head.* 2) Increment the tail pointer in a cyclic way (The HEAD is* incremented automaticaly by the GT)** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: Data pointed by tail.*********************************************************************/unsigned int inBoundPostQueuePop(){ unsigned int tailAddrPointer; unsigned int data; unsigned int cirQueSize; unsigned int qBar; unsigned int inBoundPostQbase; /* Gets the Inbound Post TAIL pointer */ GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, &tailAddrPointer); /* Gets the Data From the pointer Address */ READ_WORD(tailAddrPointer, &data); /* incrementing head process: */ /* Gets the fifo's base Address */ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); qBar = qBar & 0xfff00000; /* Gets the fifo's size */ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); cirQueSize = 0x1f && (cirQueSize >> 1); /* calculating The Inbound Post Queue Base Address */ inBoundPostQbase = qBar + 1 * cirQueSize * _16K; /* incrementing Inbound Post queue TAIL in a cyclic loop */ tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) % (_16K * cirQueSize)); /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */ GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, tailAddrPointer); return data;}/********************************************************************* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set.* can be used for polling mode.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: true if the corresponding bit in the cause register is set otherwise* false.*********************************************************************/bool isInBoundPostQueueInterruptSet(){ unsigned int regData; GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); return (regData & BIT4); /* if set return '1' (true), else '0' (false) */}/********************************************************************* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: true.*********************************************************************/bool clearInBoundPostQueueInterrupt(){ GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4); return true;}/********************************************************************* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking* the interrupt you can work in polling mode.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS:*********************************************************************/void maskInBoundPostQueueInterrupt(){ unsigned int regData; GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, regData | BIT4);}/********************************************************************* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new* message from the PCI agent.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS:*********************************************************************/void enableInBoundPostQueueInterrupt(){ unsigned int regData; GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, regData & 0xfffffffb);}/********************************************************************* inBoundFreeQueuePush - Two actions are being taken upon push:* 1) Place the user`s data on the Queue`s head.* 2) Increment the haed pointer in a cyclic way (The tail is* decremented automaticaly by the GT)** INPUTS: unsigned int data - Data to be placed in the queue.* OUTPUT: N/A.* RETURNS: true.*********************************************************************/bool inBoundFreeQueuePush(unsigned int data){ unsigned int headPointer; unsigned int cirQueSize; unsigned int qBar; unsigned int inBoundFreeQbase; GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, &headPointer); /* placing the data in the queue */ WRITE_WORD(headPointer, data); /* incrementing head process: */ /* Gets the fifo's base Address */ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); qBar = qBar & 0xfff00000; /* Gets the fifo's size */ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); cirQueSize = 0x1f && (cirQueSize >> 1); /* calculating The Inbound Free Queue Base Address */ inBoundFreeQbase = qBar; /* incrementing Inbound Free queue HEAD in a cyclic loop */ headPointer = inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize)); /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, headPointer); return true;}/********************************************************************* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty.* Can be used for acknowledging the messages* being sent by us to the PCI agent.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: true if the queue is empty , otherwise false.*********************************************************************/bool isInBoundFreeQueueEmpty(){ unsigned int inBoundFreeQueHead; unsigned int inBoundFreeQueTail; GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, &inBoundFreeQueHead); GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, &inBoundFreeQueTail); if (inBoundFreeQueHead == inBoundFreeQueTail) { return true; } else return false;}/********************************************************************* outBoundPostQueuePush - Two actions are being taken upon push:* 1) Place the user`s data on the Queue`s head.* 2) Increment the haed pointer in a cyclic way (The tail is* decremented automaticaly by the GT when the Agent on the* PCI have read data from the Outbound Port).** INPUTS: unsigned int data - Data to be placed in the queue`s head.* OUTPUT: N/A.* RETURNS: true.*********************************************************************/bool outBoundPostQueuePush(unsigned int data){ unsigned int headPointer; unsigned int cirQueSize; unsigned int qBar; unsigned int outBoundPostQbase; GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, &headPointer); /* placing the data in the queue (where the head point to..) */ WRITE_WORD(headPointer, data); /* incrementing head process: */ /* Gets the fifo's base Address */ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); qBar = qBar & 0xfff00000; /* Gets the fifo's size */ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); cirQueSize = 0x1f && (cirQueSize >> 1); /* calculating The Outbound Post Queue Base Address */ outBoundPostQbase = qBar + 2 * cirQueSize * _16K; /* incrementing Outbound Post queue in a cyclic loop */ headPointer = outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize)); /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, headPointer); return true;}/********************************************************************* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty.* Can be used for acknowledging the messages* being sent by us to the PCI agent.** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: true if the queue is empty , otherwise false.*********************************************************************/bool isOutBoundPostQueueEmpty(){ unsigned int outBoundPostQueHead; unsigned int outBoundPostQueTail; GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, &outBoundPostQueHead); GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, &outBoundPostQueTail); if (outBoundPostQueHead == outBoundPostQueTail) { return true; } else return false;}/********************************************************************* outBoundFreeQueuePop - Two actions are being taken upon pop:* 1) Getting out the data from the Queue`s head.* 2) Increment the tail pointer in a cyclic way (The HEAD is* incremented automaticaly by the GT)** INPUTS: N/A.* OUTPUT: N/A.* RETURNS: Data pointed by tail.*********************************************************************/unsigned int outBoundFreeQueuePop(){ unsigned int tailAddrPointer; unsigned int data; unsigned int cirQueSize; unsigned int qBar; unsigned int outBoundFreeQbase; /* Gets the Inbound Post TAIL pointer */ GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, &tailAddrPointer); /* Gets the Data From the pointer Address */ READ_WORD(tailAddrPointer, &data); /* incrementing head process: */ /* Gets the fifo's base Address */ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); qBar = qBar & 0xfff00000; /* Gets the fifo's size */ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); cirQueSize = 0x1f && (cirQueSize >> 1); /* calculating The Inbound Post Queue Base Address */ outBoundFreeQbase = qBar + 3 * cirQueSize * _16K; /* incrementing Outbound Free queue TAlL in a cyclic loop */ tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) % (_16K * cirQueSize)); /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */ GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, tailAddrPointer); return data;}EXPORT_SYMBOL(isInBoundDoorBellInterruptSet);EXPORT_SYMBOL(initiateOutBoundDoorBellInt);EXPORT_SYMBOL(clearInBoundDoorBellInt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -