Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_fbuf.c
| Show First 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | pci_fbuf_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
| DPRINTF(DEBUG_VERBOSE, | DPRINTF(DEBUG_VERBOSE, | ||||
| ("fbuf rd: offset 0x%lx, size: %d, value: 0x%lx", | ("fbuf rd: offset 0x%lx, size: %d, value: 0x%lx", | ||||
| offset, size, value)); | offset, size, value)); | ||||
| return (value); | return (value); | ||||
| } | } | ||||
| static void | static int | ||||
| pci_fbuf_baraddr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, | pci_fbuf_baraddr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, | ||||
| int enabled, uint64_t address) | int enabled, uint64_t address) | ||||
| { | { | ||||
| struct pci_fbuf_softc *sc; | struct pci_fbuf_softc *sc; | ||||
| int prot; | int prot; | ||||
| if (baridx != 1) | if (baridx != 1) | ||||
| return; | return (-1); | ||||
| sc = pi->pi_arg; | sc = pi->pi_arg; | ||||
| if (!enabled && sc->fbaddr != 0) { | if (!enabled && sc->fbaddr != 0) { | ||||
| if (vm_munmap_memseg(ctx, sc->fbaddr, FB_SIZE) != 0) | if (vm_munmap_memseg(ctx, sc->fbaddr, FB_SIZE) != 0) | ||||
| EPRINTLN("pci_fbuf: munmap_memseg failed"); | EPRINTLN("pci_fbuf: munmap_memseg failed"); | ||||
| sc->fbaddr = 0; | sc->fbaddr = 0; | ||||
| } else if (sc->fb_base != NULL && sc->fbaddr == 0) { | } else if (sc->fb_base != NULL && sc->fbaddr == 0) { | ||||
| prot = PROT_READ | PROT_WRITE; | prot = PROT_READ | PROT_WRITE; | ||||
| if (vm_mmap_memseg(ctx, address, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) | if (vm_mmap_memseg(ctx, address, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) | ||||
| EPRINTLN("pci_fbuf: mmap_memseg failed"); | EPRINTLN("pci_fbuf: mmap_memseg failed"); | ||||
| sc->fbaddr = address; | sc->fbaddr = address; | ||||
| } | } | ||||
| return (0); | |||||
| } | } | ||||
| static int | static int | ||||
| pci_fbuf_parse_config(struct pci_fbuf_softc *sc, nvlist_t *nvl) | pci_fbuf_parse_config(struct pci_fbuf_softc *sc, nvlist_t *nvl) | ||||
| { | { | ||||
| const char *value; | const char *value; | ||||
| char *cp; | char *cp; | ||||
| ▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | pci_fbuf_render(struct bhyvegc *gc, void *arg) | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| static int | static int | ||||
| pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
| { | { | ||||
| int error, prot; | int error; | ||||
| struct pci_fbuf_softc *sc; | struct pci_fbuf_softc *sc; | ||||
| if (fbuf_sc != NULL) { | if (fbuf_sc != NULL) { | ||||
| EPRINTLN("Only one frame buffer device is allowed."); | EPRINTLN("Only one frame buffer device is allowed."); | ||||
| return (-1); | return (-1); | ||||
| } | } | ||||
| sc = calloc(1, sizeof(struct pci_fbuf_softc)); | sc = calloc(1, sizeof(struct pci_fbuf_softc)); | ||||
| pi->pi_arg = sc; | pi->pi_arg = sc; | ||||
| /* initialize config space */ | /* initialize config space */ | ||||
| pci_set_cfgdata16(pi, PCIR_DEVICE, 0x40FB); | pci_set_cfgdata16(pi, PCIR_DEVICE, 0x40FB); | ||||
| pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D); | pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D); | ||||
| pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_DISPLAY); | pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_DISPLAY); | ||||
| pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_DISPLAY_VGA); | pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_DISPLAY_VGA); | ||||
| sc->fb_base = vm_create_devmem( | |||||
| ctx, VM_FRAMEBUFFER, "framebuffer", FB_SIZE); | |||||
| if (sc->fb_base == MAP_FAILED) { | |||||
| error = -1; | |||||
| goto done; | |||||
| } | |||||
| error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, DMEMSZ); | error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, DMEMSZ); | ||||
| assert(error == 0); | assert(error == 0); | ||||
| error = pci_emul_alloc_bar(pi, 1, PCIBAR_MEM32, FB_SIZE); | error = pci_emul_alloc_bar(pi, 1, PCIBAR_MEM32, FB_SIZE); | ||||
| assert(error == 0); | assert(error == 0); | ||||
| error = pci_emul_add_msicap(pi, PCI_FBUF_MSI_MSGS); | error = pci_emul_add_msicap(pi, PCI_FBUF_MSI_MSGS); | ||||
| assert(error == 0); | assert(error == 0); | ||||
| sc->fbaddr = pi->pi_bar[1].addr; | |||||
| sc->memregs.fbsize = FB_SIZE; | sc->memregs.fbsize = FB_SIZE; | ||||
| sc->memregs.width = COLS_DEFAULT; | sc->memregs.width = COLS_DEFAULT; | ||||
| sc->memregs.height = ROWS_DEFAULT; | sc->memregs.height = ROWS_DEFAULT; | ||||
| sc->memregs.depth = 32; | sc->memregs.depth = 32; | ||||
| sc->vga_enabled = 1; | sc->vga_enabled = 1; | ||||
| sc->vga_full = 0; | sc->vga_full = 0; | ||||
| sc->fsc_pi = pi; | sc->fsc_pi = pi; | ||||
| error = pci_fbuf_parse_config(sc, nvl); | error = pci_fbuf_parse_config(sc, nvl); | ||||
| if (error != 0) | if (error != 0) | ||||
| goto done; | goto done; | ||||
| /* XXX until VGA rendering is enabled */ | /* XXX until VGA rendering is enabled */ | ||||
| if (sc->vga_full != 0) { | if (sc->vga_full != 0) { | ||||
| EPRINTLN("pci_fbuf: VGA rendering not enabled"); | EPRINTLN("pci_fbuf: VGA rendering not enabled"); | ||||
| goto done; | goto done; | ||||
| } | } | ||||
| sc->fb_base = vm_create_devmem(ctx, VM_FRAMEBUFFER, "framebuffer", FB_SIZE); | |||||
| if (sc->fb_base == MAP_FAILED) { | |||||
| error = -1; | |||||
| goto done; | |||||
| } | |||||
| DPRINTF(DEBUG_INFO, ("fbuf frame buffer base: %p [sz %lu]", | DPRINTF(DEBUG_INFO, ("fbuf frame buffer base: %p [sz %lu]", | ||||
| sc->fb_base, FB_SIZE)); | sc->fb_base, FB_SIZE)); | ||||
| /* | |||||
| * Map the framebuffer into the guest address space. | |||||
| * XXX This may fail if the BAR is different than a prior | |||||
| * run. In this case flag the error. This will be fixed | |||||
| * when a change_memseg api is available. | |||||
| */ | |||||
| prot = PROT_READ | PROT_WRITE; | |||||
| if (vm_mmap_memseg(ctx, sc->fbaddr, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) { | |||||
| EPRINTLN("pci_fbuf: mapseg failed - try deleting VM and restarting"); | |||||
| error = -1; | |||||
| goto done; | |||||
| } | |||||
| console_init(sc->memregs.width, sc->memregs.height, sc->fb_base); | console_init(sc->memregs.width, sc->memregs.height, sc->fb_base); | ||||
| console_fb_register(pci_fbuf_render, sc); | console_fb_register(pci_fbuf_render, sc); | ||||
| if (sc->vga_enabled) | if (sc->vga_enabled) | ||||
| sc->vgasc = vga_init(!sc->vga_full); | sc->vgasc = vga_init(!sc->vga_full); | ||||
| sc->gc_image = console_get_image(); | sc->gc_image = console_get_image(); | ||||
| Show All 36 Lines | |||||