xref: /illumos-gate/usr/src/cmd/bhyve/pci_uart.c (revision 32640292)
14c87aefeSPatrick Mooney /*-
2*32640292SAndy Fiddaman  * SPDX-License-Identifier: BSD-2-Clause
34c87aefeSPatrick Mooney  *
44c87aefeSPatrick Mooney  * Copyright (c) 2012 NetApp, Inc.
54c87aefeSPatrick Mooney  * All rights reserved.
64c87aefeSPatrick Mooney  *
74c87aefeSPatrick Mooney  * Redistribution and use in source and binary forms, with or without
84c87aefeSPatrick Mooney  * modification, are permitted provided that the following conditions
94c87aefeSPatrick Mooney  * are met:
104c87aefeSPatrick Mooney  * 1. Redistributions of source code must retain the above copyright
114c87aefeSPatrick Mooney  *    notice, this list of conditions and the following disclaimer.
124c87aefeSPatrick Mooney  * 2. Redistributions in binary form must reproduce the above copyright
134c87aefeSPatrick Mooney  *    notice, this list of conditions and the following disclaimer in the
144c87aefeSPatrick Mooney  *    documentation and/or other materials provided with the distribution.
154c87aefeSPatrick Mooney  *
164c87aefeSPatrick Mooney  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
174c87aefeSPatrick Mooney  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184c87aefeSPatrick Mooney  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
194c87aefeSPatrick Mooney  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
204c87aefeSPatrick Mooney  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
214c87aefeSPatrick Mooney  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
224c87aefeSPatrick Mooney  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
234c87aefeSPatrick Mooney  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
244c87aefeSPatrick Mooney  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254c87aefeSPatrick Mooney  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264c87aefeSPatrick Mooney  * SUCH DAMAGE.
274c87aefeSPatrick Mooney  */
284c87aefeSPatrick Mooney 
294c87aefeSPatrick Mooney #include <sys/cdefs.h>
304c87aefeSPatrick Mooney 
314c87aefeSPatrick Mooney #include <sys/types.h>
324c87aefeSPatrick Mooney 
334c87aefeSPatrick Mooney #include <stdio.h>
344c87aefeSPatrick Mooney 
354c87aefeSPatrick Mooney #include "bhyverun.h"
362b948146SAndy Fiddaman #include "config.h"
37154972afSPatrick Mooney #include "debug.h"
384c87aefeSPatrick Mooney #include "pci_emul.h"
394c87aefeSPatrick Mooney #include "uart_emul.h"
404c87aefeSPatrick Mooney 
414c87aefeSPatrick Mooney /*
424c87aefeSPatrick Mooney  * Pick a PCI vid/did of a chip with a single uart at
434c87aefeSPatrick Mooney  * BAR0, that most versions of FreeBSD can understand:
444c87aefeSPatrick Mooney  * Siig CyberSerial 1-port.
454c87aefeSPatrick Mooney  */
464c87aefeSPatrick Mooney #define COM_VENDOR	0x131f
474c87aefeSPatrick Mooney #define COM_DEV		0x2000
484c87aefeSPatrick Mooney 
494c87aefeSPatrick Mooney static void
pci_uart_intr_assert(void * arg)504c87aefeSPatrick Mooney pci_uart_intr_assert(void *arg)
514c87aefeSPatrick Mooney {
524c87aefeSPatrick Mooney 	struct pci_devinst *pi = arg;
534c87aefeSPatrick Mooney 
544c87aefeSPatrick Mooney 	pci_lintr_assert(pi);
554c87aefeSPatrick Mooney }
564c87aefeSPatrick Mooney 
574c87aefeSPatrick Mooney static void
pci_uart_intr_deassert(void * arg)584c87aefeSPatrick Mooney pci_uart_intr_deassert(void *arg)
594c87aefeSPatrick Mooney {
604c87aefeSPatrick Mooney 	struct pci_devinst *pi = arg;
614c87aefeSPatrick Mooney 
624c87aefeSPatrick Mooney 	pci_lintr_deassert(pi);
634c87aefeSPatrick Mooney }
644c87aefeSPatrick Mooney 
654c87aefeSPatrick Mooney static void
pci_uart_write(struct pci_devinst * pi,int baridx,uint64_t offset,int size,uint64_t value)66*32640292SAndy Fiddaman pci_uart_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size,
6759d65d31SAndy Fiddaman     uint64_t value)
684c87aefeSPatrick Mooney {
694c87aefeSPatrick Mooney 	assert(baridx == 0);
704c87aefeSPatrick Mooney 	assert(size == 1);
714c87aefeSPatrick Mooney 
724c87aefeSPatrick Mooney 	uart_write(pi->pi_arg, offset, value);
734c87aefeSPatrick Mooney }
744c87aefeSPatrick Mooney 
7559d65d31SAndy Fiddaman static uint64_t
pci_uart_read(struct pci_devinst * pi,int baridx,uint64_t offset,int size)76*32640292SAndy Fiddaman pci_uart_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size)
774c87aefeSPatrick Mooney {
784c87aefeSPatrick Mooney 	uint8_t val;
794c87aefeSPatrick Mooney 
804c87aefeSPatrick Mooney 	assert(baridx == 0);
814c87aefeSPatrick Mooney 	assert(size == 1);
824c87aefeSPatrick Mooney 
834c87aefeSPatrick Mooney 	val = uart_read(pi->pi_arg, offset);
844c87aefeSPatrick Mooney 	return (val);
854c87aefeSPatrick Mooney }
864c87aefeSPatrick Mooney 
874c87aefeSPatrick Mooney static int
pci_uart_legacy_config(nvlist_t * nvl,const char * opts)882b948146SAndy Fiddaman pci_uart_legacy_config(nvlist_t *nvl, const char *opts)
892b948146SAndy Fiddaman {
902b948146SAndy Fiddaman 
912b948146SAndy Fiddaman 	if (opts != NULL)
922b948146SAndy Fiddaman 		set_config_value_node(nvl, "path", opts);
932b948146SAndy Fiddaman 	return (0);
942b948146SAndy Fiddaman }
952b948146SAndy Fiddaman 
962b948146SAndy Fiddaman static int
pci_uart_init(struct pci_devinst * pi,nvlist_t * nvl)97*32640292SAndy Fiddaman pci_uart_init(struct pci_devinst *pi, nvlist_t *nvl)
984c87aefeSPatrick Mooney {
994c87aefeSPatrick Mooney 	struct uart_softc *sc;
1002b948146SAndy Fiddaman 	const char *device;
1014c87aefeSPatrick Mooney 
1024c87aefeSPatrick Mooney 	pci_emul_alloc_bar(pi, 0, PCIBAR_IO, UART_IO_BAR_SIZE);
1034c87aefeSPatrick Mooney 	pci_lintr_request(pi);
1044c87aefeSPatrick Mooney 
1054c87aefeSPatrick Mooney 	/* initialize config space */
1064c87aefeSPatrick Mooney 	pci_set_cfgdata16(pi, PCIR_DEVICE, COM_DEV);
1074c87aefeSPatrick Mooney 	pci_set_cfgdata16(pi, PCIR_VENDOR, COM_VENDOR);
1084c87aefeSPatrick Mooney 	pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SIMPLECOMM);
1094c87aefeSPatrick Mooney 
1104c87aefeSPatrick Mooney 	sc = uart_init(pci_uart_intr_assert, pci_uart_intr_deassert, pi);
1114c87aefeSPatrick Mooney 	pi->pi_arg = sc;
1124c87aefeSPatrick Mooney 
1132b948146SAndy Fiddaman 	device = get_config_value_node(nvl, "path");
1142b948146SAndy Fiddaman 	if (uart_set_backend(sc, device) != 0) {
115154972afSPatrick Mooney 		EPRINTLN("Unable to initialize backend '%s' for "
1162b948146SAndy Fiddaman 		    "pci uart at %d:%d", device, pi->pi_slot, pi->pi_func);
1174c87aefeSPatrick Mooney 		return (-1);
1184c87aefeSPatrick Mooney 	}
1194c87aefeSPatrick Mooney 
1204c87aefeSPatrick Mooney 	return (0);
1214c87aefeSPatrick Mooney }
1224c87aefeSPatrick Mooney 
1234f3f3e9aSAndy Fiddaman static const struct pci_devemu pci_de_com = {
1244c87aefeSPatrick Mooney 	.pe_emu =	"uart",
1254c87aefeSPatrick Mooney 	.pe_init =	pci_uart_init,
1262b948146SAndy Fiddaman 	.pe_legacy_config = pci_uart_legacy_config,
1274c87aefeSPatrick Mooney 	.pe_barwrite =	pci_uart_write,
1284c87aefeSPatrick Mooney 	.pe_barread =	pci_uart_read
1294c87aefeSPatrick Mooney };
1304c87aefeSPatrick Mooney PCI_EMUL_SET(pci_de_com);
131