update code to eliminate the wrong assumption that pci address is equal to host address in all archs.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9339 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
eric_tian 2009-10-14 06:22:49 +00:00
parent 62b658dd7f
commit 739802e49c
6 changed files with 126 additions and 32 deletions

View File

@ -561,7 +561,7 @@ EhcInitHC (
// Allocate the periodic frame and associated memeory // Allocate the periodic frame and associated memeory
// management facilities if not already done. // management facilities if not already done.
// //
if (Ehc->PeriodFrame != NULL) { if (Ehc->PeriodFrameHost != NULL) {
EhcFreeSched (Ehc); EhcFreeSched (Ehc);
} }

View File

@ -34,11 +34,12 @@ EhcCreateHelpQ (
EHC_QH *Qh; EHC_QH *Qh;
QH_HW *QhHw; QH_HW *QhHw;
EHC_QTD *Qtd; EHC_QTD *Qtd;
EFI_PHYSICAL_ADDRESS PciAddr;
// //
// Create an inactive Qtd to terminate the short packet read. // Create an inactive Qtd to terminate the short packet read.
// //
Qtd = EhcCreateQtd (Ehc, NULL, 0, QTD_PID_INPUT, 0, 64); Qtd = EhcCreateQtd (Ehc, NULL, NULL, 0, QTD_PID_INPUT, 0, 64);
if (Qtd == NULL) { if (Qtd == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
@ -68,8 +69,9 @@ EhcCreateHelpQ (
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));
QhHw = &Qh->QhHw; QhHw = &Qh->QhHw;
QhHw->HorizonLink = QH_LINK (QhHw, EHC_TYPE_QH, FALSE); QhHw->HorizonLink = QH_LINK (PciAddr + OFFSET_OF(EHC_QH, QhHw), EHC_TYPE_QH, FALSE);
QhHw->Status = QTD_STAT_HALTED; QhHw->Status = QTD_STAT_HALTED;
QhHw->ReclaimHead = 1; QhHw->ReclaimHead = 1;
Ehc->ReclaimHead = Qh; Ehc->ReclaimHead = Qh;
@ -116,6 +118,7 @@ EhcInitSched (
UINTN Index; UINTN Index;
UINT32 *Desc; UINT32 *Desc;
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS PciAddr;
// //
// First initialize the periodical schedule data: // First initialize the periodical schedule data:
@ -185,10 +188,11 @@ EhcInitSched (
// //
// Initialize the frame list entries then set the registers // Initialize the frame list entries then set the registers
// //
Desc = (UINT32 *) Ehc->PeriodFrame; Desc = (UINT32 *) Ehc->PeriodFrameHost;
for (Index = 0; Index < EHC_FRAME_LEN; Index++) { for (Index = 0; Index < EHC_FRAME_LEN; Index++) {
Desc[Index] = QH_LINK (Ehc->PeriodOne, EHC_TYPE_QH, FALSE); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));
Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
} }
EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame)); EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));
@ -198,7 +202,8 @@ EhcInitSched (
// Only need to set the AsynListAddr register to // Only need to set the AsynListAddr register to
// the reclamation header // the reclamation header
// //
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (Ehc->ReclaimHead)); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -239,7 +244,7 @@ EhcFreeSched (
Ehc->MemPool = NULL; Ehc->MemPool = NULL;
} }
if (Ehc->PeriodFrame != NULL) { if (Ehc->PeriodFrameHost != NULL) {
PciIo = Ehc->PciIo; PciIo = Ehc->PciIo;
ASSERT (PciIo != NULL); ASSERT (PciIo != NULL);
@ -251,7 +256,8 @@ EhcFreeSched (
Ehc->PeriodFrameHost Ehc->PeriodFrameHost
); );
Ehc->PeriodFrame = NULL; Ehc->PeriodFrameHost = NULL;
Ehc->PeriodFrame = NULL;
} }
} }
@ -274,6 +280,7 @@ EhcLinkQhToAsync (
) )
{ {
EHC_QH *Head; EHC_QH *Head;
EFI_PHYSICAL_ADDRESS PciAddr;
// //
// Append the queue head after the reclaim header, then // Append the queue head after the reclaim header, then
@ -285,8 +292,10 @@ EhcLinkQhToAsync (
Qh->NextQh = Head->NextQh; Qh->NextQh = Head->NextQh;
Head->NextQh = Qh; Head->NextQh = Qh;
Qh->QhHw.HorizonLink = QH_LINK (Head, EHC_TYPE_QH, FALSE);; PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));
Head->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE); Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);;
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));
Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
} }
@ -306,6 +315,7 @@ EhcUnlinkQhFromAsync (
{ {
EHC_QH *Head; EHC_QH *Head;
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS PciAddr;
ASSERT (Ehc->ReclaimHead->NextQh == Qh); ASSERT (Ehc->ReclaimHead->NextQh == Qh);
@ -319,7 +329,8 @@ EhcUnlinkQhFromAsync (
Head->NextQh = Qh->NextQh; Head->NextQh = Qh->NextQh;
Qh->NextQh = NULL; Qh->NextQh = NULL;
Head->QhHw.HorizonLink = QH_LINK (Head, EHC_TYPE_QH, FALSE); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));
Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
// //
// Set and wait the door bell to synchronize with the hardware // Set and wait the door bell to synchronize with the hardware
@ -351,8 +362,9 @@ EhcLinkQhToPeriod (
UINTN Index; UINTN Index;
EHC_QH *Prev; EHC_QH *Prev;
EHC_QH *Next; EHC_QH *Next;
EFI_PHYSICAL_ADDRESS PciAddr;
Frames = Ehc->PeriodFrame; Frames = Ehc->PeriodFrameHost;
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
// //
@ -408,7 +420,8 @@ EhcLinkQhToPeriod (
Prev->NextQh = Qh; Prev->NextQh = Qh;
Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink; Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink;
Prev->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));
Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
break; break;
} }
@ -419,14 +432,17 @@ EhcLinkQhToPeriod (
// //
if (Qh->NextQh == NULL) { if (Qh->NextQh == NULL) {
Qh->NextQh = Next; Qh->NextQh = Next;
Qh->QhHw.HorizonLink = QH_LINK (Next, EHC_TYPE_QH, FALSE); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Next, sizeof (EHC_QH));
Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
} }
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));
if (Prev == NULL) { if (Prev == NULL) {
Frames[Index] = QH_LINK (Qh, EHC_TYPE_QH, FALSE); Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
} else { } else {
Prev->NextQh = Qh; Prev->NextQh = Qh;
Prev->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE); Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
} }
} }
} }
@ -451,7 +467,7 @@ EhcUnlinkQhFromPeriod (
EHC_QH *Prev; EHC_QH *Prev;
EHC_QH *This; EHC_QH *This;
Frames = Ehc->PeriodFrame; Frames = Ehc->PeriodFrameHost;
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
// //
@ -513,6 +529,7 @@ EhcCheckUrbResult (
QTD_HW *QtdHw; QTD_HW *QtdHw;
UINT8 State; UINT8 State;
BOOLEAN Finished; BOOLEAN Finished;
EFI_PHYSICAL_ADDRESS PciAddr;
ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL)); ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL));
@ -582,7 +599,8 @@ EhcCheckUrbResult (
// ShortReadStop. If it is a setup transfer, need to check the // ShortReadStop. If it is a setup transfer, need to check the
// Status Stage of the setup transfer to get the finial result // Status Stage of the setup transfer to get the finial result
// //
if (QtdHw->AltNext == QTD_LINK (Ehc->ShortReadStop, FALSE)) { PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));
if (QtdHw->AltNext == QTD_LINK (PciAddr, FALSE)) {
DEBUG ((EFI_D_INFO, "EhcCheckUrbResult: Short packet read, break\n")); DEBUG ((EFI_D_INFO, "EhcCheckUrbResult: Short packet read, break\n"));
Finished = TRUE; Finished = TRUE;
@ -803,11 +821,13 @@ ON_ERROR:
/** /**
Update the queue head for next round of asynchronous transfer. Update the queue head for next round of asynchronous transfer.
@param Ehc The EHCI device.
@param Urb The URB to update. @param Urb The URB to update.
**/ **/
VOID VOID
EhcUpdateAsyncRequest ( EhcUpdateAsyncRequest (
IN USB2_HC_DEV *Ehc,
IN URB *Urb IN URB *Urb
) )
{ {
@ -817,6 +837,7 @@ EhcUpdateAsyncRequest (
EHC_QTD *Qtd; EHC_QTD *Qtd;
QTD_HW *QtdHw; QTD_HW *QtdHw;
UINTN Index; UINTN Index;
EFI_PHYSICAL_ADDRESS PciAddr;
Qtd = NULL; Qtd = NULL;
@ -868,7 +889,8 @@ EhcUpdateAsyncRequest (
QhHw->PageHigh[Index] = 0; QhHw->PageHigh[Index] = 0;
} }
QhHw->NextQtd = QTD_LINK (FirstQtd, FALSE); PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, FirstQtd, sizeof (EHC_QTD));
QhHw->NextQtd = QTD_LINK (PciAddr, FALSE);
} }
return ; return ;
@ -936,14 +958,14 @@ EhcMonitorAsyncRequests (
ProcBuf = AllocatePool (Urb->Completed); ProcBuf = AllocatePool (Urb->Completed);
if (ProcBuf == NULL) { if (ProcBuf == NULL) {
EhcUpdateAsyncRequest (Urb); EhcUpdateAsyncRequest (Ehc, Urb);
continue; continue;
} }
CopyMem (ProcBuf, Urb->Data, Urb->Completed); CopyMem (ProcBuf, Urb->Data, Urb->Completed);
} }
EhcUpdateAsyncRequest (Urb); EhcUpdateAsyncRequest (Ehc, Urb);
// //
// Leave error recovery to its related device driver. A // Leave error recovery to its related device driver. A

