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 |