You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.8 KiB
114 lines
3.8 KiB
//--- |
|
// gint:dma - Direct Memory Access for efficient data transfer |
|
//--- |
|
|
|
#ifndef GINT_DMA |
|
#define GINT_DMA |
|
|
|
/* TODO: Enable DMA on fx-9860G */ |
|
#ifdef FXCG50 |
|
|
|
#include <gint/defs/types.h> |
|
|
|
/* dma_size_t - Transfer block size */ |
|
typedef enum |
|
{ |
|
/* Normal transfers of 1, 2, 4, 8, 16 or 32 bytes at a time */ |
|
DMA_1B = 0, |
|
DMA_2B = 1, |
|
DMA_4B = 2, |
|
DMA_8B = 7, |
|
DMA_16B = 3, |
|
DMA_32B = 4, |
|
|
|
/* Transfers of 16 or 32 bytes divided in two operations */ |
|
DMA_16B_DIV = 11, |
|
DMA_32B_DIV = 12, |
|
|
|
} dma_size_t; |
|
|
|
/* dma_address_t - Addressing mode for source and destination regions */ |
|
typedef enum |
|
{ |
|
/* Fixed address mode: the same address is read/written at each step */ |
|
DMA_FIXED = 0, |
|
/* Increment: address is incremented by transfer size at each step */ |
|
DMA_INC = 1, |
|
/* Decrement: only allowed for 1/2/4-byte transfers */ |
|
DMA_DEC = 2, |
|
/* Fixed division mode: address is fixed even in 16/32-divide mode */ |
|
DMA_FIXEDDIV = 3, |
|
|
|
} dma_address_t; |
|
|
|
/* dma_transfer() - Start a data transfer on channel 0 |
|
This function returns just when the transfer starts. The transfer will end |
|
later on and the DMA will be stopped by an interrupt. Call |
|
dma_transfer_wait() if you need to wait for the transfer to finish. Don't |
|
start a new transfer until the current one is finished! |
|
|
|
@channel DMA channel (0..5) |
|
@size Transfer size |
|
@blocks Number of blocks (transferred memory = size * blocks) |
|
@src Source pointer, must be aligned with transfer size |
|
@src_mode Source address mode |
|
@dst Destination address, must be aligned with transfer size |
|
@dst_mode Destination address mode */ |
|
void dma_transfer(int channel, dma_size_t size, uint length, |
|
void const *src, dma_address_t src_mode, |
|
void *dst, dma_address_t dst_mode); |
|
|
|
/* dma_transfer_wait() - Wait for a transfer to finish |
|
|
|
You should call this function when you need to transfer to be complete |
|
before continuing execution. If you are sure that the transfer is finished, |
|
this is not necessary (the only way to know is to look at the DMA registers |
|
or record interrupts). |
|
|
|
@channel DMA channel (0..5) */ |
|
void dma_transfer_wait(int channel); |
|
|
|
/* dma_transfer_noint() - Perform a data transfer without interrupts |
|
This function performs a transfer much like dma_transfer(), but doesn't use |
|
interrupts and *actively waits* for the transfer to finish, returning when |
|
it's finished. Don't call dma_transfer_wait() after using this function. |
|
|
|
Not using interrupts is a bad design idea for a majority of programs, and is |
|
only ever needed to display panic messages inside exception handlers. */ |
|
void dma_transfer_noint(int channel, dma_size_t size, uint blocks, |
|
void const *src, dma_address_t src_mode, |
|
void *dst, dma_address_t dst_mode); |
|
|
|
//--- |
|
// DMA-based memory manipulation functions |
|
//--- |
|
|
|
/* dma_memset(): Fast 32-aligned memset |
|
|
|
This function is your typical memset(), except that the destination and size |
|
must be 32-aligned, and that the pattern is 4 bytes instead of one. It is |
|
replicated to 32 bytes then used to fill the destination area. This 4-byte |
|
fixed size may be lifted in future versions. |
|
|
|
This function cannot be used with virtualized (P0) addresses. |
|
|
|
@dst Destination address (32-aligned) |
|
@pattern 4-byte pattern to fill @dst |
|
@size Sie of destination area (32-aligned) */ |
|
void *dma_memset(void *dst, uint32_t pattern, size_t size); |
|
|
|
/* dma_memcpy(): Fast 32-aligned memcpy |
|
|
|
This function works exactly like memcpy(), but it expects 32-aligned source, |
|
destination, and size, and uses the DMA to efficiently copy. |
|
|
|
This function cannot be used with virtualized (P0) addresses. |
|
|
|
@dst Destination address (32-aligned) |
|
@dst Source addresss (32-aligned) |
|
@size Size of region (32-aligned) */ |
|
void *dma_memcpy(void * restrict dst, const void * restrict src, size_t size); |
|
|
|
#endif /* FXCG50 */ |
|
|
|
#endif /* GINT_DMA */
|
|
|