> Date: Fri, 10 Jun 2016 14:38:05 -0500
> From: joshua stein <[email protected]>
>
> This implements a new framebuffer console (based on efifb) for amd64
> devices running Coreboot, which do not have otherwise working EFI,
> VGA text, inteldrm, or serial console. So mostly just Skylake
> Chromebooks.
>
> This is required for my HP Chromebook 13 (and would have previously
> been required for the Broadwell Chromebook Pixel 2015) since SeaBIOS
> only handles printing text on Coreboot's framebuffer while at the
> bootloader. Once the kernel loads and tries to find a vga device,
> it would fail and print nothing on the screen. With this driver I
> get a fully working console and working X11 via the wsfb driver.
>
> I've tested this on a couple non-Chromebook machines, including my
> APU which is also using Coreboot, but since that has a serial
> console, this driver does not try to attach.
The logic to decide whether this should attach looks good to me.
Mst stuff in here is duplicated from efifb though, so I wonder if code
could be shared.
> Index: dev/wscons/wsconsio.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v
> retrieving revision 1.74
> diff -u -p -u -p -r1.74 wsconsio.h
> --- dev/wscons/wsconsio.h 30 Mar 2016 23:34:12 -0000 1.74
> +++ dev/wscons/wsconsio.h 10 Jun 2016 17:35:38 -0000
> @@ -348,6 +348,7 @@ struct wsmouse_calibcoords {
> #define WSDISPLAY_TYPE_INTELDRM 69 /* Intel KMS
> framebuffer */
> #define WSDISPLAY_TYPE_RADEONDRM 70 /* ATI Radeon KMS
> framebuffer */
> #define WSDISPLAY_TYPE_EFIFB 71 /* EFI framebuffer */
> +#define WSDISPLAY_TYPE_CBFB 72 /* Coreboot framebuffer
> */
>
> /* Basic display information. Not applicable to all display types. */
> struct wsdisplay_fbinfo {
> Index: arch/amd64/amd64/cbfb.c
> ===================================================================
> RCS file: arch/amd64/amd64/cbfb.c
> diff -N arch/amd64/amd64/cbfb.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ arch/amd64/amd64/cbfb.c 10 Jun 2016 17:35:38 -0000
> @@ -0,0 +1,447 @@
> +/* $OpenBSD$ */
> +
> +/*
> + * Coreboot framebuffer console driver
> + *
> + * Copyright (c) 2016 joshua stein <[email protected]>
> + * Copyright (c) 2015 YASUOKA Masahiko <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +
> +#include <uvm/uvm_extern.h>
> +#include <machine/bus.h>
> +
> +#include <dev/wscons/wsconsio.h>
> +#include <dev/wscons/wsdisplayvar.h>
> +#include <dev/rasops/rasops.h>
> +#include <dev/pci/pcivar.h>
> +
> +#include <machine/cbfbvar.h>
> +
> +/* coreboot tables */
> +
> +struct cb_header {
> + union {
> + uint8_t signature[4]; /* "LBIO" */
> + uint32_t signature32;
> + };
> + uint32_t header_bytes;
> + uint32_t header_checksum;
> + uint32_t table_bytes;
> + uint32_t table_checksum;
> + uint32_t table_entries;
> +};
> +
> +struct cb_framebuffer {
> + uint64_t physical_address;
> + uint32_t x_resolution;
> + uint32_t y_resolution;
> + uint32_t bytes_per_line;
> + uint8_t bits_per_pixel;
> + uint8_t red_mask_pos;
> + uint8_t red_mask_size;
> + uint8_t green_mask_pos;
> + uint8_t green_mask_size;
> + uint8_t blue_mask_pos;
> + uint8_t blue_mask_size;
> + uint8_t reserved_mask_pos;
> + uint8_t reserved_mask_size;
> +};
> +
> +struct cb_entry {
> + uint32_t tag;
> +#define CB_TAG_VERSION 0x0004
> +#define CB_TAG_FORWARD 0x0011
> +#define CB_TAG_FRAMEBUFFER 0x0012
> + uint32_t size;
> + union {
> + char string[0];
> + uint64_t forward;
> + struct cb_framebuffer fb;
> + } u;
> +};
> +
> +struct cbfb {
> + struct rasops_info rinfo;
> + int depth;
> + paddr_t paddr;
> + psize_t psize;
> +
> + struct cb_framebuffer table_cbfb;
> +};
> +
> +struct cbfb_softc {
> + struct device sc_dev;
> + struct cbfb *sc_fb;
> +};
> +
> +int cbfb_match(struct device *, void *, void *);
> +void cbfb_attach(struct device *, struct device *, void *);
> +void cbfb_rasops_preinit(struct cbfb *);
> +int cbfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
> +paddr_t cbfb_mmap(void *, off_t, int);
> +int cbfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
> + int *, int *, long *);
> +void cbfb_free_screen(void *, void *);
> +int cbfb_show_screen(void *, void *, int, void (*cb) (void *, int, int),
> + void *);
> +int cbfb_list_font(void *, struct wsdisplay_font *);
> +int cbfb_load_font(void *, void *, struct wsdisplay_font *);
> +
> +int cb_parse_table(paddr_t);
> +
> +struct cfattach cbfb_ca = {
> + sizeof(struct cbfb_softc), cbfb_match, cbfb_attach, NULL
> +};
> +
> +#define CBFB_WIDTH 100
> +#define CBFB_HEIGHT 31
> +
> +struct wsdisplay_charcell cbfb_bs[CBFB_HEIGHT * CBFB_WIDTH];
> +
> +struct wsscreen_descr cbfb_std_descr = { "std" };
> +
> +const struct wsscreen_descr *cbfb_descrs[] = {
> + &cbfb_std_descr
> +};
> +
> +const struct wsscreen_list cbfb_screen_list = {
> + nitems(cbfb_descrs), cbfb_descrs
> +};
> +
> +struct wsdisplay_accessops cbfb_accessops = {
> + .ioctl = cbfb_ioctl,
> + .mmap = cbfb_mmap,
> + .alloc_screen = cbfb_alloc_screen,
> + .free_screen = cbfb_free_screen,
> + .show_screen = cbfb_show_screen,
> + .load_font = cbfb_load_font,
> + .list_font = cbfb_list_font
> +};
> +
> +struct cfdriver cbfb_cd = {
> + NULL, "cbfb", DV_DULL
> +};
> +
> +struct cbfb cbfb_console;
> +
> +int
> +cbfb_match(struct device *parent, void *cf, void *aux)
> +{
> + struct cbfb_attach_args *cbaa = aux;
> +
> + if (strcmp(cbaa->cbfbaa_name, cbfb_cd.cd_name) == 0 && cbfb_found())
> + return (1);
> +
> + return (0);
> +}
> +
> +int
> +cbfb_found(void)
> +{
> + return !!(cbfb_console.paddr);
> +}
> +
> +void
> +cbfb_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct cbfb *fb;
> + struct cbfb_softc *sc = (struct cbfb_softc *)self;
> + struct wsemuldisplaydev_attach_args aa;
> + struct rasops_info *ri;
> + int ccol = 0, crow = 0;
> + bus_space_tag_t iot = X86_BUS_SPACE_MEM;
> + bus_space_handle_t ioh;
> + long defattr;
> +
> + printf(": %dx%d, %d bpp\n",
> + cbfb_console.table_cbfb.x_resolution,
> + cbfb_console.table_cbfb.y_resolution,
> + cbfb_console.table_cbfb.bits_per_pixel);
> +
> + aa.console = 1;
> + fb = sc->sc_fb = &cbfb_console;
> + ri = &fb->rinfo;
> + ccol = ri->ri_ccol;
> + crow = ri->ri_crow;
> +
> + if (bus_space_map(iot, fb->paddr, fb->psize,
> + BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &ioh) == 0)
> + ri->ri_origbits = bus_space_vaddr(iot, ioh);
> +
> + cbfb_rasops_preinit(fb);
> + ri->ri_flg &= ~RI_CLEAR;
> + ri->ri_flg |= RI_VCONS | RI_WRONLY;
> +
> + rasops_init(ri, cbfb_std_descr.nrows, cbfb_std_descr.ncols);
> +
> + aa.scrdata = &cbfb_screen_list;
> + aa.accessops = &cbfb_accessops;
> + aa.accesscookie = sc;
> + aa.defaultscreens = 0;
> +
> + ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr);
> + wsdisplay_cnattach(&cbfb_std_descr, ri->ri_active, ccol, crow, defattr);
> +
> + config_found(self, &aa, wsemuldisplaydevprint);
> +}
> +
> +void
> +cbfb_rasops_preinit(struct cbfb *cbfb)
> +{
> +#define bmnum(_x) (fls(_x) - ffs(_x) + 1)
> +#define bmpos(_x) (ffs(_x) - 1)
> + struct rasops_info *ri = &cbfb->rinfo;
> +
> + ri->ri_width = cbfb->table_cbfb.x_resolution;
> + ri->ri_height = cbfb->table_cbfb.y_resolution;
> + ri->ri_depth = cbfb->depth;
> + ri->ri_stride = cbfb->table_cbfb.bytes_per_line;
> + ri->ri_rnum = cbfb->table_cbfb.red_mask_size;
> + ri->ri_rpos = cbfb->table_cbfb.red_mask_pos;
> + ri->ri_gnum = cbfb->table_cbfb.green_mask_size;
> + ri->ri_gpos = cbfb->table_cbfb.green_mask_pos;
> + ri->ri_bnum = cbfb->table_cbfb.blue_mask_size;
> + ri->ri_bpos = cbfb->table_cbfb.blue_mask_pos;
> +}
> +
> +int
> +cbfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
> +{
> + struct cbfb_softc *sc = v;
> + struct cbfb *fb = sc->sc_fb;
> + struct rasops_info *ri = &fb->rinfo;
> + struct wsdisplay_fbinfo *wdf;
> +
> + switch (cmd) {
> + case WSDISPLAYIO_GTYPE:
> + *(u_int *)data = WSDISPLAY_TYPE_CBFB;
> + break;
> + case WSDISPLAYIO_GINFO:
> + wdf = (struct wsdisplay_fbinfo *)data;
> + wdf->width = ri->ri_width;
> + wdf->height = ri->ri_height;
> + wdf->depth = ri->ri_depth;
> + wdf->cmsize = 0; /* color map is unavailable */
> + break;
> + case WSDISPLAYIO_LINEBYTES:
> + *(u_int *)data = ri->ri_stride;
> + break;
> + case WSDISPLAYIO_SMODE:
> + break;
> + case WSDISPLAYIO_GETSUPPORTEDDEPTH:
> + switch (ri->ri_depth) {
> + case 32:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
> + break;
> + case 24:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_24_24;
> + break;
> + case 16:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_16;
> + break;
> + case 15:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_15;
> + break;
> + case 8:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_8;
> + break;
> + case 4:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_4;
> + break;
> + case 1:
> + *(u_int *)data = WSDISPLAYIO_DEPTH_1;
> + break;
> + default:
> + return (-1);
> + }
> + break;
> + default:
> + return (-1);
> + }
> +
> + return (0);
> +}
> +
> +paddr_t
> +cbfb_mmap(void *v, off_t off, int prot)
> +{
> + struct cbfb_softc *sc = v;
> +
> + if (off < 0 || off >= sc->sc_fb->psize)
> + return (-1);
> +
> + return ((sc->sc_fb->paddr + off) | PMAP_WC);
> +}
> +
> +int
> +cbfb_alloc_screen(void *v, const struct wsscreen_descr *descr,
> + void **cookiep, int *curxp, int *curyp, long *attrp)
> +{
> + struct cbfb_softc *sc = v;
> + struct rasops_info *ri = &sc->sc_fb->rinfo;
> +
> + return rasops_alloc_screen(ri, cookiep, curxp, curyp, attrp);
> +}
> +
> +void
> +cbfb_free_screen(void *v, void *cookie)
> +{
> + struct cbfb_softc *sc = v;
> + struct rasops_info *ri = &sc->sc_fb->rinfo;
> +
> + rasops_free_screen(ri, cookie);
> +}
> +
> +int
> +cbfb_show_screen(void *v, void *cookie, int waitok,
> + void (*cb) (void *, int, int), void *cb_arg)
> +{
> + struct cbfb_softc *sc = v;
> + struct rasops_info *ri = &sc->sc_fb->rinfo;
> +
> + return rasops_show_screen(ri, cookie, waitok, cb, cb_arg);
> +}
> +
> +int
> +cbfb_load_font(void *v, void *cookie, struct wsdisplay_font *font)
> +{
> + struct cbfb_softc *sc = v;
> + struct rasops_info *ri = &sc->sc_fb->rinfo;
> +
> + return (rasops_load_font(ri, cookie, font));
> +}
> +
> +int
> +cbfb_list_font(void *v, struct wsdisplay_font *font)
> +{
> + struct cbfb_softc *sc = v;
> + struct rasops_info *ri = &sc->sc_fb->rinfo;
> +
> + return (rasops_list_font(ri, font));
> +}
> +
> +int
> +cbfb_cnattach(void)
> +{
> + if (cb_parse_table((paddr_t)0x0) || !cbfb_console.paddr)
> + return (-1);
> +
> + return (0);
> +}
> +
> +int
> +cbfb_is_console(struct pci_attach_args *pa)
> +{
> + return !!(cbfb_console.paddr);
> +}
> +
> +void
> +cbfb_cndetach(void)
> +{
> + cbfb_console.paddr = 0;
> +}
> +
> +static uint16_t
> +cb_checksum(const void *addr, unsigned size)
> +{
> + const uint16_t *p = addr;
> + unsigned i, n = size / 2;
> + uint32_t sum = 0;
> +
> + for (i = 0; i < n; i++)
> + sum += p[i];
> +
> + sum = (sum >> 16) + (sum & 0xffff);
> + sum += (sum >> 16);
> + sum = ~sum & 0xffff;
> +
> + return (uint16_t)sum;
> +}
> +
> +static void
> +cb_fb_init(struct cb_framebuffer *table_cbfb)
> +{
> + struct cbfb *cbfb;
> + struct rasops_info *ri = &cbfb->rinfo;
> + long defattr = 0;
> +
> + memset(&cbfb_console, 0, sizeof(cbfb_console));
> + memcpy(&cbfb_console.table_cbfb, table_cbfb,
> + sizeof(struct cb_framebuffer));
> +
> + cbfb = &cbfb_console;
> + cbfb->paddr = table_cbfb->physical_address;
> + cbfb->depth = table_cbfb->bits_per_pixel;
> + cbfb->psize = table_cbfb->y_resolution * table_cbfb->bytes_per_line;
> +
> + ri->ri_bits = (u_char *)PMAP_DIRECT_MAP(cbfb->paddr);
> +
> + cbfb_rasops_preinit(cbfb);
> +
> + ri->ri_bs = cbfb_bs;
> + ri->ri_flg = RI_CLEAR | RI_CENTER | RI_WRONLY;
> + rasops_init(ri, CBFB_HEIGHT, CBFB_WIDTH);
> + cbfb_std_descr.ncols = ri->ri_cols;
> + cbfb_std_descr.nrows = ri->ri_rows;
> + cbfb_std_descr.textops = &ri->ri_ops;
> + cbfb_std_descr.fontwidth = ri->ri_font->fontwidth;
> + cbfb_std_descr.fontheight = ri->ri_font->fontheight;
> + cbfb_std_descr.capabilities = ri->ri_caps;
> +
> + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
> + wsdisplay_cnattach(&cbfb_std_descr, ri, 0, 0, defattr);
> +}
> +
> +int
> +cb_parse_table(paddr_t addr)
> +{
> + int i, j;
> +
> + for (i = 0; i < (4 * 1024); i += 16) {
> + struct cb_header *cbh;
> + struct cb_entry *cbe;
> + void *cbtable;
> +
> + cbh = (struct cb_header *)(PMAP_DIRECT_MAP(addr + i));
> + if (memcmp(cbh->signature, "LBIO", 4) != 0)
> + continue;
> +
> + if (!cbh->header_bytes)
> + continue;
> +
> + if (cb_checksum(cbh, sizeof(*cbh)) != 0)
> + return (-1);
> +
> + cbtable = (void *)PMAP_DIRECT_MAP(addr + i + cbh->header_bytes);
> +
> + for (j = 0; j < cbh->table_bytes; j += cbe->size) {
> + cbe = (struct cb_entry *)((char *)cbtable + j);
> +
> + switch (cbe->tag) {
> + case CB_TAG_FORWARD:
> + return cb_parse_table(cbe->u.forward);
> +
> + case CB_TAG_FRAMEBUFFER:
> + cb_fb_init(&cbe->u.fb);
> + break;
> + }
> + }
> + }
> +
> + return (0);
> +}
> Index: arch/amd64/amd64/mainbus.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/mainbus.c,v
> retrieving revision 1.36
> diff -u -p -u -p -r1.36 mainbus.c
> --- arch/amd64/amd64/mainbus.c 12 Dec 2015 12:33:49 -0000 1.36
> +++ arch/amd64/amd64/mainbus.c 10 Jun 2016 17:35:38 -0000
> @@ -52,6 +52,7 @@
> #include "vmm.h"
> #include "pvbus.h"
> #include "efifb.h"
> +#include "cbfb.h"
>
> #include <machine/cpuvar.h>
> #include <machine/i82093var.h>
> @@ -74,6 +75,10 @@
> #include <machine/efifbvar.h>
> #endif
>
> +#if NCBFB > 0
> +#include <machine/cbfbvar.h>
> +#endif
> +
> int mainbus_match(struct device *, void *, void *);
> void mainbus_attach(struct device *, struct device *, void *);
>
> @@ -105,6 +110,9 @@ union mainbus_attach_args {
> #if NEFIFB > 0
> struct efifb_attach_args mba_eaa;
> #endif
> +#if NCBFB > 0
> + struct cbfb_attach_args mba_cbfbaa;
> +#endif
> };
>
> /*
> @@ -255,6 +263,13 @@ mainbus_attach(struct device *parent, st
> #if NEFIFB > 0
> if (bios_efiinfo != NULL) {
> mba.mba_eaa.eaa_name = "efifb";
> + config_found(self, &mba, mainbus_print);
> + }
> +#endif
> +
> +#if NCBFB > 0
> + if (cbfb_found()) {
> + mba.mba_cbfbaa.cbfbaa_name = "cbfb";
> config_found(self, &mba, mainbus_print);
> }
> #endif
> Index: arch/amd64/amd64/wscons_machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/wscons_machdep.c,v
> retrieving revision 1.12
> diff -u -p -u -p -r1.12 wscons_machdep.c
> --- arch/amd64/amd64/wscons_machdep.c 6 Mar 2016 22:41:24 -0000 1.12
> +++ arch/amd64/amd64/wscons_machdep.c 10 Jun 2016 17:35:38 -0000
> @@ -75,6 +75,10 @@
> #if NEFIFB > 0
> #include <machine/efifbvar.h>
> #endif
> +#include "cbfb.h"
> +#if NCBFB > 0
> +#include <machine/cbfbvar.h>
> +#endif
>
> int wscn_video_init(void);
> void wscn_input_init(int);
> @@ -145,6 +149,10 @@ wscn_video_init(void)
> #endif
> #if (NVGA > 0)
> if (vga_cnattach(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM, -1, 1) == 0)
> + return (0);
> +#endif
> +#if (NCBFB > 0)
> + if (cbfb_cnattach() == 0)
> return (0);
> #endif
> #if (NPCDISPLAY > 0)
> Index: arch/amd64/conf/GENERIC
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
> retrieving revision 1.419
> diff -u -p -u -p -r1.419 GENERIC
> --- arch/amd64/conf/GENERIC 1 Jun 2016 09:48:20 -0000 1.419
> +++ arch/amd64/conf/GENERIC 10 Jun 2016 17:35:38 -0000
> @@ -358,6 +358,9 @@ lpt* at puc?
> efifb0 at mainbus? # EFI Framebuffer
> wsdisplay0 at efifb? console 1
>
> +cbfb0 at mainbus? # Coreboot Framebuffer
> +wsdisplay0 at cbfb? console 1
> +
> #bha* at pci? # BusLogic [57]4X SCSI
> controllers
> ahc* at pci? # Adaptec 2940 SCSI controllers
> jmb* at pci? # JMicron JMB36x controllers
> Index: arch/amd64/conf/files.amd64
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
> retrieving revision 1.85
> diff -u -p -u -p -r1.85 files.amd64
> --- arch/amd64/conf/files.amd64 8 Jan 2016 15:54:13 -0000 1.85
> +++ arch/amd64/conf/files.amd64 10 Jun 2016 17:35:38 -0000
> @@ -114,6 +114,13 @@ attach efifb at mainbus
> file arch/amd64/amd64/efifb.c efifb needs-flag
>
> #
> +# Coreboot Framebuffer
> +#
> +device cbfb: wsemuldisplaydev, rasops32, rasops16, rasops8, rasops4
> +attach cbfb at mainbus
> +file arch/amd64/amd64/cbfb.c cbfb needs-flag
> +
> +#
> # PCI drivers
> #
>
> Index: arch/amd64/include/cbfbvar.h
> ===================================================================
> RCS file: arch/amd64/include/cbfbvar.h
> diff -N arch/amd64/include/cbfbvar.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ arch/amd64/include/cbfbvar.h 10 Jun 2016 17:35:38 -0000
> @@ -0,0 +1,34 @@
> +/* $OpenBSD$ */
> +
> +/*
> + * Copyright (c) 2016 joshua stein <[email protected]>
> + * Copyright (c) 2015 YASUOKA Masahiko <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#ifndef _MACHINE_CBFB_H_
> +#define _MACHINE_CBFB_H_
> +
> +struct cbfb_attach_args {
> + const char *cbfbaa_name;
> +};
> +
> +struct pci_attach_args;
> +
> +int cbfb_found(void);
> +int cbfb_cnattach(void);
> +int cbfb_is_console(struct pci_attach_args *);
> +void cbfb_cndetach(void);
> +
> +#endif /* _MACHINE_CBFB_H_ */
>
>