1098ca2bdSWarner Losh /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
42ae4f1fdSMarcel Moolenaar * Copyright (c) 2003, 2004 Marcel Moolenaar
527d5dc18SMarcel Moolenaar * All rights reserved.
627d5dc18SMarcel Moolenaar *
727d5dc18SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without
827d5dc18SMarcel Moolenaar * modification, are permitted provided that the following conditions
927d5dc18SMarcel Moolenaar * are met:
1027d5dc18SMarcel Moolenaar *
1127d5dc18SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright
1227d5dc18SMarcel Moolenaar * notice, this list of conditions and the following disclaimer.
1327d5dc18SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright
1427d5dc18SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the
1527d5dc18SMarcel Moolenaar * documentation and/or other materials provided with the distribution.
1627d5dc18SMarcel Moolenaar *
1727d5dc18SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1827d5dc18SMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1927d5dc18SMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2027d5dc18SMarcel Moolenaar * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2127d5dc18SMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2227d5dc18SMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2327d5dc18SMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2427d5dc18SMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2527d5dc18SMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2627d5dc18SMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727d5dc18SMarcel Moolenaar */
2827d5dc18SMarcel Moolenaar
2927d5dc18SMarcel Moolenaar #ifndef _DEV_UART_CPU_H_
3027d5dc18SMarcel Moolenaar #define _DEV_UART_CPU_H_
3127d5dc18SMarcel Moolenaar
328af03381SMarcel Moolenaar #include <sys/kdb.h>
338af03381SMarcel Moolenaar #include <sys/lock.h>
348af03381SMarcel Moolenaar #include <sys/mutex.h>
358af03381SMarcel Moolenaar
36d76a1ef4SWarner Losh struct uart_softc;
37d76a1ef4SWarner Losh
3827d5dc18SMarcel Moolenaar /*
3927d5dc18SMarcel Moolenaar * Low-level operations for use by console and/or debug port support.
4027d5dc18SMarcel Moolenaar */
4127d5dc18SMarcel Moolenaar struct uart_ops {
4227d5dc18SMarcel Moolenaar int (*probe)(struct uart_bas *);
4327d5dc18SMarcel Moolenaar void (*init)(struct uart_bas *, int, int, int, int);
4427d5dc18SMarcel Moolenaar void (*term)(struct uart_bas *);
4527d5dc18SMarcel Moolenaar void (*putc)(struct uart_bas *, int);
4697202af2SMarius Strobl int (*rxready)(struct uart_bas *);
47634e63c9SMarcel Moolenaar int (*getc)(struct uart_bas *, struct mtx *);
4827d5dc18SMarcel Moolenaar };
4927d5dc18SMarcel Moolenaar
502ae4f1fdSMarcel Moolenaar extern bus_space_tag_t uart_bus_space_io;
512ae4f1fdSMarcel Moolenaar extern bus_space_tag_t uart_bus_space_mem;
522ae4f1fdSMarcel Moolenaar
5327d5dc18SMarcel Moolenaar /*
54ad93649dSColin Percival * PCI ID used for matching "unique" devices to a console.
55ad93649dSColin Percival */
56ad93649dSColin Percival struct uart_pci_info {
57ad93649dSColin Percival uint16_t vendor;
58ad93649dSColin Percival uint16_t device;
59ad93649dSColin Percival };
60ad93649dSColin Percival
61ad93649dSColin Percival /*
6227d5dc18SMarcel Moolenaar * Console and debug port device info.
6327d5dc18SMarcel Moolenaar */
6427d5dc18SMarcel Moolenaar struct uart_devinfo {
6527d5dc18SMarcel Moolenaar SLIST_ENTRY(uart_devinfo) next;
66f8100ce2SMarcel Moolenaar struct uart_ops *ops;
6727d5dc18SMarcel Moolenaar struct uart_bas bas;
6827d5dc18SMarcel Moolenaar int baudrate;
6927d5dc18SMarcel Moolenaar int databits;
7027d5dc18SMarcel Moolenaar int stopbits;
7127d5dc18SMarcel Moolenaar int parity;
7227d5dc18SMarcel Moolenaar int type;
7327d5dc18SMarcel Moolenaar #define UART_DEV_CONSOLE 0
7427d5dc18SMarcel Moolenaar #define UART_DEV_DBGPORT 1
7527d5dc18SMarcel Moolenaar #define UART_DEV_KEYBOARD 2
7627d5dc18SMarcel Moolenaar int (*attach)(struct uart_softc*);
7727d5dc18SMarcel Moolenaar int (*detach)(struct uart_softc*);
7827d5dc18SMarcel Moolenaar void *cookie; /* Type dependent use. */
798af03381SMarcel Moolenaar struct mtx *hwmtx;
80d76a1ef4SWarner Losh struct uart_softc *sc; /* valid only from start of attach */
81ad93649dSColin Percival struct uart_pci_info pci_info;
8227d5dc18SMarcel Moolenaar };
8327d5dc18SMarcel Moolenaar
845cc70551SMarcel Moolenaar int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
855cc70551SMarcel Moolenaar int uart_cpu_getdev(int, struct uart_devinfo *);
86f8100ce2SMarcel Moolenaar
87f8100ce2SMarcel Moolenaar int uart_getenv(int, struct uart_devinfo *, struct uart_class *);
88f8100ce2SMarcel Moolenaar const char *uart_getname(struct uart_class *);
89f8100ce2SMarcel Moolenaar struct uart_ops *uart_getops(struct uart_class *);
90f8100ce2SMarcel Moolenaar int uart_getrange(struct uart_class *);
91405ada37SAndrew Turner u_int uart_getregshift(struct uart_class *);
92c214a270SRuslan Bukin u_int uart_getregiowidth(struct uart_class *);
9327d5dc18SMarcel Moolenaar
9427d5dc18SMarcel Moolenaar void uart_add_sysdev(struct uart_devinfo *);
9527d5dc18SMarcel Moolenaar
9627d5dc18SMarcel Moolenaar /*
9727d5dc18SMarcel Moolenaar * Operations for low-level access to the UART. Primarily for use
9827d5dc18SMarcel Moolenaar * by console and debug port logic.
9927d5dc18SMarcel Moolenaar */
1008af03381SMarcel Moolenaar
1018af03381SMarcel Moolenaar static __inline void
uart_lock(struct mtx * hwmtx)1028af03381SMarcel Moolenaar uart_lock(struct mtx *hwmtx)
1038af03381SMarcel Moolenaar {
1048af03381SMarcel Moolenaar if (!kdb_active && hwmtx != NULL)
1058af03381SMarcel Moolenaar mtx_lock_spin(hwmtx);
1068af03381SMarcel Moolenaar }
1078af03381SMarcel Moolenaar
1088af03381SMarcel Moolenaar static __inline void
uart_unlock(struct mtx * hwmtx)1098af03381SMarcel Moolenaar uart_unlock(struct mtx *hwmtx)
1108af03381SMarcel Moolenaar {
1118af03381SMarcel Moolenaar if (!kdb_active && hwmtx != NULL)
1128af03381SMarcel Moolenaar mtx_unlock_spin(hwmtx);
1138af03381SMarcel Moolenaar }
1148af03381SMarcel Moolenaar
11527d5dc18SMarcel Moolenaar static __inline int
uart_probe(struct uart_devinfo * di)11627d5dc18SMarcel Moolenaar uart_probe(struct uart_devinfo *di)
11727d5dc18SMarcel Moolenaar {
1188af03381SMarcel Moolenaar int res;
1198af03381SMarcel Moolenaar
1208af03381SMarcel Moolenaar uart_lock(di->hwmtx);
121f8100ce2SMarcel Moolenaar res = di->ops->probe(&di->bas);
1228af03381SMarcel Moolenaar uart_unlock(di->hwmtx);
1238af03381SMarcel Moolenaar return (res);
12427d5dc18SMarcel Moolenaar }
12527d5dc18SMarcel Moolenaar
12627d5dc18SMarcel Moolenaar static __inline void
uart_init(struct uart_devinfo * di)12727d5dc18SMarcel Moolenaar uart_init(struct uart_devinfo *di)
12827d5dc18SMarcel Moolenaar {
1298af03381SMarcel Moolenaar uart_lock(di->hwmtx);
130f8100ce2SMarcel Moolenaar di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits,
13127d5dc18SMarcel Moolenaar di->parity);
1328af03381SMarcel Moolenaar uart_unlock(di->hwmtx);
13327d5dc18SMarcel Moolenaar }
13427d5dc18SMarcel Moolenaar
13527d5dc18SMarcel Moolenaar static __inline void
uart_term(struct uart_devinfo * di)13627d5dc18SMarcel Moolenaar uart_term(struct uart_devinfo *di)
13727d5dc18SMarcel Moolenaar {
1388af03381SMarcel Moolenaar uart_lock(di->hwmtx);
139f8100ce2SMarcel Moolenaar di->ops->term(&di->bas);
1408af03381SMarcel Moolenaar uart_unlock(di->hwmtx);
14127d5dc18SMarcel Moolenaar }
14227d5dc18SMarcel Moolenaar
14327d5dc18SMarcel Moolenaar static __inline void
uart_putc(struct uart_devinfo * di,int c)14427d5dc18SMarcel Moolenaar uart_putc(struct uart_devinfo *di, int c)
14527d5dc18SMarcel Moolenaar {
1468af03381SMarcel Moolenaar uart_lock(di->hwmtx);
147f8100ce2SMarcel Moolenaar di->ops->putc(&di->bas, c);
1488af03381SMarcel Moolenaar uart_unlock(di->hwmtx);
14927d5dc18SMarcel Moolenaar }
15027d5dc18SMarcel Moolenaar
15127d5dc18SMarcel Moolenaar static __inline int
uart_rxready(struct uart_devinfo * di)15297202af2SMarius Strobl uart_rxready(struct uart_devinfo *di)
15397202af2SMarius Strobl {
15497202af2SMarius Strobl int res;
15597202af2SMarius Strobl
15697202af2SMarius Strobl uart_lock(di->hwmtx);
157f8100ce2SMarcel Moolenaar res = di->ops->rxready(&di->bas);
15897202af2SMarius Strobl uart_unlock(di->hwmtx);
15997202af2SMarius Strobl return (res);
16097202af2SMarius Strobl }
16197202af2SMarius Strobl
16297202af2SMarius Strobl static __inline int
uart_poll(struct uart_devinfo * di)16327d5dc18SMarcel Moolenaar uart_poll(struct uart_devinfo *di)
16427d5dc18SMarcel Moolenaar {
1658af03381SMarcel Moolenaar int res;
1668af03381SMarcel Moolenaar
1678af03381SMarcel Moolenaar uart_lock(di->hwmtx);
168f8100ce2SMarcel Moolenaar if (di->ops->rxready(&di->bas))
169f8100ce2SMarcel Moolenaar res = di->ops->getc(&di->bas, NULL);
17097202af2SMarius Strobl else
17197202af2SMarius Strobl res = -1;
1728af03381SMarcel Moolenaar uart_unlock(di->hwmtx);
1738af03381SMarcel Moolenaar return (res);
17427d5dc18SMarcel Moolenaar }
17527d5dc18SMarcel Moolenaar
17627d5dc18SMarcel Moolenaar static __inline int
uart_getc(struct uart_devinfo * di)17727d5dc18SMarcel Moolenaar uart_getc(struct uart_devinfo *di)
17827d5dc18SMarcel Moolenaar {
1798af03381SMarcel Moolenaar
180f8100ce2SMarcel Moolenaar return (di->ops->getc(&di->bas, di->hwmtx));
18127d5dc18SMarcel Moolenaar }
18227d5dc18SMarcel Moolenaar
183d76a1ef4SWarner Losh void uart_grab(struct uart_devinfo *di);
184d76a1ef4SWarner Losh void uart_ungrab(struct uart_devinfo *di);
185d76a1ef4SWarner Losh
18627d5dc18SMarcel Moolenaar #endif /* _DEV_UART_CPU_H_ */
187