static grub_err_t grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { grub_err_t err; struct grub_video_palette_data fb_palette_data[256]; err = grub_video_fb_set_palette (start, count, palette_data); if (err) return err; grub_video_fb_get_palette (0, 256, fb_palette_data); /* TODO. */ return GRUB_ERR_NONE; }
grub_err_t grub_video_capture_start (const struct grub_video_mode_info *mode_info, struct grub_video_palette_data *palette, unsigned int palette_size) { grub_err_t err; grub_memset (&framebuffer, 0, sizeof (framebuffer)); grub_video_fb_init (); framebuffer.mode_info = *mode_info; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch); if (!framebuffer.ptr) return grub_errno; err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) return err; err = grub_video_fb_set_active_render_target (framebuffer.render_target); if (err) return err; err = grub_video_fb_set_palette (0, palette_size, palette); if (err) return err; saved = grub_video_adapter_active; if (saved) { grub_video_get_info (&saved_mode_info); if (saved->fini) saved->fini (); } grub_video_adapter_active = &grub_video_capture_adapter; return GRUB_ERR_NONE; }
static grub_err_t grub_video_cbfb_setup (unsigned int width, unsigned int height, unsigned int mode_type __attribute__ ((unused)), unsigned int mode_mask __attribute__ ((unused))) { grub_err_t err; if (!grub_video_coreboot_fbtable) return grub_error (GRUB_ERR_IO, "Couldn't find display device."); if (!((width == grub_video_coreboot_fbtable->width && height == grub_video_coreboot_fbtable->height) || (width == 0 && height == 0))) return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); err = grub_video_cbfb_fill_mode_info (&framebuffer.mode_info); if (err) { grub_dprintf ("video", "CBFB: couldn't fill mode info\n"); return err; } framebuffer.ptr = (void *) (grub_addr_t) grub_video_coreboot_fbtable->lfb; grub_dprintf ("video", "CBFB: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); err = grub_video_fb_setup (mode_type, mode_mask, &framebuffer.mode_info, framebuffer.ptr, NULL, NULL); if (err) return err; grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); return err; }
static grub_err_t grub_video_gop_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) { unsigned int depth; struct grub_efi_gop_mode_info *info = NULL; unsigned best_mode = 0; grub_err_t err; unsigned bpp; int found = 0; unsigned long long best_volume = 0; depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; /* Keep current mode if possible. */ if (gop->mode->info) { bpp = grub_video_gop_get_bpp (gop->mode->info); if (bpp && ((width == gop->mode->info->width && height == gop->mode->info->height) || (width == 0 && height == 0)) && (depth == bpp || depth == 0)) { grub_dprintf ("video", "GOP: keeping mode %d\n", gop->mode->mode); best_mode = gop->mode->mode; found = 1; } } if (!found) { unsigned mode; grub_dprintf ("video", "GOP: %d modes detected\n", gop->mode->max_mode); for (mode = 0; mode < gop->mode->max_mode; mode++) { grub_efi_uintn_t size; grub_efi_status_t status; status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); if (status) { info = 0; continue; } grub_dprintf ("video", "GOP: mode %d: %dx%d\n", mode, info->width, info->height); bpp = grub_video_gop_get_bpp (info); if (!bpp) { grub_dprintf ("video", "GOP: mode %d: incompatible pixel mode\n", mode); continue; } grub_dprintf ("video", "GOP: mode %d: depth %d\n", mode, bpp); if (!(((info->width == width && info->height == height) || (width == 0 && height == 0)) && (bpp == depth || depth == 0))) { grub_dprintf ("video", "GOP: mode %d: rejected\n", mode); continue; } if (best_volume < ((unsigned long long) info->width) * ((unsigned long long) info->height) * ((unsigned long long) bpp)) { best_volume = ((unsigned long long) info->width) * ((unsigned long long) info->height) * ((unsigned long long) bpp); best_mode = mode; } found = 1; } } if (!found) { grub_dprintf ("video", "GOP: no mode found\n"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); } if (best_mode != gop->mode->mode) { if (!restore_needed) { old_mode = gop->mode->mode; restore_needed = 1; } efi_call_2 (gop->set_mode, gop, best_mode); } info = gop->mode->info; err = grub_video_gop_fill_mode_info (gop->mode->mode, info, &framebuffer.mode_info); if (err) { grub_dprintf ("video", "GOP: couldn't fill mode info\n"); return err; } framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base; grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) { grub_dprintf ("video", "GOP: Couldn't create FB target\n"); return err; } err = grub_video_fb_set_active_render_target (framebuffer.render_target); if (err) { grub_dprintf ("video", "GOP: Couldn't set FB target\n"); return err; } err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); if (err) grub_dprintf ("video", "GOP: Couldn't set palette\n"); else grub_dprintf ("video", "GOP: Success\n"); return err; }
static grub_err_t grub_video_ieee1275_setup (unsigned int width, unsigned int height, unsigned int mode_type __attribute__ ((unused)), unsigned int mode_mask __attribute__ ((unused))) { grub_uint32_t current_width, current_height, address; grub_err_t err; grub_ieee1275_phandle_t dev; if (!display) return grub_error (GRUB_ERR_IO, "Couldn't find display device."); if (grub_ieee1275_finddevice (display, &dev)) return grub_error (GRUB_ERR_IO, "Couldn't open display device."); if (grub_ieee1275_get_integer_property (dev, "width", ¤t_width, sizeof (current_width), 0)) return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width."); if (grub_ieee1275_get_integer_property (dev, "height", ¤t_height, sizeof (current_width), 0)) return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height."); if ((width == current_width && height == current_height) || (width == 0 && height == 0)) { grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n", current_width, current_height); } else { grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height); /* TODO. */ return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); } err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info); if (err) { grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n"); return err; } if (grub_ieee1275_get_integer_property (dev, "address", (void *) &address, sizeof (address), 0)) return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address."); /* For some reason sparc64 uses 32-bit pointer too. */ framebuffer.ptr = (void *) (grub_addr_t) address; grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) { grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n"); return err; } err = grub_video_fb_set_active_render_target (framebuffer.render_target); if (err) { grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n"); return err; } err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); if (err) grub_dprintf ("video", "IEEE1275: Couldn't set palette\n"); else grub_dprintf ("video", "IEEE1275: Success\n"); return err; }