Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_uart.c
Show All 30 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "bhyverun.h" | #include "bhyverun.h" | ||||
#include "config.h" | |||||
#include "debug.h" | #include "debug.h" | ||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "uart_emul.h" | #include "uart_emul.h" | ||||
/* | /* | ||||
* Pick a PCI vid/did of a chip with a single uart at | * Pick a PCI vid/did of a chip with a single uart at | ||||
* BAR0, that most versions of FreeBSD can understand: | * BAR0, that most versions of FreeBSD can understand: | ||||
* Siig CyberSerial 1-port. | * Siig CyberSerial 1-port. | ||||
Show All 37 Lines | pci_uart_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
assert(baridx == 0); | assert(baridx == 0); | ||||
assert(size == 1); | assert(size == 1); | ||||
val = uart_read(pi->pi_arg, offset); | val = uart_read(pi->pi_arg, offset); | ||||
return (val); | return (val); | ||||
} | } | ||||
static int | static int | ||||
pci_uart_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | pci_uart_legacy_config(nvlist_t *nvl, const char *opts) | ||||
{ | { | ||||
if (opts != NULL) | |||||
set_config_value_node(nvl, "path", opts); | |||||
return (0); | |||||
} | |||||
static int | |||||
pci_uart_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | |||||
{ | |||||
struct uart_softc *sc; | struct uart_softc *sc; | ||||
const char *device; | |||||
pci_emul_alloc_bar(pi, 0, PCIBAR_IO, UART_IO_BAR_SIZE); | pci_emul_alloc_bar(pi, 0, PCIBAR_IO, UART_IO_BAR_SIZE); | ||||
pci_lintr_request(pi); | pci_lintr_request(pi); | ||||
/* initialize config space */ | /* initialize config space */ | ||||
pci_set_cfgdata16(pi, PCIR_DEVICE, COM_DEV); | pci_set_cfgdata16(pi, PCIR_DEVICE, COM_DEV); | ||||
pci_set_cfgdata16(pi, PCIR_VENDOR, COM_VENDOR); | pci_set_cfgdata16(pi, PCIR_VENDOR, COM_VENDOR); | ||||
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SIMPLECOMM); | pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SIMPLECOMM); | ||||
sc = uart_init(pci_uart_intr_assert, pci_uart_intr_deassert, pi); | sc = uart_init(pci_uart_intr_assert, pci_uart_intr_deassert, pi); | ||||
pi->pi_arg = sc; | pi->pi_arg = sc; | ||||
if (uart_set_backend(sc, opts) != 0) { | device = get_config_value_node(nvl, "path"); | ||||
if (uart_set_backend(sc, device) != 0) { | |||||
EPRINTLN("Unable to initialize backend '%s' for " | EPRINTLN("Unable to initialize backend '%s' for " | ||||
"pci uart at %d:%d", opts, pi->pi_slot, pi->pi_func); | "pci uart at %d:%d", device, pi->pi_slot, pi->pi_func); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
struct pci_devemu pci_de_com = { | struct pci_devemu pci_de_com = { | ||||
.pe_emu = "uart", | .pe_emu = "uart", | ||||
.pe_init = pci_uart_init, | .pe_init = pci_uart_init, | ||||
.pe_legacy_config = pci_uart_legacy_config, | |||||
.pe_barwrite = pci_uart_write, | .pe_barwrite = pci_uart_write, | ||||
.pe_barread = pci_uart_read | .pe_barread = pci_uart_read | ||||
}; | }; | ||||
PCI_EMUL_SET(pci_de_com); | PCI_EMUL_SET(pci_de_com); |