sync hh.org
[hh.org.git] / arch / arm / mm / consistent.c
blob2c3ac94b5f3a6e7e79759e1cefd31d8ea1e07fa1
1 /*
2 * linux/arch/arm/mm/consistent.c
4 * Copyright (C) 2000-2004 Russell King
6 * Device local coherent memory support added by Ian Molton (spyro@f2s.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * DMA uncached mapping support.
14 #include <linux/module.h>
15 #include <linux/mm.h>
16 #include <linux/slab.h>
17 #include <linux/errno.h>
18 #include <linux/list.h>
19 #include <linux/init.h>
20 #include <linux/device.h>
21 #include <linux/dma-mapping.h>
23 #include <asm/memory.h>
24 #include <asm/cacheflush.h>
25 #include <asm/io.h>
26 #include <asm/tlbflush.h>
27 #include <asm/sizes.h>
29 /* Sanity check size */
30 #if (CONSISTENT_DMA_SIZE % SZ_2M)
31 #error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
32 #endif
34 #define CONSISTENT_END (0xffe00000)
35 #define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE)
37 #define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
38 #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
39 #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
41 struct dma_coherent_mem {
42 void *virt_base;
43 u32 device_base;
44 int size;
45 int flags;
46 unsigned long *bitmap;
50 * These are the page tables (2MB each) covering uncached, DMA consistent allocations
52 static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
53 static DEFINE_SPINLOCK(consistent_lock);
56 * VM region handling support.
58 * This should become something generic, handling VM region allocations for
59 * vmalloc and similar (ioremap, module space, etc).
61 * I envisage vmalloc()'s supporting vm_struct becoming:
63 * struct vm_struct {
64 * struct vm_region region;
65 * unsigned long flags;
66 * struct page **pages;
67 * unsigned int nr_pages;
68 * unsigned long phys_addr;
69 * };
71 * get_vm_area() would then call vm_region_alloc with an appropriate
72 * struct vm_region head (eg):
74 * struct vm_region vmalloc_head = {
75 * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list),
76 * .vm_start = VMALLOC_START,
77 * .vm_end = VMALLOC_END,
78 * };
80 * However, vmalloc_head.vm_start is variable (typically, it is dependent on
81 * the amount of RAM found at boot time.) I would imagine that get_vm_area()
82 * would have to initialise this each time prior to calling vm_region_alloc().
84 struct vm_region {
85 struct list_head vm_list;
86 unsigned long vm_start;
87 unsigned long vm_end;
88 struct page *vm_pages;
89 int vm_active;
92 static struct vm_region consistent_head = {
93 .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
94 .vm_start = CONSISTENT_BASE,
95 .vm_end = CONSISTENT_END,
98 static struct vm_region *
99 vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp)
101 unsigned long addr = head->vm_start, end = head->vm_end - size;
102 unsigned long flags;
103 struct vm_region *c, *new;
105 new = kmalloc(sizeof(struct vm_region), gfp);
106 if (!new)
107 goto out;
109 spin_lock_irqsave(&consistent_lock, flags);
111 list_for_each_entry(c, &head->vm_list, vm_list) {
112 if ((addr + size) < addr)
113 goto nospc;
114 if ((addr + size) <= c->vm_start)
115 goto found;
116 addr = c->vm_end;
117 if (addr > end)
118 goto nospc;
121 found:
123 * Insert this entry _before_ the one we found.
125 list_add_tail(&new->vm_list, &c->vm_list);
126 new->vm_start = addr;
127 new->vm_end = addr + size;
128 new->vm_active = 1;
130 spin_unlock_irqrestore(&consistent_lock, flags);
131 return new;
133 nospc:
134 spin_unlock_irqrestore(&consistent_lock, flags);
135 kfree(new);
136 out:
137 return NULL;
140 static struct vm_region *vm_region_find(struct vm_region *head, unsigned long addr)
142 struct vm_region *c;
144 list_for_each_entry(c, &head->vm_list, vm_list) {
145 if (c->vm_active && c->vm_start == addr)
146 goto out;
148 c = NULL;
149 out:
150 return c;
153 #ifdef CONFIG_HUGETLB_PAGE
154 #error ARM Coherent DMA allocator does not (yet) support huge TLB
155 #endif
157 static void *
158 __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
159 pgprot_t prot)
161 struct page *page;
162 struct vm_region *c;
163 unsigned long order;
164 u64 mask = ISA_DMA_THRESHOLD, limit;
166 /* Following is a work-around (a.k.a. hack) to prevent pages
167 * with __GFP_COMP being passed to split_page() which cannot
168 * handle them. The real problem is that this flag probably
169 * should be 0 on ARM as it is not supported on this
170 * platform--see CONFIG_HUGETLB_PAGE. */
171 gfp &= ~(__GFP_COMP);
173 if (!consistent_pte[0]) {
174 printk(KERN_ERR "%s: not initialised\n", __func__);
175 dump_stack();
176 return NULL;
179 if (dev) {
181 if(dev->dma_mem) {
182 unsigned long flags;
183 int page;
184 void *ret;
186 spin_lock_irqsave(&consistent_lock, flags);
187 page = bitmap_find_free_region(dev->dma_mem->bitmap,
188 dev->dma_mem->size,
189 get_order(size));
190 spin_unlock_irqrestore(&consistent_lock, flags);
192 if (page >= 0) {
193 *handle = dev->dma_mem->device_base + (page << PAGE_SHIFT);
194 ret = dev->dma_mem->virt_base + (page << PAGE_SHIFT);
195 memset(ret, 0, size);
196 return ret;
200 mask = dev->coherent_dma_mask;
203 * Sanity check the DMA mask - it must be non-zero, and
204 * must be able to be satisfied by a DMA allocation.
206 if (mask == 0) {
207 dev_warn(dev, "coherent DMA mask is unset\n");
208 goto no_page;
211 if ((~mask) & ISA_DMA_THRESHOLD) {
212 dev_warn(dev, "coherent DMA mask %#llx is smaller "
213 "than system GFP_DMA mask %#llx\n",
214 mask, (unsigned long long)ISA_DMA_THRESHOLD);
215 goto no_page;
218 if (dev->dma_mem && dev->dma_mem->flags & DMA_MEMORY_EXCLUSIVE)
219 return NULL;
223 * Sanity check the allocation size.
225 size = PAGE_ALIGN(size);
226 limit = (mask + 1) & ~mask;
227 if ((limit && size >= limit) ||
228 size >= (CONSISTENT_END - CONSISTENT_BASE)) {
229 printk(KERN_WARNING "coherent allocation too big "
230 "(requested %#x mask %#llx)\n", size, mask);
231 goto no_page;
234 order = get_order(size);
236 if (mask != 0xffffffff)
237 gfp |= GFP_DMA;
239 page = alloc_pages(gfp, order);
240 if (!page)
241 goto no_page;
244 * Invalidate any data that might be lurking in the
245 * kernel direct-mapped region for device DMA.
248 unsigned long kaddr = (unsigned long)page_address(page);
249 memset(page_address(page), 0, size);
250 dmac_flush_range(kaddr, kaddr + size);
254 * Allocate a virtual address in the consistent mapping region.
256 c = vm_region_alloc(&consistent_head, size,
257 gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
258 if (c) {
259 pte_t *pte;
260 struct page *end = page + (1 << order);
261 int idx = CONSISTENT_PTE_INDEX(c->vm_start);
262 u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
264 pte = consistent_pte[idx] + off;
265 c->vm_pages = page;
267 split_page(page, order);
270 * Set the "dma handle"
272 *handle = page_to_dma(dev, page);
274 do {
275 BUG_ON(!pte_none(*pte));
278 * x86 does not mark the pages reserved...
280 SetPageReserved(page);
281 set_pte(pte, mk_pte(page, prot));
282 page++;
283 pte++;
284 off++;
285 if (off >= PTRS_PER_PTE) {
286 off = 0;
287 pte = consistent_pte[++idx];
289 } while (size -= PAGE_SIZE);
292 * Free the otherwise unused pages.
294 while (page < end) {
295 __free_page(page);
296 page++;
299 return (void *)c->vm_start;
302 if (page)
303 __free_pages(page, order);
304 no_page:
305 *handle = ~0;
306 return NULL;
310 * Allocate DMA-coherent memory space and return both the kernel remapped
311 * virtual and bus address for that space.
313 void *
314 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
316 if (arch_is_coherent()) {
317 void *virt;
319 virt = kmalloc(size, gfp);
320 if (!virt)
321 return NULL;
322 *handle = virt_to_dma(dev, virt);
324 return virt;
327 return __dma_alloc(dev, size, handle, gfp,
328 pgprot_noncached(pgprot_kernel));
330 EXPORT_SYMBOL(dma_alloc_coherent);
333 * Allocate a writecombining region, in much the same way as
334 * dma_alloc_coherent above.
336 void *
337 dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
339 return __dma_alloc(dev, size, handle, gfp,
340 pgprot_writecombine(pgprot_kernel));
342 EXPORT_SYMBOL(dma_alloc_writecombine);
344 static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
345 void *cpu_addr, dma_addr_t dma_addr, size_t size)
347 unsigned long flags, user_size, kern_size;
348 struct vm_region *c;
349 int ret = -ENXIO;
351 user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
353 spin_lock_irqsave(&consistent_lock, flags);
354 c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
355 spin_unlock_irqrestore(&consistent_lock, flags);
357 if (c) {
358 unsigned long off = vma->vm_pgoff;
360 kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
362 if (off < kern_size &&
363 user_size <= (kern_size - off)) {
364 vma->vm_flags |= VM_RESERVED;
365 ret = remap_pfn_range(vma, vma->vm_start,
366 page_to_pfn(c->vm_pages) + off,
367 user_size << PAGE_SHIFT,
368 vma->vm_page_prot);
372 return ret;
375 int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
376 void *cpu_addr, dma_addr_t dma_addr, size_t size)
378 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
379 return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
381 EXPORT_SYMBOL(dma_mmap_coherent);
383 int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
384 void *cpu_addr, dma_addr_t dma_addr, size_t size)
386 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
387 return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
389 EXPORT_SYMBOL(dma_mmap_writecombine);
392 * free a page as defined by the above mapping.
393 * Must not be called with IRQs disabled.
395 void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
397 struct vm_region *c;
398 unsigned long flags, addr;
399 pte_t *ptep;
400 int idx;
401 u32 off;
402 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
403 unsigned long order;
405 WARN_ON(irqs_disabled());
407 if (arch_is_coherent()) {
408 kfree(cpu_addr);
409 return;
412 size = PAGE_ALIGN(size);
413 order = get_order(size);
415 /* What if mem is valid and the range is not? */
416 if (mem && cpu_addr >= mem->virt_base && cpu_addr < (mem->virt_base + (mem->size << PAGE_SHIFT)))
418 int page = (cpu_addr - mem->virt_base) >> PAGE_SHIFT;
420 bitmap_release_region(mem->bitmap, page, order);
421 return;
424 spin_lock_irqsave(&consistent_lock, flags);
425 c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
426 if (!c)
427 goto no_area;
429 c->vm_active = 0;
430 spin_unlock_irqrestore(&consistent_lock, flags);
432 if ((c->vm_end - c->vm_start) != size) {
433 printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
434 __func__, c->vm_end - c->vm_start, size);
435 dump_stack();
436 size = c->vm_end - c->vm_start;
439 idx = CONSISTENT_PTE_INDEX(c->vm_start);
440 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
441 ptep = consistent_pte[idx] + off;
442 addr = c->vm_start;
443 do {
444 pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
445 unsigned long pfn;
447 ptep++;
448 addr += PAGE_SIZE;
449 off++;
450 if (off >= PTRS_PER_PTE) {
451 off = 0;
452 ptep = consistent_pte[++idx];
455 if (!pte_none(pte) && pte_present(pte)) {
456 pfn = pte_pfn(pte);
458 if (pfn_valid(pfn)) {
459 struct page *page = pfn_to_page(pfn);
462 * x86 does not mark the pages reserved...
464 ClearPageReserved(page);
466 __free_page(page);
467 continue;
471 printk(KERN_CRIT "%s: bad page in kernel page table\n",
472 __func__);
473 } while (size -= PAGE_SIZE);
475 flush_tlb_kernel_range(c->vm_start, c->vm_end);
477 spin_lock_irqsave(&consistent_lock, flags);
478 list_del(&c->vm_list);
479 spin_unlock_irqrestore(&consistent_lock, flags);
481 kfree(c);
482 return;
484 no_area:
485 spin_unlock_irqrestore(&consistent_lock, flags);
486 printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
487 __func__, cpu_addr);
488 dump_stack();
490 EXPORT_SYMBOL(dma_free_coherent);
492 int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
493 dma_addr_t device_addr, size_t size, int flags)
495 void *mem_base;
496 int pages = size >> PAGE_SHIFT;
497 int bitmap_size = (pages + 31)/32;
499 if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
500 goto out;
501 if (!size)
502 goto out;
503 if (dev->dma_mem)
504 goto out;
506 /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
507 mem_base = ioremap_nocache(bus_addr, size);
508 if (!mem_base)
509 goto out;
511 dev->dma_mem = kmalloc(GFP_KERNEL, sizeof(struct dma_coherent_mem));
512 if (!dev->dma_mem)
513 goto out;
514 memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem));
515 dev->dma_mem->bitmap = kmalloc(GFP_KERNEL, bitmap_size);
516 if (!dev->dma_mem->bitmap)
517 goto free1_out;
518 memset(dev->dma_mem->bitmap, 0, bitmap_size);
520 dev->dma_mem->virt_base = mem_base;
521 dev->dma_mem->device_base = device_addr;
522 dev->dma_mem->size = pages;
523 dev->dma_mem->flags = flags;
525 if (flags & DMA_MEMORY_MAP)
526 return DMA_MEMORY_MAP;
528 return DMA_MEMORY_IO;
530 free1_out:
531 kfree(dev->dma_mem->bitmap);
532 out:
533 return 0;
535 EXPORT_SYMBOL(dma_declare_coherent_memory);
537 void dma_release_declared_memory(struct device *dev)
539 struct dma_coherent_mem *mem = dev->dma_mem;
541 if(!mem)
542 return;
543 dev->dma_mem = NULL;
544 kfree(mem->bitmap);
545 kfree(mem);
547 EXPORT_SYMBOL(dma_release_declared_memory);
549 void *dma_mark_declared_memory_occupied(struct device *dev,
550 dma_addr_t device_addr, size_t size)
552 struct dma_coherent_mem *mem = dev->dma_mem;
553 int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
554 int pos, err;
556 if (!mem)
557 return ERR_PTR(-EINVAL);
559 pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
560 err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
561 if (err != 0)
562 return ERR_PTR(err);
563 return mem->virt_base + (pos << PAGE_SHIFT);
565 EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
568 * Initialise the consistent memory allocation.
570 static int __init consistent_init(void)
572 pgd_t *pgd;
573 pmd_t *pmd;
574 pte_t *pte;
575 int ret = 0, i = 0;
576 u32 base = CONSISTENT_BASE;
578 do {
579 pgd = pgd_offset(&init_mm, base);
580 pmd = pmd_alloc(&init_mm, pgd, base);
581 if (!pmd) {
582 printk(KERN_ERR "%s: no pmd tables\n", __func__);
583 ret = -ENOMEM;
584 break;
586 WARN_ON(!pmd_none(*pmd));
588 pte = pte_alloc_kernel(pmd, base);
589 if (!pte) {
590 printk(KERN_ERR "%s: no pte tables\n", __func__);
591 ret = -ENOMEM;
592 break;
595 consistent_pte[i++] = pte;
596 base += (1 << PGDIR_SHIFT);
597 } while (base < CONSISTENT_END);
599 return ret;
602 core_initcall(consistent_init);
605 * Make an area consistent for devices.
606 * Note: Drivers should NOT use this function directly, as it will break
607 * platforms with CONFIG_DMABOUNCE.
608 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
610 void consistent_sync(void *vaddr, size_t size, int direction)
612 unsigned long start = (unsigned long)vaddr;
613 unsigned long end = start + size;
615 switch (direction) {
616 case DMA_FROM_DEVICE: /* invalidate only */
617 dmac_inv_range(start, end);
618 break;
619 case DMA_TO_DEVICE: /* writeback only */
620 dmac_clean_range(start, end);
621 break;
622 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
623 dmac_flush_range(start, end);
624 break;
625 default:
626 BUG();
629 EXPORT_SYMBOL(consistent_sync);