1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2011 by Nathan Whitehorn. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 #include <sys/endian.h>
29 #include <sys/param.h>
30 #include <sys/kdb.h>
31 #include <sys/kernel.h>
32 #include <sys/priv.h>
33 #include <sys/systm.h>
34 #include <sys/module.h>
35 #include <sys/types.h>
36 #include <sys/conf.h>
37 #include <sys/cons.h>
38 #include <sys/tty.h>
39 #include <machine/bus.h>
40
41 #include <dev/ofw/openfirm.h>
42 #include <dev/ofw/ofw_bus.h>
43 #include <dev/ofw/ofw_bus_subr.h>
44 #include <dev/uart/uart.h>
45 #include <dev/uart/uart_cpu.h>
46 #include <dev/uart/uart_bus.h>
47
48 #include "phyp-hvcall.h"
49 #include "uart_if.h"
50
51 struct uart_phyp_softc {
52 device_t dev;
53 phandle_t node;
54 int vtermid;
55
56 struct tty *tp;
57 struct resource *irqres;
58 int irqrid;
59 struct callout callout;
60 void *sc_icookie;
61 int polltime;
62
63 struct mtx sc_mtx;
64 int protocol;
65
66 union {
67 uint64_t u64[2];
68 char str[16];
69 } phyp_inbuf;
70 uint64_t inbuflen;
71 uint8_t outseqno;
72 };
73
74 static struct uart_phyp_softc *console_sc = NULL;
75 #if defined(KDB)
76 static int alt_break_state;
77 #endif
78
79 enum {
80 HVTERM1, HVTERMPROT
81 };
82
83 #define VS_DATA_PACKET_HEADER 0xff
84 #define VS_CONTROL_PACKET_HEADER 0xfe
85 #define VSV_SET_MODEM_CTL 0x01
86 #define VSV_MODEM_CTL_UPDATE 0x02
87 #define VSV_RENEGOTIATE_CONNECTION 0x03
88 #define VS_QUERY_PACKET_HEADER 0xfd
89 #define VSV_SEND_VERSION_NUMBER 0x01
90 #define VSV_SEND_MODEM_CTL_STATUS 0x02
91 #define VS_QUERY_RESPONSE_PACKET_HEADER 0xfc
92
93 static int uart_phyp_probe(device_t dev);
94 static int uart_phyp_attach(device_t dev);
95 static void uart_phyp_intr(void *v);
96
97 static device_method_t uart_phyp_methods[] = {
98 /* Device interface */
99 DEVMETHOD(device_probe, uart_phyp_probe),
100 DEVMETHOD(device_attach, uart_phyp_attach),
101
102 DEVMETHOD_END
103 };
104
105 static driver_t uart_phyp_driver = {
106 "uart",
107 uart_phyp_methods,
108 sizeof(struct uart_phyp_softc),
109 };
110
111 DRIVER_MODULE(uart_phyp, vdevice, uart_phyp_driver, 0, 0);
112
113 static cn_probe_t uart_phyp_cnprobe;
114 static cn_init_t uart_phyp_cninit;
115 static cn_term_t uart_phyp_cnterm;
116 static cn_getc_t uart_phyp_cngetc;
117 static cn_putc_t uart_phyp_cnputc;
118 static cn_grab_t uart_phyp_cngrab;
119 static cn_ungrab_t uart_phyp_cnungrab;
120
121 CONSOLE_DRIVER(uart_phyp);
122
123 static void uart_phyp_ttyoutwakeup(struct tty *tp);
124
125 static struct ttydevsw uart_phyp_tty_class = {
126 .tsw_flags = TF_INITLOCK|TF_CALLOUT,
127 .tsw_outwakeup = uart_phyp_ttyoutwakeup,
128 };
129
130 static int
uart_phyp_probe_node(struct uart_phyp_softc * sc)131 uart_phyp_probe_node(struct uart_phyp_softc *sc)
132 {
133 phandle_t node = sc->node;
134 uint32_t reg;
135 char buf[64];
136
137 sc->inbuflen = 0;
138 sc->outseqno = 0;
139
140 if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0)
141 return (ENXIO);
142 if (strcmp(buf, "vty") != 0)
143 return (ENXIO);
144
145 if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0)
146 return (ENXIO);
147 if (strcmp(buf, "serial") != 0)
148 return (ENXIO);
149
150 reg = -1;
151 OF_getencprop(node, "reg", ®, sizeof(reg));
152 if (reg == -1)
153 return (ENXIO);
154 sc->vtermid = reg;
155 sc->node = node;
156
157 if (OF_getprop(node, "compatible", buf, sizeof(buf)) <= 0)
158 return (ENXIO);
159 if (strcmp(buf, "hvterm1") == 0) {
160 sc->protocol = HVTERM1;
161 return (0);
162 } else if (strcmp(buf, "hvterm-protocol") == 0) {
163 sc->protocol = HVTERMPROT;
164 return (0);
165 }
166
167 return (ENXIO);
168 }
169
170 static int
uart_phyp_probe(device_t dev)171 uart_phyp_probe(device_t dev)
172 {
173 const char *name;
174 struct uart_phyp_softc sc;
175 int err;
176
177 name = ofw_bus_get_name(dev);
178 if (name == NULL || strcmp(name, "vty") != 0)
179 return (ENXIO);
180
181 sc.node = ofw_bus_get_node(dev);
182 err = uart_phyp_probe_node(&sc);
183 if (err != 0)
184 return (err);
185
186 device_set_desc(dev, "POWER Hypervisor Virtual Serial Port");
187
188 return (err);
189 }
190
191 static void
uart_phyp_cnprobe(struct consdev * cp)192 uart_phyp_cnprobe(struct consdev *cp)
193 {
194 char buf[64];
195 ihandle_t stdout;
196 phandle_t input, chosen;
197 static struct uart_phyp_softc sc;
198
199 if ((chosen = OF_finddevice("/chosen")) == -1)
200 goto fail;
201
202 /* Check if OF has an active stdin/stdout */
203 input = -1;
204 if (OF_getencprop(chosen, "stdout", &stdout,
205 sizeof(stdout)) == sizeof(stdout) && stdout != 0)
206 input = OF_instance_to_package(stdout);
207 if (input == -1)
208 goto fail;
209
210 if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
211 goto fail;
212 if (strcmp(buf, "serial") != 0)
213 goto fail;
214
215 sc.node = input;
216 if (uart_phyp_probe_node(&sc) != 0)
217 goto fail;
218 mtx_init(&sc.sc_mtx, "uart_phyp", NULL, MTX_SPIN | MTX_QUIET |
219 MTX_NOWITNESS);
220
221 cp->cn_pri = CN_NORMAL;
222 console_sc = ≻
223 return;
224
225 fail:
226 cp->cn_pri = CN_DEAD;
227 return;
228 }
229
230 static int
uart_phyp_attach(device_t dev)231 uart_phyp_attach(device_t dev)
232 {
233 struct uart_phyp_softc *sc;
234 int unit;
235
236 sc = device_get_softc(dev);
237 sc->dev = dev;
238 sc->node = ofw_bus_get_node(dev);
239 uart_phyp_probe_node(sc);
240
241 unit = device_get_unit(dev);
242 sc->tp = tty_alloc(&uart_phyp_tty_class, sc);
243 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL,
244 MTX_SPIN | MTX_QUIET | MTX_NOWITNESS);
245
246 if (console_sc != NULL && console_sc->vtermid == sc->vtermid) {
247 sc->outseqno = console_sc->outseqno;
248 console_sc = sc;
249 sprintf(uart_phyp_consdev.cn_name, "ttyu%r", unit);
250 tty_init_console(sc->tp, 0);
251 }
252
253 sc->irqrid = 0;
254 sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqrid,
255 RF_ACTIVE | RF_SHAREABLE);
256 if (sc->irqres != NULL) {
257 bus_setup_intr(dev, sc->irqres, INTR_TYPE_TTY | INTR_MPSAFE,
258 NULL, uart_phyp_intr, sc, &sc->sc_icookie);
259 } else {
260 callout_init(&sc->callout, 1);
261 sc->polltime = hz / 20;
262 if (sc->polltime < 1)
263 sc->polltime = 1;
264 callout_reset(&sc->callout, sc->polltime, uart_phyp_intr, sc);
265 }
266
267 tty_makedev(sc->tp, NULL, "u%r", unit);
268
269 return (0);
270 }
271
272 static void
uart_phyp_cninit(struct consdev * cp)273 uart_phyp_cninit(struct consdev *cp)
274 {
275
276 strcpy(cp->cn_name, "phypcons");
277 }
278
279 static void
uart_phyp_cnterm(struct consdev * cp)280 uart_phyp_cnterm(struct consdev *cp)
281 {
282 }
283
284 static int
uart_phyp_get(struct uart_phyp_softc * sc,void * buffer,size_t bufsize)285 uart_phyp_get(struct uart_phyp_softc *sc, void *buffer, size_t bufsize)
286 {
287 int err;
288 int hdr = 0;
289 uint64_t i, j;
290
291 uart_lock(&sc->sc_mtx);
292 if (sc->inbuflen == 0) {
293 err = phyp_pft_hcall(H_GET_TERM_CHAR, sc->vtermid,
294 0, 0, 0, &sc->inbuflen, &sc->phyp_inbuf.u64[0],
295 &sc->phyp_inbuf.u64[1]);
296 #if BYTE_ORDER == LITTLE_ENDIAN
297 sc->phyp_inbuf.u64[0] = be64toh(sc->phyp_inbuf.u64[0]);
298 sc->phyp_inbuf.u64[1] = be64toh(sc->phyp_inbuf.u64[1]);
299 #endif
300 if (err != H_SUCCESS) {
301 uart_unlock(&sc->sc_mtx);
302 return (-1);
303 }
304 hdr = 1;
305 }
306
307 if (sc->inbuflen == 0) {
308 uart_unlock(&sc->sc_mtx);
309 return (0);
310 }
311
312 if ((sc->protocol == HVTERMPROT) && (hdr == 1)) {
313 sc->inbuflen = sc->inbuflen - 4;
314 /* The VTERM protocol has a 4 byte header, skip it here. */
315 memmove(&sc->phyp_inbuf.str[0], &sc->phyp_inbuf.str[4],
316 sc->inbuflen);
317 }
318
319 /*
320 * Since version 2.11.0, QEMU became bug-compatible with
321 * PowerVM's vty implementation, by inserting a \0 after
322 * every \r going to the guest. Guests are expected to
323 * workaround this issue by removing every \0 immediately
324 * following a \r.
325 */
326 if (hdr == 1) {
327 for (i = 0, j = 0; i < sc->inbuflen; i++, j++) {
328 if (i > j)
329 sc->phyp_inbuf.str[j] = sc->phyp_inbuf.str[i];
330
331 if (sc->phyp_inbuf.str[i] == '\r' &&
332 i < sc->inbuflen - 1 &&
333 sc->phyp_inbuf.str[i + 1] == '\0')
334 i++;
335 }
336 sc->inbuflen -= i - j;
337 }
338
339 if (bufsize > sc->inbuflen)
340 bufsize = sc->inbuflen;
341
342 memcpy(buffer, sc->phyp_inbuf.str, bufsize);
343 sc->inbuflen -= bufsize;
344 if (sc->inbuflen > 0)
345 memmove(&sc->phyp_inbuf.str[0], &sc->phyp_inbuf.str[bufsize],
346 sc->inbuflen);
347
348 uart_unlock(&sc->sc_mtx);
349 return (bufsize);
350 }
351
352 static int
uart_phyp_put(struct uart_phyp_softc * sc,void * buffer,size_t bufsize)353 uart_phyp_put(struct uart_phyp_softc *sc, void *buffer, size_t bufsize)
354 {
355 uint16_t seqno;
356 uint64_t len = 0;
357 int err;
358
359 union {
360 uint64_t u64[2];
361 char bytes[16];
362 } cbuf;
363
364 uart_lock(&sc->sc_mtx);
365 switch (sc->protocol) {
366 case HVTERM1:
367 if (bufsize > 16)
368 bufsize = 16;
369 memcpy(&cbuf, buffer, bufsize);
370 len = bufsize;
371 break;
372 case HVTERMPROT:
373 if (bufsize > 12)
374 bufsize = 12;
375 seqno = sc->outseqno++;
376 cbuf.bytes[0] = VS_DATA_PACKET_HEADER;
377 cbuf.bytes[1] = 4 + bufsize; /* total length, max 16 bytes */
378 cbuf.bytes[2] = (seqno >> 8) & 0xff;
379 cbuf.bytes[3] = seqno & 0xff;
380 memcpy(&cbuf.bytes[4], buffer, bufsize);
381 len = 4 + bufsize;
382 break;
383 }
384
385 do {
386 err = phyp_hcall(H_PUT_TERM_CHAR, sc->vtermid, len, htobe64(cbuf.u64[0]),
387 htobe64(cbuf.u64[1]));
388 DELAY(100);
389 } while (err == H_BUSY);
390
391 uart_unlock(&sc->sc_mtx);
392
393 return (bufsize);
394 }
395
396 static int
uart_phyp_cngetc(struct consdev * cp)397 uart_phyp_cngetc(struct consdev *cp)
398 {
399 unsigned char c;
400 int retval;
401
402 retval = uart_phyp_get(console_sc, &c, 1);
403 if (retval != 1)
404 return (-1);
405 #if defined(KDB)
406 kdb_alt_break(c, &alt_break_state);
407 #endif
408
409 return (c);
410 }
411
412 static void
uart_phyp_cnputc(struct consdev * cp,int c)413 uart_phyp_cnputc(struct consdev *cp, int c)
414 {
415 unsigned char ch = c;
416 uart_phyp_put(console_sc, &ch, 1);
417 }
418
419 static void
uart_phyp_cngrab(struct consdev * cp)420 uart_phyp_cngrab(struct consdev *cp)
421 {
422 }
423
424 static void
uart_phyp_cnungrab(struct consdev * cp)425 uart_phyp_cnungrab(struct consdev *cp)
426 {
427 }
428
429 static void
uart_phyp_ttyoutwakeup(struct tty * tp)430 uart_phyp_ttyoutwakeup(struct tty *tp)
431 {
432 struct uart_phyp_softc *sc;
433 char buffer[8];
434 int len;
435
436 sc = tty_softc(tp);
437
438 while ((len = ttydisc_getc(tp, buffer, sizeof(buffer))) != 0)
439 uart_phyp_put(sc, buffer, len);
440 }
441
442 static void
uart_phyp_intr(void * v)443 uart_phyp_intr(void *v)
444 {
445 struct uart_phyp_softc *sc = v;
446 struct tty *tp = sc->tp;
447 unsigned char c;
448 int len;
449
450 tty_lock(tp);
451 while ((len = uart_phyp_get(sc, &c, 1)) > 0)
452 ttydisc_rint(tp, c, 0);
453 ttydisc_rint_done(tp);
454 tty_unlock(tp);
455
456 if (sc->irqres == NULL)
457 callout_reset(&sc->callout, sc->polltime, uart_phyp_intr, sc);
458 }
459