View File

@ -21,7 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Create a single QTD to hold the data. Create a single QTD to hold the data.
@param Ehc The EHCI device. @param Ehc The EHCI device.
@param Data Current data not associated with a QTD. @param Data The cpu memory address of current data not associated with a QTD.
@param DataPhy The pci bus address of current data not associated with a QTD.
@param DataLen The length of the data. @param DataLen The length of the data.
@param PktId Packet ID to use in the QTD. @param PktId Packet ID to use in the QTD.
@param Toggle Data toggle to use in the QTD. @param Toggle Data toggle to use in the QTD.
@ -34,6 +35,7 @@ EHC_QTD *
EhcCreateQtd ( EhcCreateQtd (
IN USB2_HC_DEV *Ehc, IN USB2_HC_DEV *Ehc,
IN UINT8 *Data, IN UINT8 *Data,
IN UINT8 *DataPhy,
IN UINTN DataLen, IN UINTN DataLen,
IN UINT8 PktId, IN UINT8 PktId,
IN UINT8 Toggle, IN UINT8 Toggle,
@ -82,10 +84,10 @@ EhcCreateQtd (
// compute the offset and clear Reserved fields. This is already // compute the offset and clear Reserved fields. This is already
// done in the data point. // done in the data point.
// //
QtdHw->Page[Index] = EHC_LOW_32BIT (Data); QtdHw->Page[Index] = EHC_LOW_32BIT (DataPhy);
QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (Data); QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (DataPhy);
ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (Data) & QTD_BUF_MASK); ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK);
if (Len + ThisBufLen >= DataLen) { if (Len + ThisBufLen >= DataLen) {
Len = DataLen; Len = DataLen;
@ -94,6 +96,7 @@ EhcCreateQtd (
Len += ThisBufLen; Len += ThisBufLen;
Data += ThisBufLen; Data += ThisBufLen;
DataPhy += ThisBufLen;
} }
// //
@ -375,6 +378,7 @@ EhcCreateQtds (
UINT8 Toggle; UINT8 Toggle;
UINTN Len; UINTN Len;
UINT8 Pid; UINT8 Pid;
EFI_PHYSICAL_ADDRESS PhyAddr;
ASSERT ((Urb != NULL) && (Urb->Qh != NULL)); ASSERT ((Urb != NULL) && (Urb->Qh != NULL));
@ -390,8 +394,9 @@ EhcCreateQtds (
StatusQtd = NULL; StatusQtd = NULL;
AlterNext = QTD_LINK (NULL, TRUE); AlterNext = QTD_LINK (NULL, TRUE);
PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));
if (Ep->Direction == EfiUsbDataIn) { if (Ep->Direction == EfiUsbDataIn) {
AlterNext = QTD_LINK (Ehc->ShortReadStop, FALSE); AlterNext = QTD_LINK (PhyAddr, FALSE);
} }
// //
@ -399,7 +404,7 @@ EhcCreateQtds (
// //
if (Urb->Ep.Type == EHC_CTRL_TRANSFER) { if (Urb->Ep.Type == EHC_CTRL_TRANSFER) {
Len = sizeof (EFI_USB_DEVICE_REQUEST); Len = sizeof (EFI_USB_DEVICE_REQUEST);
Qtd = EhcCreateQtd (Ehc, Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket); Qtd = EhcCreateQtd (Ehc, (UINT8 *)Urb->Request, (UINT8 *)Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket);
if (Qtd == NULL) { if (Qtd == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
@ -419,14 +424,15 @@ EhcCreateQtds (
Pid = QTD_PID_INPUT; Pid = QTD_PID_INPUT;
} }
StatusQtd = EhcCreateQtd (Ehc, NULL, 0, Pid, 1, Ep->MaxPacket); StatusQtd = EhcCreateQtd (Ehc, NULL, NULL, 0, Pid, 1, Ep->MaxPacket);
if (StatusQtd == NULL) { if (StatusQtd == NULL) {
goto ON_ERROR; goto ON_ERROR;
} }
if (Ep->Direction == EfiUsbDataIn) { if (Ep->Direction == EfiUsbDataIn) {
AlterNext = QTD_LINK (StatusQtd, FALSE); PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, StatusQtd, sizeof (EHC_QTD));
AlterNext = QTD_LINK (PhyAddr, FALSE);
} }
Toggle = 1; Toggle = 1;
@ -447,6 +453,7 @@ EhcCreateQtds (
while (Len < Urb->DataLen) { while (Len < Urb->DataLen) {
Qtd = EhcCreateQtd ( Qtd = EhcCreateQtd (
Ehc, Ehc,
(UINT8 *) Urb->Data + Len,
(UINT8 *) Urb->DataPhy + Len, (UINT8 *) Urb->DataPhy + Len,
Urb->DataLen - Len, Urb->DataLen - Len,
Pid, Pid,
@ -492,14 +499,16 @@ EhcCreateQtds (
} }
NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList); NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList);
Qtd->QtdHw.NextQtd = QTD_LINK (NextQtd, FALSE); PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));
Qtd->QtdHw.NextQtd = QTD_LINK (PhyAddr, FALSE);
} }
// //
// Link the QTDs to the queue head // Link the QTDs to the queue head
// //
NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList); NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList);
Qh->QhHw.NextQtd = QTD_LINK (NextQtd, FALSE); PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));
Qh->QhHw.NextQtd = QTD_LINK (PhyAddr, FALSE);
return EFI_SUCCESS; return EFI_SUCCESS;
ON_ERROR: ON_ERROR:

