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.
| |||||
bool | dma_phys_free (size_t dma_start, size_t len) | ||||
Free the DMA memory area from dma_start to dma_start+len address.
| |||||
Variables | |||||
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). |
|
The DMA-memory frame is marked as busy.
|
|
The DMA-memory frame is marked as free.
|
|
The size of the DMA memory area.
|
|
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 } |
|
Return a pointer of
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 } |
|
Free the DMA memory area from
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 } |
|
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).
|