~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to grub-core/video/ieee1275.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  GRUB  --  GRand Unified Bootloader
 
3
 *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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/>.
 
17
 */
 
18
 
 
19
#define grub_video_render_target grub_video_fbrender_target
 
20
 
 
21
#include <grub/err.h>
 
22
#include <grub/types.h>
 
23
#include <grub/dl.h>
 
24
#include <grub/misc.h>
 
25
#include <grub/mm.h>
 
26
#include <grub/video.h>
 
27
#include <grub/video_fb.h>
 
28
#include <grub/ieee1275/ieee1275.h>
 
29
 
 
30
/* Only 8-bit indexed color is supported for now.  */
 
31
 
 
32
static unsigned old_width, old_height;
 
33
static int restore_needed;
 
34
static char *display;
 
35
static grub_ieee1275_ihandle_t stdout_ihandle;
 
36
static int have_setcolors = 0;
 
37
 
 
38
static struct
 
39
{
 
40
  struct grub_video_mode_info mode_info;
 
41
  struct grub_video_render_target *render_target;
 
42
  grub_uint8_t *ptr;
 
43
} framebuffer;
 
44
 
 
45
static grub_err_t
 
46
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
 
47
                                 struct grub_video_palette_data *palette_data);
 
48
 
 
49
static void
 
50
set_video_mode (unsigned width __attribute__ ((unused)),
 
51
                unsigned height __attribute__ ((unused)))
 
52
{
 
53
  /* TODO */
 
54
}
 
55
 
 
56
static void
 
57
find_display (void)
 
58
{
 
59
  auto int hook (struct grub_ieee1275_devalias *alias);
 
60
  int hook (struct grub_ieee1275_devalias *alias)
 
61
  {
 
62
    if (grub_strcmp (alias->type, "display") == 0)
 
63
      {
 
64
        grub_dprintf ("video", "Found display %s\n", alias->path);
 
65
        display = grub_strdup (alias->path);
 
66
        return 1;
 
67
      }
 
68
    return 0;
 
69
  }
 
70
  
 
71
  grub_ieee1275_devices_iterate (hook);
 
72
}
 
73
 
 
74
static grub_err_t
 
75
grub_video_ieee1275_init (void)
 
76
{
 
77
  grub_ssize_t actual;
 
78
 
 
79
  grub_memset (&framebuffer, 0, sizeof(framebuffer));
 
80
 
 
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))
 
86
    have_setcolors = 1;
 
87
 
 
88
  return grub_video_fb_init ();
 
89
}
 
90
 
 
91
static grub_err_t
 
92
grub_video_ieee1275_fini (void)
 
93
{
 
94
  if (restore_needed)
 
95
    {
 
96
      set_video_mode (old_width, old_height);
 
97
      restore_needed = 0;
 
98
    }
 
99
  return grub_video_fb_fini ();
 
100
}
 
101
 
 
102
static grub_err_t
 
103
grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
 
104
                                    struct grub_video_mode_info *out)
 
105
{
 
106
  grub_uint32_t tmp;
 
107
 
 
108
  grub_memset (out, 0, sizeof (*out));
 
109
 
 
110
  if (grub_ieee1275_get_integer_property (dev, "width", &tmp,
 
111
                                          sizeof (tmp), 0))
 
112
    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
 
113
  out->width = tmp;
 
114
 
 
115
  if (grub_ieee1275_get_integer_property (dev, "height", &tmp,
 
116
                                          sizeof (tmp), 0))
 
117
    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
 
118
  out->height = tmp;
 
119
 
 
120
  if (grub_ieee1275_get_integer_property (dev, "linebytes", &tmp,
 
121
                                          sizeof (tmp), 0))
 
122
    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
 
123
  out->pitch = tmp;
 
124
 
 
125
  out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
 
126
  out->bpp = 8;
 
127
  out->bytes_per_pixel = 1;
 
128
  out->number_of_colors = 256;
 
129
 
 
130
  out->blit_format = grub_video_get_blit_format (out);
 
131
  return GRUB_ERR_NONE;
 
132
}
 
133
 
 
134
static grub_err_t
 
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)))
 
