summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2002-02-17 09:16:45 +0000
committernyan <nyan@FreeBSD.org>2002-02-17 09:16:45 +0000
commit1ed4a21d0776cd372c00c7ab70a145f6e190ca94 (patch)
tree571d8b4d1f2c199abf241bfb63550acc815576d8
parent1b92815504348bc906649e6b123b56d1add3cc0e (diff)
downloadFreeBSD-src-1ed4a21d0776cd372c00c7ab70a145f6e190ca94.zip
FreeBSD-src-1ed4a21d0776cd372c00c7ab70a145f6e190ca94.tar.gz
- Split the routine to initialize a bus_space_handle into the separate
function. - Only access a bus_space_handle if the resource type is SYS_RES_MEMORY or SYS_RES_IOPORT. - Add the bus_space_subregion supports.
-rw-r--r--sys/amd64/amd64/legacy.c51
-rw-r--r--sys/amd64/amd64/nexus.c51
-rw-r--r--sys/amd64/isa/isa.c12
-rw-r--r--sys/i386/i386/legacy.c51
-rw-r--r--sys/i386/i386/nexus.c51
-rw-r--r--sys/i386/include/bus_pc98.h25
-rw-r--r--sys/i386/isa/isa.c12
-rw-r--r--sys/pc98/i386/busiosubr.c114
-rw-r--r--sys/pc98/pc98/busiosubr.c114
9 files changed, 339 insertions, 142 deletions
diff --git a/sys/amd64/amd64/legacy.c b/sys/amd64/amd64/legacy.c
index 07518ad..d4fa131 100644
--- a/sys/amd64/amd64/legacy.c
+++ b/sys/amd64/amd64/legacy.c
@@ -76,9 +76,6 @@
#include <i386/isa/intr_machdep.h>
#include <sys/rtprio.h>
-#ifdef PC98
-static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
-#endif
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
@@ -438,40 +435,32 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
-#ifdef PC98
- /* Allocate bushandle. */
- rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE,
- M_NOWAIT | M_ZERO);
- if (rv->r_bushandle == 0) {
- rman_release_resource(rv);
- return 0;
- }
-#endif
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, I386_BUS_SPACE_MEM);
} else if (type == SYS_RES_IOPORT) {
rman_set_bustag(rv, I386_BUS_SPACE_IO);
-#ifdef PC98
- /* PC-98: the type of bus_space_handle_t is the structure. */
- rv->r_bushandle->bsh_base = rv->r_start;
- rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- rv->r_bushandle->bsh_iatsz = 0;
- rv->r_bushandle->bsh_res = NULL;
- rv->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da;
-#else
- /* IBM-PC: the type of bus_space_handle_t is u_int */
+#ifndef PC98
rman_set_bushandle(rv, rv->r_start);
#endif
}
+#ifdef PC98
+ if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
+ i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
+ &rv->r_bushandle) != 0) {
+ rman_release_resource(rv);
+ return 0;
+ }
+#endif
+
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
- free(rv->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(rv->r_bustag,
+ rv->r_bushandle, rv->r_bushandle->bsh_sz);
+ }
#endif
rman_release_resource(rv);
return 0;
@@ -511,13 +500,6 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#ifdef PC98
/* PC-98: the type of bus_space_handle_t is the structure. */
r->r_bushandle->bsh_base = (bus_addr_t) vaddr;
- r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- r->r_bushandle->bsh_iatsz = 0;
- r->r_bushandle->bsh_res = NULL;
- r->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- r->r_bushandle->bsh_bam = r->r_bustag->bs_da;
#else
/* IBM-PC: the type of bus_space_handle_t is u_int */
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
@@ -554,7 +536,10 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return error;
}
#ifdef PC98
- free(r->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(r->r_bustag, r->r_bushandle,
+ r->r_bushandle->bsh_sz);
+ }
#endif
return (rman_release_resource(r));
}
diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c
index 07518ad..d4fa131 100644
--- a/sys/amd64/amd64/nexus.c
+++ b/sys/amd64/amd64/nexus.c
@@ -76,9 +76,6 @@
#include <i386/isa/intr_machdep.h>
#include <sys/rtprio.h>
-#ifdef PC98
-static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
-#endif
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
@@ -438,40 +435,32 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
-#ifdef PC98
- /* Allocate bushandle. */
- rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE,
- M_NOWAIT | M_ZERO);
- if (rv->r_bushandle == 0) {
- rman_release_resource(rv);
- return 0;
- }
-#endif
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, I386_BUS_SPACE_MEM);
} else if (type == SYS_RES_IOPORT) {
rman_set_bustag(rv, I386_BUS_SPACE_IO);
-#ifdef PC98
- /* PC-98: the type of bus_space_handle_t is the structure. */
- rv->r_bushandle->bsh_base = rv->r_start;
- rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- rv->r_bushandle->bsh_iatsz = 0;
- rv->r_bushandle->bsh_res = NULL;
- rv->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da;
-#else
- /* IBM-PC: the type of bus_space_handle_t is u_int */
+#ifndef PC98
rman_set_bushandle(rv, rv->r_start);
#endif
}
+#ifdef PC98
+ if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
+ i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
+ &rv->r_bushandle) != 0) {
+ rman_release_resource(rv);
+ return 0;
+ }
+#endif
+
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
- free(rv->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(rv->r_bustag,
+ rv->r_bushandle, rv->r_bushandle->bsh_sz);
+ }
#endif
rman_release_resource(rv);
return 0;
@@ -511,13 +500,6 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#ifdef PC98
/* PC-98: the type of bus_space_handle_t is the structure. */
r->r_bushandle->bsh_base = (bus_addr_t) vaddr;
- r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- r->r_bushandle->bsh_iatsz = 0;
- r->r_bushandle->bsh_res = NULL;
- r->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- r->r_bushandle->bsh_bam = r->r_bustag->bs_da;
#else
/* IBM-PC: the type of bus_space_handle_t is u_int */
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
@@ -554,7 +536,10 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return error;
}
#ifdef PC98
- free(r->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(r->r_bustag, r->r_bushandle,
+ r->r_bushandle->bsh_sz);
+ }
#endif
return (rman_release_resource(r));
}
diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c
index 9124c8d..bd1df32 100644
--- a/sys/amd64/isa/isa.c
+++ b/sys/amd64/isa/isa.c
@@ -236,11 +236,13 @@ isa_release_resource(device_t bus, device_t child, int type, int rid,
*/
int i;
- for (i = 1; i < r->r_bushandle->bsh_ressz; i++)
- resource_list_release(rl, bus, child, type, rid + i,
- r->r_bushandle->bsh_res[i]);
- if (r->r_bushandle->bsh_res != NULL)
- free(r->r_bushandle->bsh_res, M_DEVBUF);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ for (i = 1; i < r->r_bushandle->bsh_ressz; i++)
+ resource_list_release(rl, bus, child, type, rid + i,
+ r->r_bushandle->bsh_res[i]);
+ if (r->r_bushandle->bsh_res != NULL)
+ free(r->r_bushandle->bsh_res, M_DEVBUF);
+ }
#endif
return resource_list_release(rl, bus, child, type, rid, r);
}
diff --git a/sys/i386/i386/legacy.c b/sys/i386/i386/legacy.c
index 07518ad..d4fa131 100644
--- a/sys/i386/i386/legacy.c
+++ b/sys/i386/i386/legacy.c
@@ -76,9 +76,6 @@
#include <i386/isa/intr_machdep.h>
#include <sys/rtprio.h>
-#ifdef PC98
-static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
-#endif
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
@@ -438,40 +435,32 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
-#ifdef PC98
- /* Allocate bushandle. */
- rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE,
- M_NOWAIT | M_ZERO);
- if (rv->r_bushandle == 0) {
- rman_release_resource(rv);
- return 0;
- }
-#endif
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, I386_BUS_SPACE_MEM);
} else if (type == SYS_RES_IOPORT) {
rman_set_bustag(rv, I386_BUS_SPACE_IO);
-#ifdef PC98
- /* PC-98: the type of bus_space_handle_t is the structure. */
- rv->r_bushandle->bsh_base = rv->r_start;
- rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- rv->r_bushandle->bsh_iatsz = 0;
- rv->r_bushandle->bsh_res = NULL;
- rv->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da;
-#else
- /* IBM-PC: the type of bus_space_handle_t is u_int */
+#ifndef PC98
rman_set_bushandle(rv, rv->r_start);
#endif
}
+#ifdef PC98
+ if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
+ i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
+ &rv->r_bushandle) != 0) {
+ rman_release_resource(rv);
+ return 0;
+ }
+#endif
+
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
- free(rv->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(rv->r_bustag,
+ rv->r_bushandle, rv->r_bushandle->bsh_sz);
+ }
#endif
rman_release_resource(rv);
return 0;
@@ -511,13 +500,6 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#ifdef PC98
/* PC-98: the type of bus_space_handle_t is the structure. */
r->r_bushandle->bsh_base = (bus_addr_t) vaddr;
- r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- r->r_bushandle->bsh_iatsz = 0;
- r->r_bushandle->bsh_res = NULL;
- r->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- r->r_bushandle->bsh_bam = r->r_bustag->bs_da;
#else
/* IBM-PC: the type of bus_space_handle_t is u_int */
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
@@ -554,7 +536,10 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return error;
}
#ifdef PC98
- free(r->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(r->r_bustag, r->r_bushandle,
+ r->r_bushandle->bsh_sz);
+ }
#endif
return (rman_release_resource(r));
}
diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c
index 07518ad..d4fa131 100644
--- a/sys/i386/i386/nexus.c
+++ b/sys/i386/i386/nexus.c
@@ -76,9 +76,6 @@
#include <i386/isa/intr_machdep.h>
#include <sys/rtprio.h>
-#ifdef PC98
-static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
-#endif
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
struct nexus_device {
struct resource_list nx_resources;
@@ -438,40 +435,32 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
return 0;
-#ifdef PC98
- /* Allocate bushandle. */
- rv->r_bushandle = malloc(sizeof *rv->r_bushandle, M_BUSSPACEHANDLE,
- M_NOWAIT | M_ZERO);
- if (rv->r_bushandle == 0) {
- rman_release_resource(rv);
- return 0;
- }
-#endif
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, I386_BUS_SPACE_MEM);
} else if (type == SYS_RES_IOPORT) {
rman_set_bustag(rv, I386_BUS_SPACE_IO);
-#ifdef PC98
- /* PC-98: the type of bus_space_handle_t is the structure. */
- rv->r_bushandle->bsh_base = rv->r_start;
- rv->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- rv->r_bushandle->bsh_iatsz = 0;
- rv->r_bushandle->bsh_res = NULL;
- rv->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- rv->r_bushandle->bsh_bam = rv->r_bustag->bs_da;
-#else
- /* IBM-PC: the type of bus_space_handle_t is u_int */
+#ifndef PC98
rman_set_bushandle(rv, rv->r_start);
#endif
}
+#ifdef PC98
+ if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
+ i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
+ &rv->r_bushandle) != 0) {
+ rman_release_resource(rv);
+ return 0;
+ }
+#endif
+
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
- free(rv->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(rv->r_bustag,
+ rv->r_bushandle, rv->r_bushandle->bsh_sz);
+ }
#endif
rman_release_resource(rv);
return 0;
@@ -511,13 +500,6 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#ifdef PC98
/* PC-98: the type of bus_space_handle_t is the structure. */
r->r_bushandle->bsh_base = (bus_addr_t) vaddr;
- r->r_bushandle->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
- r->r_bushandle->bsh_iatsz = 0;
- r->r_bushandle->bsh_res = NULL;
- r->r_bushandle->bsh_ressz = 0;
-
- /* default: direct access */
- r->r_bushandle->bsh_bam = r->r_bustag->bs_da;
#else
/* IBM-PC: the type of bus_space_handle_t is u_int */
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
@@ -554,7 +536,10 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
return error;
}
#ifdef PC98
- free(r->r_bushandle, M_BUSSPACEHANDLE);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ i386_bus_space_handle_free(r->r_bustag, r->r_bushandle,
+ r->r_bushandle->bsh_sz);
+ }
#endif
return (rman_release_resource(r));
}
diff --git a/sys/i386/include/bus_pc98.h b/sys/i386/include/bus_pc98.h
index 99ac7a8..e1ab78f 100644
--- a/sys/i386/include/bus_pc98.h
+++ b/sys/i386/include/bus_pc98.h
@@ -148,6 +148,8 @@ extern struct bus_space_tag SBUS_mem_space_tag;
*/
struct bus_space_handle {
bus_addr_t bsh_base;
+ size_t bsh_sz;
+
bus_addr_t bsh_iat[BUS_SPACE_IAT_MAXSIZE];
size_t bsh_maxiatsz;
size_t bsh_iatsz;
@@ -160,6 +162,29 @@ struct bus_space_handle {
typedef struct bus_space_handle *bus_space_handle_t;
/*
+ * Allocate/Free bus_space_handle
+ */
+int i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa,
+ bus_size_t size, bus_space_handle_t *bshp);
+void i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
+ size_t size);
+
+/*
+ * int bus_space_subregion (bus_space_tag_t t,
+ * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
+ * bus_space_handle_t *nbshp);
+ *
+ * Get a new handle for a subregion of an already-mapped area of bus space.
+ */
+
+int i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size,
+ bus_space_handle_t *nbshp);
+
+#define bus_space_subregion(t, h, o, s, nhp) \
+ i386_memio_subregion((t), (h), (o), (s), (nhp))
+
+/*
* Access methods for bus resources and address space.
*/
#define _BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \
diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c
index 9124c8d..bd1df32 100644
--- a/sys/i386/isa/isa.c
+++ b/sys/i386/isa/isa.c
@@ -236,11 +236,13 @@ isa_release_resource(device_t bus, device_t child, int type, int rid,
*/
int i;
- for (i = 1; i < r->r_bushandle->bsh_ressz; i++)
- resource_list_release(rl, bus, child, type, rid + i,
- r->r_bushandle->bsh_res[i]);
- if (r->r_bushandle->bsh_res != NULL)
- free(r->r_bushandle->bsh_res, M_DEVBUF);
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ for (i = 1; i < r->r_bushandle->bsh_ressz; i++)
+ resource_list_release(rl, bus, child, type, rid + i,
+ r->r_bushandle->bsh_res[i]);
+ if (r->r_bushandle->bsh_res != NULL)
+ free(r->r_bushandle->bsh_res, M_DEVBUF);
+ }
#endif
return resource_list_release(rl, bus, child, type, rid, r);
}
diff --git a/sys/pc98/i386/busiosubr.c b/sys/pc98/i386/busiosubr.c
index c2c6228..4df0c1b 100644
--- a/sys/pc98/i386/busiosubr.c
+++ b/sys/pc98/i386/busiosubr.c
@@ -43,8 +43,11 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/malloc.h>
#include <machine/bus.h>
+static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
+
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4)
@@ -142,3 +145,114 @@ struct bus_space_tag NEPC_mem_space_tag = {
};
#endif /* DEV_MECIA */
+
+/*************************************************************************
+ * map init
+ *************************************************************************/
+static __inline void
+bus_space_iat_init(bus_space_handle_t bsh)
+{
+ int i;
+
+ for (i = 0; i < bsh->bsh_maxiatsz; i++)
+ bsh->bsh_iat[i] = bsh->bsh_base + i;
+}
+
+/*************************************************************************
+ * handle allocation
+ *************************************************************************/
+int
+i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
+ bus_space_handle_t *bshp)
+{
+ bus_space_handle_t bsh;
+
+ bsh = (bus_space_handle_t) malloc(sizeof (*bsh), M_BUSSPACEHANDLE,
+ M_NOWAIT | M_ZERO);
+ if (bsh == NULL)
+ return ENOMEM;
+
+ bsh->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
+ bsh->bsh_iatsz = 0;
+ bsh->bsh_base = bpa;
+ bsh->bsh_sz = size;
+ bsh->bsh_res = NULL;
+ bsh->bsh_ressz = 0;
+ bus_space_iat_init(bsh);
+
+ bsh->bsh_bam = t->bs_da; /* default: direct access */
+
+ *bshp = bsh;
+ return 0;
+}
+
+void
+i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
+ size_t size)
+{
+
+ free(bsh, M_BUSSPACEHANDLE);
+}
+
+/*************************************************************************
+ * map
+ *************************************************************************/
+int
+i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
+ bus_size_t offset, bus_size_t size,
+ bus_space_handle_t *tbshp)
+{
+ int i, error = 0;
+ bus_space_handle_t bsh;
+ bus_addr_t pbase;
+
+ pbase = pbsh->bsh_base + offset;
+ switch (t->bs_tag) {
+ case BUS_SPACE_IO:
+ if (pbsh->bsh_iatsz > 0) {
+ if (offset >= pbsh->bsh_iatsz ||
+ offset + size > pbsh->bsh_iatsz)
+ return EINVAL;
+ pbase = pbsh->bsh_base;
+ }
+ break;
+
+ case BUS_SPACE_MEM:
+ if (pbsh->bsh_iatsz > 0)
+ return EINVAL;
+ if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
+ return EINVAL;
+ break;
+
+ default:
+ panic("i386_memio_subregion: bad bus space tag");
+ break;
+ }
+
+ error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
+ if (error != 0)
+ return error;
+
+ switch (t->bs_tag) {
+ case BUS_SPACE_IO:
+ if (pbsh->bsh_iatsz > 0) {
+ for (i = 0; i < size; i ++)
+ bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
+ bsh->bsh_iatsz = size;
+ } else if (pbsh->bsh_base > bsh->bsh_base ||
+ pbsh->bsh_base + pbsh->bsh_sz <
+ bsh->bsh_base + bsh->bsh_sz) {
+ i386_bus_space_handle_free(t, bsh, size);
+ return EINVAL;
+ }
+ break;
+
+ case BUS_SPACE_MEM:
+ break;
+ }
+
+ if (pbsh->bsh_iatsz > 0)
+ bsh->bsh_bam = t->bs_ra; /* relocate access */
+ *tbshp = bsh;
+ return error;
+}
diff --git a/sys/pc98/pc98/busiosubr.c b/sys/pc98/pc98/busiosubr.c
index c2c6228..4df0c1b 100644
--- a/sys/pc98/pc98/busiosubr.c
+++ b/sys/pc98/pc98/busiosubr.c
@@ -43,8 +43,11 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/malloc.h>
#include <machine/bus.h>
+static MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle");
+
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4)
@@ -142,3 +145,114 @@ struct bus_space_tag NEPC_mem_space_tag = {
};
#endif /* DEV_MECIA */
+
+/*************************************************************************
+ * map init
+ *************************************************************************/
+static __inline void
+bus_space_iat_init(bus_space_handle_t bsh)
+{
+ int i;
+
+ for (i = 0; i < bsh->bsh_maxiatsz; i++)
+ bsh->bsh_iat[i] = bsh->bsh_base + i;
+}
+
+/*************************************************************************
+ * handle allocation
+ *************************************************************************/
+int
+i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
+ bus_space_handle_t *bshp)
+{
+ bus_space_handle_t bsh;
+
+ bsh = (bus_space_handle_t) malloc(sizeof (*bsh), M_BUSSPACEHANDLE,
+ M_NOWAIT | M_ZERO);
+ if (bsh == NULL)
+ return ENOMEM;
+
+ bsh->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE;
+ bsh->bsh_iatsz = 0;
+ bsh->bsh_base = bpa;
+ bsh->bsh_sz = size;
+ bsh->bsh_res = NULL;
+ bsh->bsh_ressz = 0;
+ bus_space_iat_init(bsh);
+
+ bsh->bsh_bam = t->bs_da; /* default: direct access */
+
+ *bshp = bsh;
+ return 0;
+}
+
+void
+i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
+ size_t size)
+{
+
+ free(bsh, M_BUSSPACEHANDLE);
+}
+
+/*************************************************************************
+ * map
+ *************************************************************************/
+int
+i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
+ bus_size_t offset, bus_size_t size,
+ bus_space_handle_t *tbshp)
+{
+ int i, error = 0;
+ bus_space_handle_t bsh;
+ bus_addr_t pbase;
+
+ pbase = pbsh->bsh_base + offset;
+ switch (t->bs_tag) {
+ case BUS_SPACE_IO:
+ if (pbsh->bsh_iatsz > 0) {
+ if (offset >= pbsh->bsh_iatsz ||
+ offset + size > pbsh->bsh_iatsz)
+ return EINVAL;
+ pbase = pbsh->bsh_base;
+ }
+ break;
+
+ case BUS_SPACE_MEM:
+ if (pbsh->bsh_iatsz > 0)
+ return EINVAL;
+ if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
+ return EINVAL;
+ break;
+
+ default:
+ panic("i386_memio_subregion: bad bus space tag");
+ break;
+ }
+
+ error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
+ if (error != 0)
+ return error;
+
+ switch (t->bs_tag) {
+ case BUS_SPACE_IO:
+ if (pbsh->bsh_iatsz > 0) {
+ for (i = 0; i < size; i ++)
+ bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
+ bsh->bsh_iatsz = size;
+ } else if (pbsh->bsh_base > bsh->bsh_base ||
+ pbsh->bsh_base + pbsh->bsh_sz <
+ bsh->bsh_base + bsh->bsh_sz) {
+ i386_bus_space_handle_free(t, bsh, size);
+ return EINVAL;
+ }
+ break;
+
+ case BUS_SPACE_MEM:
+ break;
+ }
+
+ if (pbsh->bsh_iatsz > 0)
+ bsh->bsh_bam = t->bs_ra; /* relocate access */
+ *tbshp = bsh;
+ return error;
+}
OpenPOWER on IntegriCloud