Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

The DMA (Direct Memory Access) Allocator
[Memory Manager]


Defines

#define DMA_MEMORY_DIM   (DMA_MEMORY_END-DMA_MEMORY_START)
 The size of the DMA memory area.

#define DMA_FREE_FRAME   0
 The DMA-memory frame is marked as free.

#define DMA_BUSY_FRAME   1
 The DMA-memory frame is marked as busy.


Functions

void dma_alloc_init ()
 Initialize the DMA memory allocator.

void * dma_phys_alloc (size_t len)
 Return a pointer of len contiguous bytes into the DMA address space.
Parameters:
len  The size of the buffer we want to allocate.
Returns:
A pointer to the allocated buffer.
Note:
The pointer is the physical address of the buffer and not the virtual address!!!
Exceptions:
NULL  Out of DMA memory area!


bool dma_phys_free (size_t dma_start, size_t len)
 Free the DMA memory area from dma_start to dma_start+len address.
Parameters:
dma_start  The beginning of the area to free.
len  The size of the buffer to free.
Returns:
Note:
The dma_start address is the physical address of the buffer to free and not the virtual address!!!



Variables

bytedma_free_frames
 DMA free frames vector. It maps every frame into the DMA memory area. On i386 we have to reserve the first 16MB of physical memory to the DMA, because on the bus we have a 24-bit register dedicated to the addressing (2^24=16MB).


Detailed Description

The allocator for the DMA memory area.

Define Documentation

#define DMA_BUSY_FRAME   1
 

The DMA-memory frame is marked as busy.

Definition at line 113 of file dma.c.

#define DMA_FREE_FRAME   0
 

The DMA-memory frame is marked as free.

Definition at line 111 of file dma.c.

#define DMA_MEMORY_DIM   (DMA_MEMORY_END-DMA_MEMORY_START)
 

The size of the DMA memory area.

Definition at line 97 of file dma.c.


Function Documentation

void dma_alloc_init  
 

Initialize the DMA memory allocator.

Definition at line 116 of file dma.c.

00117 {
00118         uint32_t i;
00119         extern dword *K_VIR_END;
00120 
00121         // Initialize the DMA free frames vector                        //
00122         dma_free_frames = kmalloc(DMA_MEMORY_DIM/PAGE_SIZE);
00123         memset(dma_free_frames, DMA_FREE_FRAME, DMA_MEMORY_DIM/PAGE_SIZE);
00124 
00125         // Set the kernel physical space busy                           //
00126         for (i=0; i<=(uint32_t)K_VIR_END-K_VIR_START; i+=PAGE_SIZE)
00127                 dma_free_frames[K_PHYS_ADDR+i] = DMA_BUSY_FRAME;
00128 }

void* dma_phys_alloc size_t    len
 

Return a pointer of len contiguous bytes into the DMA address space.

Parameters:
len  The size of the buffer we want to allocate.
Returns:
A pointer to the allocated buffer.
Note:
The pointer is the physical address of the buffer and not the virtual address!!!
Exceptions:
NULL  Out of DMA memory area!

Definition at line 141 of file dma.c.

00142 {
00143         dword i, j, ret;
00144         char flag=0;
00145 
00146         // len must be not null!                                        //
00147         if (!len) return(NULL);
00148 
00149         // Round up len to frames boundary                              //
00150         len = PAGE_ALIGN_UP(len);
00151 
00152         sched_enter_critical_region();
00153 
00154         // Search for a free dma page                                   //
00155         for(i=0; i<(DMA_MEMORY_DIM/PAGE_SIZE); i++)
00156         {
00157                 if (dma_free_frames[i] == DMA_FREE_FRAME)
00158                 {
00159                         // Found a free frame!                          //
00160                         // OK, now I require (len/PAGE_SIZE-1)          //
00161                         // others free frames                           //
00162                         for(j=1, flag=0; j<len/PAGE_SIZE; j++)
00163                         {
00164                                 if (dma_free_frames[i+j] == DMA_BUSY_FRAME)
00165                                 {
00166                                         // Nooo! Found a busy frame!    //
00167                                         flag = 1;
00168                                         break;
00169                                 }
00170                         }
00171                         if (flag == 1)
00172                         {
00173                                 // Not a valid contiguous free space.   //
00174                                 // Continue after j position...         //
00175                                 i += j;
00176                         }
00177                         else
00178                         {
00179                                 // Found a valid contiguous free        //
00180                                 // space, so mark it                    //
00181                                 for(j=0; j<len/PAGE_SIZE; j++)
00182                                         dma_free_frames[i+j] = DMA_BUSY_FRAME;
00183                                 break;
00184                         }
00185                 }
00186         }
00187         // Check if we have found the free DMA location                 //
00188         if (flag == 0)
00189                 // We found it!!!                                       //
00190                 ret = (i * PAGE_SIZE + DMA_MEMORY_START);
00191         else
00192                 // Not found!!!                                         //
00193                 ret = NULL;
00194 
00195         sched_leave_critical_region();
00196         return((void *)ret);
00197 }

bool dma_phys_free size_t    dma_start,
size_t    len
 

Free the DMA memory area from dma_start to dma_start+len address.

Parameters:
dma_start  The beginning of the area to free.
len  The size of the buffer to free.
Returns:
Note:
The dma_start address is the physical address of the buffer to free and not the virtual address!!!

Definition at line 210 of file dma.c.

00211 {
00212         int i;
00213 
00214         if (!len) return(FALSE);
00215 
00216         // Round up len to frames boundary                              //
00217         len = PAGE_ALIGN_UP(len);
00218 
00219         if (
00220                 (dma_start >= DMA_MEMORY_START) && (dma_start < DMA_MEMORY_END) &&
00221                 ((dma_start + len) < DMA_MEMORY_END)
00222         )
00223         {
00224                 sched_enter_critical_region();
00225 
00226                 // Mark the DMA region as free                          //
00227                 for(i=(dma_start-DMA_MEMORY_START)/PAGE_SIZE; i<DMA_MEMORY_DIM/PAGE_SIZE; i++)
00228                         dma_free_frames[i] = DMA_FREE_FRAME;
00229 
00230                 sched_leave_critical_region();
00231 
00232                 return(TRUE);
00233         }
00234         else
00235                 // Invalid DMA memory range                             //
00236                 return(FALSE);
00237 }


Variable Documentation

byte* dma_free_frames
 

DMA free frames vector. It maps every frame into the DMA memory area. On i386 we have to reserve the first 16MB of physical memory to the DMA, because on the bus we have a 24-bit register dedicated to the addressing (2^24=16MB).

Todo:
Yes I know! A vector is ugly... a bitmap should be much better. It requests some bit twiddling, but we can gain a lot of memory! Unfortunately for now I've not much time to spent here! :-(

Definition at line 108 of file dma.c.


Generated on Fri Feb 20 15:32:22 2004 for Minirighi by doxygen1.2.18