Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch Implement bus_space_tag_create() and _destroy().



details:   https://anonhg.NetBSD.org/src/rev/58130353df87
branches:  trunk
changeset: 766999:58130353df87
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Wed Jul 06 18:46:04 2011 +0000

description:
Implement bus_space_tag_create() and _destroy().

Factor bus_space_reserve(), bus_space_release(), et cetera out of
bus_space_alloc(), bus_space_map(), bus_space_free(), bus_space_unmap(),
et cetera.

For i386 and amd64, activate the use of <machine/bus_defs.h> and
<machine/bus_funcs.h> by #defining __HAVE_NEW_STYLE_BUS_H in
their respective types.h.  While I'm here, remove unnecessary
__HAVE_DEVICE_REGISTER #defines.

diffstat:

 sys/arch/amd64/include/types.h |    4 +-
 sys/arch/i386/include/types.h  |    4 +-
 sys/arch/x86/x86/bus_space.c   |  356 +++++++++++++++++++++++++++++++++-------
 3 files changed, 292 insertions(+), 72 deletions(-)

diffs (truncated from 510 to 300 lines):

diff -r eb8c751e0629 -r 58130353df87 sys/arch/amd64/include/types.h
--- a/sys/arch/amd64/include/types.h    Wed Jul 06 18:27:31 2011 +0000
+++ b/sys/arch/amd64/include/types.h    Wed Jul 06 18:46:04 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: types.h,v 1.38 2011/06/12 03:35:38 rmind Exp $ */
+/*     $NetBSD: types.h,v 1.39 2011/07/06 18:46:04 dyoung Exp $        */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -76,7 +76,7 @@
 /* The amd64 does not have strict alignment requirements. */
 #define        __NO_STRICT_ALIGNMENT
 
-#define        __HAVE_DEVICE_REGISTER
+#define        __HAVE_NEW_STYLE_BUS_H
 #define        __HAVE_CPU_COUNTER
 #define        __HAVE_CPU_DATA_FIRST
 #define        __HAVE_MD_CPU_OFFLINE
diff -r eb8c751e0629 -r 58130353df87 sys/arch/i386/include/types.h
--- a/sys/arch/i386/include/types.h     Wed Jul 06 18:27:31 2011 +0000
+++ b/sys/arch/i386/include/types.h     Wed Jul 06 18:46:04 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: types.h,v 1.73 2011/06/12 03:35:42 rmind Exp $ */
+/*     $NetBSD: types.h,v 1.74 2011/07/06 18:46:04 dyoung Exp $        */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -101,7 +101,7 @@
 /* The x86 does not have strict alignment requirements. */
 #define        __NO_STRICT_ALIGNMENT
 
-#define        __HAVE_DEVICE_REGISTER
+#define        __HAVE_NEW_STYLE_BUS_H
 #define        __HAVE_CPU_DATA_FIRST
 #define        __HAVE_CPU_COUNTER
 #define        __HAVE_MD_CPU_OFFLINE
diff -r eb8c751e0629 -r 58130353df87 sys/arch/x86/x86/bus_space.c
--- a/sys/arch/x86/x86/bus_space.c      Wed Jul 06 18:27:31 2011 +0000
+++ b/sys/arch/x86/x86/bus_space.c      Wed Jul 06 18:46:04 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_space.c,v 1.33 2011/02/11 23:08:38 jmcneill Exp $  */
+/*     $NetBSD: bus_space.c,v 1.34 2011/07/06 18:46:04 dyoung Exp $    */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,12 +31,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.33 2011/02/11 23:08:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.34 2011/07/06 18:46:04 dyoung Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/extent.h>
+#include <sys/kmem.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -156,42 +157,58 @@
 bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
                int flags, bus_space_handle_t *bshp)
 {
+       bus_space_reservation_t bsr;
        int error;
-       struct extent *ex;
+
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_MAP) != 0) {
+               return (*t->bst_ov->ov_space_map)(t->bst_ctx, t, bpa, size,
+                   flags, bshp);
+       }
+       if (t->bst_super != NULL)
+               return bus_space_map(t->bst_super, bpa, size, flags, bshp);
+
+       error = bus_space_reserve(t, bpa, size, flags, &bsr);
+       if (error != 0)
+               return error;
+
+       error = bus_space_reservation_map(t, &bsr, flags, bshp);
+       if (error != 0)
+               bus_space_release(t, &bsr);
 
-       /*
-        * Pick the appropriate extent map.
-        */
-       if (x86_bus_space_is_io(t)) {
-               if (flags & BUS_SPACE_MAP_LINEAR)
-                       return (EOPNOTSUPP);
-               ex = ioport_ex;
-       } else if (x86_bus_space_is_mem(t))
-               ex = iomem_ex;
-       else
-               panic("x86_memio_map: bad bus space tag");
+       return error;
+}
+
+int
+bus_space_reservation_map(bus_space_tag_t t, bus_space_reservation_t *bsr,
+    int flags, bus_space_handle_t *bshp)
+{
+       bus_addr_t bpa;
+       bus_size_t size;
 
-       /*
-        * Before we go any further, let's make sure that this
-        * region is available.
-        */
-       error = extent_alloc_region(ex, bpa, size,
-           EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
-       if (error)
-               return (error);
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_RESERVATION_MAP) != 0) {
+               return (*t->bst_ov->ov_space_reservation_map)(t->bst_ctx, t,
+                   bsr, flags, bshp);
+       }
+       if (t->bst_super != NULL) {
+               return bus_space_reservation_map(t->bst_super,
+                   bsr, flags, bshp);
+       }
+
+       bpa = bus_space_reservation_addr(bsr);
+       size = bus_space_reservation_size(bsr);
 
        /*
         * For I/O space, that's all she wrote.
         */
        if (x86_bus_space_is_io(t)) {
                *bshp = bpa;
-               return (0);
+               return 0;
        }
 
 #ifndef XEN
        if (bpa >= IOM_BEGIN && (bpa + size) != 0 && (bpa + size) <= IOM_END) {
                *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa);
-               return(0);
+               return 0;
        }
 #endif /* !XEN */
 
@@ -199,17 +216,7 @@
         * For memory space, map the bus physical address to
         * a kernel virtual address.
         */
-       error = x86_mem_add_mapping(bpa, size, flags, bshp);
-       if (error) {
-               if (extent_free(ex, bpa, size, EX_NOWAIT |
-                   (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
-                       printf("x86_memio_map: pa 0x%jx, size 0x%jx\n",
-                           (uintmax_t)bpa, (uintmax_t)size);
-                       printf("x86_memio_map: can't free region\n");
-               }
-       }
-
-       return (error);
+       return x86_mem_add_mapping(bpa, size, flags, bshp);
 }
 
 int
@@ -235,14 +242,66 @@
 }
 
 int
-bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
-               bus_size_t size, bus_size_t alignment, bus_size_t boundary,
-               int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
+bus_space_reserve(bus_space_tag_t t,
+    bus_addr_t bpa,
+    bus_size_t size,
+    int flags, bus_space_reservation_t *bsrp)
 {
        struct extent *ex;
+       int error;
+
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_RESERVE) != 0) {
+               return (*t->bst_ov->ov_space_reserve)(t->bst_ctx, t,
+                   bpa, size, flags, bsrp);
+       }
+       if (t->bst_super != NULL)
+               return bus_space_reserve(t->bst_super, bpa, size, flags, bsrp);
+
+       /*
+        * Pick the appropriate extent map.
+        */
+       if (x86_bus_space_is_io(t)) {
+               if (flags & BUS_SPACE_MAP_LINEAR)
+                       return (EOPNOTSUPP);
+               ex = ioport_ex;
+       } else if (x86_bus_space_is_mem(t))
+               ex = iomem_ex;
+       else
+               panic("x86_memio_alloc: bad bus space tag");
+
+       /*
+        * Before we go any further, let's make sure that this
+        * region is available.
+        */
+       error = extent_alloc_region(ex, bpa, size,
+           EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
+
+       if (error != 0)
+               return error;
+
+       bus_space_reservation_init(bsrp, bpa, size);
+
+       return 0;
+}
+
+int
+bus_space_reserve_subregion(bus_space_tag_t t,
+    bus_addr_t rstart, bus_addr_t rend,
+    bus_size_t size, bus_size_t alignment, bus_size_t boundary,
+    int flags, bus_space_reservation_t *bsrp)
+{
+       bus_space_reservation_t bsr;
+       struct extent *ex;
        u_long bpa;
        int error;
 
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_RESERVE_SUBREGION) != 0) {
+               return (*t->bst_ov->ov_space_reserve_subregion)(t->bst_ctx, t,
+                   rstart, rend, size, alignment, boundary, flags, bsrp);
+       }
+       if (t->bst_super != NULL)
+               return bus_space_reserve(t->bst_super, bpa, size, flags, bsrp);
+
        /*
         * Pick the appropriate extent map.
         */
@@ -258,7 +317,9 @@
        /*
         * Sanity check the allocation against the extent's boundaries.
         */
-       if (rstart < ex->ex_start || rend > ex->ex_end)
+       rstart = MAX(rstart, ex->ex_start);
+       rend = MIN(rend, ex->ex_end);
+       if (rstart >= rend)
                panic("x86_memio_alloc: bad region start/end");
 
        /*
@@ -272,31 +333,79 @@
        if (error)
                return (error);
 
+       bus_space_reservation_init(&bsr, bpa, size);
+
+       *bsrp = bsr;
+
+       return 0;
+}
+
+void
+bus_space_release(bus_space_tag_t t, bus_space_reservation_t *bsr)
+{
+       struct extent *ex;
+
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_RELEASE) != 0) {
+               (*t->bst_ov->ov_space_release)(t->bst_ctx, t, bsr);
+               return;
+       }
+       if (t->bst_super != NULL) {
+               bus_space_release(t->bst_super, bsr);
+               return;
+       }
        /*
-        * For I/O space, that's all she wrote.
+        * Pick the appropriate extent map.
         */
        if (x86_bus_space_is_io(t)) {
-               *bshp = *bpap = bpa;
-               return (0);
+               ex = ioport_ex;
+       } else if (x86_bus_space_is_mem(t))
+               ex = iomem_ex;
+       else
+               panic("x86_memio_alloc: bad bus space tag");
+
+       if (extent_free(ex, bus_space_reservation_addr(bsr),
+           bus_space_reservation_size(bsr), EX_NOWAIT |
+           (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
+               printf("%s: pa 0x%jx, size 0x%jx\n", __func__,
+                   (uintmax_t)bus_space_reservation_addr(bsr),
+                   (uintmax_t)bus_space_reservation_size(bsr));
+               printf("%s: can't free region\n", __func__);
+       }
+}
+
+int
+bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
+               bus_size_t size, bus_size_t alignment, bus_size_t boundary,
+               int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+       bus_space_reservation_t bsr;
+       int error;
+
+       if ((t->bst_present & BUS_SPACE_OVERRIDE_ALLOC) != 0) {
+               return (*t->bst_ov->ov_space_alloc)(t->bst_ctx, t, rstart, rend,
+                   size, alignment, boundary, flags, bpap, bshp);
+       }



Home | Main Index | Thread Index | Old Index