All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] minios: add ioremap/iounmap
@ 2009-02-19 18:04 Rolf Neugebauer
  2009-02-24  0:44 ` Samuel Thibault
  2009-03-02 10:27 ` [PATCH 1/3] minios: add ioremap/iounmap [resend] Rolf Neugebauer
  0 siblings, 2 replies; 6+ messages in thread
From: Rolf Neugebauer @ 2009-02-19 18:04 UTC (permalink / raw)
  To: Xen-devel; +Cc: samuel.thibault

Add ioremap and iounmap functions to minios. Also move some unmapping 
code from and clean up mem_test.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@netronome.com>
---
diff -r 11c2a7e44ee6 extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c	Thu Feb 19 16:38:53 2009 +0000
+++ b/extras/mini-os/arch/ia64/mm.c	Thu Feb 19 16:39:01 2009 +0000
@@ -156,6 +156,12 @@
  	return (void*) __va(frames[0] << PAGE_SHIFT);
  }

+int unmap_frames(unsigned long virt_addr, unsigned long num_frames)
+{
+    /* TODO */
+    ASSERT(0);
+}
+
  void arch_init_p2m(unsigned long max_pfn)
  {
      printk("Warn: p2m map not implemented.\n");
diff -r 11c2a7e44ee6 extras/mini-os/arch/x86/ioremap.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/arch/x86/ioremap.c	Thu Feb 19 16:39:01 2009 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009,  Netronome Systems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person 
obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without 
limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or
+ * sell copies of the Software, and to permit persons to whom the 
Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be 
included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <types.h>
+#include <lib.h>
+#include <xmalloc.h>
+#include <mm.h>
+#include <ioremap.h>
+
+/* Map a physical address range into virtual address space with provided
+ * flags. Return a virtual address range it is mapped to. */
+static void *__do_ioremap(unsigned long phys_addr, unsigned long size,
+                          unsigned long prot)
+{
+    unsigned long va;
+    unsigned long *mfns, mfn;
+    unsigned long num_pages, offset;
+    int i;
+
+    /* allow non page aligned addresses but for mapping we need to 
align them */
+    offset = (phys_addr & ~PAGE_MASK);
+    num_pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
+    phys_addr &= PAGE_MASK;
+    mfn = phys_addr >> PAGE_SHIFT;
+
+    /* create a list of MFNs to map */
+    mfns = xmalloc_array(unsigned long, num_pages);
+    for ( i = 0; i < num_pages; i++, mfn++ )
+    {
+        if ( mfn_is_ram(mfn) )
+        {
+            printk("ioremap: mfn 0x%ulx is RAM\n", mfn);
+            goto mfn_invalid;
+        }
+
+        mfns[i] = mfn;
+    }
+    va = (unsigned long)map_frames_ex(mfns, num_pages, 1, 0, 1,
+                                      DOMID_IO, 0, prot);
+    return (void *)(va + offset);
+
+
+mfn_invalid:
+    xfree(mfns);
+    return NULL;
+}
+
+void *ioremap(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT);
+}
+
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT_NOCACHE);
+}
+
+/* Un-map the io-remapped region. Currently no list of existing mappings is
+ * maintained, so the caller has to supply the size */
+void iounmap(void *virt_addr, unsigned long size)
+{
+    unsigned long num_pages;
+    unsigned long va = (unsigned long)virt_addr;
+
+    /* work out number of frames to unmap */
+    num_pages = ((va & ~PAGE_MASK) + size + PAGE_SIZE - 1) / PAGE_SIZE;
+
+    unmap_frames(va & PAGE_MASK, num_pages);
+}
+
+
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 11c2a7e44ee6 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c	Thu Feb 19 16:38:53 2009 +0000
+++ b/extras/mini-os/arch/x86/mm.c	Thu Feb 19 16:39:01 2009 +0000
@@ -316,31 +316,60 @@
      }
  }

-void mem_test(unsigned long *start_add, unsigned long *end_add)
+/*
+ * A useful mem testing function. Write the address to every address in the
+ * range provided and read back the value. If verbose, print page walk to
+ * some VA
+ *
+ * If we get MEM_TEST_MAX_ERRORS we might as well stop
+ */
+#define MEM_TEST_MAX_ERRORS 10
+int mem_test(unsigned long *start_va, unsigned long *end_va, int verbose)
  {
      unsigned long mask = 0x10000;
      unsigned long *pointer;
-
-    for(pointer = start_add; pointer < end_add; pointer++)
+    int error_count = 0;
+
+    /* write values and print page walks */
+    if ( verbose && (((unsigned long)start_va) & 0xfffff) )
      {
-        if(!(((unsigned long)pointer) & 0xfffff))
+        printk("MemTest Start: 0x%lx\n", start_va);
+        page_walk((unsigned long)start_va);
+    }
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( verbose && !(((unsigned long)pointer) & 0xfffff) )
          {
              printk("Writing to %lx\n", pointer);
              page_walk((unsigned long)pointer);
          }
          *pointer = (unsigned long)pointer & ~mask;
      }