View File

@ -244,7 +244,8 @@ struct _URB {
Create a single QTD to hold the data. Create a single QTD to hold the data.
@param Ehc The EHCI device. @param Ehc The EHCI device.
@param Data Current data not associated with a QTD. @param Data The cpu memory address of current data not associated with a QTD.
@param DataPhy The pci bus address of current data not associated with a QTD.
@param DataLen The length of the data. @param DataLen The length of the data.
@param PktId Packet ID to use in the QTD. @param PktId Packet ID to use in the QTD.
@param Toggle Data toggle to use in the QTD. @param Toggle Data toggle to use in the QTD.
@ -257,6 +258,7 @@ EHC_QTD *
EhcCreateQtd ( EhcCreateQtd (
IN USB2_HC_DEV *Ehc, IN USB2_HC_DEV *Ehc,
IN UINT8 *Data, IN UINT8 *Data,
IN UINT8 *DataPhy,
IN UINTN DataLen, IN UINTN DataLen,
IN UINT8 PktId, IN UINT8 PktId,
IN UINT8 Toggle, IN UINT8 Toggle,

View File

@ -221,6 +221,50 @@ UsbHcAllocMemFromBlock (
return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
} }
/**
Get the pci memory address according to the allocated host memory address.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINTN AllocSize;
EFI_PHYSICAL_ADDRESS PhyAddr;
UINTN Offset;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the allocated memory.
//
if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + Block->BufLen))) {
break;
}
}
ASSERT ((Block != NULL));
//
// calculate the pci memory address for host memory address.
//
Offset = (UINT8 *)Mem - Block->BufHost;
PhyAddr = (EFI_PHYSICAL_ADDRESS)(Block->Buf + Offset);
return PhyAddr;
}
/** /**
Insert the memory block to the pool's list of the blocks. Insert the memory block to the pool's list of the blocks.

View File

@ -135,4 +135,21 @@ UsbHcFreeMem (
IN VOID *Mem, IN VOID *Mem,
IN UINTN Size IN UINTN Size
); );
/**
Get the pci memory address according to the allocated host memory address.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
);
#endif #endif