📄 mpc107msg.c
字号:
/* valid only for Inbound Door Bell */ /* Register */ ) { ULONG regNum; if (inOutBound == MPC107_MSG_INBOUND) /* Inbound Doorbell Register */ { regNum = MPC107_MSG_IDBR; message |= (machineCheck << MPC107_MSG_IDBR_MC_SHIFT); /* Write the message to the specified register */ mpc107MsgRegMod (0x0, MPC107_MSG_WRITE, regNum, message, 0); } else if (inOutBound == MPC107_MSG_OUTBOUND) /* Outbound Doorbell Register */ { regNum = MPC107_MSG_ODBR; message |= MPC107_MSG_ODBR_DATA_MASK; /* Write the message to the specified register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, regNum, message, 0); } else { errnoSet (EINVAL); return (ERROR); } return (OK); }/***************************************************************************** mpc107MsgDoorbellRead - read from Doorbell Registers** This routine is used for reading data from the Inbound / Outbound* Doorbell registers** The Inbound Doorbell register is read by the local proceesor and the* bits set in the register are cleared by writing a 1 those bits .** The Outbound Doorbell Register is read by the remote processor and the* bits set in the register are cleared by writing a 1 those bits .** RETURNS: OK, or ERROR if <inOutBound> is neither Inbound nor Outbound.*/STATUS mpc107MsgDoorbellRead ( UINT32 inOutBound, /* whether Inbound or Outbound Message Reg */ UINT32 *pMsgDoorbellRead /* data read */ ) { ULONG tempReadData; /* data read from the register */ if (inOutBound == MPC107_MSG_INBOUND) /* Inbound Doorbell Register */ { /* read the inbound doorbell register */ tempReadData = mpc107MsgRegMod (0x0, MPC107_MSG_READ, MPC107_MSG_IDBR, 0, 0); *(UINT32 *)pMsgDoorbellRead = tempReadData; /* clear the bits set in the door bell registers */ mpc107MsgRegMod (0x0, MPC107_MSG_WRITE, MPC107_MSG_IDBR, tempReadData, 0); } else if (inOutBound == MPC107_MSG_OUTBOUND) /* Outbound Doorbell Register */ { /* read the Outbound doorbell register */ tempReadData = mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_READ, MPC107_MSG_ODBR, 0, 0); *(UINT32 *)pMsgDoorbellRead = tempReadData; /* clear the bits set in the door bell registers */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, MPC107_MSG_ODBR, tempReadData, 0); } else { errnoSet (EINVAL); return (ERROR); } return (OK); }/***************************************************************************** mpc107MsgExtDoorbellSetWrite - write to Extended Doorbell Write1 Set Register** This routine is used for writing data to Extended Doorbell Write 1* Set register causing an interrupt to be generated .** RETURNS: OK, or ERROR if the specified interrupt type <cpuIntA> is* not correct.*/STATUS mpc107MsgExtDoorbellSetWrite ( UINT32 message, /* message to be sent */ UINT32 cpuIntA /* whether message is for generating INTA (zero) */ /* or CPU Interrupt (One) */ ) { if (cpuIntA == MPC107_MSG_INTAGEN) { message = ((message & MPC107_MSG_GENERAL_LSB_MSK ) << MPC107_MSG_EDBW1S_INTA_SHIFT) & MPC107_MSG_EDBW1S_INTA_MSK ; } else if (cpuIntA == MPC107_MSG_CP0GEN) { message = ((message & MPC107_MSG_GENERAL_LSB_MSK ) << MPC107_MSG_EDBW1S_CP0_SHIFT) & MPC107_MSG_EDBW1S_CP0_MSK ; } else { errnoSet (EINVAL); return (ERROR); } /* Write the data to Extended Doorbell Write 1 Register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, MPC107_MSG_EDBW1S, 0, 0); return (OK); }/***************************************************************************** mpc107MsgExtDoorbellClrRead - read Extended Doorbell Write1 Clear Register** This routine is used for reading data from the Extended Doorbell Write 1* Clear Register.This register is cleared after reading the data** RETURNS: The data read is returned*/ULONG mpc107MsgExtDoorbellClrRead (void) { ULONG tempData ; /* Read the data from Extended Door Bell Write1 Clear Register */ tempData = mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, MPC107_MSG_EDBW1C, 0, 0); /* Clear all the bits in the Extended Doorbell Write1 Clear Register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, MPC107_MSG_EDBW1C, tempData, 0); return (tempData); }/***************************************************************************** mpc107MsgI2oInit - initialization of I20 Interface of Message Unit** This routine sets up the size of the inbound and outbound FIFOs .* Memory for messages is allocated and the inbound Free Fifo/Outbound Free FIFO* are initialized with the Message Frame Addresses .** RETURNS: OK, or ERROR if memory allocation has failed.*/STATUS mpc107MsgI2oInit (void) { UINT32 * pI2oQbaseAddr; /* pointer to Circular queue */ UINT32 tempI2oData; /* temporary data */ UINT32 i2oQueueSize; /* queue size */ UINT32 * pInboundFreeListBase; /* pointer to Inbound Free List FIFO */ UINT32 * pOutboundFreeListBase;/* pointer to Outbound Free List FIFO */ UINT32 tempIndex; /* index */ UINT32 tempMfaAddress; /* temporary MFA address */ /* Initiailze the Message Unit I20 Control Register */ mpc107MsgRegMod (0x0, MPC107_MSG_WRITE, MPC107_MSG_I2O_MUCR, MPC107_MSG_I2O_MUCR_DEFAULT, 0); tempI2oData = mpc107MsgRegMod (0x0, MPC107_MSG_READ, MPC107_MSG_I2O_MUCR , 0, 0) & MPC107_MSG_I2O_CQS; switch (tempI2oData & MPC107_MSG_I2O_CQS) { case MPC107_MSG_I2O_CQS_16K: /* FIFO size is 4 K entries (16 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_16K_SIZE; break; case MPC107_MSG_I2O_CQS_32K: /* FIFO size is 8 K entries (32 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_32K_SIZE; break; case MPC107_MSG_I2O_CQS_64K: /* FIFO size is 16 K entries (64 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_64K_SIZE; break; case MPC107_MSG_I2O_CQS_128K: /* FIFO size is 32 K entries (128 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_128K_SIZE; break; case MPC107_MSG_I2O_CQS_256K: /* FIFO size is 64 K entries (256 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_256K_SIZE; break; default: /* FIFO size is 4 K entries (16 K Bytes) */ i2oQueueSize = MPC107_MSG_I2O_CQS_16K_SIZE; break; } /* Allocate memory for the circular queues */ pI2oQbaseAddr = (UINT32 *)memalign (MPC107_MSG_I2O_MUCR_QBAR_ALIGN, sizeof(UINT32) * i2oQueueSize * 4 ); if ((pI2oQbaseAddr) != 0 ) /* If memory allocated */ { /* Initialize the Queue Base Address Register */ mpc107MsgRegMod (0x0, MPC107_MSG_WRITE, MPC107_MSG_I2O_QBAR, (UINT32)pI2oQbaseAddr, 0); /* Pointer to Inbound Free List FIFO base */ (UINT32 *)pInboundFreeListBase = (UINT32 *) (pI2oQbaseAddr); /* Pointer to Outbound Free List FIFO base */ (UINT32 *)pOutboundFreeListBase =(UINT32 *) (pI2oQbaseAddr + ((i2oQueueSize) *3)); /* Initialize the In Bound Free FIFO list with the MFAs */ for (tempIndex = 0; tempIndex <i2oQueueSize; tempIndex++) { tempMfaAddress = ((UINT32)malloc(sizeof(UINT32)) * MPC107_MSG_I2O_MFRAME_SIZE); if ((tempMfaAddress) != 0) /* If memory is allocated */ { *((UINT32 *) (pInboundFreeListBase + tempIndex)) = tempMfaAddress; } else return (ERROR); } /* Initialize the Out Bound Free FIFO list with the MFAs */ for (tempIndex = 0; tempIndex <i2oQueueSize; tempIndex++) { tempMfaAddress = ((UINT32)malloc(sizeof(UINT32)) * MPC107_MSG_I2O_MFRAME_SIZE); if ((tempMfaAddress) != 0) /* If memory is allocated */ { *((UINT32 *) (pOutboundFreeListBase + tempIndex)) = tempMfaAddress; } else return (ERROR); } } else return (ERROR); return (OK); }/***************************************************************************** mpc107MsgI2oInboundRead - read from I2O Inbound Interface** This routine is used by the host processor to read messages posted to* the I2O Outbound Interface by the external PCI master** RETURNS: N/A*/void mpc107MsgI2oInboundRead (void) { UINT32 ** ppTempMfa; /* pointer to Message Frame pointer */ UINT32 * pTempReadMfa; /* pointer to Message Frame */ ULONG tempIndex; /* index */ UINT32 pBuf[MPC107_MSG_I2O_MFRAME_SIZE]; /* buffer for read data */ /* Read Inbound Post Fifo Tail Pointer Register (IPTPR) to get MFA */ ppTempMfa = (UINT32 **)mpc107MsgRegMod (0, MPC107_MSG_READ, MPC107_MSG_I2O_IPTPR, 0, 0); pTempReadMfa = *ppTempMfa; /* Read the messages */ for (tempIndex = 0; tempIndex < MPC107_MSG_I2O_MFRAME_SIZE; tempIndex++) { *((UINT32 *)(pBuf + tempIndex)) = *((UINT32 *)(pTempReadMfa + tempIndex)); } /* Increment the value in Inbound Post FIFO Tail Pointer Reg (IPTPR) */ mpc107MsgRegMod (0, MPC107_MSG_WRITE, MPC107_MSG_I2O_IPTPR, (UINT32)(ppTempMfa + 1) , 0); /* * Return the message to the Inbound Free List Fifo by * writing the MFAs to Inbound Free Fifo Head Pointer Reg */ mpc107MsgRegMod (0, MPC107_MSG_WRITE, MPC107_MSG_I2O_IFHPR, (UINT32)ppTempMfa, 0); }/***************************************************************************** mpc107MsgI2oOutboundWrite - write to I20 Outbound interface** This routine is used by the host processor to write messages to* the I2O Outbound Interface .** The host processor obtains a free MFA and posts the messages.** RETURNS: N/A*/void mpc107MsgI2oOutboundWrite ( UINT32 * pBuf /* pointer to message to be written */ /* to Outbound I2O interface */ ) { UINT32 ** ppTempMfa; /* pointer to Message Frame pointer */ UINT32 ** ppTempOfhpr; /* pointer to Message Frame pointer */ UINT32 * pTempWriteMfa;/* pointer to Message Frame */ ULONG tempIndex; /* index */ /* Read Outbound Free Fifo Tail Pointer Reg (OFTPR) to Get MFA */ ppTempMfa = (UINT32 **) mpc107MsgRegMod (0, MPC107_MSG_READ, MPC107_MSG_I2O_OFTPR, 0, 0); /* Read Outbound Free Fifo Head Pointer Register (OFHPR) to Get MFA */ ppTempOfhpr = (UINT32 **) mpc107MsgRegMod (0, MPC107_MSG_READ, MPC107_MSG_I2O_OFHPR, 0, 0); if (ppTempMfa != ppTempOfhpr) /* If the FIFO is not empty */ { pTempWriteMfa = *ppTempMfa; /* Write the message in the Message Frame */ for (tempIndex = 0; tempIndex < MPC107_MSG_I2O_MFRAME_SIZE; tempIndex++) { *((UINT32 *)(pTempWriteMfa + tempIndex)) = *((UINT32 *)(pBuf+ tempIndex)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -