2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc.
5
* GRUB is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19
#define grub_video_render_target grub_video_fbrender_target
22
#include <grub/types.h>
24
#include <grub/misc.h>
26
#include <grub/video.h>
27
#include <grub/video_fb.h>
28
#include <grub/ieee1275/ieee1275.h>
30
/* Only 8-bit indexed color is supported for now. */
32
static unsigned old_width, old_height;
33
static int restore_needed;
35
static grub_ieee1275_ihandle_t stdout_ihandle;
36
static int have_setcolors = 0;
40
struct grub_video_mode_info mode_info;
41
struct grub_video_render_target *render_target;
46
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
47
struct grub_video_palette_data *palette_data);
50
set_video_mode (unsigned width __attribute__ ((unused)),
51
unsigned height __attribute__ ((unused)))
59
auto int hook (struct grub_ieee1275_devalias *alias);
60
int hook (struct grub_ieee1275_devalias *alias)
62
if (grub_strcmp (alias->type, "display") == 0)
64
grub_dprintf ("video", "Found display %s\n", alias->path);
65
display = grub_strdup (alias->path);
71
grub_ieee1275_devices_iterate (hook);
75
grub_video_ieee1275_init (void)
79
grub_memset (&framebuffer, 0, sizeof(framebuffer));
81
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)
82
&& !grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
83
"stdout", &stdout_ihandle,
84
sizeof (stdout_ihandle), &actual)
85
&& actual == sizeof (stdout_ihandle))
88
return grub_video_fb_init ();
92
grub_video_ieee1275_fini (void)
96
set_video_mode (old_width, old_height);
99
return grub_video_fb_fini ();
103
grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
104
struct grub_video_mode_info *out)
108
grub_memset (out, 0, sizeof (*out));
110
if (grub_ieee1275_get_integer_property (dev, "width", &tmp,
112
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
115
if (grub_ieee1275_get_integer_property (dev, "height", &tmp,
117
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
120
if (grub_ieee1275_get_integer_property (dev, "linebytes", &tmp,
122
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
125
out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
127
out->bytes_per_pixel = 1;
128
out->number_of_colors = 256;
130
out->blit_format = grub_video_get_blit_format (out);
131
return GRUB_ERR_NONE;
135
grub_video_ieee1275_setup (unsigned int width, unsigned int height,
136
unsigned int mode_type __attribute__ ((unused)),
137
unsigned int mode_mask __attribute__ ((unused)))
139
grub_uint32_t current_width, current_height, address;
141
grub_ieee1275_phandle_t dev;
144
return grub_error (GRUB_ERR_IO, "Couldn't find display device.");
146
if (grub_ieee1275_finddevice (display, &dev))
147
return grub_error (GRUB_ERR_IO, "Couldn't open display device.");
149
if (grub_ieee1275_get_integer_property (dev, "width", ¤t_width,
150
sizeof (current_width), 0))
151
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
153
if (grub_ieee1275_get_integer_property (dev, "height", ¤t_height,
154
sizeof (current_width), 0))
155
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
157
if ((width == current_width && height == current_height)
158
|| (width == 0 && height == 0))
160
grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n",
161
current_width, current_height);
165
grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height);
167
return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height);
170
err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info);
173
grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n");
177
if (grub_ieee1275_get_integer_property (dev, "address", (void *) &address,
178
sizeof (address), 0))
179
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address.");
181
/* For some reason sparc64 uses 32-bit pointer too. */
182
framebuffer.ptr = (void *) (grub_addr_t) address;
184
grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n",
185
framebuffer.ptr, framebuffer.mode_info.width,
186
framebuffer.mode_info.height, framebuffer.mode_info.bpp);
188
err = grub_video_fb_create_render_target_from_pointer
189
(&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
193
grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n");
197
err = grub_video_fb_set_active_render_target (framebuffer.render_target);
201
grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n");
205
grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
206
grub_video_fbstd_colors);
212
grub_video_ieee1275_swap_buffers (void)
214
/* TODO: Implement buffer swapping. */
215
return GRUB_ERR_NONE;
219
grub_video_ieee1275_set_active_render_target (struct grub_video_render_target *target)
221
if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
222
target = framebuffer.render_target;
224
return grub_video_fb_set_active_render_target (target);
228
grub_video_ieee1275_get_info_and_fini (struct grub_video_mode_info *mode_info,
231
grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
232
*framebuf = (char *) framebuffer.ptr;
234
grub_video_fb_fini ();
236
return GRUB_ERR_NONE;
240
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
241
struct grub_video_palette_data *palette_data)
244
struct grub_video_palette_data fb_palette_data[256];
246
err = grub_video_fb_set_palette (start, count, palette_data);
250
grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data);
256
for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
257
grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
258
fb_palette_data[col].g,
259
fb_palette_data[col].b);
262
return GRUB_ERR_NONE;
265
static struct grub_video_adapter grub_video_ieee1275_adapter =
267
.name = "IEEE1275 video driver",
269
.prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE,
271
.init = grub_video_ieee1275_init,
272
.fini = grub_video_ieee1275_fini,
273
.setup = grub_video_ieee1275_setup,
274
.get_info = grub_video_fb_get_info,
275
.get_info_and_fini = grub_video_ieee1275_get_info_and_fini,
276
.set_palette = grub_video_ieee1275_set_palette,
277
.get_palette = grub_video_fb_get_palette,
278
.set_viewport = grub_video_fb_set_viewport,
279
.get_viewport = grub_video_fb_get_viewport,
280
.map_color = grub_video_fb_map_color,
281
.map_rgb = grub_video_fb_map_rgb,
282
.map_rgba = grub_video_fb_map_rgba,
283
.unmap_color = grub_video_fb_unmap_color,
284
.fill_rect = grub_video_fb_fill_rect,
285
.blit_bitmap = grub_video_fb_blit_bitmap,
286
.blit_render_target = grub_video_fb_blit_render_target,
287
.scroll = grub_video_fb_scroll,
288
.swap_buffers = grub_video_ieee1275_swap_buffers,
289
.create_render_target = grub_video_fb_create_render_target,
290
.delete_render_target = grub_video_fb_delete_render_target,
291
.set_active_render_target = grub_video_ieee1275_set_active_render_target,
292
.get_active_render_target = grub_video_fb_get_active_render_target,
297
GRUB_MOD_INIT(ieee1275_fb)
301
grub_video_register (&grub_video_ieee1275_adapter);
304
GRUB_MOD_FINI(ieee1275_fb)
308
set_video_mode (old_width, old_height);
312
grub_video_unregister (&grub_video_ieee1275_adapter);