Re: pgprot_writecombine & shub 1.x

Jesse Barnes
2005-01-19T21:51:45Z

[-- Attachment #1: Type: text/plain, Size: 550 bytes --]

On Wednesday, January 19, 2005 10:04 am, David Mosberger wrote:
> Adding new routines for supporting this sounds reasonable, but I think
> it needs to be added to linux/efi.h, since EFI isn't ia64-specific.

Something like this then? Works for my test cases.

Add a new EFI memory map checking function called efi_range_is_wc for checking
if address ranges can be mapped with the WC (write coalescing) attribute.
Useful for fbmem, userspace PCI mapping, and other places where write
combining might be beneficial but unavailable.

Thanks,
Jesse

[-- Attachment #2: efi-check-wc-range-3.patch --]
[-- Type: text/plain, Size: 2365 bytes --]

===== arch/ia64/pci/pci.c 1.65 vs edited =====
--- 1.65/arch/ia64/pci/pci.c 2005-01-12 10:08:48 -08:00
+++ edited/arch/ia64/pci/pci.c 2005-01-19 11:09:32 -08:00
@@ -539,7 +539,8 @@
*/
vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);

- if (write_combine)
+ if (write_combine && efi_range_is_wc(vma->vm_start,
+ vma->vm_end - vma->vm_start))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
===== drivers/video/fbmem.c 1.148 vs edited =====
--- 1.148/drivers/video/fbmem.c 2005-01-05 15:46:41 -08:00
+++ edited/drivers/video/fbmem.c 2005-01-19 13:45:35 -08:00
@@ -35,6 +35,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/device.h>
+#include <linux/efi.h>

#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
@@ -950,9 +951,14 @@
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#elif defined(__hppa__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-#elif defined(__ia64__) || defined(__arm__) || defined(__sh__) || \
+#elif defined(__arm__) || defined(__sh__) || \
defined(__m32r__)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#elif defined(__ia64)
+ if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
#else
#warning What do we have to do here??
#endif
===== include/linux/efi.h 1.12 vs edited =====
--- 1.12/include/linux/efi.h 2004-11-18 23:03:10 -08:00
+++ edited/include/linux/efi.h 2005-01-19 13:41:44 -08:00
@@ -305,6 +305,27 @@
extern int __init efi_set_rtc_mmss(unsigned long nowtime);
extern struct efi_memory_map memmap;

+/**
+ * efi_range_is_wc - check the WC bit on an address range
+ * @start: starting kvirt address
+ * @len: length of range
+ *
+ * Consult the EFI memory map and make sure it's ok to set this range WC.
+ * Returns true or false.
+ */
+static inline int efi_range_is_wc(unsigned long start, unsigned long len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ unsigned long paddr = __pa(start + i);
+ if (!(efi_mem_attributes(paddr) & EFI_MEMORY_WC))
+ return 0;
+ }
+ /* The range checked out */
+ return 1;
+}
+
#ifdef CONFIG_EFI_PCDP
extern int __init efi_setup_pcdp_console(char *);
#endif