Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/vt/hw/efifb/efifb.c
Show First 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
vt_efifb_init(struct vt_device *vd) | vt_efifb_init(struct vt_device *vd) | ||||
{ | { | ||||
struct fb_info *info; | struct fb_info *info; | ||||
struct efi_fb *efifb; | struct efi_fb *efifb; | ||||
caddr_t kmdp; | caddr_t kmdp; | ||||
int memattr; | |||||
int roff, goff, boff; | int roff, goff, boff; | ||||
char attr[16]; | |||||
/* | |||||
* XXX TODO: I think there's more nuance here than we're acknowledging, | |||||
* and we should look into it. It may be that the framebuffer lives in | |||||
* a segment of memory that doesn't support one or both of these. We | |||||
* should likely be consulting the memory map for any applicable | |||||
* cacheability attributes before making a final decision. | |||||
*/ | |||||
memattr = VM_MEMATTR_WRITE_COMBINING; | |||||
if (TUNABLE_STR_FETCH("hw.efifb.cache_attr", attr, sizeof(attr))) { | |||||
/* | |||||
* We'll allow WC but it's currently the default, UC is the only | |||||
* other tested one at this time. | |||||
*/ | |||||
if (strcasecmp(attr, "wc") != 0 && | |||||
strcasecmp(attr, "uc") != 0) { | |||||
printf("efifb: unsupported cache attr specified: %s\n", | |||||
attr); | |||||
printf("efifb: expected \"wc\" or \"uc\"\n"); | |||||
} else if (strcasecmp(attr, "uc") == 0) { | |||||
memattr = VM_MEMATTR_UNCACHEABLE; | |||||
} | |||||
} | |||||
info = vd->vd_softc; | info = vd->vd_softc; | ||||
if (info == NULL) | if (info == NULL) | ||||
info = vd->vd_softc = (void *)&local_info; | info = vd->vd_softc = (void *)&local_info; | ||||
kmdp = preload_search_by_type("elf kernel"); | kmdp = preload_search_by_type("elf kernel"); | ||||
if (kmdp == NULL) | if (kmdp == NULL) | ||||
kmdp = preload_search_by_type("elf64 kernel"); | kmdp = preload_search_by_type("elf64 kernel"); | ||||
efifb = (struct efi_fb *)preload_search_info(kmdp, | efifb = (struct efi_fb *)preload_search_info(kmdp, | ||||
Show All 20 Lines | vt_config_cons_colors(info, COLOR_FORMAT_RGB, | ||||
efifb->fb_mask_red >> roff, roff, | efifb->fb_mask_red >> roff, roff, | ||||
efifb->fb_mask_green >> goff, goff, | efifb->fb_mask_green >> goff, goff, | ||||
efifb->fb_mask_blue >> boff, boff); | efifb->fb_mask_blue >> boff, boff); | ||||
info->fb_cmsize = NCOLORS; | info->fb_cmsize = NCOLORS; | ||||
info->fb_size = info->fb_height * info->fb_stride; | info->fb_size = info->fb_height * info->fb_stride; | ||||
info->fb_pbase = efifb->fb_addr; | info->fb_pbase = efifb->fb_addr; | ||||
info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, | info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, | ||||
info->fb_size, VM_MEMATTR_WRITE_COMBINING); | info->fb_size, memattr); | ||||
vt_fb_init(vd); | vt_fb_init(vd); | ||||
return (CN_INTERNAL); | return (CN_INTERNAL); | ||||
} | } | ||||
static void | static void | ||||
vt_efifb_fini(struct vt_device *vd, void *softc) | vt_efifb_fini(struct vt_device *vd, void *softc) | ||||
{ | { | ||||
struct fb_info *info = softc; | struct fb_info *info = softc; | ||||
vt_fb_fini(vd, softc); | vt_fb_fini(vd, softc); | ||||
pmap_unmapdev((void *)info->fb_vbase, info->fb_size); | pmap_unmapdev((void *)info->fb_vbase, info->fb_size); | ||||
} | } |