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); | ||||