+    if ( verbose && (((unsigned long)end_va) & 0xfffff) )
+    {
+        printk("MemTest End: %lx\n", end_va-1);
+        page_walk((unsigned long)end_va-1);
+    }
+
+    /* verify values */
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( ((unsigned long)pointer & ~mask) != *pointer )
+        {
+            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
+                   (unsigned long)pointer, *pointer,
+                   ((unsigned long)pointer & ~mask));
+            error_count++;
+            if ( error_count >= MEM_TEST_MAX_ERRORS )
+            {
+                printk("mem_test: too many errors\n");
+                return -1;
+            }
+        }
+    }
+    return 0;
+}

-    for(pointer = start_add; pointer < end_add; pointer++)
-    {
-        if(((unsigned long)pointer & ~mask) != *pointer)
-            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
-                (unsigned long)pointer,
-                *pointer,
-                ((unsigned long)pointer & ~mask));
-    }
-
-}

  static pgentry_t *get_pgt(unsigned long addr)
  {
@@ -537,6 +566,72 @@
      return (void *)addr;
  }

+/*
+ * Unmap nun_frames frames mapped at virtual address va.
+ */
+#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
+int unmap_frames(unsigned long va, unsigned long num_frames)
+{
+    int n = UNMAP_BATCH;
+    multicall_entry_t call[n];
+    int ret;
+    int i;
+
+    ASSERT(!((unsigned long)va & ~PAGE_MASK));
+
+    DEBUG("va=%p, num=0x%lx\n", va, num_frames);
+
+    while ( num_frames ) {
+        if ( n > num_frames )
+            n = num_frames;
+
+        for ( i = 0; i < n; i++ )
+        {
+            int arg = 0;
+            /* simply update the PTE for the VA and invalidate TLB */
+            call[i].op = __HYPERVISOR_update_va_mapping;
+            call[i].args[arg++] = va;
+            call[i].args[arg++] = 0;
+#ifdef __i386__
+            call[i].args[arg++] = 0;
+#endif
+            call[i].args[arg++] = UVMF_INVLPG;
+
+            va += PAGE_SIZE;
+        }
+
+        ret = HYPERVISOR_multicall(call, n);
+        if ( ret )
+        {
+            printk("update_va_mapping hypercall failed with rc=%d.\n", 
ret);
+            return -ret;
+        }
+
+        for ( i = 0; i < n; i++ )
+        {
+            if ( call[i].result )
+            {
+                printk("update_va_mapping failed for with rc=%d.\n", ret);
+                return -(call[i].result);
+            }
+        }
+        num_frames -= n;
+    }
+    return 0;
+}
+
+/*
+ * Check if a given MFN refers to real memory
+ */
+static long system_ram_end_mfn;
+int mfn_is_ram(unsigned long mfn)
+{
+    /* very crude check if a given MFN is memory or not. Probably should
+     * make this a little more sophisticated ;) */
+    return (mfn <= system_ram_end_mfn) ? 1 : 0;
+}
+
+
  static void clear_bootstrap(void)
  {
      pte_t nullpte = { };
@@ -625,6 +720,10 @@
      clear_bootstrap();
      set_readonly(&_text, &_erodata);

+    /* get the number of physical pages the system has. Used to check for
+     * system memory. */
+    system_ram_end_mfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, 
NULL);
+
      *start_pfn_p = start_pfn;
      *max_pfn_p = max_pfn;
  }
diff -r 11c2a7e44ee6 extras/mini-os/include/ioremap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/ioremap.h	Thu Feb 19 16:39:01 2009 +0000
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2009 Netronome Systems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person 
obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without 
limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or
+ * sell copies of the Software, and to permit persons to whom the 
Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be 
included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _IOREMAP_H_
+#define _IOREMAP_H_
+
+/* Maybe these should be defined in the respective arch_mm.h */
+#if defined(__i386__) || defined(__x86_64__)
+#define IO_PROT (L1_PROT)
+#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
+#elif defined(__ia64__)
+/* XXX IA64 needs to define these as appropriate. */
+#define IO_PROT 0
+#define IO_PROT_NOCACHE 0
+#else
+#error "Unsupported architecture"
+#endif
+
+void *ioremap(unsigned long phys_addr, unsigned long size);
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+void iounmap(void *virt_addr, unsigned long size);
+
+#endif /* _IOREMAP_H_ */
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 11c2a7e44ee6 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h	Thu Feb 19 16:38:53 2009 +0000
+++ b/extras/mini-os/include/mm.h	Thu Feb 19 16:39:01 2009 +0000
@@ -71,6 +71,7 @@
  void do_map_frames(unsigned long addr,
          unsigned long *f, unsigned long n, unsigned long stride,
  	unsigned long increment, domid_t id, int may_fail, unsigned long prot);
+int unmap_frames(unsigned long va, unsigned long num_frames);
  #ifdef HAVE_LIBC
  extern unsigned long heap, brk, heap_mapped, heap_end;
  #endif
diff -r 11c2a7e44ee6 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h	Thu Feb 19 16:38:53 2009 +0000
+++ b/extras/mini-os/include/x86/arch_mm.h	Thu Feb 19 16:39:01 2009 +0000
@@ -222,5 +222,6 @@
  #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, 
DOMID_SELF, 0, L1_PROT_RO)

  pgentry_t *need_pgt(unsigned long addr);
