1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2011-2012 Robert N. M. Watson
5  * All rights reserved.
6  *
7  * This software was developed by SRI International and the University of
8  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9  * ("CTSRD"), as part of the DARPA CRASH research programme.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifndef _DEV_ALTERA_JTAG_UART_H_
34 #define	_DEV_ALTERA_JTAG_UART_H_
35 
36 struct altera_jtag_uart_softc {
37 	device_t		 ajus_dev;
38 	int			 ajus_unit;
39 
40 	/*
41 	 * Hardware resources.
42 	 */
43 	struct resource		*ajus_irq_res;
44 	int			 ajus_irq_rid;
45 	void			*ajus_irq_cookie;
46 	struct resource		*ajus_mem_res;
47 	int			 ajus_mem_rid;
48 
49 	/*
50 	 * TTY resources.
51 	 */
52 	struct tty		*ajus_ttyp;
53 	int			 ajus_alt_break_state;
54 
55 	/*
56 	 * Driver resources.
57 	 */
58 	u_int			 ajus_flags;
59 	struct mtx		*ajus_lockp;
60 	struct mtx		 ajus_lock;
61 	struct callout		 ajus_io_callout;
62 	struct callout		 ajus_ac_callout;
63 
64 	/*
65 	 * One-character buffer required because it's not possible to peek at
66 	 * the input FIFO without reading it.
67 	 */
68 	int			 ajus_buffer_valid;
69 	int			*ajus_buffer_validp;
70 	uint8_t			 ajus_buffer_data;
71 	uint8_t			*ajus_buffer_datap;
72 	int			 ajus_jtag_present;
73 	int			*ajus_jtag_presentp;
74 	u_int			 ajus_jtag_missed;
75 	u_int			*ajus_jtag_missedp;
76 };
77 
78 #define	AJU_TTYNAME	"ttyj"
79 
80 /*
81  * Flag values for ajus_flags.
82  */
83 #define	ALTERA_JTAG_UART_FLAG_CONSOLE	0x00000001	/* Is console. */
84 
85 /*
86  * Because tty-level use of the I/O ports completes with low-level console
87  * use, spinlocks must be employed here.
88  */
89 #define	AJU_CONSOLE_LOCK_INIT() do {					\
90 	mtx_init(&aju_cons_lock, "aju_cons_lock", NULL, MTX_SPIN);	\
91 } while (0)
92 
93 #define	AJU_CONSOLE_LOCK() do {						\
94 	if (!kdb_active)						\
95 		mtx_lock_spin(&aju_cons_lock);				\
96 } while (0)
97 
98 #define	AJU_CONSOLE_LOCK_ASSERT() {					\
99 	if (!kdb_active)						\
100 		mtx_assert(&aju_cons_lock, MA_OWNED);			\
101 } while (0)
102 
103 #define	AJU_CONSOLE_UNLOCK() do {					\
104 	if (!kdb_active)						\
105 		mtx_unlock_spin(&aju_cons_lock);			\
106 } while (0)
107 
108 #define	AJU_LOCK_INIT(sc) do {						\
109 	mtx_init(&(sc)->ajus_lock, "aju_lock", NULL, MTX_SPIN);		\
110 } while (0)
111 
112 #define	AJU_LOCK_DESTROY(sc) do {					\
113 	mtx_destroy(&(sc)->ajus_lock);					\
114 } while (0)
115 
116 #define	AJU_LOCK(sc) do {						\
117 	mtx_lock_spin((sc)->ajus_lockp);				\
118 } while (0)
119 
120 #define	AJU_LOCK_ASSERT(sc) do {					\
121 	mtx_assert((sc)->ajus_lockp, MA_OWNED);				\
122 } while (0)
123 
124 #define	AJU_UNLOCK(sc) do {						\
125 	mtx_unlock_spin((sc)->ajus_lockp);				\
126 } while (0)
127 
128 /*
129  * When a TTY-level Altera JTAG UART instance is also the low-level console,
130  * the TTY layer borrows the console-layer lock and buffer rather than using
131  * its own.
132  */
133 extern struct mtx	aju_cons_lock;
134 extern char  		aju_cons_buffer_data;
135 extern int		aju_cons_buffer_valid;
136 extern int		aju_cons_jtag_present;
137 extern u_int		aju_cons_jtag_missed;
138 
139 /*
140  * Base physical address of the JTAG UART in BERI.
141  */
142 #define	BERI_UART_BASE		0x7f000000	/* JTAG UART */
143 
144 /*-
145  * Routines for interacting with the BERI console JTAG UART.  Programming
146  * details from the June 2011 "Embedded Peripherals User Guide" by Altera
147  * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register
148  * Bits), and 6-4 (Control Register Bits).
149  *
150  * Offsets of data and control registers relative to the base.  Altera
151  * conventions are maintained in BERI.
152  */
153 #define	ALTERA_JTAG_UART_DATA_OFF	0x00000000
154 #define	ALTERA_JTAG_UART_CONTROL_OFF	0x00000004
155 
156 /*
157  * Offset 0: 'data' register -- bits 31-16 (RAVAIL), 15 (RVALID),
158  * 14-8 (Reserved), 7-0 (DATA).
159  *
160  * DATA - One byte read or written.
161  * RAVAIL - Bytes available to read (excluding the current byte).
162  * RVALID - Whether the byte in DATA is valid.
163  */
164 #define	ALTERA_JTAG_UART_DATA_DATA		0x000000ff
165 #define	ALTERA_JTAG_UART_DATA_RESERVED		0x00007f00
166 #define	ALTERA_JTAG_UART_DATA_RVALID		0x00008000
167 #define	ALTERA_JTAG_UART_DATA_RAVAIL		0xffff0000
168 #define	ALTERA_JTAG_UART_DATA_RAVAIL_SHIFT	16
169 
170 /*-
171  * Offset 1: 'control' register -- bits 31-16 (WSPACE), 15-11 (Reserved),
172  * 10 (AC), 9 (WI), 8 (RI), 7..2 (Reserved), 1 (WE), 0 (RE).
173  *
174  * RE - Enable read interrupts.
175  * WE - Enable write interrupts.
176  * RI - Read interrupt pending.
177  * WI - Write interrupt pending.
178  * AC - Activity bit; set to '1' to clear to '0'.
179  * WSPACE - Space available in the write FIFO.
180  */
181 #define	ALTERA_JTAG_UART_CONTROL_RE		0x00000001
182 #define	ALTERA_JTAG_UART_CONTROL_WE		0x00000002
183 #define	ALTERA_JTAG_UART_CONTROL_RESERVED0	0x000000fc
184 #define	ALTERA_JTAG_UART_CONTROL_RI		0x00000100
185 #define	ALTERA_JTAG_UART_CONTROL_WI		0x00000200
186 #define	ALTERA_JTAG_UART_CONTROL_AC		0x00000400
187 #define	ALTERA_JTAG_UART_CONTROL_RESERVED1	0x0000f800
188 #define	ALTERA_JTAG_UART_CONTROL_WSPACE		0xffff0000
189 #define	ALTERA_JTAG_UART_CONTROL_WSPACE_SHIFT	16
190 
191 /*
192  * Driver attachment functions for Nexus.
193  */
194 int	altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc);
195 void	altera_jtag_uart_detach(struct altera_jtag_uart_softc *sc);
196 
197 #endif /* _DEV_ALTERA_JTAG_UART_H_ */
198