📄 ixm1200hpc.c
字号:
if (sysCpuRev < 2) { /* Due to an A3/B0 bug, if a PCI device is writing to a PCI CSR at the right time, out write can get lost; so we had better check it. */ while (1) { IXM1200_REG_READ(IXM1200_DOORBELL, i); if ((i & DOORBELL_SEND_MASK) != 0) break; IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK); } /* end while */ } /* end if sysCpuRev < 2 */#endif /* ifdef IXM1200 || PA1104 */ }}voidprocBufferLoop(HPC_GLOBAL_STATE *state){ while (1) { semTake(state->DPCSem, WAIT_FOREVER); semTake(state->commonSem, WAIT_FOREVER); procBuffers(state); semGive(state->commonSem); } /* end while 1 */}inthpcPolledRcv(int channel, unsigned char *buf, unsigned int bsize, unsigned int *incomp){ int index = 2 * channel + HPC_RX_OFFSET; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[index]; unsigned int size, size2; unsigned int sizeValid; unsigned int incomplete; sizeValid = configStatus->sizeValid[index]; if (0 == sizeValid) { return 0; } incomplete = sizeValid & BUFFER_INCOMPLETE_MASK; CLEAR(sizeValid, BUFFER_INCOMPLETE_MASK); size = sizeValid - binfo->bytesUsed;; size2 = bsize; if (size > size2) size = size2; bcopy(binfo->buff + binfo->bytesUsed, /* src */ buf, /* dst */ size); binfo->bytesUsed += size; if (incomp) { if (incomplete || (binfo->bytesUsed < sizeValid)) *incomp = 1; else *incomp = 0; } if (binfo->bytesUsed == sizeValid) { /* buffer is empty */ configStatus->sizeValid[index] = 0; binfo->bytesUsed = 0; if (configStatus->NTIsWaitingMask & binfo->waitingMask) {#if defined(IXM1200) REG_WRITE16(doorbellAddr, DOORBELL_SEND_MASK);#else IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK); if (sysCpuRev < 2) { /* Due to an A3/B0 bug, if a PCI device is writing to a PCI CSR at the right time, out write can get lost; so we had better check it. */ while (1) { unsigned int i; IXM1200_REG_READ(IXM1200_DOORBELL, i); if ((i & DOORBELL_SEND_MASK) != 0) break; IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK); } /* end while */ } /* end if sysCpuRev < 2 */#endif /* ifdef IXM1200 || PA1104 */ } } return size;}inthpcPolledSend(int channel, unsigned char *buf, unsigned int bsize){ int index = 2 * channel + HPC_TX_OFFSET; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[index]; unsigned int size; if (0 != configStatus->sizeValid[index]) return 0; size = bsize; if (size > SHARED_DATA_BUFFER_SIZE) size = SHARED_DATA_BUFFER_SIZE; bcopy(buf, /* src */ binfo->buff, /* dst */ size); if (size < bsize) size |= BUFFER_INCOMPLETE_MASK; configStatus->sizeValid[index] = size; if (configStatus->NTIsWaitingMask & binfo->waitingMask) {#if defined(IXM1200) REG_WRITE16(doorbellAddr, DOORBELL_SEND_MASK);#else IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK); if (sysCpuRev < 2) { /* Due to an A3/B0 bug, if a PCI device is writing to a PCI CSR at the right time, out write can get lost; so we had better check it. */ while (1) { unsigned int i; IXM1200_REG_READ(IXM1200_DOORBELL, i); if ((i & DOORBELL_SEND_MASK) != 0) break; IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK); } /* end while */ } /* end if sysCpuRev < 2 */#endif /* ifdef IXM1200 || PA1104 */ } return size & ~BUFFER_INCOMPLETE_MASK;}voidhpcMemInit(){ int i; for (i=0; i<NUM_SHARED_DATA_BUFFERS; i++) configStatus->sizeValid[i] = 0; configStatus->NTIsWaitingMask = 0; configStatus->IXM1200IsWaitingMask = 0; configStatus->Signature = SIGNATURE;}voidhpcMemDummyInit(){ configStatus->Signature = 0;}voidhpcIsr(int param){ UINT32 val; IXM1200_REG_READ(IXM1200_DOORBELL, val); if ((val & DOORBELL_RECV_MASK) == 0) { IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_RECV_MASK); if (sysCpuRev < 2) { /* Due to an A3/B0 bug, if a PCI device is writing to a PCI CSR at the right time, out write can get lost; so we had better check it. */ while (1) { IXM1200_REG_READ(IXM1200_DOORBELL, val); if ((val & DOORBELL_RECV_MASK) != 0) break; IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_RECV_MASK); } /* end while */ } /* end if sysCpuRev < 2 */ semGive(hpcGlobalState.DPCSem); }}/* * A "simple" init skips the following steps: * configuration of doorbell registers * Normally this should not be skipped (i.e. simple should be 0), but this * can be set to 1 in the case that a previous OS has set up the doorbell * registers, and the new OS does not want to clobber them. */voidhpcSysInit(int simple){ int i; HPC_BUFFER_INFO *binfo; UINT32 val; for (i=0; i<NUM_SHARED_DATA_BUFFERS; i++) { binfo = &hpcGlobalState.bufferInfo[i]; binfo->buff = &dataBuffer[i][0]; binfo->interface = HPC_NONE; binfo->waitingMask = 1 << i; HPC_QUEUE_INIT(&binfo->queue); binfo->irp.done = semBCreate(SEM_Q_FIFO, SEM_EMPTY); binfo->irpSem = semBCreate(SEM_Q_FIFO, SEM_FULL); } /* end for i */ hpcGlobalState.DPCSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY); hpcGlobalState.commonSem = semBCreate(SEM_Q_FIFO, SEM_FULL); pciIntConnect((void*) INT_VEC_DFH, hpcIsr, 0); if (! simple) { IXM1200_REG_READ(IXM1200_DOORBELL_SETUP, val); SET(val, DOORBELL_RECV_MASK); CLEAR(val, DOORBELL_SEND_MASK); IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL_SETUP, val); IXM1200_REG_READ(IXM1200_DBELL_PCI_MASK, val); val |= DOORBELL_SEND_MASK; IXM1200_PCI_REG_WRITE(IXM1200_DBELL_PCI_MASK, val); IXM1200_REG_READ(IXM1200_DBELL_SA_MASK, val); val |= DOORBELL_RECV_MASK; IXM1200_PCI_REG_WRITE(IXM1200_DBELL_SA_MASK, val); } doorbellAddr = sysGet21555DBAddr(); /* * This task needs to run at zero priority because the boot task for a * bootrom image runs at priority 1 and spins watching the clock. If we run at * a higher priority, then HPC won't get processed until the countdown finishes. */ taskSpawn("tHpcDpc", /* name */ 0, /* priority: 0..255, 0 is highest */ 0, /* options */ 4*1024, /* stack size */ (FUNCPTR) procBufferLoop, /* entry */ (int)&hpcGlobalState, 0, 0, 0, 0, 0, 0, 0, 0, 0); /* arguments for entry */}HPC_ERROR_CODEhpcOpenW32(int channelNum){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; int i; semTake(hpcGlobalState.commonSem, WAIT_FOREVER); if (binfo->interface != HPC_NONE) { semGive(hpcGlobalState.commonSem); return HPC_ALREADY_OPENED; } for (i=0; i<2; i++) { if (! HPC_QUEUE_IS_EMPTY(&binfo[i].queue)) { semGive(hpcGlobalState.commonSem); return HPC_INTERNAL_ERROR; } } for (i=0; i<2; i++) { binfo[i].interface = HPC_W32; binfo[i].bytesUsed = 0; CLEAR(configStatus->IXM1200IsWaitingMask, binfo[i].waitingMask); binfo[i].irp.returnStatus = HPC_OK; binfo[i].ibMode = HPC_IB_NONE; } semGive(hpcGlobalState.commonSem); return HPC_OK;}HPC_ERROR_CODEhpcOpenSio(int channelNum, PUT_RCV_CHARS putRcvChars, void* putData, GET_TX_CHARS getTxChars, void* getData){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; int i; semTake(hpcGlobalState.commonSem, WAIT_FOREVER); if (binfo->interface != HPC_NONE) { semGive(hpcGlobalState.commonSem); return HPC_ALREADY_OPENED; } for (i=0; i<2; i++) { binfo[i].interface = HPC_SIO; binfo[i].bytesUsed = 0; binfo[i].putRcvChars = putRcvChars; binfo[i].putData = putData; binfo[i].getTxChars = getTxChars; binfo[i].getData = getData; if (HPC_IS_TX(buffNum+i)) { CLEAR(configStatus->IXM1200IsWaitingMask, binfo[i].waitingMask); binfo[i].txWaiting = FALSE; } else { SET(configStatus->IXM1200IsWaitingMask, binfo[i].waitingMask); } binfo[i].irp.bUsed = 0; binfo[i].irp.bSize = 0; binfo[i].ibMode = HPC_IB_NONE; } semGive(hpcGlobalState.commonSem); return HPC_OK;}static voidhpcDoCancelio(int channelNum, HPC_OP whichOnes){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; HPC_IRP *irp; if (whichOnes != HPC_READ) { while ((irp = HPC_QUEUE_POP(&binfo[HPC_TX_OFFSET].queue))) { irp->returnStatus = HPC_CANCELED; semGive(irp->done); } /* end while */ } if (whichOnes != HPC_WRITE) { while ((irp = HPC_QUEUE_POP(&binfo[HPC_RX_OFFSET].queue))) { irp->returnStatus = HPC_CANCELED; semGive(irp->done); } /* end while */ }}HPC_ERROR_CODEhpcCancelio(int channelNum, HPC_OP whichOnes){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; semTake(hpcGlobalState.commonSem, WAIT_FOREVER); if (binfo->interface == HPC_NONE) { semGive(hpcGlobalState.commonSem); return HPC_NOT_OPENED; } hpcDoCancelio(channelNum, whichOnes); semGive(hpcGlobalState.commonSem); return HPC_OK;}HPC_ERROR_CODEhpcClose(int channelNum){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; int i; semTake(hpcGlobalState.commonSem, WAIT_FOREVER); if (binfo->interface == HPC_NONE) { semGive(hpcGlobalState.commonSem); return HPC_NOT_OPENED; } hpcDoCancelio(channelNum, HPC_BOTH); for (i=0; i<2; i++) { binfo[i].interface = HPC_NONE; CLEAR(configStatus->IXM1200IsWaitingMask, binfo[i].waitingMask); configStatus->sizeValid[buffNum+i] = 0; } /* end for i */ semGive(hpcGlobalState.commonSem); return HPC_OK;}HPC_ERROR_CODEhpcSetmode(int channelNum, HPC_IB_MODE mode){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; semTake(hpcGlobalState.commonSem, WAIT_FOREVER); if (binfo->interface == HPC_NONE) { semGive(hpcGlobalState.commonSem); return HPC_NOT_OPENED; } binfo[0].ibMode = mode; binfo[1].ibMode = mode; semGive(hpcGlobalState.commonSem); return HPC_OK;}HPC_ERROR_CODEhpcGetmode(int channelNum, HPC_IB_MODE *mode){ int buffNum = channelNum * QUEUES_PER_CHANNEL; HPC_BUFFER_INFO *binfo = &hpcGlobalState.bufferInfo[buffNum]; semTake(hpcGlobalState.commonSem, WAIT_FOREVER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -