1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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  * $FreeBSD$
33  */
34 
35 #ifndef _DEV_ALTERA_JTAG_UART_H_
36 #define	_DEV_ALTERA_JTAG_UART_H_
37 
38 struct altera_jtag_uart_softc {
39 	device_t		 ajus_dev;
40 	int			 ajus_unit;
41 
42 	/*
43 	 * Hardware resources.
44 	 */
45 	struct resource		*ajus_irq_res;
46 	int			 ajus_irq_rid;
47 	void			*ajus_irq_cookie;
48 	struct resource		*ajus_mem_res;
49 	int			 ajus_mem_rid;
50 
51 	/*
52 	 * TTY resources.
53 	 */
54 	struct tty		*ajus_ttyp;
55 	int			 ajus_alt_break_state;
56 
57 	/*
58 	 * Driver resources.
59 	 */
60 	u_int			 ajus_flags;
61 	struct mtx		*ajus_lockp;
62 	struct mtx		 ajus_lock;
63 	struct callout		 ajus_io_callout;
64 	struct callout		 ajus_ac_callout;
65 
66 	/*
67 	 * One-character buffer required because it's not possible to peek at
68 	 * the input FIFO without reading it.
69 	 */
70 	int			 ajus_buffer_valid;
71 	int			*ajus_buffer_validp;
72 	uint8_t			 ajus_buffer_data;
73 	uint8_t			*ajus_buffer_datap;
74 	int			 ajus_jtag_present;
75 	int			*ajus_jtag_presentp;
76 	u_int			 ajus_jtag_missed;
77 	u_int			*ajus_jtag_missedp;
78 };
79 
80 #define	AJU_TTYNAME	"ttyj"
81 
82 /*
83  * Flag values for ajus_flags.
84  */
85 #define	ALTERA_JTAG_UART_FLAG_CONSOLE	0x00000001	/* Is console. */
86 
87 /*
88  * Because tty-level use of the I/O ports completes with low-level console
89  * use, spinlocks must be employed here.
90  */
91 #define	AJU_CONSOLE_LOCK_INIT() do {					\
92 	mtx_init(&aju_cons_lock, "aju_cons_lock", NULL, MTX_SPIN);	\
93 } while (0)
94 
95 #define	AJU_CONSOLE_LOCK() do {						\
96 	if (!kdb_active)						\
97 		mtx_lock_spin(&aju_cons_lock);				\
98 } while (0)
99 
100 #define	AJU_CONSOLE_LOCK_ASSERT() {					\
101 	if (!kdb_active)						\
102 		mtx_assert(&aju_cons_lock, MA_OWNED);			\
103 } while (0)
104 
105 #define	AJU_CONSOLE_UNLOCK() do {					\
106 	if (!kdb_active)						\
107 		mtx_unlock_spin(&aju_cons_lock);			\
108 } while (0)
109 
110 #define	AJU_LOCK_INIT(sc) do {						\
111 	mtx_init(&(sc)->ajus_lock, "aju_lock", NULL, MTX_SPIN);		\
112 } while (0)
113 
114 #define	AJU_LOCK_DESTROY(sc) do {					\
115 	mtx_destroy(&(sc)->ajus_lock);					\
116 } while (0)
117 
118 #define	AJU_LOCK(sc) do {						\
119 	mtx_lock_spin((sc)->ajus_lockp);				\
120 } while (0)
121 
122 #define	AJU_LOCK_ASSERT(sc) do {					\
123 	mtx_assert((sc)->ajus_lockp, MA_OWNED);				\
124 } while (0)
125 
126 #define	AJU_UNLOCK(sc) do {						\
127 	mtx_unlock_spin((sc)->ajus_lockp);				\
128 } while (0)
129 
130 /*
131  * When a TTY-level Altera JTAG UART instance is also the low-level console,
132  * the TTY layer borrows the console-layer lock and buffer rather than using
133  * its own.
134  */
135 extern struct mtx	aju_cons_lock;
136 extern char  		aju_cons_buffer_data;
137 extern int		aju_cons_buffer_valid;
138 extern int		aju_cons_jtag_present;
139 extern u_int		aju_cons_jtag_missed;
140 
141 /*
142  * Base physical address of the JTAG UART in BERI.
143  */
144 #define	BERI_UART_BASE		0x7f000000	/* JTAG UART */
145 
146 /*-
147  * Routines for interacting with the BERI console JTAG UART.  Programming
148  * details from the June 2011 "Embedded Peripherals User Guide" by Altera
149  * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register
150  * Bits), and 6-4 (Control Register Bits).
151  *
152  * Offsets of data and control registers relative to the base.  Altera
153  * conventions are maintained in BERI.
154  */
155 #define	ALTERA_JTAG_UART_DATA_OFF	0x00000000
156 #define	ALTERA_JTAG_UART_CONTROL_OFF	0x00000004
157 
158 /*
159  * Offset 0: 'data' register -- bits 31-16 (RAVAIL), 15 (RVALID),
160  * 14-8 (Reserved), 7-0 (DATA).
161  *
162  * DATA - One byte read or written.
163  * RAVAIL - Bytes available to read (excluding the current byte).
164  * RVALID - Whether the byte in DATA is valid.
165  */
166 #define	ALTERA_JTAG_UART_DATA_DATA		0x000000ff
167 #define	ALTERA_JTAG_UART_DATA_RESERVED		0x00007f00
168 #define	ALTERA_JTAG_UART_DATA_RVALID		0x00008000
169 #define	ALTERA_JTAG_UART_DATA_RAVAIL		0xffff0000
170 #define	ALTERA_JTAG_UART_DATA_RAVAIL_SHIFT	16
171 
172 /*-
173  * Offset 1: 'control' register -- bits 31-16 (WSPACE), 15-11 (Reserved),
174  * 10 (AC), 9 (WI), 8 (RI), 7..2 (Reserved), 1 (WE), 0 (RE).
175  *
176  * RE - Enable read interrupts.
177  * WE - Enable write interrupts.
178  * RI - Read interrupt pending.
179  * WI - Write interrupt pending.
180  * AC - Activity bit; set to '1' to clear to '0'.
181  * WSPACE - Space available in the write FIFO.
182  */
183 #define	ALTERA_JTAG_UART_CONTROL_RE		0x00000001
184 #define	ALTERA_JTAG_UART_CONTROL_WE		0x00000002
185 #define	ALTERA_JTAG_UART_CONTROL_RESERVED0	0x000000fc
186 #define	ALTERA_JTAG_UART_CONTROL_RI		0x00000100
187 #define	ALTERA_JTAG_UART_CONTROL_WI		0x00000200
188 #define	ALTERA_JTAG_UART_CONTROL_AC		0x00000400
189 #define	ALTERA_JTAG_UART_CONTROL_RESERVED1	0x0000f800
190 #define	ALTERA_JTAG_UART_CONTROL_WSPACE		0xffff0000
191 #define	ALTERA_JTAG_UART_CONTROL_WSPACE_SHIFT	16
192 
193 /*
194  * Driver attachment functions for Nexus.
195  */
196 int	altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc);
197 void	altera_jtag_uart_detach(struct altera_jtag_uart_softc *sc);
198 
199 extern devclass_t	altera_jtag_uart_devclass;
200 
201 #endif /* _DEV_ALTERA_JTAG_UART_H_ */
202