+int mfn_is_ram(unsigned long mfn);

  #endif /* _ARCH_MM_H_ */
diff -r 11c2a7e44ee6 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c	Thu Feb 19 16:38:53 2009 +0000
+++ b/extras/mini-os/lib/sys.c	Thu Feb 19 16:39:01 2009 +0000
@@ -1206,47 +1206,15 @@
      } else ASSERT(0);
  }

-#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
  int munmap(void *start, size_t length)
  {
      int total = length / PAGE_SIZE;
-    ASSERT(!((unsigned long)start & ~PAGE_MASK));
-    while (total) {
-        int n = UNMAP_BATCH;
-        if (n > total)
-            n = total;
-        {
-            int i;
-            multicall_entry_t call[n];
-            unsigned char (*data)[PAGE_SIZE] = start;
-            int ret;
+    int ret;

-            for (i = 0; i < n; i++) {
-                int arg = 0;
-                call[i].op = __HYPERVISOR_update_va_mapping;
-                call[i].args[arg++] = (unsigned long) &data[i];
-                call[i].args[arg++] = 0;
-#ifdef __i386__
-                call[i].args[arg++] = 0;
-#endif
-                call[i].args[arg++] = UVMF_INVLPG;
-            }
-
-            ret = HYPERVISOR_multicall(call, n);
-            if (ret) {
-                errno = -ret;
-                return -1;
-            }
-
-            for (i = 0; i < n; i++) {
-                if (call[i].result) {
-                    errno = call[i].result;
-                    return -1;
-                }
-            }
-        }
-        start = (char *)start + n * PAGE_SIZE;
-        total -= n;
+    ret = unmap_frames((unsigned long)start, (unsigned long)total);
+    if (ret) {
+        errno = ret;
+        return -1;
      }
      return 0;
  }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] minios: add ioremap/iounmap
  2009-02-19 18:04 [PATCH 1/3] minios: add ioremap/iounmap Rolf Neugebauer
@ 2009-02-24  0:44 ` Samuel Thibault
  2009-02-24 11:48   ` Rolf Neugebauer
  2009-03-02 10:27 ` [PATCH 1/3] minios: add ioremap/iounmap [resend] Rolf Neugebauer
  1 sibling, 1 reply; 6+ messages in thread
From: Samuel Thibault @ 2009-02-24  0:44 UTC (permalink / raw)
  To: Rolf Neugebauer; +Cc: Xen-devel

Rolf Neugebauer, le Thu 19 Feb 2009 18:04:41 +0000, a écrit :
> + *
> + * Permission is hereby granted, free of charge, to any person 
> obtaining a copy

The lines of the patch got wrapped.

> +    /* create a list of MFNs to map */
> +    mfns = xmalloc_array(unsigned long, num_pages);
> +    for ( i = 0; i < num_pages; i++, mfn++ )
> +    {
> +        if ( mfn_is_ram(mfn) )
> +        {
> +            printk("ioremap: mfn 0x%ulx is RAM\n", mfn);
> +            goto mfn_invalid;
> +        }
> +
> +        mfns[i] = mfn;
> +    }
> +    va = (unsigned long)map_frames_ex(mfns, num_pages, 1, 0, 1,
> +                                      DOMID_IO, 0, prot);

Instead of allocating an array, why not using the incr parameter of
map_frames_ex?

> +/* Maybe these should be defined in the respective arch_mm.h */
> +#if defined(__i386__) || defined(__x86_64__)
> +#define IO_PROT (L1_PROT)
> +#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
> +#elif defined(__ia64__)
> +/* XXX IA64 needs to define these as appropriate. */
> +#define IO_PROT 0
> +#define IO_PROT_NOCACHE 0
> +#else
> +#error "Unsupported architecture"
> +#endif

Shouldn't these go to include/<arch>/arch_mm.h?

Samuel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] minios: add ioremap/iounmap
  2009-02-24  0:44 ` Samuel Thibault
@ 2009-02-24 11:48   ` Rolf Neugebauer
  2009-02-24 12:02     ` Samuel Thibault
  2009-03-01 14:44     ` Keir Fraser
  0 siblings, 2 replies; 6+ messages in thread
From: Rolf Neugebauer @ 2009-02-24 11:48 UTC (permalink / raw)
  To: Samuel Thibault, Rolf Neugebauer, Xen-devel



Samuel Thibault wrote:
> Rolf Neugebauer, le Thu 19 Feb 2009 18:04:41 +0000, a écrit :
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a copy
> 
> The lines of the patch got wrapped.
> 
>> +    /* create a list of MFNs to map */
>> +    mfns = xmalloc_array(unsigned long, num_pages);
>> +    for ( i = 0; i < num_pages; i++, mfn++ )
>> +    {
>> +        if ( mfn_is_ram(mfn) )
>> +        {
>> +            printk("ioremap: mfn 0x%ulx is RAM\n", mfn);
>> +            goto mfn_invalid;
>> +        }
>> +
>> +        mfns[i] = mfn;
>> +    }
>> +    va = (unsigned long)map_frames_ex(mfns, num_pages, 1, 0, 1,
>> +                                      DOMID_IO, 0, prot);
> 
> Instead of allocating an array, why not using the incr parameter of
> map_frames_ex?
> 
>> +/* Maybe these should be defined in the respective arch_mm.h */
>> +#if defined(__i386__) || defined(__x86_64__)
>> +#define IO_PROT (L1_PROT)
>> +#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
>> +#elif defined(__ia64__)
>> +/* XXX IA64 needs to define these as appropriate. */
>> +#define IO_PROT 0
>> +#define IO_PROT_NOCACHE 0
>> +#else
>> +#error "Unsupported architecture"
>> +#endif
> 
> Shouldn't these go to include/<arch>/arch_mm.h?
> 
> Samuel

Thanks for your comments. An updated patch is
attached (hopefully without my mailer wrapping the line)

rolf

Add ioremap and iounmap functions to minios. Also move some unmapping
code from and clean up mem_test.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@netronome.com>
---
diff -r 13688a8401c1 extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/arch/ia64/mm.c	Tue Feb 24 10:58:46 2009 +0000
@@ -156,6 +156,12 @@
  	return (void*) __va(frames[0] << PAGE_SHIFT);
  }

+int unmap_frames(unsigned long virt_addr, unsigned long num_frames)
+{
+    /* TODO */
+    ASSERT(0);
+}
+
  void arch_init_p2m(unsigned long max_pfn)
  {
      printk("Warn: p2m map not implemented.\n");
diff -r 13688a8401c1 extras/mini-os/arch/x86/ioremap.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/arch/x86/ioremap.c	Tue Feb 24 10:58:46 2009 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009,  Netronome Systems, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person 
obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without 
limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or
+ * sell copies of the Software, and to permit persons to whom the 
Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be 
included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <types.h>
+#include <lib.h>
+#include <xmalloc.h>
+#include <mm.h>
+#include <ioremap.h>
+
+/* Map a physical address range into virtual address space with provided
+ * flags. Return a virtual address range it is mapped to. */
+static void *__do_ioremap(unsigned long phys_addr, unsigned long size,
+                          unsigned long prot)
+{
+    unsigned long va;
+    unsigned long mfns, mfn;
+    unsigned long num_pages, offset;
+    int i;
+
+    /* allow non page aligned addresses but for mapping we need to 
align them */
+    offset = (phys_addr & ~PAGE_MASK);
+    num_pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
+    phys_addr &= PAGE_MASK;
+    mfns = mfn = phys_addr >> PAGE_SHIFT;
+
+    /* sanity checks on list of MFNs */
+    for ( i = 0; i < num_pages; i++, mfn++ )
+    {
+        if ( mfn_is_ram(mfn) )
+        {
+            printk("ioremap: mfn 0x%ulx is RAM\n", mfn);
+            goto mfn_invalid;
+        }
+    }
+    va = (unsigned long)map_frames_ex(&mfns, num_pages, 0, 1, 1,
+                                      DOMID_IO, 0, prot);
+    return (void *)(va + offset);
+
+mfn_invalid:
+    return NULL;
+}
+
+void *ioremap(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT);
+}
+
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT_NOCACHE);
+}
+
+/* Un-map the io-remapped region. Currently no list of existing mappings is
+ * maintained, so the caller has to supply the size */
+void iounmap(void *virt_addr, unsigned long size)
+{
+    unsigned long num_pages;
+    unsigned long va = (unsigned long)virt_addr;
+
+    /* work out number of frames to unmap */
+    num_pages = ((va & ~PAGE_MASK) + size + PAGE_SIZE - 1) / PAGE_SIZE;
+
+    unmap_frames(va & PAGE_MASK, num_pages);
+}
+
+
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 13688a8401c1 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/arch/x86/mm.c	Tue Feb 24 10:58:46 2009 +0000
@@ -316,31 +316,60 @@
      }
  }

-void mem_test(unsigned long *start_add, unsigned long *end_add)
+/*
+ * A useful mem testing function. Write the address to every address in the
+ * range provided and read back the value. If verbose, print page walk to
+ * some VA
+ *
+ * If we get MEM_TEST_MAX_ERRORS we might as well stop
+ */
+#define MEM_TEST_MAX_ERRORS 10
+int mem_test(unsigned long *start_va, unsigned long *end_va, int verbose)
  {
      unsigned long mask = 0x10000;
      unsigned long *pointer;
-
-    for(pointer = start_add; pointer < end_add; pointer++)
+    int error_count = 0;
+
+    /* write values and print page walks */
+    if ( verbose && (((unsigned long)start_va) & 0xfffff) )
      {
-        if(!(((unsigned long)pointer) & 0xfffff))
+        printk("MemTest Start: 0x%lx\n", start_va);
+        page_walk((unsigned long)start_va);
+    }
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( verbose && !(((unsigned long)pointer) & 0xfffff) )
          {
              printk("Writing to %lx\n", pointer);
              page_walk((unsigned long)pointer);
          }
          *pointer = (unsigned long)pointer & ~mask;
      }
+    if ( verbose && (((unsigned long)end_va) & 0xfffff) )
+    {
+        printk("MemTest End: %lx\n", end_va-1);
+        page_walk((unsigned long)end_va-1);
+    }
+
+    /* verify values */
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( ((unsigned long)pointer & ~mask) != *pointer )
+        {
+            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
+                   (unsigned long)pointer, *pointer,
+                   ((unsigned long)pointer & ~mask));
+            error_count++;
+            if ( error_count >= MEM_TEST_MAX_ERRORS )
+            {
+                printk("mem_test: too many errors\n");
+                return -1;
+            }
+        }
+    }
+    return 0;
+}

-    for(pointer = start_add; pointer < end_add; pointer++)
-    {
-        if(((unsigned long)pointer & ~mask) != *pointer)
-            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
-                (unsigned long)pointer,
-                *pointer,
-                ((unsigned long)pointer & ~mask));
-    }
-
-}

  static pgentry_t *get_pgt(unsigned long addr)
  {
@@ -537,6 +566,72 @@
      return (void *)addr;
  }

+/*
+ * Unmap nun_frames frames mapped at virtual address va.
+ */
+#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
+int unmap_frames(unsigned long va, unsigned long num_frames)
+{
+    int n = UNMAP_BATCH;
+    multicall_entry_t call[n];
+    int ret;
+    int i;
+
+    ASSERT(!((unsigned long)va & ~PAGE_MASK));
+
+    DEBUG("va=%p, num=0x%lx\n", va, num_frames);
+
+    while ( num_frames ) {
+        if ( n > num_frames )
+            n = num_frames;
+
+        for ( i = 0; i < n; i++ )
+        {
+            int arg = 0;
+            /* simply update the PTE for the VA and invalidate TLB */
+            call[i].op = __HYPERVISOR_update_va_mapping;
+            call[i].args[arg++] = va;
+            call[i].args[arg++] = 0;
+#ifdef __i386__
+            call[i].args[arg++] = 0;
+#endif
+            call[i].args[arg++] = UVMF_INVLPG;
+
+            va += PAGE_SIZE;
+        }
+
+        ret = HYPERVISOR_multicall(call, n);
+        if ( ret )
+        {
+            printk("update_va_mapping hypercall failed with rc=%d.\n", 
ret);
+            return -ret;
+        }
+
+        for ( i = 0; i < n; i++ )
+        {
+            if ( call[i].result )
+            {
+                printk("update_va_mapping failed for with rc=%d.\n", ret);
+                return -(call[i].result);
+            }
+        }
+        num_frames -= n;
+    }
+    return 0;
+}
+
+/*
+ * Check if a given MFN refers to real memory
+ */
+static long system_ram_end_mfn;
+int mfn_is_ram(unsigned long mfn)
+{
+    /* very crude check if a given MFN is memory or not. Probably should
+     * make this a little more sophisticated ;) */
+    return (mfn <= system_ram_end_mfn) ? 1 : 0;
+}
+
+
  static void clear_bootstrap(void)
  {
      pte_t nullpte = { };
@@ -625,6 +720,10 @@
      clear_bootstrap();
      set_readonly(&_text, &_erodata);

+    /* get the number of physical pages the system has. Used to check for
+     * system memory. */
+    system_ram_end_mfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, 
NULL);
+
      *start_pfn_p = start_pfn;
      *max_pfn_p = max_pfn;
  }
diff -r 13688a8401c1 extras/mini-os/include/ioremap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/ioremap.h	Tue Feb 24 10:58:46 2009 +0000
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2009 Netronome Systems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person 
obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without 
limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or
+ * sell copies of the Software, and to permit persons to whom the 
Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be 
included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _IOREMAP_H_
+#define _IOREMAP_H_
+
+void *ioremap(unsigned long phys_addr, unsigned long size);
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+void iounmap(void *virt_addr, unsigned long size);
+
+#endif /* _IOREMAP_H_ */
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 13688a8401c1 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/include/mm.h	Tue Feb 24 10:58:46 2009 +0000
@@ -71,6 +71,7 @@
  void do_map_frames(unsigned long addr,
          unsigned long *f, unsigned long n, unsigned long stride,
  	unsigned long increment, domid_t id, int may_fail, unsigned long prot);
+int unmap_frames(unsigned long va, unsigned long num_frames);
  #ifdef HAVE_LIBC
  extern unsigned long heap, brk, heap_mapped, heap_end;
  #endif
diff -r 13688a8401c1 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/include/x86/arch_mm.h	Tue Feb 24 10:58:46 2009 +0000
@@ -133,6 +133,10 @@
  #define L4_PROT 
(_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
  #endif /* __i386__ || __x86_64__ */

+/* flags for ioremap */
+#define IO_PROT (L1_PROT)
+#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
+
  #include "arch_limits.h"
  #define PAGE_SIZE       __PAGE_SIZE
  #define PAGE_SHIFT      __PAGE_SHIFT
@@ -222,5 +226,6 @@
  #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, 
DOMID_SELF, 0, L1_PROT_RO)

  pgentry_t *need_pgt(unsigned long addr);
+int mfn_is_ram(unsigned long mfn);

  #endif /* _ARCH_MM_H_ */
diff -r 13688a8401c1 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/lib/sys.c	Tue Feb 24 10:58:46 2009 +0000
@@ -1206,47 +1206,15 @@
      } else ASSERT(0);
  }

-#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
  int munmap(void *start, size_t length)
  {
      int total = length / PAGE_SIZE;
-    ASSERT(!((unsigned long)start & ~PAGE_MASK));
-    while (total) {
-        int n = UNMAP_BATCH;
-        if (n > total)
-            n = total;
-        {
-            int i;
-            multicall_entry_t call[n];
-            unsigned char (*data)[PAGE_SIZE] = start;
-            int ret;
+    int ret;

-            for (i = 0; i < n; i++) {
-                int arg = 0;
-                call[i].op = __HYPERVISOR_update_va_mapping;
-                call[i].args[arg++] = (unsigned long) &data[i];
-                call[i].args[arg++] = 0;
-#ifdef __i386__
-                call[i].args[arg++] = 0;
-#endif
-                call[i].args[arg++] = UVMF_INVLPG;
-            }
-
-            ret = HYPERVISOR_multicall(call, n);
-            if (ret) {
-                errno = -ret;
-                return -1;
-            }
-
-            for (i = 0; i < n; i++) {
-                if (call[i].result) {
-                    errno = call[i].result;
-                    return -1;
-                }
-            }
-        }
-        start = (char *)start + n * PAGE_SIZE;
-        total -= n;
+    ret = unmap_frames((unsigned long)start, (unsigned long)total);
+    if (ret) {
+        errno = ret;
+        return -1;
      }
      return 0;
  }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] minios: add ioremap/iounmap
  2009-02-24 11:48   ` Rolf Neugebauer
@ 2009-02-24 12:02     ` Samuel Thibault
  2009-03-01 14:44     ` Keir Fraser
  1 sibling, 0 replies; 6+ messages in thread
From: Samuel Thibault @ 2009-02-24 12:02 UTC (permalink / raw)
  To: Rolf Neugebauer; +Cc: Xen-devel

Rolf Neugebauer, le Tue 24 Feb 2009 11:48:42 +0000, a écrit :
> hopefully without my mailer wrapping the line

failed :)

> Add ioremap and iounmap functions to minios. Also move some unmapping
> code from and clean up mem_test.
> 
> Signed-off-by: Rolf Neugebauer <rolf.neugebauer@netronome.com>

Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re: [PATCH 1/3] minios: add ioremap/iounmap
  2009-02-24 11:48   ` Rolf Neugebauer
  2009-02-24 12:02     ` Samuel Thibault
@ 2009-03-01 14:44     ` Keir Fraser
  1 sibling, 0 replies; 6+ messages in thread
From: Keir Fraser @ 2009-03-01 14:44 UTC (permalink / raw)
  To: Rolf Neugebauer, Samuel Thibault, Xen-devel

On 24/02/2009 11:48, "Rolf Neugebauer" <rolf.neugebauer@netronome.com>
wrote:

> Thanks for your comments. An updated patch is
> attached (hopefully without my mailer wrapping the line)
> 
> rolf
> 
> Add ioremap and iounmap functions to minios. Also move some unmapping
> code from and clean up mem_test.

This patch still has line wraps and so still does not apply. In fact all
your patches have line wraps, so I threw them all away. Please re-send as
attachments, each with changeset comment and sign-off and Samuel's acked-by.

 -- Keir

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] minios: add ioremap/iounmap [resend]
  2009-02-19 18:04 [PATCH 1/3] minios: add ioremap/iounmap Rolf Neugebauer
  2009-02-24  0:44 ` Samuel Thibault
@ 2009-03-02 10:27 ` Rolf Neugebauer
  1 sibling, 0 replies; 6+ messages in thread
From: Rolf Neugebauer @ 2009-03-02 10:27 UTC (permalink / raw)
  To: Xen-devel

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

Add ioremap and iounmap functions to minios. Also move some unmapping 
code from and clean up mem_test.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@netronome.com>
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---

[-- Attachment #2: minios-ioremap.patch --]
[-- Type: text/x-patch, Size: 13078 bytes --]

diff -r 13688a8401c1 extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/arch/ia64/mm.c	Tue Feb 24 10:58:46 2009 +0000
@@ -156,6 +156,12 @@
 	return (void*) __va(frames[0] << PAGE_SHIFT);
 }
 
+int unmap_frames(unsigned long virt_addr, unsigned long num_frames)
+{  
+    /* TODO */
+    ASSERT(0);
+}
+
 void arch_init_p2m(unsigned long max_pfn)
 {
     printk("Warn: p2m map not implemented.\n");
diff -r 13688a8401c1 extras/mini-os/arch/x86/ioremap.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/arch/x86/ioremap.c	Tue Feb 24 10:58:46 2009 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009,  Netronome Systems, Inc.
+ *                
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <types.h>
+#include <lib.h>
+#include <xmalloc.h>
+#include <mm.h>
+#include <ioremap.h>
+
+/* Map a physical address range into virtual address space with provided
+ * flags. Return a virtual address range it is mapped to. */
+static void *__do_ioremap(unsigned long phys_addr, unsigned long size, 
+                          unsigned long prot)
+{
+    unsigned long va;
+    unsigned long mfns, mfn;
+    unsigned long num_pages, offset;
+    int i;
+
+    /* allow non page aligned addresses but for mapping we need to align them */
+    offset = (phys_addr & ~PAGE_MASK);
+    num_pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
+    phys_addr &= PAGE_MASK;
+    mfns = mfn = phys_addr >> PAGE_SHIFT;
+    
+    /* sanity checks on list of MFNs */
+    for ( i = 0; i < num_pages; i++, mfn++ )
+    {
+        if ( mfn_is_ram(mfn) )
+        {
+            printk("ioremap: mfn 0x%ulx is RAM\n", mfn);
+            goto mfn_invalid;
+        }
+    }   
+    va = (unsigned long)map_frames_ex(&mfns, num_pages, 0, 1, 1,
+                                      DOMID_IO, 0, prot);
+    return (void *)(va + offset);
+    
+mfn_invalid:
+    return NULL;
+}
+
+void *ioremap(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT);
+}
+
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+{
+    return __do_ioremap(phys_addr, size, IO_PROT_NOCACHE);
+}
+
+/* Un-map the io-remapped region. Currently no list of existing mappings is
+ * maintained, so the caller has to supply the size */
+void iounmap(void *virt_addr, unsigned long size)
+{   
+    unsigned long num_pages;
+    unsigned long va = (unsigned long)virt_addr;
+
+    /* work out number of frames to unmap */
+    num_pages = ((va & ~PAGE_MASK) + size + PAGE_SIZE - 1) / PAGE_SIZE;
+
+    unmap_frames(va & PAGE_MASK, num_pages);
+}
+
+
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 13688a8401c1 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/arch/x86/mm.c	Tue Feb 24 10:58:46 2009 +0000
@@ -316,31 +316,60 @@
     }
 }
 
-void mem_test(unsigned long *start_add, unsigned long *end_add)
+/*
+ * A useful mem testing function. Write the address to every address in the
+ * range provided and read back the value. If verbose, print page walk to
+ * some VA
+ * 
+ * If we get MEM_TEST_MAX_ERRORS we might as well stop
+ */
+#define MEM_TEST_MAX_ERRORS 10 
+int mem_test(unsigned long *start_va, unsigned long *end_va, int verbose)
 {
     unsigned long mask = 0x10000;
     unsigned long *pointer;
-
-    for(pointer = start_add; pointer < end_add; pointer++)
+    int error_count = 0;
+ 
+    /* write values and print page walks */
+    if ( verbose && (((unsigned long)start_va) & 0xfffff) )
     {
-        if(!(((unsigned long)pointer) & 0xfffff))
+        printk("MemTest Start: 0x%lx\n", start_va);
+        page_walk((unsigned long)start_va);
+    }
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( verbose && !(((unsigned long)pointer) & 0xfffff) )
         {
             printk("Writing to %lx\n", pointer);
             page_walk((unsigned long)pointer);
         }
         *pointer = (unsigned long)pointer & ~mask;
     }
+    if ( verbose && (((unsigned long)end_va) & 0xfffff) )
+    {
+        printk("MemTest End: %lx\n", end_va-1);
+        page_walk((unsigned long)end_va-1);
+    }
+ 
+    /* verify values */
+    for ( pointer = start_va; pointer < end_va; pointer++ )
+    {
+        if ( ((unsigned long)pointer & ~mask) != *pointer )
+        {
+            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
+                   (unsigned long)pointer, *pointer, 
+                   ((unsigned long)pointer & ~mask));
+            error_count++;
+            if ( error_count >= MEM_TEST_MAX_ERRORS )
+            {
+                printk("mem_test: too many errors\n");
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
 
-    for(pointer = start_add; pointer < end_add; pointer++)
-    {
-        if(((unsigned long)pointer & ~mask) != *pointer)
-            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
-                (unsigned long)pointer, 
-                *pointer, 
-                ((unsigned long)pointer & ~mask));
-    }
-
-}
 
 static pgentry_t *get_pgt(unsigned long addr)
 {
@@ -537,6 +566,72 @@
     return (void *)addr;
 }
 
+/*
+ * Unmap nun_frames frames mapped at virtual address va.
+ */
+#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
+int unmap_frames(unsigned long va, unsigned long num_frames)
+{
+    int n = UNMAP_BATCH;
+    multicall_entry_t call[n];
+    int ret;
+    int i;
+
+    ASSERT(!((unsigned long)va & ~PAGE_MASK));
+
+    DEBUG("va=%p, num=0x%lx\n", va, num_frames);
+
+    while ( num_frames ) {
+        if ( n > num_frames )
+            n = num_frames;
+
+        for ( i = 0; i < n; i++ )
+        {
+            int arg = 0;
+            /* simply update the PTE for the VA and invalidate TLB */
+            call[i].op = __HYPERVISOR_update_va_mapping;
+            call[i].args[arg++] = va;
+            call[i].args[arg++] = 0;
+#ifdef __i386__
+            call[i].args[arg++] = 0;
+#endif  
+            call[i].args[arg++] = UVMF_INVLPG;
+
+            va += PAGE_SIZE;
+        }
+
+        ret = HYPERVISOR_multicall(call, n);
+        if ( ret )
+        {
+            printk("update_va_mapping hypercall failed with rc=%d.\n", ret);
+            return -ret;
+        }
+
+        for ( i = 0; i < n; i++ )
+        {
+            if ( call[i].result ) 
+            {
+                printk("update_va_mapping failed for with rc=%d.\n", ret);
+                return -(call[i].result);
+            }
+        }
+        num_frames -= n;
+    }
+    return 0;
+}
+
+/*
+ * Check if a given MFN refers to real memory
+ */
+static long system_ram_end_mfn;
+int mfn_is_ram(unsigned long mfn)
+{
+    /* very crude check if a given MFN is memory or not. Probably should
+     * make this a little more sophisticated ;) */
+    return (mfn <= system_ram_end_mfn) ? 1 : 0;
+}
+
+
 static void clear_bootstrap(void)
 {
     pte_t nullpte = { };
@@ -625,6 +720,10 @@
     clear_bootstrap();
     set_readonly(&_text, &_erodata);
 
+    /* get the number of physical pages the system has. Used to check for
+     * system memory. */
+    system_ram_end_mfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
+
     *start_pfn_p = start_pfn;
     *max_pfn_p = max_pfn;
 }
diff -r 13688a8401c1 extras/mini-os/include/ioremap.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/ioremap.h	Tue Feb 24 10:58:46 2009 +0000
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2009 Netronome Systems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _IOREMAP_H_
+#define _IOREMAP_H_
+
+void *ioremap(unsigned long phys_addr, unsigned long size);
+void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+void iounmap(void *virt_addr, unsigned long size);
+
+#endif /* _IOREMAP_H_ */
+
+/* -*-  Mode:C; c-basic-offset:4; tab-width:4 indent-tabs-mode:nil -*- */
diff -r 13688a8401c1 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/include/mm.h	Tue Feb 24 10:58:46 2009 +0000
@@ -71,6 +71,7 @@
 void do_map_frames(unsigned long addr,
         unsigned long *f, unsigned long n, unsigned long stride,
 	unsigned long increment, domid_t id, int may_fail, unsigned long prot);
+int unmap_frames(unsigned long va, unsigned long num_frames);
 #ifdef HAVE_LIBC
 extern unsigned long heap, brk, heap_mapped, heap_end;
 #endif
diff -r 13688a8401c1 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/include/x86/arch_mm.h	Tue Feb 24 10:58:46 2009 +0000
@@ -133,6 +133,10 @@
 #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 #endif /* __i386__ || __x86_64__ */
 
+/* flags for ioremap */
+#define IO_PROT (L1_PROT)
+#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
+
 #include "arch_limits.h"
 #define PAGE_SIZE       __PAGE_SIZE
 #define PAGE_SHIFT      __PAGE_SHIFT
@@ -222,5 +226,6 @@
 #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO)
 
 pgentry_t *need_pgt(unsigned long addr);
+int mfn_is_ram(unsigned long mfn);
 
 #endif /* _ARCH_MM_H_ */
diff -r 13688a8401c1 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c	Thu Feb 19 17:28:28 2009 +0000
+++ b/extras/mini-os/lib/sys.c	Tue Feb 24 10:58:46 2009 +0000
@@ -1206,47 +1206,15 @@
     } else ASSERT(0);
 }
 
-#define UNMAP_BATCH ((STACK_SIZE / 2) / sizeof(multicall_entry_t))
 int munmap(void *start, size_t length)
 {
     int total = length / PAGE_SIZE;
-    ASSERT(!((unsigned long)start & ~PAGE_MASK));
-    while (total) {
-        int n = UNMAP_BATCH;
-        if (n > total)
-            n = total;
-        {
-            int i;
-            multicall_entry_t call[n];
-            unsigned char (*data)[PAGE_SIZE] = start;
-            int ret;
+    int ret;
 
-            for (i = 0; i < n; i++) {
-                int arg = 0;
-                call[i].op = __HYPERVISOR_update_va_mapping;
-                call[i].args[arg++] = (unsigned long) &data[i];
-                call[i].args[arg++] = 0;
-#ifdef __i386__
-                call[i].args[arg++] = 0;
-#endif
-                call[i].args[arg++] = UVMF_INVLPG;
-            }
-
-            ret = HYPERVISOR_multicall(call, n);
-            if (ret) {
-                errno = -ret;
-                return -1;
-            }
-
-            for (i = 0; i < n; i++) {
-                if (call[i].result) {
-                    errno = call[i].result;
-                    return -1;
-                }
-            }
-        }
-        start = (char *)start + n * PAGE_SIZE;
-        total -= n;
+    ret = unmap_frames((unsigned long)start, (unsigned long)total);
+    if (ret) {
+        errno = ret;
+        return -1;
     }
     return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-03-02 10:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-19 18:04 [PATCH 1/3] minios: add ioremap/iounmap Rolf Neugebauer
2009-02-24  0:44 ` Samuel Thibault
2009-02-24 11:48   ` Rolf Neugebauer
2009-02-24 12:02     ` Samuel Thibault
2009-03-01 14:44     ` Keir Fraser
2009-03-02 10:27 ` [PATCH 1/3] minios: add ioremap/iounmap [resend] Rolf Neugebauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.