From 0e141e3c323e56200e61ddbecea76cf7614cb41e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 20 May 2016 00:45:16 +0000 Subject: [PATCH] [bhnd] Add remaining bus_(read|write|set)_(1|2|4) APIs This adds bhnd-compatible implementations of bus_(read|write|set)_(1|2|4) APIs, and upgrades the SPROM parsing code to use bhnd_bus_read_region_stream_2(). This a precursor to bridge support for resource adjustment and the new ChipCommon bus support. Tested: * Tested against BCM4331 * Kernel build verified via tinderbox. Submitted by: Landon Fuller Differential Revision: https://reviews.freebsd.org/D6469 --- sys/dev/bhnd/bhnd.c | 88 ++++++++++----- sys/dev/bhnd/bhnd.h | 108 +++++++++++++++++++ sys/dev/bhnd/bhnd_bus_if.m | 186 ++++++++++++++++++++++++++++++++ sys/dev/bhnd/bhndb/bhndb.c | 64 ++++++----- sys/dev/bhnd/nvram/bhnd_sprom.c | 12 +-- sys/dev/bhnd/tools/bus_macro.sh | 21 ++-- 6 files changed, 415 insertions(+), 64 deletions(-) diff --git a/sys/dev/bhnd/bhnd.c b/sys/dev/bhnd/bhnd.c index 11e34ddf36de..8f85900cef2a 100644 --- a/sys/dev/bhnd/bhnd.c +++ b/sys/dev/bhnd/bhnd.c @@ -529,36 +529,36 @@ bhnd_generic_resume_child(device_t dev, device_t child) /* * Delegate all indirect I/O to the parent device. When inherited by * non-bridged bus implementations, resources will never be marked as - * indirect, and these methods should never be called. + * indirect, and these methods will never be called. */ -#define BHND_IO_READ(_type, _name, _method) \ -static _type \ -bhnd_read_ ## _name (device_t dev, device_t child, \ - struct bhnd_resource *r, bus_size_t offset) \ -{ \ - return (BHND_BUS_READ_ ## _method( \ - device_get_parent(dev), child, r, offset)); \ +#define BHND_IO_READ(_type, _name, _method) \ +static _type \ +bhnd_read_ ## _name (device_t dev, device_t child, \ + struct bhnd_resource *r, bus_size_t offset) \ +{ \ + return (BHND_BUS_READ_ ## _method( \ + device_get_parent(dev), child, r, offset)); \ } -#define BHND_IO_WRITE(_type, _name, _method) \ -static void \ -bhnd_write_ ## _name (device_t dev, device_t child, \ - struct bhnd_resource *r, bus_size_t offset, _type value) \ -{ \ - return (BHND_BUS_WRITE_ ## _method( \ - device_get_parent(dev), child, r, offset, \ +#define BHND_IO_WRITE(_type, _name, _method) \ +static void \ +bhnd_write_ ## _name (device_t dev, device_t child, \ + struct bhnd_resource *r, bus_size_t offset, _type value) \ +{ \ + return (BHND_BUS_WRITE_ ## _method( \ + device_get_parent(dev), child, r, offset, \ value)); \ } -#define BHND_IO_MULTI(_type, _rw, _name, _method) \ +#define BHND_IO_MISC(_type, _op, _method) \ static void \ -bhnd_ ## _rw ## _multi_ ## _name (device_t dev, device_t child, \ - struct bhnd_resource *r, bus_size_t offset, _type *datap, \ +bhnd_ ## _op (device_t dev, device_t child, \ + struct bhnd_resource *r, bus_size_t offset, _type datap, \ bus_size_t count) \ { \ BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ offset, datap, count); \ -} +} #define BHND_IO_METHODS(_type, _size) \ BHND_IO_READ(_type, _size, _size) \ @@ -567,13 +567,28 @@ bhnd_ ## _rw ## _multi_ ## _name (device_t dev, device_t child, \ BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ \ - BHND_IO_MULTI(_type, read, _size, READ_MULTI_ ## _size) \ - BHND_IO_MULTI(_type, write, _size, WRITE_MULTI_ ## _size) \ + BHND_IO_MISC(_type*, read_multi_ ## _size, \ + READ_MULTI_ ## _size) \ + BHND_IO_MISC(_type*, write_multi_ ## _size, \ + WRITE_MULTI_ ## _size) \ \ - BHND_IO_MULTI(_type, read, stream_ ## _size, \ + BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ READ_MULTI_STREAM_ ## _size) \ - BHND_IO_MULTI(_type, write, stream_ ## _size, \ + BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ WRITE_MULTI_STREAM_ ## _size) \ + \ + BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ + BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ + \ + BHND_IO_MISC(_type*, read_region_ ## _size, \ + READ_REGION_ ## _size) \ + BHND_IO_MISC(_type*, write_region_ ## _size, \ + WRITE_REGION_ ## _size) \ + \ + BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ + READ_REGION_STREAM_ ## _size) \ + BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ + WRITE_REGION_STREAM_ ## _size) \ BHND_IO_METHODS(uint8_t, 1); BHND_IO_METHODS(uint16_t, 2); @@ -627,12 +642,15 @@ static device_method_t bhnd_methods[] = { DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var), + + /* BHND interface (bus I/O) */ DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), + DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), @@ -654,7 +672,29 @@ static device_method_t bhnd_methods[] = { DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), - DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), + DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), + DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), + DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), + + DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), + DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), + DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), + + DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), + DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), + DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), + DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), + DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), + DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), + + DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), + DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), + DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), + DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), + DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), + DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), + + DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), DEVMETHOD_END }; diff --git a/sys/dev/bhnd/bhnd.h b/sys/dev/bhnd/bhnd.h index d01903ffbdb0..e1603dd56b84 100644 --- a/sys/dev/bhnd/bhnd.h +++ b/sys/dev/bhnd/bhnd.h @@ -869,6 +869,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_1( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_1(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_1((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_1(r, o, v) \ ((r)->direct) ? \ bus_write_1((r)->res, (o), (v)) : \ @@ -881,6 +887,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_1( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_1(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_1((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_read_stream_1(r, o) \ ((r)->direct) ? \ bus_read_stream_1((r)->res, (o)) : \ @@ -893,6 +905,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_STREAM_1( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_stream_1(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_stream_1((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_STREAM_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_stream_1(r, o, v) \ ((r)->direct) ? \ bus_write_stream_1((r)->res, (o), (v)) : \ @@ -905,6 +923,24 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_STREAM_1( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_stream_1(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_stream_1((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_STREAM_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_set_multi_1(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_multi_1((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_MULTI_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) +#define bhnd_bus_set_region_1(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_region_1((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_REGION_1( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) #define bhnd_bus_read_2(r, o) \ ((r)->direct) ? \ bus_read_2((r)->res, (o)) : \ @@ -917,6 +953,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_2( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_2(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_2((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_2(r, o, v) \ ((r)->direct) ? \ bus_write_2((r)->res, (o), (v)) : \ @@ -929,6 +971,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_2( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_2(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_2((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_read_stream_2(r, o) \ ((r)->direct) ? \ bus_read_stream_2((r)->res, (o)) : \ @@ -941,6 +989,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_STREAM_2( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_stream_2(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_stream_2((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_STREAM_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_stream_2(r, o, v) \ ((r)->direct) ? \ bus_write_stream_2((r)->res, (o), (v)) : \ @@ -953,6 +1007,24 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_STREAM_2( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_stream_2(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_stream_2((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_STREAM_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_set_multi_2(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_multi_2((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_MULTI_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) +#define bhnd_bus_set_region_2(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_region_2((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_REGION_2( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) #define bhnd_bus_read_4(r, o) \ ((r)->direct) ? \ bus_read_4((r)->res, (o)) : \ @@ -965,6 +1037,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_4( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_4(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_4((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_4(r, o, v) \ ((r)->direct) ? \ bus_write_4((r)->res, (o), (v)) : \ @@ -977,6 +1055,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_4( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_4(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_4((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_read_stream_4(r, o) \ ((r)->direct) ? \ bus_read_stream_4((r)->res, (o)) : \ @@ -989,6 +1073,12 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_READ_MULTI_STREAM_4( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_read_region_stream_4(r, o, d, c) \ + ((r)->direct) ? \ + bus_read_region_stream_4((r)->res, (o), (d), (c)) : \ + BHND_BUS_READ_REGION_STREAM_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) #define bhnd_bus_write_stream_4(r, o, v) \ ((r)->direct) ? \ bus_write_stream_4((r)->res, (o), (v)) : \ @@ -1001,5 +1091,23 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, BHND_BUS_WRITE_MULTI_STREAM_4( \ device_get_parent(rman_get_device((r)->res)), \ rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_write_region_stream_4(r, o, d, c) \ + ((r)->direct) ? \ + bus_write_region_stream_4((r)->res, (o), (d), (c)) : \ + BHND_BUS_WRITE_REGION_STREAM_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (d), (c)) +#define bhnd_bus_set_multi_4(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_multi_4((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_MULTI_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) +#define bhnd_bus_set_region_4(r, o, v, c) \ + ((r)->direct) ? \ + bus_set_region_4((r)->res, (o), (v), (c)) : \ + BHND_BUS_SET_REGION_4( \ + device_get_parent(rman_get_device((r)->res)), \ + rman_get_device((r)->res), (r), (o), (v), (c)) #endif /* _BHND_BHND_H_ */ diff --git a/sys/dev/bhnd/bhnd_bus_if.m b/sys/dev/bhnd/bhnd_bus_if.m index 35402a4115b1..5098bce3a1cc 100644 --- a/sys/dev/bhnd/bhnd_bus_if.m +++ b/sys/dev/bhnd/bhnd_bus_if.m @@ -670,6 +670,192 @@ METHOD void write_multi_stream_4 { bus_size_t count; } +/** An implementation of bus_set_multi_1() compatible with bhnd_resource */ +METHOD void set_multi_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t value; + bus_size_t count; +} + +/** An implementation of bus_set_multi_2() compatible with bhnd_resource */ +METHOD void set_multi_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t value; + bus_size_t count; +} + +/** An implementation of bus_set_multi_4() compatible with bhnd_resource */ +METHOD void set_multi_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t value; + bus_size_t count; +} + +/** An implementation of bus_set_region_1() compatible with bhnd_resource */ +METHOD void set_region_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t value; + bus_size_t count; +} + +/** An implementation of bus_set_region_2() compatible with bhnd_resource */ +METHOD void set_region_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t value; + bus_size_t count; +} + +/** An implementation of bus_set_region_4() compatible with bhnd_resource */ +METHOD void set_region_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t value; + bus_size_t count; +} + +/** An implementation of bus_read_region_1() compatible with bhnd_resource */ +METHOD void read_region_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t *datap; + bus_size_t count; +} + +/** An implementation of bus_read_region_2() compatible with bhnd_resource */ +METHOD void read_region_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t *datap; + bus_size_t count; +} + +/** An implementation of bus_read_region_4() compatible with bhnd_resource */ +METHOD void read_region_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t *datap; + bus_size_t count; +} + +/** An implementation of bus_read_region_stream_1() compatible with + * bhnd_resource */ +METHOD void read_region_stream_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t *datap; + bus_size_t count; +} + +/** An implementation of bus_read_region_stream_2() compatible with + * bhnd_resource */ +METHOD void read_region_stream_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t *datap; + bus_size_t count; +} + +/** An implementation of bus_read_region_stream_4() compatible with + * bhnd_resource */ +METHOD void read_region_stream_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_1() compatible with bhnd_resource */ +METHOD void write_region_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_2() compatible with bhnd_resource */ +METHOD void write_region_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_4() compatible with bhnd_resource */ +METHOD void write_region_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_stream_1() compatible with + * bhnd_resource */ +METHOD void write_region_stream_1 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint8_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_stream_2() compatible with + * bhnd_resource */ +METHOD void write_region_stream_2 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint16_t *datap; + bus_size_t count; +} + +/** An implementation of bus_write_region_stream_4() compatible with + * bhnd_resource */ +METHOD void write_region_stream_4 { + device_t dev; + device_t child; + struct bhnd_resource *r; + bus_size_t offset; + uint32_t *datap; + bus_size_t count; +} + /** An implementation of bus_barrier() compatible with bhnd_resource */ METHOD void barrier { device_t dev; diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c index 218827fbbd33..1d70bb17a822 100644 --- a/sys/dev/bhnd/bhndb/bhndb.c +++ b/sys/dev/bhnd/bhndb/bhndb.c @@ -1766,15 +1766,15 @@ bhndb_bus_write_ ## _name (device_t dev, device_t child, \ BHNDB_IO_COMMON_TEARDOWN(); \ } -/* Defines a bhndb_bus_(read|write)_multi_* method implementation */ -#define BHNDB_IO_MULTI(_type, _rw, _name) \ +/* Defines a bhndb_bus_(read|write|set)_(multi|region)_* method */ +#define BHNDB_IO_MISC(_type, _ptr, _op, _size) \ static void \ -bhndb_bus_ ## _rw ## _multi_ ## _name (device_t dev, \ +bhndb_bus_ ## _op ## _ ## _size (device_t dev, \ device_t child, struct bhnd_resource *r, bus_size_t offset, \ - _type *datap, bus_size_t count) \ + _type _ptr datap, bus_size_t count) \ { \ BHNDB_IO_COMMON_SETUP(sizeof(_type) * count); \ - bus_ ## _rw ## _multi_ ## _name (io_res, io_offset, \ + bus_ ## _op ## _ ## _size (io_res, io_offset, \ datap, count); \ BHNDB_IO_COMMON_TEARDOWN(); \ } @@ -1787,11 +1787,19 @@ bhndb_bus_ ## _rw ## _multi_ ## _name (device_t dev, \ BHNDB_IO_READ(_type, stream_ ## _size) \ BHNDB_IO_WRITE(_type, stream_ ## _size) \ \ - BHNDB_IO_MULTI(_type, read, _size) \ - BHNDB_IO_MULTI(_type, write, _size) \ + BHNDB_IO_MISC(_type, *, read_multi, _size) \ + BHNDB_IO_MISC(_type, *, write_multi, _size) \ \ - BHNDB_IO_MULTI(_type, read, stream_ ## _size) \ - BHNDB_IO_MULTI(_type, write, stream_ ## _size) + BHNDB_IO_MISC(_type, *, read_multi_stream, _size) \ + BHNDB_IO_MISC(_type, *, write_multi_stream, _size) \ + \ + BHNDB_IO_MISC(_type, , set_multi, _size) \ + BHNDB_IO_MISC(_type, , set_region, _size) \ + BHNDB_IO_MISC(_type, *, read_region, _size) \ + BHNDB_IO_MISC(_type, *, write_region, _size) \ + \ + BHNDB_IO_MISC(_type, *, read_region_stream, _size) \ + BHNDB_IO_MISC(_type, *, write_region_stream, _size) BHNDB_IO_METHODS(uint8_t, 1); BHNDB_IO_METHODS(uint16_t, 2); @@ -1804,24 +1812,9 @@ static void bhndb_bus_barrier(device_t dev, device_t child, struct bhnd_resource *r, bus_size_t offset, bus_size_t length, int flags) { - bus_size_t remain; - BHNDB_IO_COMMON_SETUP(length); - /* TODO: It's unclear whether we need a barrier implementation, - * and if we do, what it needs to actually do. This may need - * revisiting once we have a better idea of requirements after - * porting the core drivers. */ - panic("implementation incorrect"); - - /* Use 4-byte reads where possible */ - remain = length % sizeof(uint32_t); - for (bus_size_t i = 0; i < (length - remain); i += 4) - bus_read_4(io_res, io_offset + offset + i); - - /* Use 1 byte reads for the remainder */ - for (bus_size_t i = 0; i < remain; i++) - bus_read_1(io_res, io_offset + offset + length + i); + bus_barrier(io_res, io_offset + offset, length, flags); BHNDB_IO_COMMON_TEARDOWN(); } @@ -1970,6 +1963,27 @@ static device_method_t bhndb_methods[] = { DEVMETHOD(bhnd_bus_write_multi_stream_2,bhndb_bus_write_multi_stream_2), DEVMETHOD(bhnd_bus_write_multi_stream_4,bhndb_bus_write_multi_stream_4), + DEVMETHOD(bhnd_bus_set_multi_1, bhndb_bus_set_multi_1), + DEVMETHOD(bhnd_bus_set_multi_2, bhndb_bus_set_multi_2), + DEVMETHOD(bhnd_bus_set_multi_4, bhndb_bus_set_multi_4), + DEVMETHOD(bhnd_bus_set_region_1, bhndb_bus_set_region_1), + DEVMETHOD(bhnd_bus_set_region_2, bhndb_bus_set_region_2), + DEVMETHOD(bhnd_bus_set_region_4, bhndb_bus_set_region_4), + + DEVMETHOD(bhnd_bus_read_region_1, bhndb_bus_read_region_1), + DEVMETHOD(bhnd_bus_read_region_2, bhndb_bus_read_region_2), + DEVMETHOD(bhnd_bus_read_region_4, bhndb_bus_read_region_4), + DEVMETHOD(bhnd_bus_write_region_1, bhndb_bus_write_region_1), + DEVMETHOD(bhnd_bus_write_region_2, bhndb_bus_write_region_2), + DEVMETHOD(bhnd_bus_write_region_4, bhndb_bus_write_region_4), + + DEVMETHOD(bhnd_bus_read_region_stream_1,bhndb_bus_read_region_stream_1), + DEVMETHOD(bhnd_bus_read_region_stream_2,bhndb_bus_read_region_stream_2), + DEVMETHOD(bhnd_bus_read_region_stream_4,bhndb_bus_read_region_stream_4), + DEVMETHOD(bhnd_bus_write_region_stream_1,bhndb_bus_write_region_stream_1), + DEVMETHOD(bhnd_bus_write_region_stream_2,bhndb_bus_write_region_stream_2), + DEVMETHOD(bhnd_bus_write_region_stream_4,bhndb_bus_write_region_stream_4), + DEVMETHOD(bhnd_bus_barrier, bhndb_bus_barrier), DEVMETHOD_END diff --git a/sys/dev/bhnd/nvram/bhnd_sprom.c b/sys/dev/bhnd/nvram/bhnd_sprom.c index 54c1faaa8ed5..6cddb60a8253 100644 --- a/sys/dev/bhnd/nvram/bhnd_sprom.c +++ b/sys/dev/bhnd/nvram/bhnd_sprom.c @@ -508,7 +508,6 @@ sprom_direct_read(struct bhnd_sprom *sc, size_t offset, void *buf, size_t nbytes, uint8_t *crc) { bus_size_t res_offset; - size_t nread; uint16_t *p; KASSERT(nbytes % sizeof(uint16_t) == 0, ("unaligned sprom size")); @@ -520,15 +519,12 @@ sprom_direct_read(struct bhnd_sprom *sc, size_t offset, void *buf, return (EINVAL); } + /* Perform read and update CRC */ p = (uint16_t *)buf; res_offset = sc->sp_res_off + offset; - /* Perform read */ - for (nread = 0; nread < nbytes; nread += 2) { - *p = bhnd_bus_read_stream_2(sc->sp_res, res_offset+nread); - *crc = bhnd_nvram_crc8(p, sizeof(*p), *crc); - p++; - }; + bhnd_bus_read_region_stream_2(sc->sp_res, res_offset, p, nbytes); + *crc = bhnd_nvram_crc8(p, nbytes, *crc); return (0); } @@ -569,4 +565,4 @@ sprom_var_defn(struct bhnd_sprom *sc, const char *name, /* Not supported by this SPROM revision */ return (ENOENT); -} \ No newline at end of file +} diff --git a/sys/dev/bhnd/tools/bus_macro.sh b/sys/dev/bhnd/tools/bus_macro.sh index a11ed0c1854a..b5de494d32b1 100644 --- a/sys/dev/bhnd/tools/bus_macro.sh +++ b/sys/dev/bhnd/tools/bus_macro.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2015 Landon Fuller +# Copyright (c) 2015-2016 Landon Fuller # Copyright (c) 2004-2005 Poul-Henning Kamp. # All rights reserved. # @@ -63,8 +63,6 @@ macro () { macro barrier o l f -# We only support a subset of the bus I/O methods; this may -# be expanded when/if additional functions are required. for w in 1 2 4 #8 do # macro copy_region_$w so dh do c @@ -74,11 +72,20 @@ do do macro read_$s$w o macro read_multi_$s$w o d c -# macro read_region_$s$w o d c -# macro set_multi_$s$w o v c -# macro set_region_$s$w o v c + macro read_region_$s$w o d c macro write_$s$w o v macro write_multi_$s$w o d c -# macro write_region_$s$w o d c + macro write_region_$s$w o d c + done + + # set_(multi_)?_stream is not supported on ARM/ARM64, and so for + # simplicity, we don't support their use with bhnd resources. + # + # if that changes, these can be merged back into the stream-eanbled + # loop above. + for s in "" + do + macro set_multi_$s$w o v c + macro set_region_$s$w o v c done done