1262197Srwatson/*-
2262197Srwatson * Copyright (c) 2011, 2013 Robert N. M. Watson
3262197Srwatson * All rights reserved.
4262197Srwatson *
5262197Srwatson * This software was developed by SRI International and the University of
6262197Srwatson * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7262197Srwatson * ("CTSRD"), as part of the DARPA CRASH research programme.
8262197Srwatson *
9262197Srwatson * Redistribution and use in source and binary forms, with or without
10262197Srwatson * modification, are permitted provided that the following conditions
11262197Srwatson * are met:
12262197Srwatson * 1. Redistributions of source code must retain the above copyright
13262197Srwatson *    notice, this list of conditions and the following disclaimer.
14262197Srwatson * 2. Redistributions in binary form must reproduce the above copyright
15262197Srwatson *    notice, this list of conditions and the following disclaimer in the
16262197Srwatson *    documentation and/or other materials provided with the distribution.
17262197Srwatson *
18262197Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19262197Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20262197Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21262197Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22262197Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23262197Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24262197Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25262197Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26262197Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27262197Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28262197Srwatson * SUCH DAMAGE.
29262197Srwatson *
30262197Srwatson * $FreeBSD: stable/11/stand/mips/beri/common/altera_jtag_uart.c 332149 2018-04-06 19:59:27Z kevans $
31262197Srwatson */
32262197Srwatson
33329175Skevans#include "stand.h"
34262197Srwatson#include "mips.h"
35262197Srwatson
36262197Srwatson/*-
37262197Srwatson * Routines for interacting with the CHERI console UART.  Programming details
38262197Srwatson * from the June 2011 "Embedded Peripherals User Guide" by Altera
39262197Srwatson * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register
40262197Srwatson * Bits), and 6-4 (Control Register Bits).
41262197Srwatson *
42262197Srwatson * Hard-coded physical address for the first JTAG UART -- true on all BERI and
43262197Srwatson * CHERI boards.
44262197Srwatson */
45262197Srwatson#define	CHERI_UART_BASE		0x7f000000	/* JTAG UART */
46262197Srwatson
47262197Srwatson/*
48262197Srwatson *
49262197Srwatson * Offsets of data and control registers relative to the base.  Altera
50262197Srwatson * conventions are maintained in CHERI.
51262197Srwatson */
52262197Srwatson#define	ALTERA_JTAG_UART_DATA_OFF	0x00000000
53262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_OFF	0x00000004
54262197Srwatson
55262197Srwatson/*
56262197Srwatson * Offset 0: 'data' register -- bits 31-16 (RAVAIL), 15 (RVALID),
57262197Srwatson * 14-8 (Reserved), 7-0 (DATA).
58262197Srwatson *
59262197Srwatson * DATA - One byte read or written.
60262197Srwatson * RAVAIL - Bytes available to read (excluding the current byte).
61262197Srwatson * RVALID - Whether the byte in DATA is valid.
62262197Srwatson */
63262197Srwatson#define	ALTERA_JTAG_UART_DATA_DATA		0x000000ff
64262197Srwatson#define	ALTERA_JTAG_UART_DATA_RESERVED		0x00007f00
65262197Srwatson#define	ALTERA_JTAG_UART_DATA_RVALID		0x00008000
66262197Srwatson#define	ALTERA_JTAG_UART_DATA_RAVAIL		0xffff0000
67262197Srwatson#define	ALTERA_JTAG_UART_DATA_RAVAIL_SHIFT	16
68262197Srwatson
69262197Srwatson/*-
70262197Srwatson * Offset 1: 'control' register -- bits 31-16 (WSPACE), 15-11 (Reserved),
71262197Srwatson * 10 (AC), 9 (WI), 8 (RI), 7..2 (Reserved), 1 (WE), 0 (RE).
72262197Srwatson *
73262197Srwatson * RE - Enable read interrupts.
74262197Srwatson * WE - Enable write interrupts.
75262197Srwatson * RI - Read interrupt pending.
76262197Srwatson * WI - Write interrupt pending.
77262197Srwatson * AC - Activity bit; set to '1' to clear to '0'.
78262197Srwatson * WSPACE - Space available in the write FIFO.
79262197Srwatson */
80262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_RE		0x00000001
81262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_WE		0x00000002
82262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_RESERVED0	0x000000fc
83262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_RI		0x00000100
84262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_WI		0x00000200
85262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_AC		0x00000400
86262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_RESERVED1	0x0000f800
87262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_WSPACE		0xffff0000
88262197Srwatson#define	ALTERA_JTAG_UART_CONTROL_WSPACE_SHIFT	16
89262197Srwatson
90262197Srwatson/*
91262197Srwatson * One-byte buffer as we can't check whether the UART is readable without
92262197Srwatson * actually reading from it.
93262197Srwatson */
94262197Srwatsonstatic char	buffer_data;
95262197Srwatsonstatic int	buffer_valid;
96262197Srwatson
97262197Srwatson/*
98262197Srwatson * Low-level read and write register routines; the Altera UART is little
99262197Srwatson * endian, so we byte swap 32-bit reads and writes.
100262197Srwatson */
101262197Srwatsonstatic inline uint32_t
102262197Srwatsonuart_data_read(void)
103262197Srwatson{
104262197Srwatson
105262197Srwatson	return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
106262197Srwatson	    ALTERA_JTAG_UART_DATA_OFF)));
107262197Srwatson}
108262197Srwatson
109262197Srwatsonstatic inline void
110262197Srwatsonuart_data_write(uint32_t v)
111262197Srwatson{
112262197Srwatson
113262197Srwatson	mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
114262197Srwatson	    ALTERA_JTAG_UART_DATA_OFF), v);
115262197Srwatson}
116262197Srwatson
117262197Srwatsonstatic inline uint32_t
118262197Srwatsonuart_control_read(void)
119262197Srwatson{
120262197Srwatson
121262197Srwatson	return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
122262197Srwatson	    ALTERA_JTAG_UART_CONTROL_OFF)));
123262197Srwatson}
124262197Srwatson
125262197Srwatsonstatic inline void
126262197Srwatsonuart_control_write(uint32_t v)
127262197Srwatson{
128262197Srwatson
129262197Srwatson	mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
130262197Srwatson	    ALTERA_JTAG_UART_DATA_OFF), v);
131262197Srwatson}
132262197Srwatson
133262197Srwatsonstatic int
134262197Srwatsonuart_readable(void)
135262197Srwatson{
136262197Srwatson	uint32_t v;
137262197Srwatson
138262197Srwatson	if (buffer_valid)
139262197Srwatson		return (1);
140262197Srwatson	v = uart_data_read();
141262197Srwatson	if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) {
142262197Srwatson		buffer_valid = 1;
143262197Srwatson		buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA);
144262197Srwatson	}
145262197Srwatson	return (0);
146262197Srwatson}
147262197Srwatson
148262197Srwatsonint
149262197Srwatsonkeyhit(int seconds)
150262197Srwatson{
151262197Srwatson	register_t stoptime;
152262197Srwatson
153262197Srwatson	stoptime = cp0_count_get() + seconds * 100000000;	/* 100 MHz. */
154262197Srwatson	do {
155262197Srwatson		if (uart_readable())
156262197Srwatson			return (1);
157262197Srwatson	} while (cp0_count_get() < stoptime);
158262197Srwatson	return (0);
159262197Srwatson}
160262197Srwatson
161262197Srwatsonint
162332149Skevansberi_getc(void)
163262197Srwatson{
164262197Srwatson
165262197Srwatson	while (!(uart_readable()));
166262197Srwatson	buffer_valid = 0;
167262197Srwatson	return (buffer_data);
168262197Srwatson}
169262197Srwatson
170262197Srwatsonvoid
171332149Skevansberi_putc(int ch)
172262197Srwatson{
173262197Srwatson
174262197Srwatson	uart_data_write(ch);
175262197Srwatson}
176