From: Michael Brown Date: Tue, 8 Jul 2025 11:38:05 +0000 (+0100) Subject: [dma] Use virtual addresses for dma_map() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22de0c4edf2fe1cdbca5e22c52c86a2289d04816;p=thirdparty%2Fipxe.git [dma] Use virtual addresses for dma_map() Cache management operations must generally be performed on virtual addresses rather than physical addresses. Change the address parameter in dma_map() to be a virtual address, and make dma() the API-level primitive instead of dma_phys(). Signed-off-by: Michael Brown --- diff --git a/src/core/dma.c b/src/core/dma.c index cf4b20379..cbc9b8d10 100644 --- a/src/core/dma.c +++ b/src/core/dma.c @@ -47,7 +47,7 @@ PROVIDE_DMAAPI_INLINE ( flat, dma_free ); PROVIDE_DMAAPI_INLINE ( flat, dma_umalloc ); PROVIDE_DMAAPI_INLINE ( flat, dma_ufree ); PROVIDE_DMAAPI_INLINE ( flat, dma_set_mask ); -PROVIDE_DMAAPI_INLINE ( flat, dma_phys ); +PROVIDE_DMAAPI_INLINE ( flat, dma ); /****************************************************************************** * @@ -67,7 +67,7 @@ PROVIDE_DMAAPI_INLINE ( flat, dma_phys ); * @ret rc Return status code */ static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map, - physaddr_t addr, size_t len, int flags ) { + void *addr, size_t len, int flags ) { struct dma_operations *op = dma->op; if ( ! op ) @@ -175,4 +175,4 @@ PROVIDE_DMAAPI ( op, dma_free, dma_op_free ); PROVIDE_DMAAPI ( op, dma_umalloc, dma_op_umalloc ); PROVIDE_DMAAPI ( op, dma_ufree, dma_op_ufree ); PROVIDE_DMAAPI ( op, dma_set_mask, dma_op_set_mask ); -PROVIDE_DMAAPI_INLINE ( op, dma_phys ); +PROVIDE_DMAAPI_INLINE ( op, dma ); diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index 82b07833c..1d4c22a09 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -65,8 +65,8 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl, /* Map dummy target location */ if ( ( rc = dma_map ( intelxl->dma, &intelxl->msix.map, - virt_to_phys ( &intelxl->msix.msg ), - sizeof ( intelxl->msix.msg ), DMA_RX ) ) != 0 ) { + &intelxl->msix.msg, sizeof ( intelxl->msix.msg ), + DMA_RX ) ) != 0 ) { DBGC ( intelxl, "INTELXL %p could not map MSI-X target: %s\n", intelxl, strerror ( rc ) ); goto err_map; diff --git a/src/include/ipxe/dma.h b/src/include/ipxe/dma.h index 6e5c43289..d450ef523 100644 --- a/src/include/ipxe/dma.h +++ b/src/include/ipxe/dma.h @@ -68,7 +68,7 @@ struct dma_operations { * @ret rc Return status code */ int ( * map ) ( struct dma_device *dma, struct dma_mapping *map, - physaddr_t addr, size_t len, int flags ); + void *addr, size_t len, int flags ); /** * Unmap buffer * @@ -178,8 +178,7 @@ struct dma_operations { */ static inline __always_inline int DMAAPI_INLINE ( flat, dma_map ) ( struct dma_device *dma, - struct dma_mapping *map, - physaddr_t addr __unused, + struct dma_mapping *map, void *addr __unused, size_t len __unused, int flags __unused ) { /* Increment mapping count (for debugging) */ @@ -319,32 +318,31 @@ DMAAPI_INLINE ( flat, dma_set_mask ) ( struct dma_device *dma __unused, } /** - * Get DMA address from physical address + * Get DMA address from virtual address * * @v map DMA mapping - * @v addr Physical address within the mapped region + * @v addr Address within the mapped region * @ret addr Device-side DMA address */ static inline __always_inline physaddr_t -DMAAPI_INLINE ( flat, dma_phys ) ( struct dma_mapping *map __unused, - physaddr_t addr ) { +DMAAPI_INLINE ( flat, dma ) ( struct dma_mapping *map __unused, void *addr ) { /* Use physical address as device address */ - return addr; + return virt_to_phys ( addr ); } /** - * Get DMA address from physical address + * Get DMA address from virtual address * * @v map DMA mapping - * @v addr Physical address within the mapped region + * @v addr Address within the mapped region * @ret addr Device-side DMA address */ static inline __always_inline physaddr_t -DMAAPI_INLINE ( op, dma_phys ) ( struct dma_mapping *map, physaddr_t addr ) { +DMAAPI_INLINE ( op, dma ) ( struct dma_mapping *map, void *addr ) { /* Adjust physical address using mapping offset */ - return ( addr + map->offset ); + return ( virt_to_phys ( addr ) + map->offset ); } /** @@ -358,7 +356,7 @@ DMAAPI_INLINE ( op, dma_phys ) ( struct dma_mapping *map, physaddr_t addr ) { * @ret rc Return status code */ int dma_map ( struct dma_device *dma, struct dma_mapping *map, - physaddr_t addr, size_t len, int flags ); + void *addr, size_t len, int flags ); /** * Unmap buffer @@ -417,28 +415,14 @@ void dma_ufree ( struct dma_mapping *map, void *addr, size_t len ); */ void dma_set_mask ( struct dma_device *dma, physaddr_t mask ); -/** - * Get DMA address from physical address - * - * @v map DMA mapping - * @v addr Physical address within the mapped region - * @ret addr Device-side DMA address - */ -physaddr_t dma_phys ( struct dma_mapping *map, physaddr_t addr ); - /** * Get DMA address from virtual address * * @v map DMA mapping - * @v addr Virtual address within the mapped region + * @v addr Address within the mapped region * @ret addr Device-side DMA address */ -static inline __always_inline physaddr_t dma ( struct dma_mapping *map, - void *addr ) { - - /* Get DMA address from corresponding physical address */ - return dma_phys ( map, virt_to_phys ( addr ) ); -} +physaddr_t dma ( struct dma_mapping *map, void *addr ); /** * Check if DMA unmapping is required diff --git a/src/include/ipxe/iobuf.h b/src/include/ipxe/iobuf.h index 2bdca6b5d..df8d0b854 100644 --- a/src/include/ipxe/iobuf.h +++ b/src/include/ipxe/iobuf.h @@ -230,8 +230,7 @@ static inline void iob_populate ( struct io_buffer *iobuf, static inline __always_inline int iob_map ( struct io_buffer *iobuf, struct dma_device *dma, size_t len, int flags ) { - return dma_map ( dma, &iobuf->map, virt_to_phys ( iobuf->data ), - len, flags ); + return dma_map ( dma, &iobuf->map, iobuf->data, len, flags ); } /** diff --git a/src/interface/efi/efi_pci.c b/src/interface/efi/efi_pci.c index 1b1f05816..ae0ec4264 100644 --- a/src/interface/efi/efi_pci.c +++ b/src/interface/efi/efi_pci.c @@ -455,7 +455,7 @@ PROVIDE_PCIAPI ( efi, pci_ioremap, efipci_ioremap ); * @ret rc Return status code */ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map, - physaddr_t addr, size_t len, int flags ) { + void *addr, size_t len, int flags ) { struct efi_pci_device *efipci = container_of ( dma, struct efi_pci_device, pci.dma ); struct pci_device *pci = &efipci->pci; @@ -464,6 +464,7 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map, EFI_PHYSICAL_ADDRESS bus; UINTN count; VOID *mapping; + physaddr_t phys; EFI_STATUS efirc; int rc; @@ -486,18 +487,19 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map, } /* Map buffer (if non-zero length) */ + phys = virt_to_phys ( addr ); count = len; if ( len ) { - if ( ( efirc = pci_io->Map ( pci_io, op, phys_to_virt ( addr ), - &count, &bus, &mapping ) ) != 0 ) { + if ( ( efirc = pci_io->Map ( pci_io, op, addr, &count, &bus, + &mapping ) ) != 0 ) { rc = -EEFI ( efirc ); - DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %08lx+%zx: " + DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %p+%zx: " "%s\n", PCI_ARGS ( pci ), addr, len, strerror ( rc ) ); goto err_map; } } else { - bus = addr; + bus = phys; mapping = NULL; } @@ -508,14 +510,14 @@ static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map, */ if ( count != len ) { DBGC ( pci, "EFIPCI " PCI_FMT " attempted split mapping for " - "%08lx+%zx\n", PCI_ARGS ( pci ), addr, len ); + "%p+%zx\n", PCI_ARGS ( pci ), addr, len ); rc = -ENOTSUP; goto err_len; } /* Populate mapping */ map->dma = dma; - map->offset = ( bus - addr ); + map->offset = ( bus - phys ); map->token = mapping; /* Increment mapping count (for debugging) */ @@ -594,8 +596,7 @@ static void * efipci_dma_alloc ( struct dma_device *dma, memset ( addr, 0, ( pages * EFI_PAGE_SIZE ) ); /* Map buffer */ - if ( ( rc = efipci_dma_map ( dma, map, virt_to_phys ( addr ), - ( pages * EFI_PAGE_SIZE ), + if ( ( rc = efipci_dma_map ( dma, map, addr, ( pages * EFI_PAGE_SIZE ), DMA_BI ) ) != 0 ) goto err_map;