📄 cha.c
字号:
/*
* cha.c -- Channel/CHA operations code for MPCPQ27e Driver
*
Revision History:
*
*/
#include "MPCPQ27eDriver.h"
/********************************************************************/
/* Function Name: ReserveChannelStatic */
/* Purpose: To allocate a channel for use by a single task. */
/* Input: channel - the channel number (1-4) */
/* callingTaskId - the task id */
/* Output: channel - the channel number that allocated */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code */
/********************************************************************/
int ReserveChannelStatic(PULONG channel, int callingTaskId)
{
unsigned long chan;
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic\n"));
IOLockChannelAssignment(); /*semaphore take*/
/* look for a free channel */
for (chan=0; chan<NUM_CHANNELS; chan++)
{
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic chan=%d\n", (int)chan));
if (ChannelAssignments[chan].assignment == CHANNEL_FREE)
{
/* found a free channel, make it static */
ChannelAssignments[chan].assignment = CHANNEL_STATIC_ASSIGNED;
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic found a free channel\n"));
FreeChannels--;
/* set the channel's owner task ID */
ChannelAssignments[chan].ownerTaskId = callingTaskId;
IOUnLockChannelAssignment();
/* set return value */
*channel = chan+1;
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic->*channel=%d\n", (int)*channel));
return (MPCPQ27e_SUCCESS);
}
}
IOUnLockChannelAssignment();
/* we didn't find a free channel */
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelStatic->we didn't find a free channel\n"));
return (MPCPQ27e_CHANNEL_NOT_AVAILABLE);
}
/************************************************************************/
/* Function Name: ReserveChannelManual */
/* Purpose: To reserve a crypto channel for use in manual/debug mode */
/* Input: reserve - the MPCPQ27e_RESERVE_MANUAL structure */
/* callingTaskId - the task id */
/* Output: reserve->channel - the channel Id if success */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code */
/************************************************************************/
int ReserveChannelManual(MPCPQ27e_RESERVE_MANUAL *reserve, int callingTaskId)
{
int channel;
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual\n"));
IOLockChannelAssignment();
/* look for a free channel */
for (channel=0; channel<NUM_CHANNELS; channel++)
{
if (ChannelAssignments[channel].assignment == CHANNEL_FREE)
{
/* found a free channel, make it manual */
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->FreeChannel=%d\n",(int)channel));
ChannelAssignments[channel].assignment = CHANNEL_MANUAL;
FreeChannels--;
/* set the channel's owner task ID */
ChannelAssignments[channel].ownerTaskId = callingTaskId;
IOUnLockChannelAssignment();
/* set return value */
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->(reserve->channel)=%d\n", (int)channel+1));
*(reserve->channel) = channel + 1;
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->Return\n"));
return (MPCPQ27e_SUCCESS);
}
}
IOUnLockChannelAssignment();
/* we didn't find a free channel */
MPCPQ27eDump(MPCINITDEV, ("ReserveChannelManual->we didn't find a free channel\n"));
return (MPCPQ27e_CHANNEL_NOT_AVAILABLE);
}
/**************************************************************************/
/* Function Name: AssignCha */
/* Purpose: To reserve a specific CHA for use by either a static channel */
/* or a manual channel. */
/* Input: channelCha - the bottom eight bits is the CHA chaType */
/* the next eight bits is the channel number (1-4) */
/* callingTaskId - the task id */
/* Return: MPCPQ27e_SUCCESS if success otherwise the error code */
/**************************************************************************/
int AssignCha(unsigned long channelCha, int callingTaskId)
{
unsigned char channel = (unsigned char)((channelCha >> 8) & 0xFF);
unsigned char chaType = (unsigned char)(channelCha & 0xFF);
unsigned long chaStatus[2] = {0,0};
unsigned long chaAssignment;
unsigned long temp[2] = {0,0};
unsigned long cha;
int chasLeft=0;
int numChas=0;
int chaBitMask;
GENERIC_REQ *request;
MPCPQ27eDump(MPCINITDEV, ("AssignCha channel=%d chaType=0x%x\n",channel,chaType));
/* check channel value */
if ((channel == 0) || (channel > (unsigned char) NUM_CHANNELS))
return (MPCPQ27e_INVALID_CHANNEL);
/* check chaType value */
if ((chaType != CHA_AFHA) && (chaType != CHA_DES) && (chaType != CHA_MDHA)
&& (chaType != CHA_RNG) && (chaType != CHA_PKHA)
&& (chaType != CHA_AESA)
)
return (MPCPQ27e_INVALID_CHA_TYPE);
IOLockChannelAssignment();
/* check that requested channel is either static or manual */
if ((ChannelAssignments[channel - 1].assignment != CHANNEL_STATIC_ASSIGNED) &&
(ChannelAssignments[channel - 1].assignment != CHANNEL_MANUAL))
{
/* error, channel assignment is wrong */
IOUnLockChannelAssignment();
return (MPCPQ27e_INVALID_CHANNEL);
}
/* check that callingTaskId matches channel owner */
if (callingTaskId != ChannelAssignments[channel - 1].ownerTaskId)
{
/* error, channel is not owned by the caller */
IOUnLockChannelAssignment();
return (MPCPQ27e_INVALID_CHANNEL);
}
/* check how many non-static CHAs of this type are left */
switch (chaType)
{
case CHA_AFHA:
chasLeft = FreeAfhas;
numChas = NUM_AFHAS;
chaBitMask = CHA_AFHA_BITMASK;
break;
case CHA_DES:
chasLeft = FreeDesas;
numChas = NUM_DESAS;
chaBitMask = CHA_DESA_BITMASK;
break;
case CHA_MDHA:
chasLeft = FreeMdhas;
numChas = NUM_MDHAS;
chaBitMask = CHA_MDHA_BITMASK;
break;
case CHA_RNG:
chasLeft = FreeRngas;
numChas = NUM_RNGAS;
chaBitMask = CHA_RNGA_BITMASK;
break;
case CHA_PKHA:
chasLeft = FreePkhas;
numChas = NUM_PKHAS;
chaBitMask = CHA_PKHA_BITMASK;
break;
case CHA_AESA:
chasLeft = FreeAesas;
numChas = NUM_AESAS;
chaBitMask = CHA_AESA_BITMASK;
break;
case CHA_KEA:
chasLeft = FreeKeas;
numChas = NUM_KEAS;
chaBitMask = CHA_KEA_BITMASK;
break;
}
/* check to see that there is at least one CHA left */
if (chasLeft == 0)
{
/* no CHAs left to assign, return error */
IOUnLockChannelAssignment();
return (MPCPQ27e_CHA_NOT_AVAILABLE);
}
else if (chasLeft == 1)
{
/* check to see if there are dynamic requests for this CHA in the queue */
request = ProcessQueueTop->pReq;
while (request != NULL)
{
if (CheckChas(request->opId) != 0)
{
/* found a queued request that requires the last non-static CHA */
IOUnLockChannelAssignment();
return (MPCPQ27e_CHA_NOT_AVAILABLE);
}
/* move to next request in the queue */
request = ProcessQueueTop->next->pReq;
}
}
/* read CHA assignment status register */
IORead(chaStatus, 2, ChaAssignmentStatusRegister);
/* at least one CHA of this type is potentially available */
/*
cha=0 , AFEU
cha=1 , MDEU
cha=2 , PKEU
cha=3 , RNG
cha=4 , AESU
cha=5 , DEU
*/
for (cha=chaType; cha<(chaType+numChas); cha++)
{
if (ChaAssignments[cha] == CHA_DYNAMIC)
{
/* found a potentially free CHA, check the CHA assignment register */
if (cha < 4) /* 4 chas per status word */
{
/* cha is in lower half of cha status */
chaAssignment = 0xF << (cha * 8);
if ((chaStatus[0] & chaAssignment) != 0)
{
/* this CHA is being used dynamically, try next CHA */
continue;
}
else
{
/* cha is not in use, assign it */
/* set flag to indicate attempting CHA assignment ??? */
chaStatus[0] |= (channel << (cha * 8));
IOWrite(chaStatus, 2, ChaAssignmentControlRegister);
ChaAssignments[cha] = channel;
break;
}
}
else
{
/* cha is in upper half of cha status */
chaAssignment = (0xF << ((cha - 4) * 8)) << 16;
if ((chaStatus[1] & chaAssignment) != 0)
{
/* this CHA is being used dynamically, try next CHA */
continue;
}
else
{
/* cha is not in use, assign it */
/* set flag to indicate attempting CHA assignment ??? */
chaStatus[1] |= (channel << ((cha - 4) * 8)) << 16;
IOWrite(chaStatus, 2, ChaAssignmentControlRegister);
ChaAssignments[cha] = channel;
break;
}
}
}
}
/* see if we were successful */
if (cha >= (chaType + numChas))
{
/* we didn't find a non-busy CHA, return an error */
IOUnLockChannelAssignment();
return (MPCPQ27e_CHA_NOT_AVAILABLE);
}
/* check that assignment was successful (check flag) ??? */
/* wait until here to make ChaAssignment[cha] update ??? */
/* if channel is in manual mode, enable the CHA done interrupt */
if (ChannelAssignments[channel].assignment == CHANNEL_MANUAL)
{
/* read current interrupt enables */
IORead(temp, 2, InterruptControlRegister);
/* set CHA interrupt for this CHA */
temp[1] |= (0x1 << (2*cha));
/* write data back to interrupt control register */
IOWrite(temp, 2, InterruptControlRegister);
}
/* update free CHA counts */
switch (chaType)
{
case CHA_AFHA:
FreeAfhas--;
break;
case CHA_DES:
FreeDesas--;
break;
case CHA_MDHA:
FreeMdhas--;
break;
case CHA_RNG:
FreeRngas--;
break;
case CHA_PKHA:
FreePkhas--;
break;
case CHA_AESA:
FreeAesas--;
break;
case CHA_KEA:
FreeKeas--;
break;
}
IOUnLockChannelAssignment();
return (MPCPQ27e_SUCCESS);
} /* AssignCha */
/**************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -