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

« back to all changes in this revision

Viewing changes to video/i386/pc/vga.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) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  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/machine/vga.h>
22
 
#include <grub/machine/console.h>
23
 
#include <grub/cpu/io.h>
24
 
#include <grub/mm.h>
25
 
#include <grub/video.h>
26
 
#include <grub/video_fb.h>
27
 
#include <grub/types.h>
28
 
#include <grub/dl.h>
29
 
#include <grub/misc.h>
30
 
#include <grub/vga.h>
31
 
 
32
 
#define VGA_WIDTH       640
33
 
#define VGA_HEIGHT      350
34
 
#define VGA_MEM         ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR)
35
 
#define PAGE_OFFSET(x)  ((x) * (VGA_WIDTH * VGA_HEIGHT / 8))
36
 
 
37
 
static unsigned char text_mode;
38
 
static unsigned char saved_map_mask;
39
 
 
40
 
static struct
41
 
{
42
 
  struct grub_video_mode_info mode_info;
43
 
  struct grub_video_render_target *render_target;
44
 
  grub_uint8_t *temporary_buffer;
45
 
  int front_page;
46
 
  int back_page;
47
 
} framebuffer;
48
 
 
49
 
static inline void
50
 
wait_vretrace (void)
51
 
{
52
 
  /* Wait until there is a vertical retrace.  */
53
 
  while (! (grub_inb (GRUB_VGA_IO_INPUT_STATUS1_REGISTER)
54
 
            & GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT));
55
 
}
56
 
 
57
 
/* Get Map Mask Register.  */
58
 
static unsigned char
59
 
get_map_mask (void)
60
 
{
61
 
  return grub_vga_sr_read (GRUB_VGA_SR_MAP_MASK_REGISTER);
62
 
}
63
 
 
64
 
/* Set Map Mask Register.  */
65
 
static void
66
 
set_map_mask (unsigned char mask)
67
 
{
68
 
  grub_vga_sr_write (mask, GRUB_VGA_SR_MAP_MASK_REGISTER);
69
 
}
70
 
 
71
 
#if 0
72
 
/* Set Read Map Register.  */
73
 
static void
74
 
set_read_map (unsigned char map)
75
 
{
76
 
  grub_vga_gr_write (map, GRUB_VGA_GR_READ_MAP_REGISTER);
77
 
}
78
 
#endif
79
 
 
80
 
/* Set start address.  */
81
 
static void
82
 
set_start_address (unsigned int start)
83
 
{
84
 
  grub_vga_cr_write (start & 0xFF, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
85
 
  grub_vga_cr_write (start >> 8, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
86
 
}
87
 
 
88
 
static int setup = 0;
89
 
static int is_target = 0;
90
 
 
91
 
static grub_err_t
92
 
grub_video_vga_init (void)
93
 
{
94
 
  return GRUB_ERR_NONE;
95
 
}
96
 
 
97
 
static grub_err_t
98
 
grub_video_vga_setup (unsigned int width, unsigned int height,
99
 
                      unsigned int mode_type, unsigned int mode_mask)
100
 
{
101
 
  grub_err_t err;
102
 
 
103
 
  if ((width && width != VGA_WIDTH) || (height && height != VGA_HEIGHT))
104
 
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
105
 
 
106
 
  framebuffer.temporary_buffer = grub_malloc (VGA_HEIGHT * VGA_WIDTH);
107
 
  framebuffer.front_page = 0;
108
 
  framebuffer.back_page = 0;
109
 
  if (!framebuffer.temporary_buffer)
110
 
    return grub_errno;
111
 
 
112
 
  saved_map_mask = get_map_mask ();
113
 
 
114
 
  text_mode = grub_vga_set_mode (0x10);
115
 
  setup = 1;
116
 
  set_map_mask (0x0f);
117
 
  set_start_address (PAGE_OFFSET (framebuffer.front_page));
118
 
 
119
 
  framebuffer.mode_info.width = VGA_WIDTH;
120
 
  framebuffer.mode_info.height = VGA_HEIGHT;
121
 
 
122
 
  framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
123
 
 
124
 
  if (grub_video_check_mode_flag (mode_type, mode_mask,
125
 
                                  GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1))
126
 
    {
127
 
      framebuffer.back_page = 1;
128
 
      framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
129
 
    }
130
 
 
131
 
  framebuffer.mode_info.bpp = 8;
132
 
  framebuffer.mode_info.bytes_per_pixel = 1;
133
 
  framebuffer.mode_info.pitch = VGA_WIDTH;
134
 
  framebuffer.mode_info.number_of_colors = 16;
135
 
  framebuffer.mode_info.red_mask_size = 0;
136
 
  framebuffer.mode_info.red_field_pos = 0;
137
 
  framebuffer.mode_info.green_mask_size = 0;
138
 
  framebuffer.mode_info.green_field_pos = 0;
139
 
  framebuffer.mode_info.blue_mask_size = 0;
140
 
  framebuffer.mode_info.blue_field_pos = 0;
141
 
  framebuffer.mode_info.reserved_mask_size = 0;
142
 
  framebuffer.mode_info.reserved_field_pos = 0;
143
 
 
144
 
  framebuffer.mode_info.blit_format
145
 
    = grub_video_get_blit_format (&framebuffer.mode_info);
146
 
 
147
 
  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target,
148
 
                                                         &framebuffer.mode_info,
149
 
                                                         framebuffer.temporary_buffer);
150
 
 
151
 
  if (err)
152
 
    {
153
 
      grub_dprintf ("video", "Couldn't create FB target\n");
154
 
      return err;
155
 
    }
156
 
 
157
 
  is_target = 1;
158
 
  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
159
 
 
160
 
  if (err)
161
 
    return err;
162
 
 
163
 
  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
164
 
                                   grub_video_fbstd_colors);
165
 
 
166
 
  return GRUB_ERR_NONE;
167
 
}
168
 
 
169
 
static grub_err_t
170
 
grub_video_vga_fini (void)
171
 
{
172
 
  if (setup)
173
 
    {
174
 
      set_map_mask (saved_map_mask);
175
 
      grub_vga_set_mode (text_mode);
176
 
    }
177
 
  setup = 0;
178
 
  grub_free (framebuffer.temporary_buffer);
179
 
  framebuffer.temporary_buffer = 0;
180
 
  return GRUB_ERR_NONE;
181
 
}
182
 
 
183
 
static inline void
184
 
update_target (void)
185
 
{
186
 
  int plane;
187
 
 
188
 
  if (!is_target)
189
 
    return;
190
 
 
191
 
  for (plane = 0x01; plane <= 0x08; plane <<= 1)
192
 
    {
193
 
      grub_uint8_t *ptr;
194
 
      volatile grub_uint8_t *ptr2;
195
 
      unsigned cbyte = 0;
196
 
      int shift = 7;
197
 
      set_map_mask (plane);
198
 
      for (ptr = framebuffer.temporary_buffer,
199
 
             ptr2 = VGA_MEM + PAGE_OFFSET (framebuffer.back_page);
200
 
           ptr < framebuffer.temporary_buffer + VGA_WIDTH * VGA_HEIGHT; ptr++)
201
 
        {
202
 
          cbyte |= (!!(plane & *ptr)) << shift;
203
 
          shift--;
204
 
          if (shift == -1)
205
 
            {
206
 
              *ptr2++ = cbyte;
207
 
              shift = 7;
208
 
              cbyte = 0;
209
 
            }
210
 
        }
211
 
    }
212
 
}
213
 
 
214
 
static grub_err_t
215
 
grub_video_vga_blit_bitmap (struct grub_video_bitmap *bitmap,
216
 
                            enum grub_video_blit_operators oper, int x, int y,
217
 
                            int offset_x, int offset_y,
218
 
                            unsigned int width, unsigned int height)
219
 
{
220
 
  grub_err_t ret;
221
 
  ret = grub_video_fb_blit_bitmap (bitmap, oper, x, y, offset_x, offset_y,
222
 
                                   width, height);
223
 
  update_target ();
224
 
  return ret;
225
 
}
226
 
 
227
 
static grub_err_t
228
 
grub_video_vga_blit_render_target (struct grub_video_fbrender_target *source,
229
 
                                   enum grub_video_blit_operators oper,
230
 
                                   int x, int y, int offset_x, int offset_y,
231
 
                                   unsigned int width, unsigned int height)
232
 
{
233
 
  grub_err_t ret;
234
 
 
235
 
  ret = grub_video_fb_blit_render_target (source, oper, x, y,
236
 
                                          offset_x, offset_y, width, height);
237
 
  update_target ();
238
 
 
239
 
  return ret;
240
 
}
241
 
 
242
 
static grub_err_t
243
 
grub_video_vga_set_active_render_target (struct grub_video_render_target *target)
244
 
{
245
 
  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
246
 
    {
247
 
      is_target = 1;
248
 
      target = framebuffer.render_target;
249
 
    }
250
 
  else
251
 
    is_target = 0;
252
 
 
253
 
  return grub_video_fb_set_active_render_target (target);
254
 
}
255
 
 
256
 
static grub_err_t
257
 
grub_video_vga_get_active_render_target (struct grub_video_render_target **target)
258
 
{
259
 
  grub_err_t err;
260
 
  err = grub_video_fb_get_active_render_target (target);
261
 
  if (err)
262
 
    return err;
263
 
 
264
 
  if (*target == framebuffer.render_target)
265
 
    *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY;
266
 
 
267
 
  return GRUB_ERR_NONE;
268
 
}
269
 
 
270
 
static grub_err_t
271
 
grub_video_vga_swap_buffers (void)
272
 
{
273
 
  if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED))
274
 
    return GRUB_ERR_NONE;
275
 
 
276
 
  /* Activate the other page.  */
277
 
  framebuffer.front_page = !framebuffer.front_page;
278
 
  framebuffer.back_page = !framebuffer.back_page;
279
 
  wait_vretrace ();
280
 
  set_start_address (PAGE_OFFSET (framebuffer.front_page));
281
 
 
282
 
  return GRUB_ERR_NONE;
283
 
}
284
 
 
285
 
static grub_err_t
286
 
grub_video_vga_set_palette (unsigned int start __attribute__ ((unused)),
287
 
                            unsigned int count __attribute__ ((unused)),
288
 
                            struct grub_video_palette_data *palette_data __attribute__ ((unused)))
289
 
{
290
 
  return grub_error (GRUB_ERR_IO, "can't change palette");
291
 
}
292
 
 
293
 
static grub_err_t
294
 
grub_video_vga_get_info_and_fini (struct grub_video_mode_info *mode_info,
295
 
                                  void **framebuf)
296
 
{
297
 
  set_map_mask (0xf);
298
 
 
299
 
  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
300
 
  mode_info->bpp = 1;
301
 
  mode_info->bytes_per_pixel = 0;
302
 
  mode_info->pitch = VGA_WIDTH / 8;
303
 
  mode_info->number_of_colors = 1;
304
 
 
305
 
  mode_info->bg_red = 0;
306
 
  mode_info->bg_green = 0;
307
 
  mode_info->bg_blue = 0;
308
 
  mode_info->bg_alpha = 255;
309
 
 
310
 
  mode_info->fg_red = 255;
311
 
  mode_info->fg_green = 255;
312
 
  mode_info->fg_blue = 255;
313
 
  mode_info->fg_alpha = 255;
314
 
 
315
 
  *framebuf = VGA_MEM + PAGE_OFFSET (framebuffer.front_page);
316
 
 
317
 
  grub_video_fb_fini ();
318
 
  grub_free (framebuffer.temporary_buffer);
319
 
  framebuffer.temporary_buffer = 0;
320
 
  setup = 0;
321
 
 
322
 
  return GRUB_ERR_NONE;
323
 
}
324
 
 
325
 
 
326
 
static struct grub_video_adapter grub_video_vga_adapter =
327
 
  {
328
 
    .name = "VGA Video Driver",
329
 
    .id = GRUB_VIDEO_DRIVER_VGA,
330
 
 
331
 
    .prio = GRUB_VIDEO_ADAPTER_PRIO_FALLBACK,
332
 
 
333
 
    .init = grub_video_vga_init,
334
 
    .fini = grub_video_vga_fini,
335
 
    .setup = grub_video_vga_setup,
336
 
    .get_info = grub_video_fb_get_info,
337
 
    .get_info_and_fini = grub_video_vga_get_info_and_fini,
338
 
    .set_palette = grub_video_vga_set_palette,
339
 
    .get_palette = grub_video_fb_get_palette,
340
 
    .set_viewport = grub_video_fb_set_viewport,
341
 
    .get_viewport = grub_video_fb_get_viewport,
342
 
    .map_color = grub_video_fb_map_color,
343
 
    .map_rgb = grub_video_fb_map_rgb,
344
 
    .map_rgba = grub_video_fb_map_rgba,
345
 
    .unmap_color = grub_video_fb_unmap_color,
346
 
    .fill_rect = grub_video_fb_fill_rect,
347
 
    .blit_bitmap = grub_video_vga_blit_bitmap,
348
 
    .blit_render_target = grub_video_vga_blit_render_target,
349
 
    .scroll = grub_video_fb_scroll,
350
 
    .swap_buffers = grub_video_vga_swap_buffers,
351
 
    .create_render_target = grub_video_fb_create_render_target,
352
 
    .delete_render_target = grub_video_fb_delete_render_target,
353
 
    .set_active_render_target = grub_video_vga_set_active_render_target,
354
 
    .get_active_render_target = grub_video_vga_get_active_render_target,
355
 
 
356
 
    .next = 0
357
 
  };
358
 
 
359
 
GRUB_MOD_INIT(vga)
360
 
{
361
 
  grub_video_register (&grub_video_vga_adapter);
362
 
}
363
 
 
364
 
GRUB_MOD_FINI(vga)
365
 
{
366
 
  grub_video_unregister (&grub_video_vga_adapter);
367
 
}