/** @file\r
\r
-Copyright (c) 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+ Routine procedures for memory allocate/free.\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- EhciMem.c\r
-\r
-Abstract:\r
-\r
-\r
-Revision History\r
+Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-\r
#include "Ehci.h"\r
\r
-\r
-UINTN mUsbHcDebugLevel = DEBUG_INFO;\r
-\r
-\r
/**\r
- Allocate a block of memory to be used by the buffer pool\r
+ Allocate a block of memory to be used by the buffer pool.\r
\r
- @param Pool The buffer pool to allocate memory for\r
- @param Pages How many pages to allocate\r
+ @param Pool The buffer pool to allocate memory for.\r
+ @param Pages How many pages to allocate.\r
\r
- @return The allocated memory block or NULL if failed\r
+ @return The allocated memory block or NULL if failed.\r
\r
**/\r
-STATIC\r
USBHC_MEM_BLOCK *\r
UsbHcAllocMemBlock (\r
- IN USBHC_MEM_POOL *Pool,\r
- IN UINTN Pages\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN UINTN Pages\r
)\r
{\r
- USBHC_MEM_BLOCK *Block;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- VOID *BufHost;\r
- VOID *Mapping;\r
- EFI_PHYSICAL_ADDRESS MappedAddr;\r
- UINTN Bytes;\r
- EFI_STATUS Status;\r
+ USBHC_MEM_BLOCK *Block;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ VOID *BufHost;\r
+ VOID *Mapping;\r
+ EFI_PHYSICAL_ADDRESS MappedAddr;\r
+ UINTN Bytes;\r
+ EFI_STATUS Status;\r
\r
PciIo = Pool->PciIo;\r
\r
//\r
ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);\r
\r
- Block->BufLen = EFI_PAGES_TO_SIZE (Pages);\r
- Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);\r
- Block->Bits = AllocateZeroPool (Block->BitsLen);\r
+ Block->BufLen = EFI_PAGES_TO_SIZE (Pages);\r
+ Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);\r
+ Block->Bits = AllocateZeroPool (Block->BitsLen);\r
\r
if (Block->Bits == NULL) {\r
gBS->FreePool (Block);\r
goto FREE_BITARRAY;\r
}\r
\r
- Bytes = EFI_PAGES_TO_SIZE (Pages);\r
+ Bytes = EFI_PAGES_TO_SIZE (Pages);\r
Status = PciIo->Map (\r
PciIo,\r
EfiPciIoOperationBusMasterCommonBuffer,\r
goto FREE_BUFFER;\r
}\r
\r
- Block->BufHost = BufHost;\r
- Block->Buf = (UINT8 *) ((UINTN) MappedAddr);\r
- Block->Mapping = Mapping;\r
-\r
- DEBUG ((mUsbHcDebugLevel, "UsbHcAllocMemBlock: block %x created with buffer %x\n",\r
- Block, Block->Buf));\r
+ Block->BufHost = BufHost;\r
+ Block->Buf = (UINT8 *)((UINTN)MappedAddr);\r
+ Block->Mapping = Mapping;\r
\r
return Block;\r
\r
return NULL;\r
}\r
\r
-\r
/**\r
- Free the memory block from the memory pool\r
-\r
- @param Pool The memory pool to free the block from\r
- @param Block The memory block to free\r
+ Free the memory block from the memory pool.\r
\r
- @return VOID\r
+ @param Pool The memory pool to free the block from.\r
+ @param Block The memory block to free.\r
\r
**/\r
-STATIC\r
VOID\r
UsbHcFreeMemBlock (\r
- IN USBHC_MEM_POOL *Pool,\r
- IN USBHC_MEM_BLOCK *Block\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN USBHC_MEM_BLOCK *Block\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
ASSERT ((Pool != NULL) && (Block != NULL));\r
\r
gBS->FreePool (Block);\r
}\r
\r
-\r
/**\r
- Alloc some memory from the block\r
+ Alloc some memory from the block.\r
\r
- @param Block The memory block to allocate memory from\r
- @param Mem The variable to store the memory allocated\r
- @param Units Number of memory units to allocate\r
+ @param Block The memory block to allocate memory from.\r
+ @param Units Number of memory units to allocate.\r
\r
- @return EFI_SUCCESS : The needed memory is allocated\r
- @return EFI_NOT_FOUND : Can't find the free memory\r
+ @return The pointer to the allocated memory. If couldn't allocate the needed memory,\r
+ the return value is NULL.\r
\r
**/\r
-STATIC\r
VOID *\r
UsbHcAllocMemFromBlock (\r
- IN USBHC_MEM_BLOCK *Block,\r
- IN UINTN Units\r
+ IN USBHC_MEM_BLOCK *Block,\r
+ IN UINTN Units\r
)\r
{\r
- UINTN Byte;\r
- UINT8 Bit;\r
- UINTN StartByte;\r
- UINT8 StartBit;\r
- UINTN Available;\r
- UINTN Count;\r
+ UINTN Byte;\r
+ UINT8 Bit;\r
+ UINTN StartByte;\r
+ UINT8 StartBit;\r
+ UINTN Available;\r
+ UINTN Count;\r
\r
ASSERT ((Block != 0) && (Units != 0));\r
\r
- StartByte = 0;\r
- StartBit = 0;\r
- Available = 0;\r
+ StartByte = 0;\r
+ StartBit = 0;\r
+ Available = 0;\r
\r
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {\r
//\r
}\r
\r
NEXT_BIT (Byte, Bit);\r
-\r
} else {\r
NEXT_BIT (Byte, Bit);\r
\r
- Available = 0;\r
- StartByte = Byte;\r
- StartBit = Bit;\r
+ Available = 0;\r
+ StartByte = Byte;\r
+ StartBit = Bit;\r
}\r
}\r
\r
//\r
// Mark the memory as allocated\r
//\r
- Byte = StartByte;\r
- Bit = StartBit;\r
+ Byte = StartByte;\r
+ Bit = StartBit;\r
\r
for (Count = 0; Count < Units; Count++) {\r
ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));\r
\r
- Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit));\r
+ Block->Bits[Byte] = (UINT8)(Block->Bits[Byte] | USB_HC_BIT (Bit));\r
NEXT_BIT (Byte, Bit);\r
}\r
\r
- return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
+ return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
}\r
\r
-\r
/**\r
- Insert the memory block to the pool's list of the blocks\r
+ Calculate the corresponding pci bus address according to the Mem parameter.\r
+\r
+ @param Pool The memory pool of the host controller.\r
+ @param Mem The pointer to host memory.\r
+ @param Size The size of the memory region.\r
+\r
+ @return the pci memory address\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+UsbHcGetPciAddressForHostMem (\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN VOID *Mem,\r
+ IN UINTN Size\r
+ )\r
+{\r
+ USBHC_MEM_BLOCK *Head;\r
+ USBHC_MEM_BLOCK *Block;\r
+ UINTN AllocSize;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ UINTN Offset;\r
\r
- @param Head The head of the memory pool's block list\r
- @param Block The memory block to insert\r
+ Head = Pool->Head;\r
+ AllocSize = USBHC_MEM_ROUND (Size);\r
\r
- @return VOID\r
+ if (Mem == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ for (Block = Head; Block != NULL; Block = Block->Next) {\r
+ //\r
+ // scan the memory block list for the memory block that\r
+ // completely contains the allocated memory.\r
+ //\r
+ if ((Block->BufHost <= (UINT8 *)Mem) && (((UINT8 *)Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ ASSERT ((Block != NULL));\r
+ //\r
+ // calculate the pci memory address for host memory address.\r
+ //\r
+ Offset = (UINT8 *)Mem - Block->BufHost;\r
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN)(Block->Buf + Offset);\r
+ return PhyAddr;\r
+}\r
+\r
+/**\r
+ Insert the memory block to the pool's list of the blocks.\r
+\r
+ @param Head The head of the memory pool's block list.\r
+ @param Block The memory block to insert.\r
\r
**/\r
-STATIC\r
VOID\r
UsbHcInsertMemBlockToPool (\r
- IN USBHC_MEM_BLOCK *Head,\r
- IN USBHC_MEM_BLOCK *Block\r
+ IN USBHC_MEM_BLOCK *Head,\r
+ IN USBHC_MEM_BLOCK *Block\r
)\r
{\r
ASSERT ((Head != NULL) && (Block != NULL));\r
Head->Next = Block;\r
}\r
\r
-\r
/**\r
Is the memory block empty?\r
\r
- @param Block The memory block to check\r
+ @param Block The memory block to check.\r
\r
- @return TRUE : The memory block is empty\r
- @return FALSE : The memory block isn't empty\r
+ @retval TRUE The memory block is empty.\r
+ @retval FALSE The memory block isn't empty.\r
\r
**/\r
-STATIC\r
BOOLEAN\r
UsbHcIsMemBlockEmpty (\r
- IN USBHC_MEM_BLOCK *Block\r
+ IN USBHC_MEM_BLOCK *Block\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
\r
for (Index = 0; Index < Block->BitsLen; Index++) {\r
if (Block->Bits[Index] != 0) {\r
return TRUE;\r
}\r
\r
-\r
/**\r
- Unlink the memory block from the pool's list\r
+ Unlink the memory block from the pool's list.\r
\r
- @param Head The block list head of the memory's pool\r
+ @param Head The block list head of the memory's pool.\r
@param BlockToUnlink The memory block to unlink.\r
\r
- @return VOID\r
-\r
**/\r
-STATIC\r
VOID\r
UsbHcUnlinkMemBlock (\r
- IN USBHC_MEM_BLOCK *Head,\r
- IN USBHC_MEM_BLOCK *BlockToUnlink\r
+ IN USBHC_MEM_BLOCK *Head,\r
+ IN USBHC_MEM_BLOCK *BlockToUnlink\r
)\r
{\r
- USBHC_MEM_BLOCK *Block;\r
+ USBHC_MEM_BLOCK *Block;\r
\r
ASSERT ((Head != NULL) && (BlockToUnlink != NULL));\r
\r
}\r
}\r
\r
-\r
/**\r
- Initialize the memory management pool for the host controller\r
+ Initialize the memory management pool for the host controller.\r
\r
- @param Pool The USB memory pool to initialize\r
- @param PciIo The PciIo that can be used to access the host controller\r
- @param Check4G Whether the host controller requires allocated memory\r
- from one 4G address space.\r
- @param Which4G The 4G memory area each memory allocated should be from\r
+ @param PciIo The PciIo that can be used to access the host controller.\r
+ @param Check4G Whether the host controller requires allocated memory\r
+ from one 4G address space.\r
+ @param Which4G The 4G memory area each memory allocated should be from.\r
\r
- @return EFI_SUCCESS : The memory pool is initialized\r
- @return EFI_OUT_OF_RESOURCE : Fail to init the memory pool\r
+ @retval EFI_SUCCESS The memory pool is initialized.\r
+ @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.\r
\r
**/\r
USBHC_MEM_POOL *\r
IN UINT32 Which4G\r
)\r
{\r
- USBHC_MEM_POOL *Pool;\r
+ USBHC_MEM_POOL *Pool;\r
\r
Pool = AllocatePool (sizeof (USBHC_MEM_POOL));\r
\r
return Pool;\r
}\r
\r
-\r
/**\r
- Release the memory management pool\r
+ Release the memory management pool.\r
\r
- @param Pool The USB memory pool to free\r
+ @param Pool The USB memory pool to free.\r
\r
- @return EFI_SUCCESS : The memory pool is freed\r
- @return EFI_DEVICE_ERROR : Failed to free the memory pool\r
+ @retval EFI_SUCCESS The memory pool is freed.\r
+ @retval EFI_DEVICE_ERROR Failed to free the memory pool.\r
\r
**/\r
EFI_STATUS\r
UsbHcFreeMemPool (\r
- IN USBHC_MEM_POOL *Pool\r
+ IN USBHC_MEM_POOL *Pool\r
)\r
{\r
- USBHC_MEM_BLOCK *Block;\r
+ USBHC_MEM_BLOCK *Block;\r
\r
ASSERT (Pool->Head != NULL);\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Allocate some memory from the host controller's memory pool\r
which can be used to communicate with host controller.\r
\r
- @param Pool The host controller's memory pool\r
- @param Size Size of the memory to allocate\r
+ @param Pool The host controller's memory pool.\r
+ @param Size Size of the memory to allocate.\r
\r
- @return The allocated memory or NULL\r
+ @return The allocated memory or NULL.\r
\r
**/\r
VOID *\r
UsbHcAllocateMem (\r
- IN USBHC_MEM_POOL *Pool,\r
- IN UINTN Size\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN UINTN Size\r
)\r
{\r
- USBHC_MEM_BLOCK *Head;\r
- USBHC_MEM_BLOCK *Block;\r
- USBHC_MEM_BLOCK *NewBlock;\r
- VOID *Mem;\r
- UINTN AllocSize;\r
- UINTN Pages;\r
+ USBHC_MEM_BLOCK *Head;\r
+ USBHC_MEM_BLOCK *Block;\r
+ USBHC_MEM_BLOCK *NewBlock;\r
+ VOID *Mem;\r
+ UINTN AllocSize;\r
+ UINTN Pages;\r
\r
Mem = NULL;\r
AllocSize = USBHC_MEM_ROUND (Size);\r
NewBlock = UsbHcAllocMemBlock (Pool, Pages);\r
\r
if (NewBlock == NULL) {\r
- DEBUG ((mUsbHcDebugLevel, "UsbHcAllocateMem: failed to allocate block\n"));\r
+ DEBUG ((DEBUG_ERROR, "UsbHcAllocateMem: failed to allocate block\n"));\r
return NULL;\r
}\r
\r
return Mem;\r
}\r
\r
-\r
/**\r
- Free the allocated memory back to the memory pool\r
+ Free the allocated memory back to the memory pool.\r
\r
- @param Pool The memory pool of the host controller\r
- @param Mem The memory to free\r
- @param Size The size of the memory to free\r
-\r
- @return VOID\r
+ @param Pool The memory pool of the host controller.\r
+ @param Mem The memory to free.\r
+ @param Size The size of the memory to free.\r
\r
**/\r
VOID\r
UsbHcFreeMem (\r
- IN USBHC_MEM_POOL *Pool,\r
- IN VOID *Mem,\r
- IN UINTN Size\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN VOID *Mem,\r
+ IN UINTN Size\r
)\r
{\r
- USBHC_MEM_BLOCK *Head;\r
- USBHC_MEM_BLOCK *Block;\r
- UINT8 *ToFree;\r
- UINTN AllocSize;\r
- UINTN Byte;\r
- UINTN Bit;\r
- UINTN Count;\r
+ USBHC_MEM_BLOCK *Head;\r
+ USBHC_MEM_BLOCK *Block;\r
+ UINT8 *ToFree;\r
+ UINTN AllocSize;\r
+ UINTN Byte;\r
+ UINTN Bit;\r
+ UINTN Count;\r
\r
Head = Pool->Head;\r
AllocSize = USBHC_MEM_ROUND (Size);\r
- ToFree = (UINT8 *) Mem;\r
+ ToFree = (UINT8 *)Mem;\r
\r
for (Block = Head; Block != NULL; Block = Block->Next) {\r
//\r
// scan the memory block list for the memory block that\r
// completely contains the memory to free.\r
//\r
- if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) {\r
+ if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
//\r
// compute the start byte and bit in the bit array\r
//\r
- Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8;\r
- Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;\r
+ Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;\r
+ Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;\r
\r
//\r
- // reset associated bits in bit arry\r
+ // reset associated bits in bit array\r
//\r
for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {\r
ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));\r
\r
- Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));\r
+ Block->Bits[Byte] = (UINT8)(Block->Bits[Byte] ^ USB_HC_BIT (Bit));\r
NEXT_BIT (Byte, Bit);\r
}\r
\r
// Release the current memory block if it is empty and not the head\r
//\r
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {\r
- DEBUG ((mUsbHcDebugLevel, "UsbHcFreeMem: block %x is empty, recycle\n", Block));\r
-\r
UsbHcUnlinkMemBlock (Head, Block);\r
UsbHcFreeMemBlock (Pool, Block);\r
}\r
\r
- return ;\r
+ return;\r
}\r