138
{
 
139
  grub_uint32_t current_width, current_height, address;
 
140
  grub_err_t err;
 
141
  grub_ieee1275_phandle_t dev;
 
142
 
 
143
  if (!display)
 
144
    return grub_error (GRUB_ERR_IO, "Couldn't find display device.");
 
145
 
 
146
  if (grub_ieee1275_finddevice (display, &dev))
 
147
    return grub_error (GRUB_ERR_IO, "Couldn't open display device.");
 
148
 
 
149
  if (grub_ieee1275_get_integer_property (dev, "width", &current_width,
 
150
                                          sizeof (current_width), 0))
 
151
    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
 
152
 
 
153
  if (grub_ieee1275_get_integer_property (dev, "height", &current_height,
 
154
                                          sizeof (current_width), 0))
 
155
    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
 
156
 
 
157
  if ((width == current_width && height == current_height)
 
158
      || (width == 0 && height == 0))
 
159
    {
 
160
      grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n",
 
161
                    current_width, current_height);
 
162
    }
 
163
  else
 
164
    {
 
165
      grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height);
 
166
      /* TODO. */
 
167
      return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height);
 
168
    }
 
169
  
 
170
  err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info);
 
171
  if (err)
 
172
    {
 
173
      grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n");
 
174
      return err;
 
175
    }
 
176
 
 
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.");
 
180
 
 
181
  /* For some reason sparc64 uses 32-bit pointer too.  */
 
182
  framebuffer.ptr = (void *) (grub_addr_t) address;
 
183
 
 
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);
 
187
  
 
188
  err = grub_video_fb_create_render_target_from_pointer 
 
189
    (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
 
190
 
 
191
  if (err)
 
192
    {
 
193
      grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n");
 
194
      return err;
 
195
    }
 
196
  
 
197
  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
 
198
  
 
199
  if (err)
 
200
    {
 
201
      grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n");
 
202
      return err;
 
203
    }
 
204
 
 
205
  grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
 
206
                                   grub_video_fbstd_colors);
 
207
    
 
208
  return err;
 
209
}
 
210
 
 
211
static grub_err_t
 
212
grub_video_ieee1275_swap_buffers (void)
 
213
{
 
214
  /* TODO: Implement buffer swapping.  */
 
215
  return GRUB_ERR_NONE;
 
216
}
 
217
 
 
218
static grub_err_t
 
219
grub_video_ieee1275_set_active_render_target (struct grub_video_render_target *target)
 
220
{
 
221
  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
 
222
    target = framebuffer.render_target;
 
223
 
 
224
  return grub_video_fb_set_active_render_target (target);
 
225
}
 
226
 
 
227
static grub_err_t
 
228
grub_video_ieee1275_get_info_and_fini (struct grub_video_mode_info *mode_info,
 
229
                                  void **framebuf)
 
230
{
 
231
  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
 
232
  *framebuf = (char *) framebuffer.ptr;
 
233
 
 
234
  grub_video_fb_fini ();
 
235
 
 
236
  return GRUB_ERR_NONE;
 
237
}
 
238
 
 
239
static grub_err_t
 
240
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
 
241
                                 struct grub_video_palette_data *palette_data)
 
242
{
 
243
  grub_err_t err;
 
244
  struct grub_video_palette_data fb_palette_data[256];
 
245
 
 
246
  err = grub_video_fb_set_palette (start, count, palette_data);
 
247
  if (err)
 
248
    return err;
 
249
 
 
250
  grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data);
 
251
 
 
252
  /* Set colors.  */
 
253
  if (have_setcolors)
 
254
    {
 
255
      unsigned col;
 
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);
 
260
    }
 
261
 
 
262
  return GRUB_ERR_NONE;
 
263
}
 
264
 
 
265
static struct grub_video_adapter grub_video_ieee1275_adapter =
 
266
  {
 
267
    .name = "IEEE1275 video driver",
 
268
 
 
269
    .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE,
 
270
 
 
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,
 
293
 
 
294
    .next = 0
 
295
  };
 
296
 
 
297
GRUB_MOD_INIT(ieee1275_fb)
 
298
{
 
299
  find_display ();
 
300
  if (display)
 
301
    grub_video_register (&grub_video_ieee1275_adapter);
 
302
}
 
303
 
 
304
GRUB_MOD_FINI(ieee1275_fb)
 
305
{
 
306
  if (restore_needed)
 
307
    {
 
308
      set_video_mode (old_width, old_height);
 
309
      restore_needed = 0;
 
310
    }
 
311
  if (display)
 
312
    grub_video_unregister (&grub_video_ieee1275_adapter);
 
313
  grub_free (display);
 
314
}