summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-28 13:00:58 +0000
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-28 13:00:58 +0000
commit592b87a46de52d69471379cc619b264360f8613b (patch)
tree05eba856721790aa3af8834a7d555eb222222be4 /MdeModulePkg
parent1ae301da81823ea3ab401e6b6da5ede8cb43100c (diff)
downloadedk2-592b87a46de52d69471379cc619b264360f8613b.tar.gz
edk2-592b87a46de52d69471379cc619b264360f8613b.tar.bz2
edk2-592b87a46de52d69471379cc619b264360f8613b.zip
update Ehci driver to distinct pci memory address and host address
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10121 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c6
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h5
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c14
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c92
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c16
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h6
6 files changed, 86 insertions, 53 deletions
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 3161ede949..6cf4aefea6 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -969,7 +969,8 @@ EhcAsyncInterruptTransfer (
//
// Validate parameters
//
- if (!EHCI_IS_DATAIN (EndPointAddress)) {
+ if (!(EndPointAddress >= 0x01 && EndPointAddress <= 0x0F)
+ && !(EndPointAddress >= 0x81 && EndPointAddress <= 0x8F)) {
return EFI_INVALID_PARAMETER;
}
@@ -1118,7 +1119,8 @@ EhcSyncInterruptTransfer (
return EFI_INVALID_PARAMETER;
}
- if (!EHCI_IS_DATAIN (EndPointAddress)) {
+ if (!(EndPointAddress >= 0x01 && EndPointAddress <= 0x0F)
+ && !(EndPointAddress >= 0x81 && EndPointAddress <= 0x8F)) {
return EFI_INVALID_PARAMETER;
}
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
index 07abcaf82c..d6f0003557 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
@@ -139,8 +139,8 @@ struct _USB2_HC_DEV {
//
// Peroidic (interrupt) transfer schedule data:
//
- VOID *PeriodFrame; // Mapped as common buffer
- VOID *PeriodFrameHost;
+ VOID *PeriodFrame; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor.
+ VOID *PeriodFrameHost; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor.
VOID *PeriodFrameMap;
EHC_QH *PeriodOne;
@@ -152,7 +152,6 @@ struct _USB2_HC_DEV {
UINT32 HcStructParams; // Cache of HC structure parameter, EHC_HCSPARAMS_OFFSET
UINT32 HcCapParams; // Cache of HC capability parameter, HCCPARAMS
UINT32 CapLen; // Capability length
- UINT32 High32bitAddr;
//
// Misc
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
index 7a533d78e1..0b8187a52d 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
@@ -564,7 +564,7 @@ EhcInitHC (
// Allocate the periodic frame and associated memeory
// management facilities if not already done.
//
- if (Ehc->PeriodFrameHost != NULL) {
+ if (Ehc->PeriodFrame != NULL) {
EhcFreeSched (Ehc);
}
@@ -573,24 +573,20 @@ EhcInitHC (
if (EFI_ERROR (Status)) {
return Status;
}
- //
- // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr
- //
- EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr);
//
- // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling
+ // 1. Clear USBINTR to disable all the interrupt. UEFI works by polling
//
EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);
//
- // 3. Program periodic frame list, already done in EhcInitSched
- // 4. Start the Host Controller
+ // 2. Program periodic frame list, already done in EhcInitSched
+ // 3. Start the Host Controller
//
EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);
//
- // 5. Set all ports routing to EHC
+ // 4. Set all ports routing to EHC
//
EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
index c1d44f5282..2086206404 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
@@ -116,7 +116,6 @@ EhcInitSched (
UINTN Pages;
UINTN Bytes;
UINTN Index;
- UINT32 *Desc;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS PciAddr;
@@ -159,10 +158,17 @@ EhcInitSched (
return EFI_OUT_OF_RESOURCES;
}
- Ehc->PeriodFrameHost = Buf;
- Ehc->PeriodFrame = (VOID *) ((UINTN) PhyAddr);
+ Ehc->PeriodFrame = Buf;
Ehc->PeriodFrameMap = Map;
- Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr);
+
+ //
+ // Program the FRAMELISTBASE register with the low 32 bit addr
+ //
+ EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (PhyAddr));
+ //
+ // Program the CTRLDSSEGMENT register with the high 32 bit addr
+ //
+ EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, EHC_HIGH_32BIT (PhyAddr));
//
// Init memory pool management then create the helper
@@ -172,31 +178,41 @@ EhcInitSched (
Ehc->MemPool = UsbHcInitMemPool (
PciIo,
EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT),
- Ehc->High32bitAddr
+ EHC_HIGH_32BIT (PhyAddr)
);
if (Ehc->MemPool == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
}
Status = EhcCreateHelpQ (Ehc);
if (EFI_ERROR (Status)) {
- return Status;
+ goto ErrorExit;
}
//
// Initialize the frame list entries then set the registers
//
- Desc = (UINT32 *) Ehc->PeriodFrameHost;
+ Ehc->PeriodFrameHost = AllocateZeroPool (EHC_FRAME_LEN * sizeof (UINTN));
+ if (Ehc->PeriodFrameHost == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));
for (Index = 0; Index < EHC_FRAME_LEN; Index++) {
- PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));
- Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
+ //
+ // Store the pci bus address of the QH in period frame list which will be accessed by pci bus master.
+ //
+ ((UINT32 *)(Ehc->PeriodFrame))[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
+ //
+ // Store the host address of the QH in period frame list which will be accessed by host.
+ //
+ ((UINTN *)(Ehc->PeriodFrameHost))[Index] = (UINTN)Ehc->PeriodOne;
}
- EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));
-
//
// Second initialize the asynchronous schedule:
// Only need to set the AsynListAddr register to
@@ -205,6 +221,26 @@ EhcInitSched (
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));
EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr));
return EFI_SUCCESS;
+
+ErrorExit:
+ PciIo->FreeBuffer (PciIo, Pages, Buf);
+ PciIo->Unmap (PciIo, Map);
+
+ if (Ehc->PeriodOne != NULL) {
+ UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));
+ Ehc->PeriodOne = NULL;
+ }
+
+ if (Ehc->ReclaimHead != NULL) {
+ UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));
+ Ehc->ReclaimHead = NULL;
+ }
+
+ if (Ehc->ShortReadStop != NULL) {
+ UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));
+ Ehc->ShortReadStop = NULL;
+ }
+ return Status;
}
@@ -244,7 +280,7 @@ EhcFreeSched (
Ehc->MemPool = NULL;
}
- if (Ehc->PeriodFrameHost != NULL) {
+ if (Ehc->PeriodFrame != NULL) {
PciIo = Ehc->PciIo;
ASSERT (PciIo != NULL);
@@ -253,11 +289,15 @@ EhcFreeSched (
PciIo->FreeBuffer (
PciIo,
EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE),
- Ehc->PeriodFrameHost
+ Ehc->PeriodFrame
);
+ Ehc->PeriodFrame = NULL;
+ }
+
+ if (Ehc->PeriodFrameHost != NULL) {
+ FreePool (Ehc->PeriodFrameHost);
Ehc->PeriodFrameHost = NULL;
- Ehc->PeriodFrame = NULL;
}
}
@@ -293,7 +333,7 @@ EhcLinkQhToAsync (
Head->NextQh = Qh;
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));
- Qh->QhHw.HorizonLink = QH_LINK (PciAddr, 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);
}
@@ -358,21 +398,18 @@ EhcLinkQhToPeriod (
IN EHC_QH *Qh
)
{
- UINT32 *Frames;
UINTN Index;
EHC_QH *Prev;
EHC_QH *Next;
EFI_PHYSICAL_ADDRESS PciAddr;
- Frames = Ehc->PeriodFrameHost;
-
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
//
// First QH can't be NULL because we always keep PeriodOne
// heads on the frame list
//
- ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));
- Next = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);
+ ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));
+ Next = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];
Prev = NULL;
//
@@ -439,7 +476,8 @@ EhcLinkQhToPeriod (
PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));
if (Prev == NULL) {
- Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
+ ((UINT32*)Ehc->PeriodFrame)[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
+ ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh;
} else {
Prev->NextQh = Qh;
Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);
@@ -462,20 +500,17 @@ EhcUnlinkQhFromPeriod (
IN EHC_QH *Qh
)
{
- UINT32 *Frames;
UINTN Index;
EHC_QH *Prev;
EHC_QH *This;
- Frames = Ehc->PeriodFrameHost;
-
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
//
// Frame link can't be NULL because we always keep PeroidOne
// on the frame list
//
- ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));
- This = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);
+ ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));
+ This = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];
Prev = NULL;
//
@@ -499,7 +534,8 @@ EhcUnlinkQhFromPeriod (
//
// Qh is the first entry in the frame
//
- Frames[Index] = Qh->QhHw.HorizonLink;
+ ((UINT32*)Ehc->PeriodFrame)[Index] = Qh->QhHw.HorizonLink;
+ ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh->NextQh;
} else {
Prev->NextQh = Qh->NextQh;
Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c
index 069ee5f575..5194d540a7 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c
@@ -218,15 +218,15 @@ UsbHcAllocMemFromBlock (
NEXT_BIT (Byte, Bit);
}
- return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
+ return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
}
/**
- Get the pci memory address according to the allocated host memory address.
+ Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
- @param Mem The memory to free.
- @param Size The size of the memory to free.
+ @param Mem The pointer to host memory.
+ @param Size The size of the memory region.
@return the pci memory address
**/
@@ -251,7 +251,7 @@ UsbHcGetPciAddressForHostMem (
// 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))) {
+ if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
break;
}
}
@@ -522,12 +522,12 @@ UsbHcFreeMem (
// scan the memory block list for the memory block that
// completely contains the memory to free.
//
- if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) {
+ if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {
//
// compute the start byte and bit in the bit array
//
- Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8;
- Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;
+ Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
+ Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
//
// reset associated bits in bit arry
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h
index 3394c9b99e..f851868d10 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h
@@ -139,11 +139,11 @@ UsbHcFreeMem (
);
/**
- Get the pci memory address according to the allocated host memory address.
+ Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
- @param Mem The memory to free.
- @param Size The size of the memory to free.
+ @param Mem The pointer to host memory.
+ @param Size The size of the memory region.
@return the pci memory address
**/