summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2002-06-17 19:43:55 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-06-17 19:43:55 -0700
commitc8712aebdb2455a095d596c1a5a6af358b3efde3 (patch)
tree9587e727a015c93f88dfed57ecc573ca8a259c54 /include
parentd9083ea2b8d34d827f77e3d8ceeb04c160a938ed (diff)
[PATCH] change_page_attr and AGP update
Add change_page_attr to change page attributes for the kernel linear map. Fix AGP driver to use change_page_attr for the AGP buffer. Clean up AGP driver a bit (only tested on i386/VIA+AMD) Change ioremap_nocache to use change_page_attr to avoid mappings with conflicting caching attributes.
Diffstat (limited to 'include')
-rw-r--r--include/asm-alpha/agp.h11
-rw-r--r--include/asm-i386/agp.h23
-rw-r--r--include/asm-i386/cacheflush.h3
-rw-r--r--include/asm-i386/io.h26
-rw-r--r--include/asm-i386/page.h3
-rw-r--r--include/asm-i386/pgtable-2level.h1
-rw-r--r--include/asm-i386/pgtable-3level.h2
-rw-r--r--include/asm-i386/pgtable.h3
-rw-r--r--include/asm-ia64/agp.h11
-rw-r--r--include/asm-sparc64/agp.h11
-rw-r--r--include/asm-x86_64/agp.h23
-rw-r--r--include/asm-x86_64/cacheflush.h3
-rw-r--r--include/linux/vmalloc.h3
13 files changed, 98 insertions, 25 deletions
diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h
new file mode 100644
index 000000000000..ba05bdf9a211
--- /dev/null
+++ b/include/asm-alpha/agp.h
@@ -0,0 +1,11 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+/* dummy for now */
+
+#define map_page_into_agp(page)
+#define unmap_page_from_agp(page)
+#define flush_agp_mappings()
+#define flush_agp_cache() mb()
+
+#endif
diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h
new file mode 100644
index 000000000000..9ae97c09fb49
--- /dev/null
+++ b/include/asm-i386/agp.h
@@ -0,0 +1,23 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+#include <asm/pgtable.h>
+
+/*
+ * Functions to keep the agpgart mappings coherent with the MMU.
+ * The GART gives the CPU a physical alias of pages in memory. The alias region is
+ * mapped uncacheable. Make sure there are no conflicting mappings
+ * with different cachability attributes for the same page. This avoids
+ * data corruption on some CPUs.
+ */
+
+#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
+#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
+#define flush_agp_mappings() global_flush_tlb()
+
+/* Could use CLFLUSH here if the cpu supports it. But then it would
+ need to be called for each cacheline of the whole page so it may not be
+ worth it. Would need a page for it. */
+#define flush_agp_cache() asm volatile("wbinvd":::"memory")
+
+#endif
diff --git a/include/asm-i386/cacheflush.h b/include/asm-i386/cacheflush.h
index 58d027dfc5ff..319e65a7047f 100644
--- a/include/asm-i386/cacheflush.h
+++ b/include/asm-i386/cacheflush.h
@@ -15,4 +15,7 @@
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
+void global_flush_tlb(void);
+int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+
#endif /* _I386_CACHEFLUSH_H */
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 44996d06ecc3..9922dd823c9c 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -121,31 +121,7 @@ static inline void * ioremap (unsigned long offset, unsigned long size)
return __ioremap(offset, size, 0);
}
-/**
- * ioremap_nocache - map bus memory into CPU space
- * @offset: bus address of the memory
- * @size: size of the resource to map
- *
- * ioremap_nocache performs a platform specific sequence of operations to
- * make bus memory CPU accessible via the readb/readw/readl/writeb/
- * writew/writel functions and the other mmio helpers. The returned
- * address is not guaranteed to be usable directly as a virtual
- * address.
- *
- * This version of ioremap ensures that the memory is marked uncachable
- * on the CPU as well as honouring existing caching rules from things like
- * the PCI bus. Note that there are other caches and buffers on many
- * busses. In paticular driver authors should read up on PCI writes
- *
- * It's useful if some control registers are in such an area and
- * write combining or read caching is not desirable:
- */
-
-static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
-{
- return __ioremap(offset, size, _PAGE_PCD);
-}
-
+extern void * ioremap_nocache (unsigned long offset, unsigned long size);
extern void iounmap(void *addr);
/*
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 4737ef69ae18..d8e1f404c08b 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -6,6 +6,9 @@
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index e22db0cc6824..9f8bdc13adac 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -40,6 +40,7 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
* hook is made available.
*/
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
/*
* (pmds are folded into pgds so this doesnt get actually called,
* but the define is needed for a generic inline function.)
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index bb2eaea63fde..beb0c1bc3d30 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -49,6 +49,8 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
smp_wmb();
ptep->pte_low = pte.pte_low;
}
+#define set_pte_atomic(pteptr,pteval) \
+ set_64bit((unsigned long long *)(pteptr),pte_val(pteval))
#define set_pmd(pmdptr,pmdval) \
set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval))
#define set_pgd(pgdptr,pgdval) \
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index f48db2beeeba..71b75fa234af 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -237,6 +237,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
#define pmd_page(pmd) \
(mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
+#define pmd_large(pmd) \
+ ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
+
/* to find an entry in a page-table-directory. */
#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h
new file mode 100644
index 000000000000..ba05bdf9a211
--- /dev/null
+++ b/include/asm-ia64/agp.h
@@ -0,0 +1,11 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+/* dummy for now */
+
+#define map_page_into_agp(page)
+#define unmap_page_from_agp(page)
+#define flush_agp_mappings()
+#define flush_agp_cache() mb()
+
+#endif
diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h
new file mode 100644
index 000000000000..ba05bdf9a211
--- /dev/null
+++ b/include/asm-sparc64/agp.h
@@ -0,0 +1,11 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+/* dummy for now */
+
+#define map_page_into_agp(page)
+#define unmap_page_from_agp(page)
+#define flush_agp_mappings()
+#define flush_agp_cache() mb()
+
+#endif
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h
new file mode 100644
index 000000000000..8c2fabe80419
--- /dev/null
+++ b/include/asm-x86_64/agp.h
@@ -0,0 +1,23 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+#include <asm/cacheflush.h>
+
+/*
+ * Functions to keep the agpgart mappings coherent.
+ * The GART gives the CPU a physical alias of memory. The alias is
+ * mapped uncacheable. Make sure there are no conflicting mappings
+ * with different cachability attributes for the same page.
+ */
+
+#define map_page_into_agp(page) \
+ change_page_attr(page, __pgprot(__PAGE_KERNEL | _PAGE_PCD))
+#define unmap_page_from_agp(page) change_page_attr(page, PAGE_KERNEL)
+#define flush_agp_mappings() global_flush_tlb()
+
+/* Could use CLFLUSH here if the cpu supports it. But then it would
+ need to be called for each cacheline of the whole page so it may not be
+ worth it. Would need a page for it. */
+#define flush_agp_cache() asm volatile("wbinvd":::"memory")
+
+#endif
diff --git a/include/asm-x86_64/cacheflush.h b/include/asm-x86_64/cacheflush.h
index 58d027dfc5ff..319e65a7047f 100644
--- a/include/asm-x86_64/cacheflush.h
+++ b/include/asm-x86_64/cacheflush.h
@@ -15,4 +15,7 @@
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
+void global_flush_tlb(void);
+int change_page_attr(struct page *page, int numpages, pgprot_t prot);
+
#endif /* _I386_CACHEFLUSH_H */
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 4051c031a976..9cc67b500368 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -13,6 +13,7 @@ struct vm_struct {
unsigned long flags;
void * addr;
unsigned long size;
+ unsigned long phys_addr;
struct vm_struct * next;
};
@@ -23,6 +24,8 @@ extern long vread(char *buf, char *addr, unsigned long count);
extern void vmfree_area_pages(unsigned long address, unsigned long size);
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
int gfp_mask, pgprot_t prot);
+extern struct vm_struct *remove_kernel_area(void *addr);
+
/*
* Various ways to allocate pages.
*/