From 739802e49c6ae401534d3ed3d743cb2d82ff8c62 Mon Sep 17 00:00:00 2001 From: eric_tian Date: Wed, 14 Oct 2009 06:22:49 +0000 Subject: 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 --- MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c | 2 +- MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c | 62 +++++++++++++++++++++----------- MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c | 29 +++++++++------ MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h | 4 ++- MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c | 44 +++++++++++++++++++++++ MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h | 17 +++++++++ 6 files changed, 126 insertions(+), 32 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c index eca9b0b272..9a5c76f098 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c @@ -561,7 +561,7 @@ EhcInitHC ( // Allocate the periodic frame and associated memeory // management facilities if not already done. // - if (Ehc->PeriodFrame != NULL) { + if (Ehc->PeriodFrameHost != NULL) { EhcFreeSched (Ehc); } diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c index 4b1cc7399f..2d8dc024b9 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c @@ -34,11 +34,12 @@ EhcCreateHelpQ ( EHC_QH *Qh; QH_HW *QhHw; EHC_QTD *Qtd; + EFI_PHYSICAL_ADDRESS PciAddr; // // 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) { return EFI_OUT_OF_RESOURCES; @@ -68,8 +69,9 @@ EhcCreateHelpQ ( return EFI_OUT_OF_RESOURCES; } + PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH)); 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->ReclaimHead = 1; Ehc->ReclaimHead = Qh; @@ -116,6 +118,7 @@ EhcInitSched ( UINTN Index; UINT32 *Desc; EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PciAddr; // // First initialize the periodical schedule data: @@ -185,10 +188,11 @@ EhcInitSched ( // // 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++) { - 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)); @@ -198,7 +202,8 @@ EhcInitSched ( // Only need to set the AsynListAddr register to // 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; } @@ -239,7 +244,7 @@ EhcFreeSched ( Ehc->MemPool = NULL; } - if (Ehc->PeriodFrame != NULL) { + if (Ehc->PeriodFrameHost != NULL) { PciIo = Ehc->PciIo; ASSERT (PciIo != NULL); @@ -251,7 +256,8 @@ EhcFreeSched ( Ehc->PeriodFrameHost ); - Ehc->PeriodFrame = NULL; + Ehc->PeriodFrameHost = NULL; + Ehc->PeriodFrame = NULL; } } @@ -274,6 +280,7 @@ EhcLinkQhToAsync ( ) { EHC_QH *Head; + EFI_PHYSICAL_ADDRESS PciAddr; // // Append the queue head after the reclaim header, then @@ -285,8 +292,10 @@ EhcLinkQhToAsync ( Qh->NextQh = Head->NextQh; Head->NextQh = Qh; - Qh->QhHw.HorizonLink = QH_LINK (Head, EHC_TYPE_QH, FALSE);; - Head->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE); + PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH)); + 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; EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PciAddr; ASSERT (Ehc->ReclaimHead->NextQh == Qh); @@ -319,7 +329,8 @@ EhcUnlinkQhFromAsync ( Head->NextQh = Qh->NextQh; 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 @@ -351,8 +362,9 @@ EhcLinkQhToPeriod ( UINTN Index; EHC_QH *Prev; EHC_QH *Next; + EFI_PHYSICAL_ADDRESS PciAddr; - Frames = Ehc->PeriodFrame; + Frames = Ehc->PeriodFrameHost; for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { // @@ -408,7 +420,8 @@ EhcLinkQhToPeriod ( Prev->NextQh = Qh; 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; } @@ -419,14 +432,17 @@ EhcLinkQhToPeriod ( // if (Qh->NextQh == NULL) { 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) { - Frames[Index] = QH_LINK (Qh, EHC_TYPE_QH, FALSE); + Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); } else { 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 *This; - Frames = Ehc->PeriodFrame; + Frames = Ehc->PeriodFrameHost; for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { // @@ -513,6 +529,7 @@ EhcCheckUrbResult ( QTD_HW *QtdHw; UINT8 State; BOOLEAN Finished; + EFI_PHYSICAL_ADDRESS PciAddr; ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL)); @@ -582,7 +599,8 @@ EhcCheckUrbResult ( // ShortReadStop. If it is a setup transfer, need to check the // 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")); Finished = TRUE; @@ -803,11 +821,13 @@ ON_ERROR: /** Update the queue head for next round of asynchronous transfer. + @param Ehc The EHCI device. @param Urb The URB to update. **/ VOID EhcUpdateAsyncRequest ( + IN USB2_HC_DEV *Ehc, IN URB *Urb ) { @@ -817,6 +837,7 @@ EhcUpdateAsyncRequest ( EHC_QTD *Qtd; QTD_HW *QtdHw; UINTN Index; + EFI_PHYSICAL_ADDRESS PciAddr; Qtd = NULL; @@ -868,7 +889,8 @@ EhcUpdateAsyncRequest ( 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 ; @@ -936,14 +958,14 @@ EhcMonitorAsyncRequests ( ProcBuf = AllocatePool (Urb->Completed); if (ProcBuf == NULL) { - EhcUpdateAsyncRequest (Urb); + EhcUpdateAsyncRequest (Ehc, Urb); continue; } CopyMem (ProcBuf, Urb->Data, Urb->Completed); } - EhcUpdateAsyncRequest (Urb); + EhcUpdateAsyncRequest (Ehc, Urb); // // Leave error recovery to its related device driver. A diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c index 6d1bf9b336..ba98f099ab 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c @@ -21,7 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Create a single QTD to hold the data. @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 PktId Packet ID to use in the QTD. @param Toggle Data toggle to use in the QTD. @@ -34,6 +35,7 @@ EHC_QTD * EhcCreateQtd ( IN USB2_HC_DEV *Ehc, IN UINT8 *Data, + IN UINT8 *DataPhy, IN UINTN DataLen, IN UINT8 PktId, IN UINT8 Toggle, @@ -82,10 +84,10 @@ EhcCreateQtd ( // compute the offset and clear Reserved fields. This is already // done in the data point. // - QtdHw->Page[Index] = EHC_LOW_32BIT (Data); - QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (Data); + QtdHw->Page[Index] = EHC_LOW_32BIT (DataPhy); + 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) { Len = DataLen; @@ -94,6 +96,7 @@ EhcCreateQtd ( Len += ThisBufLen; Data += ThisBufLen; + DataPhy += ThisBufLen; } // @@ -375,6 +378,7 @@ EhcCreateQtds ( UINT8 Toggle; UINTN Len; UINT8 Pid; + EFI_PHYSICAL_ADDRESS PhyAddr; ASSERT ((Urb != NULL) && (Urb->Qh != NULL)); @@ -390,8 +394,9 @@ EhcCreateQtds ( StatusQtd = NULL; AlterNext = QTD_LINK (NULL, TRUE); + PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); 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) { 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) { return EFI_OUT_OF_RESOURCES; @@ -419,14 +424,15 @@ EhcCreateQtds ( 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) { goto ON_ERROR; } if (Ep->Direction == EfiUsbDataIn) { - AlterNext = QTD_LINK (StatusQtd, FALSE); + PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, StatusQtd, sizeof (EHC_QTD)); + AlterNext = QTD_LINK (PhyAddr, FALSE); } Toggle = 1; @@ -447,6 +453,7 @@ EhcCreateQtds ( while (Len < Urb->DataLen) { Qtd = EhcCreateQtd ( Ehc, + (UINT8 *) Urb->Data + Len, (UINT8 *) Urb->DataPhy + Len, Urb->DataLen - Len, Pid, @@ -492,14 +499,16 @@ EhcCreateQtds ( } 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 // 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; ON_ERROR: diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h index 1079be003b..2e0637530f 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h @@ -244,7 +244,8 @@ struct _URB { Create a single QTD to hold the data. @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 PktId Packet ID to use in the QTD. @param Toggle Data toggle to use in the QTD. @@ -257,6 +258,7 @@ EHC_QTD * EhcCreateQtd ( IN USB2_HC_DEV *Ehc, IN UINT8 *Data, + IN UINT8 *DataPhy, IN UINTN DataLen, IN UINT8 PktId, IN UINT8 Toggle, diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c index af8070e569..177c49f1e4 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c @@ -221,6 +221,50 @@ UsbHcAllocMemFromBlock ( 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. diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h index 8152ce813b..ce0a78298f 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h +++ b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h @@ -135,4 +135,21 @@ UsbHcFreeMem ( IN VOID *Mem, 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 -- cgit v1.2.3