diff options
author | nyan <nyan@FreeBSD.org> | 2002-02-17 09:16:45 +0000 |
---|---|---|
committer | nyan <nyan@FreeBSD.org> | 2002-02-17 09:16:45 +0000 |
commit | 1ed4a21d0776cd372c00c7ab70a145f6e190ca94 (patch) | |
tree | 571d8b4d1f2c199abf241bfb63550acc815576d8 /sys | |
parent | 1b92815504348bc906649e6b123b56d1add3cc0e (diff) | |
download | FreeBSD-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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/legacy.c | 51 | ||||
-rw-r--r-- | sys/amd64/amd64/nexus.c | 51 | ||||
-rw-r--r-- | sys/amd64/isa/isa.c | 12 | ||||
-rw-r--r-- | sys/i386/i386/legacy.c | 51 | ||||
-rw-r--r-- | sys/i386/i386/nexus.c | 51 | ||||
-rw-r--r-- | sys/i386/include/bus_pc98.h | 25 | ||||
-rw-r--r-- | sys/i386/isa/isa.c | 12 | ||||
-rw-r--r-- | sys/pc98/i386/busiosubr.c | 114 | ||||
-rw-r--r-- | sys/pc98/pc98/busiosubr.c | 114 |
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; +} |