diff options
| author | jmcneill <jmcneill@NetBSD.org> | 2021-11-12 21:57:13 +0000 |
|---|---|---|
| committer | jmcneill <jmcneill@NetBSD.org> | 2021-11-12 21:57:13 +0000 |
| commit | 8a1b50e613342fa17a6cb5ce319f41117eb8cc4c (patch) | |
| tree | c1ca5f50b1dc8c80c7398e9c3027c46470774f49 /sys/dev/ic | |
| parent | 48f441c5af7a9cabf0e5c30a089a2abe7fa82e22 (diff) | |
com: Add support for 32-bit IO accesses.
Diffstat (limited to 'sys/dev/ic')
| -rw-r--r-- | sys/dev/ic/com.c | 117 | ||||
| -rw-r--r-- | sys/dev/ic/comvar.h | 10 |
2 files changed, 118 insertions, 9 deletions
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index 83213fc24f6..cf09cb54017 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.372 2021/10/30 11:43:17 jmcneill Exp $ */ +/* $NetBSD: com.c,v 1.373 2021/11/12 21:57:13 jmcneill Exp $ */ /*- * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.372 2021/10/30 11:43:17 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.373 2021/11/12 21:57:13 jmcneill Exp $"); #include "opt_com.h" #include "opt_ddb.h" @@ -128,17 +128,20 @@ __KERNEL_RCSID(0, "$NetBSD: com.c,v 1.372 2021/10/30 11:43:17 jmcneill Exp $"); #include "ioconf.h" -#define CSR_WRITE_1(r, o, v) \ - bus_space_write_1((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o], v) #define CSR_READ_1(r, o) \ - bus_space_read_1((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o]) + (r)->cr_read((r), (r)->cr_map[o]) +#define CSR_WRITE_1(r, o, v) \ + (r)->cr_write((r), (r)->cr_map[o], (v)) +#define CSR_WRITE_MULTI(r, o, p, n) \ + (r)->cr_write_multi((r), (r)->cr_map[o], (p), (n)) + +/* + * XXX COM_TYPE_AU1x00 specific + */ #define CSR_WRITE_2(r, o, v) \ bus_space_write_2((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o], v) #define CSR_READ_2(r, o) \ bus_space_read_2((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o]) -#define CSR_WRITE_MULTI(r, o, p, n) \ - bus_space_write_multi_1((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o], p, n) - static void com_enable_debugport(struct com_softc *); @@ -275,6 +278,70 @@ static const bus_size_t com_std_map[COM_REGMAP_NENTRIES] = { bus_space_barrier((r)->cr_iot, (r)->cr_ioh, 0, (r)->cr_nports, (f)) /* + * com_read_1 -- + * Default register read callback using single byte accesses. + */ +static uint8_t +com_read_1(struct com_regs *regs, u_int reg) +{ + return bus_space_read_1(regs->cr_iot, regs->cr_ioh, reg); +} + +/* + * com_write_1 -- + * Default register write callback using single byte accesses. + */ +static void +com_write_1(struct com_regs *regs, u_int reg, uint8_t val) +{ + bus_space_write_1(regs->cr_iot, regs->cr_ioh, reg, val); +} + +/* + * com_write_multi_1 -- + * Default register multi write callback using single byte accesses. + */ +static void +com_write_multi_1(struct com_regs *regs, u_int reg, const uint8_t *datap, + bus_size_t count) +{ + bus_space_write_multi_1(regs->cr_iot, regs->cr_ioh, reg, datap, count); +} + +/* + * com_read_4 -- + * Default register read callback using dword accesses. + */ +static uint8_t +com_read_4(struct com_regs *regs, u_int reg) +{ + return bus_space_read_4(regs->cr_iot, regs->cr_ioh, reg) & 0xff; +} + +/* + * com_write_4 -- + * Default register write callback using dword accesses. + */ +static void +com_write_4(struct com_regs *regs, u_int reg, uint8_t val) +{ + bus_space_write_4(regs->cr_iot, regs->cr_ioh, reg, val); +} + +/* + * com_write_multi_4 -- + * Default register multi write callback using dword accesses. + */ +static void +com_write_multi_4(struct com_regs *regs, u_int reg, const uint8_t *datap, + bus_size_t count) +{ + while (count-- > 0) { + bus_space_write_4(regs->cr_iot, regs->cr_ioh, reg, *datap++); + } +} + +/* * com_init_regs -- * Driver front-ends use this to initialize our register map * in the standard fashion. They may then tailor the map to @@ -290,6 +357,9 @@ com_init_regs(struct com_regs *regs, bus_space_tag_t st, bus_space_handle_t sh, regs->cr_ioh = sh; regs->cr_iobase = addr; regs->cr_nports = COM_NPORTS; + regs->cr_read = com_read_1; + regs->cr_write = com_write_1; + regs->cr_write_multi = com_write_multi_1; memcpy(regs->cr_map, com_std_map, sizeof(regs->cr_map)); } @@ -310,6 +380,37 @@ com_init_regs_stride(struct com_regs *regs, bus_space_tag_t st, regs->cr_nports <<= regshift; } +/* + * com_init_regs_stride_width -- + * Convenience function for front-ends that have a stride between + * registers and specific I/O width requirements. + */ +void +com_init_regs_stride_width(struct com_regs *regs, bus_space_tag_t st, + bus_space_handle_t sh, bus_addr_t addr, + u_int regshift, u_int width) +{ + + com_init_regs(regs, st, sh, addr); + for (size_t i = 0; i < __arraycount(regs->cr_map); i++) { + regs->cr_map[i] <<= regshift; + } + regs->cr_nports <<= regshift; + + switch (width) { + case 1: + /* Already set by com_init_regs */ + break; + case 4: + regs->cr_read = com_read_4; + regs->cr_write = com_write_4; + regs->cr_write_multi = com_write_multi_4; + break; + default: + panic("com: unsupported I/O width %d", width); + } +} + /*ARGSUSED*/ int comspeed(long speed, long frequency, int type) diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h index c7650e20236..9aeda39c786 100644 --- a/sys/dev/ic/comvar.h +++ b/sys/dev/ic/comvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: comvar.h,v 1.95 2021/10/12 00:21:34 thorpej Exp $ */ +/* $NetBSD: comvar.h,v 1.96 2021/11/12 21:57:13 jmcneill Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -103,12 +103,20 @@ struct com_regs { bus_addr_t cr_iobase; bus_size_t cr_nports; bus_size_t cr_map[COM_REGMAP_NENTRIES]; + uint8_t (*cr_read)(struct com_regs *, u_int); + void (*cr_write)(struct com_regs *, u_int, uint8_t); + void (*cr_write_multi)(struct com_regs *, u_int, + const uint8_t *, + bus_size_t); + }; void com_init_regs(struct com_regs *, bus_space_tag_t, bus_space_handle_t, bus_addr_t); void com_init_regs_stride(struct com_regs *, bus_space_tag_t, bus_space_handle_t, bus_addr_t, u_int); +void com_init_regs_stride_width(struct com_regs *, bus_space_tag_t, + bus_space_handle_t, bus_addr_t, u_int, u_int); struct comcons_info { struct com_regs regs; |
