WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] minios: add ioremap/iounmap

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: add ioremap/iounmap
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 03 Mar 2009 11:10:24 -0800
Delivery-date: Tue, 03 Mar 2009 11:11:21 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1235991059 0
# Node ID 9c4a38f70b168d1f30652f099e696fa48df4b59f
# Parent  b3774712e654ab669198630e34d7b14dd80aa125
minios: add ioremap/iounmap

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@xxxxxxxxxxxxx>
Acked-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
---
 extras/mini-os/arch/ia64/mm.c        |    6 +
 extras/mini-os/arch/x86/ioremap.c    |   88 +++++++++++++++++++++++
 extras/mini-os/arch/x86/mm.c         |  129 ++++++++++++++++++++++++++++++-----
 extras/mini-os/include/ioremap.h     |   33 ++++++++
 extras/mini-os/include/mm.h          |    1 
 extras/mini-os/include/x86/arch_mm.h |    5 +
 extras/mini-os/lib/sys.c             |   44 +----------
 7 files changed, 253 insertions(+), 53 deletions(-)

diff -r b3774712e654 -r 9c4a38f70b16 extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c     Mon Mar 02 10:34:37 2009 +0000
+++ b/extras/mini-os/arch/ia64/mm.c     Mon Mar 02 10:50:59 2009 +0000
@@ -156,6 +156,12 @@ map_frames_ex(unsigned long* frames, uns
        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 b3774712e654 -r 9c4a38f70b16 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 Mon Mar 02 10:50:59 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 b3774712e654 -r 9c4a38f70b16 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c      Mon Mar 02 10:34:37 2009 +0000
+++ b/extras/mini-os/arch/x86/mm.c      Mon Mar 02 10:50:59 2009 +0000
@@ -316,31 +316,60 @@ static void set_readonly(void *text, voi
     }
 }
 
-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++)
-    {
-        if(!(((unsigned long)pointer) & 0xfffff))
+    int error_count = 0;
+ 
+    /* write values and print page walks */
+    if ( verbose && (((unsigned long)start_va) & 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;
     }
-
-    for(pointer = start_add; pointer < end_add; pointer++)
-    {
-        if(((unsigned long)pointer & ~mask) != *pointer)
+    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));
-    }
-
-}
+                   (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;
+}
+
 
 static pgentry_t *get_pgt(unsigned long addr)
 {
@@ -537,6 +566,72 @@ void *map_frames_ex(unsigned long *f, un
     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 @@ void arch_init_mm(unsigned long* start_p
     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 b3774712e654 -r 9c4a38f70b16 extras/mini-os/include/ioremap.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/ioremap.h  Mon Mar 02 10:50:59 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 b3774712e654 -r 9c4a38f70b16 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Mon Mar 02 10:34:37 2009 +0000
+++ b/extras/mini-os/include/mm.h       Mon Mar 02 10:50:59 2009 +0000
@@ -71,6 +71,7 @@ void do_map_frames(unsigned long addr,
 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 b3774712e654 -r 9c4a38f70b16 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h      Mon Mar 02 10:34:37 2009 +0000
+++ b/extras/mini-os/include/x86/arch_mm.h      Mon Mar 02 10:50:59 2009 +0000
@@ -133,6 +133,10 @@ typedef unsigned long pgentry_t;
 #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 @@ static __inline__ paddr_t machine_to_phy
 #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 b3774712e654 -r 9c4a38f70b16 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Mon Mar 02 10:34:37 2009 +0000
+++ b/extras/mini-os/lib/sys.c  Mon Mar 02 10:50:59 2009 +0000
@@ -1206,47 +1206,15 @@ void *mmap(void *start, size_t length, i
     } 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;
-
-            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;
+    int ret;
+
+    ret = unmap_frames((unsigned long)start, (unsigned long)total);
+    if (ret) {
+        errno = ret;
+        return -1;
     }
     return 0;
 }

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: add ioremap/iounmap, Xen patchbot-unstable <=