📄 mpc107msg.c
字号:
/* mpc107Msg.c - MPC107 Message Unit support *//* Copyright 1996-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01a,11sep00,rcs fix include paths01a,26jun00,bri written*//*DESCRIPTIONThis module contains routines for the Message Unit interface of MPC107 .The Message Unit (MU) of MPC107 facilitates communications betweenthe host processor and peripheral processors in a multiprocessor system .The Message Unit consists of generic messages registers, doorbell registersand an an I2O-compliant interface..SH INITIALIZATIONIf the processor associated with this MPC107 is to be configured as thehost processor ,the Message Unit Interface is initialized by callingthe routine mpc107MsgMessageHostInit().If the processor associated with this MPC107 is to be configured asas a peripheral processor the Message Unit Interface is initializedby calling the routine mpc107MsgMessagePeripheralInit() .The user has to specify to which interrupt of the processor theseinterrupts are connected.*//* includes */#include "vxWorks.h"/* #include "config.h" */#include "sysLib.h"#include "stdlib.h"#include "errno.h"#include "errnoLib.h"#include "intLib.h"#include "memLib.h"#include "drv/multi/mpc107.h"#include "drv/multi/mpc107Msg.h"#include "drv/intrCtl/mpc107Epic.h"/* globals */UINT32 pciBaseAddr = 0; /* PCI base address for oubound interface *//* static file scope locals */BOOL intHandlerInbound = FALSE; /* Flag for Inbound Interrupt Handler */BOOL intHandlerOutbound = FALSE; /* Flag for Outbound Interrupt Handler *//* forward Declarations */void mpc107MessageOutInt (void);void mpc107MessageInInt (void);LOCAL void mpc107MsgWrite (UINT32 pciBar, UINT32 messageRegNum, UINT32 message);LOCAL ULONG mpc107MsgRead (UINT32 pciBar, UINT32 messageRegNum );LOCAL UINT32 mpc107MsgRegMod (UINT32 pciBar, UINT32 ioControlFlag, UINT32 address, UINT32 wdata1, UINT32 wdata2);/***************************************************************************** mpc107MsgMessageHostInit - initializaion of Message Unit (Host)** This routine initializes the Message Unit for multiprocessor communications* using Inbound/Outbound Message Registers and Inbound/Outbound Doorbell* Registers for the host interface** This routine should be called once during hardware initialization .** This routine should called before using the Message Unit for Multiprocessor* communications using Inbound/Outbound Message Registers and* Inbound/Outbound Doorbell Registers for the host interface** RETURNS: N/A*/void mpc107MsgMessageHostInit(void) { if (!intHandlerInbound) /* If Interrupt handler is not hooked */ { intConnect ((VOIDFUNCPTR*)MPC107_EPIC_MU_INT_VECT, mpc107MessageInInt, 0); /* * Setting Flag indicating that Inbound * Interrupt handler is hooked */ intHandlerInbound = TRUE; /* * Enable the Interrupts in the Inbound Message * Interrupt Mask Register */ mpc107MsgRegMod (0x0, MPC107_MSG_READ_OR_WRITE, MPC107_MSG_I2O_IMIMR, !(MPC107_MSG_I2O_IM0IM | MPC107_MSG_I2O_IM1IM | MPC107_MSG_I2O_IDIM | MPC107_MSG_I2O_MCIM), 0); } }/***************************************************************************** mpc107MsgMessagePeripheralInit - initialization of Message Unit (Peripheral)** This routine initializes the Message Unit for multiprocessor communications* using Inbound/Outbound Message Registers and Inbound/Outbound Doorbell* Registers with MPC107 as a peripheral processor** This routine should called before using the Message Unit for Multiprocessor* communications using Inbound/Outbound Message Registers and* Inbound/Outbound Doorbell Registers as a peripheral interface** RETURNS: N/A*/void mpc107MsgMessagePeripheralInit (void ) { if (!intHandlerOutbound) { /* * The PCI base Address should be obtained * after the PCI auto Config and assigned to * the variable <pciBaseAddr> */ pciBaseAddr = MPC107_PCSRBAR_VAL; /* * The ISR handlers should be hooked here if * it is not already hooked */ intConnect ((VOIDFUNCPTR*)MPC107_EPIC_MU_INT_VECT, mpc107MessageOutInt, 0); intHandlerOutbound = TRUE; /* * Enable the Interrupts in the Outbound Message * Interrupt Mask Register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_READ_OR_WRITE, MPC107_MSG_I2O_PCI_OMIMR, !(MPC107_MSG_I2O_OM0IM | MPC107_MSG_I2O_OM1IM | MPC107_MSG_I2O_ODIM ), 0); } }/***************************************************************************** mpc107MsgExtDoorbellInit - initialization of Extended Doorbell Registers** This routine initializes the Message Unit so that Extended Doorbell* Registers can be used for communication in a multiprocessor configuration** This routine should be called before using the Extended Doorbell Registers* for multiprocessor communication** If the External Doorbell registers are used for multiprocessor* communication, then the rest of the Message Unit should not be used* (or enabled).** RETURNS: OK, or ERROR if the specified interrupt type <cpuIntA> is* not correct.*/STATUS mpc107MsgExtDoorbellInit ( UINT32 cpuIntA /* Whether message is for generating INTA (zero) */ /* or CPU INT (one)*/ ) { if (cpuIntA == MPC107_MSG_INTAGEN) { /* * Disable the CPU0 Interrupt and Enable the INTA Interrupt * in the Extended Door Bell Mask Register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_READ_ANDOR_WRITE, MPC107_MSG_EDBSR, ~(MPC107_MSG_EDBMR_INTAIM_BIT), MPC107_MSG_EDBMR_C0IM_BIT); } else if (cpuIntA == MPC107_MSG_CP0GEN) { /* * Enable the CPU0 Interrupt and Disable the INTA Interrupt * in the Extended Door Bell Mask Register */ mpc107MsgRegMod (0x0, MPC107_MSG_READ_ANDOR_WRITE, MPC107_MSG_EDBSR,~(MPC107_MSG_EDBMR_C0IM_BIT), MPC107_MSG_EDBMR_INTAIM_BIT); } else { errnoSet (EINVAL); return (ERROR); } /* * Disable the Interrupts in the * Inbound Message Interrupt Mask Register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_READ_OR_WRITE, MPC107_MSG_I2O_IMIMR, MPC107_MSG_I2O_IM0IM | MPC107_MSG_I2O_IM1IM | MPC107_MSG_I2O_IDIM | MPC107_MSG_I2O_MCIM, 0); return (OK); }/***************************************************************************** mpc107MsgMessageWrite - write to Message Registers** This routine is used for writing data to the Inbound /Out Bound* Message Registers.** A remote processor can write a 32 bit message to the Inbound Message Register* which inturn generates an interrupt (INT to assert) to the local processor** The local processor can write a 32 bit message to the Outbound Message* Register which in turn causes the outbound interrupt signal INTA to be* asserted.** RETURNS: OK, or ERROR if <inOutBound> is neither Inbound nor Outbound,* and <messageRegNum> is not a valid register.*/STATUS mpc107MsgMessageWrite ( UINT32 inOutBound, /* Inbound or Outbound Message Register */ UINT32 messageRegNum, /* register Number */ UINT32 message /* message to be sent */ ) { ULONG regNum; /* register number */ if (inOutBound == MPC107_MSG_INBOUND) /* Inbound Registers */ { if (messageRegNum == MPC107_MSG_REGISTER0) { regNum = MPC107_MSG_IMR0; /* Inbound Message Register 0 */ } else if (messageRegNum == MPC107_MSG_REGISTER1) { regNum = MPC107_MSG_IMR1; /* InBound Message Register 1 */ } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } mpc107MsgRegMod (0x0, MPC107_MSG_WRITE, regNum, message, 0); } else if (inOutBound == MPC107_MSG_OUTBOUND) /* Outbound Registers */ { if (messageRegNum == MPC107_MSG_REGISTER0) { regNum = MPC107_MSG_OMR0; /* Outbound Message Register 0 */ } else if (messageRegNum == MPC107_MSG_REGISTER1) { regNum = MPC107_MSG_OMR1; /* Outbound Message Register 1 */ } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } /* Write the message to the specified register */ mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_WRITE, regNum, message, 0); } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } return (OK); }/***************************************************************************** mpc107MsgMessageRead - read from Message Registers** This routine is used for reading Inbound/Outbound Message registers .** The Inbound Message register is read by the local processor .* The Outbound Message register is read by the remote processor** RETURNS: OK, or ERROR if <inOutBound> is neither Inbound nor Outbound,* and <messageRegNum> is not a valid register.*/STATUS mpc107MsgMessageRead ( UINT32 inOutBound, /* Inbound or Outbound Message Register */ UINT32 messageRegNum, /* register Number */ UINT32 * pMessageRead /* pointer to the buffer to read message */ ) { ULONG regNum; /* register */ if (inOutBound == MPC107_MSG_INBOUND) /* Inbound registers */ { if (messageRegNum == MPC107_MSG_REGISTER0) { regNum = MPC107_MSG_IMR0; /* Inbound Message Register 0 */ } else if (messageRegNum == MPC107_MSG_REGISTER1) { regNum = MPC107_MSG_IMR1; /* InBound Message Register 1 */ } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } * (UINT32 *)pMessageRead = mpc107MsgRegMod (0x0, MPC107_MSG_READ, regNum, 0, 0); } else if (inOutBound == MPC107_MSG_OUTBOUND) /* Outbound registers */ { if (messageRegNum == MPC107_MSG_REGISTER0) { regNum = MPC107_MSG_OMR0; /* Outbound Message Register 0 */ } else if (messageRegNum == MPC107_MSG_REGISTER1) { regNum = MPC107_MSG_OMR1; /* Outbound Message Register 1 */ } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } * (UINT32 *)pMessageRead = mpc107MsgRegMod (pciBaseAddr,MPC107_MSG_READ, regNum, 0, 0); } else { errnoSet (EINVAL); return (ERROR); /* Invalid register */ } /* Read the message from the specified register */ * (UINT32 *)pMessageRead = mpc107MsgRegMod (pciBaseAddr, MPC107_MSG_READ, regNum, 0, 0); return (OK); }/***************************************************************************** mpc107MsgDoorbellWrite - write to Doorbell Registers** This routine is used for writing data to the Inbound /Outbound* Doorbell Registers** A remote processor can set a bit in the Inbound Doorbell Register from* the PCI bus which inturn generates an interrupt (INT to assert) to the* local processor. If the Machine Check bit is set then a machine* check condition is conveyed to the local processor .** The local processor can write to the Outbound Doorbell Register , which* causes the outbound interrupt signal INTA to be asserted, thus interrupting* the remote processor.** RETURNS: OK, or ERROR if <inOutBound> is neither Inbound nor Outbound .*/STATUS mpc107MsgDoorbellWrite ( UINT32 inOutBound, /* whether Inbound or Outbound Message Register */ UINT32 message, /* message to be sent */ UINT32 machineCheck /* machine Check Bit (zero or one ) This is */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -