/*
 * Dynamic DMA mapping support for AMD Hammer.
 * 
 * Use the integrated AGP GART in the Hammer northbridge as an IOMMU for PCI.
 * This allows to use PCI devices that only support 32bit addresses on systems
 * with more than 4GB. 
 *
 * See Documentation/DMA-mapping.txt for the interface specification.
 * 
 * Copyright 2002 Andi Kleen, SuSE Labs.
 */

#include <linux/config.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/agp_backend.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/topology.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/pgtable.h>
#include <asm/proto.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>

unsigned long iommu_bus_base;	/* GART remapping area (physical) */
static unsigned long iommu_size; 	/* size of remapping area bytes */
static unsigned long iommu_pages;	/* .. and in pages */

u32 *iommu_gatt_base; 		/* Remapping table */

/* If this is disabled the IOMMU will use an optimized flushing strategy
   of only flushing when an mapping is reused. With it true the GART is flushed 
   for every mapping. Problem is that doing the lazy flush seems to trigger
   bugs with some popular PCI cards, in particular 3ware (but has been also
   also seen with Qlogic at least). */
int iommu_fullflush = 1;

#define MAX_NB 8

/* Allocation bitmap for the remapping area */ 
static DEFINE_SPINLOCK(iommu_bitmap_lock);
static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */

static u32 gart_unmapped_entry; 

#define GPTE_VALID    1
#define GPTE_COHERENT 2
#define GPTE_ENCODE(x) \
	(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))

#define to_pages(addr,size) \
	(round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)

#define for_all_nb(dev) \
	dev = NULL;	\
	while ((dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, dev))!=NULL)\
	     if (dev->bus->number == 0 && 				     \
		    (PCI_SLOT(dev->devfn) >= 24) && (PCI_SLOT(dev->devfn) <= 31))

static struct pci_dev *northbridges[MAX_NB];
static u32 northbridge_flush_word[MAX_NB];

#define EMERGENCY_PAGES 32 /* = 128KB */ 

#ifdef CONFIG_AGP
#define AGPEXTERN extern
#else
#define AGPEXTERN
#endif

/* backdoor interface to AGP driver */
AGPEXTERN int agp_memory_reserved;
AGPEXTERN __u32 *agp_gatt_table;

static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
static int need_flush; 		/* global flush state. set for each gart wrap */

static unsigned long alloc_iommu(int size) 
{ 	
	unsigned long offset, flags;

	spin_lock_irqsave(&iommu_bitmap_lock, flags);	
	offset = find_next_zero_string(iommu_gart_bitmap,next_bit,iommu_pages,size);
	if (offset == -1) {
		need_flush = 1;
	       	offset = find_next_zero_string(iommu_gart_bitmap,0,next_bit,size);
	}
	if (offset != -1) { 
		set_bit_string(iommu_gart_bitmap, offset, size); 
		next_bit = offset+size; 
		if (next_bit >= iommu_pages) { 
			next_bit = 0;
			need_flush = 1;
		} 
	} 
	if (iommu_fullflush)
		need_flush = 1;
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);      
	return offset;
} 

static void free_iommu(unsigned long offset, int size)
{ 
	unsigned long flags;
	if (size == 1) { 
		clear_bit(offset, iommu_gart_bitmap); 
		return;
	}
	spin_lock_irqsave(&iommu_bitmap_lock, flags);
	__clear_bit_string(iommu_gart_bitmap, offset, size);
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
} 

/* 
 * Use global flush state to avoid races with multiple flushers.
 */
static void flush_gart(struct device *dev)
{ 
	unsigned long flags;
	int flushed = 0;
	int i, max;

	spin_lock_irqsave(&iommu_bitmap_lock, flags);
	if (need_flush) { 
		max = 0;
		for (i = 0; i < MAX_NB; i++) {
			if (!northbridges[i]) 
				continue;
			pci_write_config_dword(northbridges[i], 0x9c, 
					       northbridge_flush_word[i] | 1); 
			flushed++;
			max = i;
		}
		for (i = 0; i <= max; i++) {
			u32 w;
			if (!northbridges[i])
				continue;
			/* Make sure the hardware actually executed the flush. */
			do { 
				pci_read_config_dword(northbridges[i], 0x9c, &w);
			} while (w & 1);
		} 
		if (!flushed) 
			printk("nothing to flush?\n");
		need_flush = 0;
	} 
	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
} 



#ifdef CONFIG_IOMMU_LEAK

#define SET_LEAK(x) if (iommu_leak_tab) \
			iommu_leak_tab[x] = __builtin_return_address(0);
#define CLEAR_LEAK(x) if (iommu_leak_tab) \
			iommu_leak_tab[x] = NULL;

/* Debugging aid for drivers that don't free their IOMMU tables */
static void **iommu_leak_tab; 
static int leak_trace;
int iommu_leak_pages = 20; 
void dump_leak(void)
{
	int i;
	static int dump; 
	if (dump || !iommu_leak_tab) return;
	dump = 1;
	show_stack(NULL,NULL);
	/* Very crude. dump some from the end of the table too */ 
	printk("Dumping %d pages from end of IOMMU:\n", iommu_leak_pages); 
	for (i = 0; i < iommu_leak_pages; i+=2) {
		printk("%lu: ", iommu_pages-i);
		printk_address((unsigned long) iommu_leak_tab[iommu_pages-i]);
		printk("%c", (i+1)%2 == 0 ? '\n' : ' '); 
	} 
	printk("\n");
}
#else
#define SET_LEAK(x)
#define CLEAR_LEAK(x)
#endif

static void iommu_full(struct device *dev, size_t size, int dir)
{
	/* 
	 * Ran out of IOMMU space for this operation. This is very bad.
	 * Unfortunately the drivers cannot handle this operation properly.
	 * Return some non mapped prereserved space in the aperture and 
	 * let the Northbridge deal with it. This will result in garbage
	 * in the IO operation. When the size exceeds the prereserved space
	 * memory corruption will occur or random memory will be DMAed 
	 * out. Hopefully no network devices use single mappings that big.
	 */ 
	
	printk(KERN_ERR 
  "PCI-DMA: Out of IOMMU space for %lu bytes at device %s\n",
	       size, dev->bus_id);

	if (size > PAGE_SIZE*EMERGENCY_PAGES) {
		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
			panic("PCI-DMA: Memory would be corrupted\n");
		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) 
			panic(KERN_ERR "PCI-DMA: Random memory would be DMAed\n");
	} 

#ifdef CONFIG_IOMMU_LEAK
	dump_leak(); 
#endif
} 

static inline int need_iommu(struct device *dev, unsigned long addr, size_t size)
{ 
	u64 mask = *dev->dma_mask;
	int high = addr + size >= mask;
	int mmu = high;
	if (force_iommu) 
		mmu = 1; 
	if (no_iommu) { 
		if (high) 
			panic("PCI-DMA: high address but no IOMMU.\n"); 
		mmu = 0; 
	} 	
	return mmu; 
}

static inline int nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
{ 
	u64 mask = *dev->dma_mask;
	int high = addr + size >= mask;
	int mmu = high;
	if (no_iommu) { 
		if (high) 
			panic("PCI-DMA: high address but no IOMMU.\n"); 
		mmu = 0; 
	} 	
	return mmu; 
}

/* Map a single continuous physical area into the IOMMU.
 * Caller needs to check if the iommu is needed and flush.
 */
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
				size_t size, int dir)
{ 
	unsigned long npages = to_pages(phys_mem, size);
	unsigned long iommu_page = alloc_iommu(npages);
	int i;
	if (iommu_page == -1) {
		if (!nonforced_iommu(dev, phys_mem, size))
			return phys_mem; 
		if (panic_on_overflow)
			panic("dma_map_area overflow %lu bytes\n", size);
		iommu_full(dev, size, dir);
		return bad_dma_address;
	}

	for (i = 0; i < npages; i++) {
		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
		SET_LEAK(iommu_page + i);
		phys_mem += PAGE_SIZE;
	}
	return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
}

static dma_addr_t gart_map_simple(struct device *dev, char *buf,
				 size_t size, int dir)
{
	dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir);
	flush_gart(dev);
	return map;
}

/* Map a single area into the IOMMU */
dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir)
{
	unsigned long phys_mem, bus;

	BUG_ON(dir == DMA_NONE);

	if (!dev)
		dev = &fallback_dev;

	phys_mem = virt_to_phys(addr); 
	if (!need_iommu(dev, phys_mem, size))
		return phys_mem; 

	bus = gart_map_simple(dev, addr, size, dir);
	return bus; 
}

/*
 * Wrapper for pci_unmap_single working with scatterlists.
 */
void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
{
	int i;

	for (i = 0; i < nents; i++) {
		struct scatterlist *s = &sg[i];
		if (!s->dma_length)
			break;
		dma_unmap_single(dev, s->dma_address, s->dma_length, dir);
	}
}

/* Fallback for dma_map_sg in case of overflow */
static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
			       int nents, int dir)
{
	int i;

#ifdef CONFIG_IOMMU_DEBUG
	printk(KERN_DEBUG "dma_map_sg overflow\n");
#endif

 	for (i = 0; i < nents; i++ ) {
		struct scatterlist *s = &sg[i];
		unsigned long addr = page_to_phys(s->page) + s->offset; 
		if (nonforced_iommu(dev, addr, s->length)) { 
			addr = dma_map_area(dev, addr, s->length, dir);
			if (addr == bad_dma_address) { 
				if (i > 0) 
					gart_unmap_sg(dev, sg, i, dir);
				nents = 0; 
				sg[0].dma_length = 0;
				break;
			}
		}
		s->dma_address = addr;
		s->dma_length = s->length;
	}
	flush_gart(dev);
	return nents;
}

/* Map multiple scatterlist entries continuous into the first. */
static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
		      struct scatterlist *sout, unsigned long pages)
{
	unsigned long iommu_start = alloc_iommu(pages);
	unsigned long iommu_page = iommu_start; 
	int i;

	if (iommu_start == -1)
		return -1;
	
	for (i = start; i < stopat; i++) {
		struct scatterlist *s = &sg[i];
		unsigned long pages, addr;
		unsigned long phys_addr = s->dma_address;
		
		BUG_ON(i > start && s->offset);
		if (i == start) {
			sout->dma_address = iommu_bus_base;
			sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
			sout->dma_length = s->length;
		} else { 
			sout->dma_length += s->length; 
		}

		addr = phys_addr;
		pages = to_pages(s->offset, s->length); 
		while (pages--) { 
			iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); 
			SET_LEAK(iommu_page);
			addr += PAGE_SIZE;
			iommu_page++;
		}
	} 
	BUG_ON(iommu_page - iommu_start != pages);	
	return 0;
}

static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat,
		      struct scatterlist *sout,
		      unsigned long pages, int need)
{
	if (!need) { 
		BUG_ON(stopat - start != 1);
		sout->dma_length = sg[start].length; 
		return 0;
	} 
	return __dma_map_cont(sg, start, stopat, sout, pages);
}
		
/*
 * DMA map all entries in a scatterlist.
 * Merge chunks that have page aligned sizes into a continuous mapping. 
 */
int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
{
	int i;
	int out;
	int start;
	unsigned long pages = 0;
	int need = 0, nextneed;

	BUG_ON(dir == DMA_NONE);
	if (nents == 0) 
		return 0;

	if (!dev)
		dev = &fallback_dev;

	out = 0;
	start = 0;
	for (i = 0; i < nents; i++) {
		struct scatterlist *s = &sg[i];
		dma_addr_t addr = page_to_phys(s->page) + s->offset;
		s->dma_address = addr;
		BUG_ON(s->length == 0); 

		nextneed = need_iommu(dev, addr, s->length); 

		/* Handle the previous not yet processed entries */
		if (i > start) {
			struct scatterlist *ps = &sg[i-1];
			/* Can only merge when the last chunk ends on a page 
			   boundary and the new one doesn't have an offset. */
			if (!iommu_merge || !nextneed || !need || s->offset ||
			    (ps->offset + ps->length) % PAGE_SIZE) { 
				if (dma_map_cont(sg, start, i, sg+out, pages,
						 need) < 0)
					goto error;
				out++;
				pages = 0;
				start = i;	
			}
		}

		need = nextneed;
		pages += to_pages(s->offset, s->length);
	}
	if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0)
		goto error;
	out++;
	flush_gart(dev);
	if (out < nents) 
		sg[out].dma_length = 0; 
	return out;

error:
	flush_gart(NULL);
	gart_unmap_sg(dev, sg, nents, dir);
	/* When it was forced or merged try again in a dumb way */
	if (force_iommu || iommu_merge) {
		out = dma_map_sg_nonforce(dev, sg, nents, dir);
		if (out > 0)
			return out;
	}
	if (panic_on_overflow)
		panic("dma_map_sg: overflow on %lu pages\n", pages);
	iommu_full(dev, pages << PAGE_SHIFT, dir);
	for (i = 0; i < nents; i++)
		sg[i].dma_address = bad_dma_address;
	return 0;
} 

/*
 * Free a DMA mapping.
 */ 
void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
		      size_t size, int direction)
{
	unsigned long iommu_page; 
	int npages;
	int i;

	if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE || 
	    dma_addr >= iommu_bus_base + iommu_size)
		return;
	iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;	
	npages = to_pages(dma_addr, size);
	for (i = 0; i < npages; i++) { 
		iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; 
		CLEAR_LEAK(iommu_page + i);
	}
	free_iommu(iommu_page, npages);
}

static int no_agp;

static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
{ 
	unsigned long a; 
	if (!iommu_size) { 
		iommu_size = aper_size; 
		if (!no_agp) 
			iommu_size /= 2; 
	} 

	a = aper + iommu_size; 
	iommu_size -= round_up(a, LARGE_PAGE_SIZE) - a;

	if (iommu_size < 64*1024*1024) 
		printk(KERN_WARNING
  "PCI-DMA: Warning: Small IOMMU %luMB. Consider increasing the AGP aperture in BIOS\n",iommu_size>>20); 
	
	return iommu_size;
} 

static __init unsigned read_aperture(struct pci_dev *dev, u32 *size) 
{ 
	unsigned aper_size = 0, aper_base_32;
	u64 aper_base;
	unsigned aper_order;

	pci_read_config_dword(dev, 0x94, &aper_base_32); 
	pci_read_config_dword(dev, 0x90, &aper_order);
	aper_order = (aper_order >> 1) & 7;	

	aper_base = aper_base_32 & 0x7fff; 
	aper_base <<= 25;

	aper_size = (32 * 1024 * 1024) << aper_order; 
	if (aper_base + aper_size >= 0xffffffff || !aper_size)
		aper_base = 0;

	*size = aper_size;
	return aper_base;
} 

/* 
 * Private Northbridge GATT initialization in case we cannot use the
 * AGP driver for some reason.  
 */
static __init int init_k8_gatt(struct agp_kern_info *info)
{ 
	struct pci_dev *dev;
	void *gatt;
	unsigned aper_base, new_aper_base;
	unsigned aper_size, gatt_size, new_aper_size;
	
	printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
	aper_size = aper_base = info->aper_size = 0;
	for_all_nb(dev) { 
		new_aper_base = read_aperture(dev, &new_aper_size); 
		if (!new_aper_base) 
			goto nommu; 
		
		if (!aper_base) { 
			aper_size = new_aper_size;
			aper_base = new_aper_base;
		} 
		if (aper_size != new_aper_size || aper_base != new_aper_base) 
			goto nommu;
	}
	if (!aper_base)
		goto nommu; 
	info->aper_base = aper_base;
	info->aper_size = aper_size>>20; 

	gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32); 
	gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); 
	if (!gatt) 
		panic("Cannot allocate GATT table"); 
	memset(gatt, 0, gatt_size); 
	agp_gatt_table = gatt;
	
	for_all_nb(dev) { 
		u32 ctl; 
		u32 gatt_reg; 

		gatt_reg = __pa(gatt) >> 12; 
		gatt_reg <<= 4; 
		pci_write_config_dword(dev, 0x98, gatt_reg);
		pci_read_config_dword(dev, 0x90, &ctl); 

		ctl |= 1;
		ctl &= ~((1<<4) | (1<<5));

		pci_write_config_dword(dev, 0x90, ctl); 
	}
	flush_gart(NULL); 
	
	printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); 
	return 0;

 nommu:
 	/* Should not happen anymore */
	printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
	       KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction.\n");
	return -1; 
} 

extern int agp_amd64_init(void);

static struct dma_mapping_ops gart_dma_ops = {
	.mapping_error = NULL,
	.map_single = gart_map_single,
	.map_simple = gart_map_simple,
	.unmap_single = gart_unmap_single,
	.sync_single_for_cpu = NULL,
	.sync_single_for_device = NULL,
	.sync_single_range_for_cpu = NULL,
	.sync_single_range_for_device = NULL,
	.sync_sg_for_cpu = NULL,
	.sync_sg_for_device = NULL,
	.map_sg = gart_map_sg,
	.unmap_sg = gart_unmap_sg,
};

static int __init pci_iommu_init(void)
{ 
	struct agp_kern_info info;
	unsigned long aper_size;
	unsigned long iommu_start;
	struct pci_dev *dev;
	unsigned long scratch;
	long i;

#ifndef CONFIG_AGP_AMD64
	no_agp = 1; 
#else
	/* Makefile puts PCI initialization via subsys_initcall first. */
	/* Add other K8 AGP bridge drivers here */
	no_agp = no_agp || 
		(agp_amd64_init() < 0) || 
		(agp_copy_info(agp_bridge, &info) < 0);
#endif	

	if (swiotlb) { 
		no_iommu = 1;
		return -1; 
	} 
	
	if (no_iommu ||
	    (!force_iommu && end_pfn <= MAX_DMA32_PFN) ||
	    !iommu_aperture ||
	    (no_agp && init_k8_gatt(&info) < 0)) {
		no_iommu = 1;
		no_iommu_init();
		printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
		if (end_pfn > MAX_DMA32_PFN) {
			printk(KERN_ERR "WARNING more than 4GB of memory "
					"but IOMMU not compiled in.\n"
			       KERN_ERR "WARNING 32bit PCI may malfunction.\n"
			       KERN_ERR "You might want to enable "
					"CONFIG_GART_IOMMU\n");
		}
		return -1;
	}

	printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
	aper_size = info.aper_size * 1024 * 1024;	
	iommu_size = check_iommu_size(info.aper_base, aper_size); 
	iommu_pages = iommu_size >> PAGE_SHIFT; 

	iommu_gart_bitmap = (void*)__get_free_pages(GFP_KERNEL, 
						    get_order(iommu_pages/8)); 
	if (!iommu_gart_bitmap) 
		panic("Cannot allocate iommu bitmap\n"); 
	memset(iommu_gart_bitmap, 0, iommu_pages/8);

#ifdef CONFIG_IOMMU_LEAK
	if (leak_trace) { 
		iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL, 
				  get_order(iommu_pages*sizeof(void *)));
		if (iommu_leak_tab) 
			memset(iommu_leak_tab, 0, iommu_pages * 8); 
		else
			printk("PCI-DMA: Cannot allocate leak trace area\n"); 
	} 
#endif

	/* 
	 * Out of IOMMU space handling.
	 * Reserve some invalid pages at the beginning of the GART. 
	 */ 
	set_bit_string(iommu_gart_bitmap, 0, EMERGENCY_PAGES); 

	agp_memory_reserved = iommu_size;	
	printk(KERN_INFO
	       "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
	       iommu_size>>20); 

	iommu_start = aper_size - iommu_size;	
	iommu_bus_base = info.aper_base + iommu_start; 
	bad_dma_address = iommu_bus_base;
	iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);

	/* 
	 * Unmap the IOMMU part of the GART. The alias of the page is
	 * always mapped with cache enabled and there is no full cache
	 * coherency across the GART remapping. The unmapping avoids
	 * automatic prefetches from the CPU allocating cache lines in
	 * there. All CPU accesses are done via the direct mapping to
	 * the backing memory. The GART address is only used by PCI
	 * devices. 
	 */
	clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);

	/* 
	 * Try to workaround a bug (thanks to BenH) 
	 * Set unmapped entries to a scratch page instead of 0. 
	 * Any prefetches that hit unmapped entries won't get an bus abort
	 * then.
	 */
	scratch = get_zeroed_page(GFP_KERNEL); 
	if (!scratch) 
		panic("Cannot allocate iommu scratch page");
	gart_unmapped_entry = GPTE_ENCODE(__pa(scratch));
	for (i = EMERGENCY_PAGES; i < iommu_pages; i++) 
		iommu_gatt_base[i] = gart_unmapped_entry;

	for_all_nb(dev) {
		u32 flag; 
		int cpu = PCI_SLOT(dev->devfn) - 24;
		if (cpu >= MAX_NB)
			continue;
		northbridges[cpu] = dev;
		pci_read_config_dword(dev, 0x9c, &flag); /* cache flush word */
		northbridge_flush_word[cpu] = flag; 
	}
		     
	flush_gart(NULL);

	dma_ops = &gart_dma_ops;

	return 0;
} 

/* Must execute after PCI subsystem */
fs_initcall(pci_iommu_init);

void gart_parse_options(char *p)
{
	int arg;

#ifdef CONFIG_IOMMU_LEAK
	if (!strncmp(p,"leak",4)) {
		leak_trace = 1;
		p += 4;
		if (*p == '=') ++p;
		if (isdigit(*p) && get_option(&p, &arg))
			iommu_leak_pages = arg;
	}
#endif
	if (isdigit(*p) && get_option(&p, &arg))
		iommu_size = arg;
	if (!strncmp(p, "fullflush",8))
		iommu_fullflush = 1;
	if (!strncmp(p, "nofullflush",11))
		iommu_fullflush = 0;
	if (!strncmp(p,"noagp",5))
		no_agp = 1;
	if (!strncmp(p, "noaperture",10))
		fix_aperture = 0;
	/* duplicated from pci-dma.c */
	if (!strncmp(p,"force",5))
		iommu_aperture_allowed = 1;
	if (!strncmp(p,"allowed",7))
		iommu_aperture_allowed = 1;
	if (!strncmp(p, "memaper", 7)) {
		fallback_aper_force = 1;
		p += 7;
		if (*p == '=') {
			++p;
			if (get_option(&p, &arg))
				fallback_aper_order = arg;
		}
	}
}
