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

« back to all changes in this revision

Viewing changes to grub-core/video/sm712.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,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/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/pci.h>
 
29
#include <grub/vga.h>
 
30
 
 
31
#include "sm712_init.c"
 
32
 
 
33
#define GRUB_SM712_TOTAL_MEMORY_SPACE  0x700400
 
34
#define GRUB_SM712_REG_BASE 0x700000
 
35
#define GRUB_SM712_PCIID 0x0712126f
 
36
 
 
37
enum
 
38
  {
 
39
    GRUB_SM712_SR_TV_CONTROL = 0x65,
 
40
    GRUB_SM712_SR_RAM_LUT = 0x66,
 
41
    GRUB_SM712_SR_CLOCK_CONTROL1 = 0x68,
 
42
    GRUB_SM712_SR_CLOCK_CONTROL2 = 0x69,
 
43
    GRUB_SM712_SR_VCLK_NUM = 0x6c,
 
44
    GRUB_SM712_SR_VCLK_DENOM = 0x6d,
 
45
    GRUB_SM712_SR_VCLK2_NUM = 0x6e,
 
46
    GRUB_SM712_SR_VCLK2_DENOM = 0x6f,
 
47
    GRUB_SM712_SR_POPUP_ICON_LOW = 0x80,
 
48
    GRUB_SM712_SR_POPUP_ICON_HIGH = 0x81,
 
49
    GRUB_SM712_SR_POPUP_ICON_CTRL = 0x82,
 
50
    GRUB_SM712_SR_POPUP_ICON_COLOR1 = 0x84,
 
51
    GRUB_SM712_SR_POPUP_ICON_COLOR2 = 0x85,
 
52
    GRUB_SM712_SR_POPUP_ICON_COLOR3 = 0x86,
 
53
 
 
54
    GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW = 0x88,
 
55
    GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH = 0x89,
 
56
    GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW = 0x8a,
 
57
    GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH = 0x8b,
 
58
    GRUB_SM712_SR_HW_CURSOR_FG_COLOR = 0x8c,
 
59
    GRUB_SM712_SR_HW_CURSOR_BG_COLOR = 0x8d,
 
60
 
 
61
    GRUB_SM712_SR_POPUP_ICON_X_LOW = 0x90,
 
62
    GRUB_SM712_SR_POPUP_ICON_X_HIGH = 0x91,
 
63
    GRUB_SM712_SR_POPUP_ICON_Y_LOW = 0x92,
 
64
    GRUB_SM712_SR_POPUP_ICON_Y_HIGH = 0x93,
 
65
    GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL = 0xa0,
 
66
    GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW = 0xa1,
 
67
    GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH = 0xa2,
 
68
    GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW = 0xa3,
 
69
    GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH = 0xa4,
 
70
    GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT = 0xa5,
 
71
    GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT = 0xa6,
 
72
    GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT = 0xa7,
 
73
    GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY = 0xa8,
 
74
    GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY = 0xa9,
 
75
    GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY = 0xaa,
 
76
    GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY = 0xab,
 
77
    GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY = 0xac,
 
78
    GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY = 0xad,
 
79
    GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR = 0xae,
 
80
    GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR = 0xaf,
 
81
  };
 
82
enum
 
83
  {
 
84
    GRUB_SM712_SR_TV_CRT_SRAM = 0x00,
 
85
    GRUB_SM712_SR_TV_LCD_SRAM = 0x08
 
86
  };
 
87
enum
 
88
  {
 
89
    GRUB_SM712_SR_TV_ALT_CLOCK = 0x00,
 
90
    GRUB_SM712_SR_TV_FREE_RUN_CLOCK = 0x04
 
91
  };
 
92
enum
 
93
  {
 
94
    GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC = 0x00,
 
95
    GRUB_SM712_SR_TV_CLOCK_REFCLK_PAL = 0x04
 
96
  };
 
97
enum
 
98
  {
 
99
    GRUB_SM712_SR_TV_HSYNC = 0x00,
 
100
    GRUB_SM712_SR_TV_COMPOSITE_HSYNC = 0x01
 
101
  };
 
102
enum
 
103
  {
 
104
    GRUB_SM712_SR_RAM_LUT_NORMAL = 0,
 
105
    GRUB_SM712_SR_RAM_LUT_LCD_RAM_OFF = 0x80,
 
106
    GRUB_SM712_SR_RAM_LUT_CRT_RAM_OFF = 0x40,
 
107
    GRUB_SM712_SR_RAM_LUT_LCD_RAM_NO_WRITE = 0x20,
 
108
    GRUB_SM712_SR_RAM_LUT_CRT_RAM_NO_WRITE = 0x10,
 
109
    GRUB_SM712_SR_RAM_LUT_CRT_8BIT = 0x08,
 
110
    GRUB_SM712_SR_RAM_LUT_CRT_GAMMA = 0x04
 
111
  };
 
112
 
 
113
enum
 
114
  {
 
115
    GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR = 0x40,
 
116
    GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK = 0x10,
 
117
  };
 
118
 
 
119
enum
 
120
  {
 
121
    GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK = 0x03
 
122
  };
 
123
 
 
124
#define GRUB_SM712_SR_POPUP_ICON_HIGH_MASK 0x7
 
125
#define GRUB_SM712_SR_POPUP_ICON_HIGH_HW_CURSOR_EN 0x80
 
126
  enum
 
127
  {
 
128
    GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED = 0,
 
129
    GRUB_SM712_SR_POPUP_ICON_CTRL_ZOOM_ENABLED = 0x40,
 
130
    GRUB_SM712_SR_POPUP_ICON_CTRL_ENABLED = 0x80
 
131
  };
 
132
#define RGB332_BLACK 0
 
133
#define RGB332_WHITE 0xff
 
134
 
 
135
  enum
 
136
  {
 
137
    GRUB_SM712_CR_OVERFLOW_INTERLACE = 0x30,
 
138
    GRUB_SM712_CR_INTERLACE_RETRACE = 0x31,
 
139
    GRUB_SM712_CR_TV_VDISPLAY_START = 0x32,
 
140
    GRUB_SM712_CR_TV_VDISPLAY_END_HIGH = 0x33,
 
141
    GRUB_SM712_CR_TV_VDISPLAY_END_LOW = 0x34,
 
142
    GRUB_SM712_CR_DDA_CONTROL_LOW = 0x35,
 
143
    GRUB_SM712_CR_DDA_CONTROL_HIGH = 0x36,
 
144
    GRUB_SM712_CR_TV_EQUALIZER = 0x38,
 
145
    GRUB_SM712_CR_TV_SERRATION = 0x39,
 
146
    GRUB_SM712_CR_HSYNC_CTRL = 0x3a,
 
147
    GRUB_SM712_CR_DEBUG = 0x3c,
 
148
    GRUB_SM712_CR_SHADOW_VGA_HTOTAL = 0x40,
 
149
    GRUB_SM712_CR_SHADOW_VGA_HBLANK_START = 0x41,
 
150
    GRUB_SM712_CR_SHADOW_VGA_HBLANK_END = 0x42,
 
151
    GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START = 0x43,
 
152
    GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END = 0x44,
 
153
    GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL = 0x45,
 
154
    GRUB_SM712_CR_SHADOW_VGA_VBLANK_START = 0x46,
 
155
    GRUB_SM712_CR_SHADOW_VGA_VBLANK_END = 0x47,
 
156
    GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START = 0x48,
 
157
    GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END = 0x49,    
 
158
    GRUB_SM712_CR_SHADOW_VGA_OVERFLOW = 0x4a,
 
159
    GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT = 0x4b,
 
160
    GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END = 0x4c,
 
161
    GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END = 0x4d,
 
162
    GRUB_SM712_CR_DDA_LOOKUP_REG3_START = 0x90,
 
163
    GRUB_SM712_CR_DDA_LOOKUP_REG2_START = 0x91,
 
164
    GRUB_SM712_CR_DDA_LOOKUP_REG1_START = 0xa0,
 
165
    GRUB_SM712_CR_VCENTERING_OFFSET = 0xa6,
 
166
    GRUB_SM712_CR_HCENTERING_OFFSET = 0xa7,
 
167
  };
 
168
 
 
169
#define GRUB_SM712_CR_DEBUG_NONE 0
 
170
 
 
171
#define SM712_DDA_REG3_COMPARE_SHIFT 2
 
172
#define SM712_DDA_REG3_COMPARE_MASK  0xfc
 
173
#define SM712_DDA_REG3_DDA_SHIFT 8
 
174
#define SM712_DDA_REG3_DDA_MASK  0x3
 
175
#define SM712_DDA_REG2_DDA_MASK  0xff
 
176
#define SM712_DDA_REG2_VCENTER_MASK 0x3f
 
177
 
 
178
static struct
 
179
{
 
180
  grub_uint8_t compare;
 
181
  grub_uint16_t dda;
 
182
  grub_uint8_t vcentering;
 
183
} dda_lookups[] = {
 
184
  { 21, 469,  2},
 
185
  { 23, 477,  2},
 
186
  { 33, 535,  2},
 
187
  { 35, 682, 21},
 
188
  { 34, 675,  2},
 
189
  { 55, 683,  6},
 
190
};
 
191
 
 
192
static struct
 
193
{
 
194
  struct grub_video_mode_info mode_info;
 
195
  struct grub_video_render_target *render_target;
 
196
 
 
197
  grub_uint8_t *ptr;
 
198
  int mapped;
 
199
  grub_uint32_t base;
 
200
  grub_pci_device_t dev;
 
201
} framebuffer;
 
202
 
 
203
#ifndef TEST
 
204
static grub_err_t
 
205
grub_video_sm712_video_init (void)
 
206
{
 
207
  /* Reset frame buffer.  */
 
208
  grub_memset (&framebuffer, 0, sizeof(framebuffer));
 
209
 
 
210
  return grub_video_fb_init ();
 
211
}
 
212
 
 
213
static grub_err_t
 
214
grub_video_sm712_video_fini (void)
 
215
{
 
216
  if (framebuffer.mapped)
 
217
    grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr,
 
218
                                 GRUB_SM712_TOTAL_MEMORY_SPACE);
 
219
 
 
220
  return grub_video_fb_fini ();
 
221
}
 
222
#endif
 
223
 
 
224
static inline void
 
225
grub_sm712_write_reg (grub_uint8_t val, grub_uint16_t addr)
 
226
{
 
227
#ifdef TEST
 
228
  printf ("  {1, 0x%x, 0x%x},\n", addr, val);
 
229
#else
 
230
   *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
 
231
                               + addr) = val;
 
232
#endif
 
233
}
 
234
 
 
235
static inline grub_uint8_t
 
236
grub_sm712_read_reg (grub_uint16_t addr)
 
237
{
 
238
#ifdef TEST
 
239
  printf ("  {-1, 0x%x, 0x5},\n", addr);
 
240
#else
 
241
  return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
 
242
                                     + addr);
 
243
#endif
 
244
}
 
245
 
 
246
static inline grub_uint8_t
 
247
grub_sm712_sr_read (grub_uint8_t addr)
 
248
{
 
249
  grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX);
 
250
  return grub_sm712_read_reg (GRUB_VGA_IO_SR_DATA);
 
251
}
 
252
 
 
253
static inline void
 
254
grub_sm712_sr_write (grub_uint8_t val, grub_uint8_t addr)
 
255
{
 
256
  grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX);
 
257
  grub_sm712_write_reg (val, GRUB_VGA_IO_SR_DATA);
 
258
}
 
259
 
 
260
static inline void
 
261
grub_sm712_gr_write (grub_uint8_t val, grub_uint8_t addr)
 
262
{
 
263
  grub_sm712_write_reg (addr, GRUB_VGA_IO_GR_INDEX);
 
264
  grub_sm712_write_reg (val, GRUB_VGA_IO_GR_DATA);
 
265
}
 
266
 
 
267
static inline void
 
268
grub_sm712_cr_write (grub_uint8_t val, grub_uint8_t addr)
 
269
{
 
270
  grub_sm712_write_reg (addr, GRUB_VGA_IO_CR_INDEX);
 
271
  grub_sm712_write_reg (val, GRUB_VGA_IO_CR_DATA);
 
272
}
 
273
 
 
274
static inline void
 
275
grub_sm712_write_arx (grub_uint8_t val, grub_uint8_t addr)
 
276
{
 
277
  grub_sm712_read_reg (GRUB_VGA_IO_INPUT_STATUS1_REGISTER);
 
278
  grub_sm712_write_reg (addr, GRUB_VGA_IO_ARX);
 
279
  grub_sm712_read_reg (GRUB_VGA_IO_ARX_READ);
 
280
  grub_sm712_write_reg (val, GRUB_VGA_IO_ARX);
 
281
}
 
282
 
 
283
static inline void
 
284
grub_sm712_cr_shadow_write (grub_uint8_t val, grub_uint8_t addr)
 
285
{
 
286
  grub_uint8_t mapping[] =
 
287
    {
 
288
      [GRUB_VGA_CR_HTOTAL] = GRUB_SM712_CR_SHADOW_VGA_HTOTAL,
 
289
      [GRUB_VGA_CR_HORIZ_END] = 0xff,
 
290
      [GRUB_VGA_CR_HBLANK_START] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_START,
 
291
      [GRUB_VGA_CR_HBLANK_END] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_END,
 
292
      [GRUB_VGA_CR_HORIZ_SYNC_PULSE_START] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START,
 
293
      [GRUB_VGA_CR_HORIZ_SYNC_PULSE_END] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END,
 
294
      [GRUB_VGA_CR_VERT_TOTAL] = GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL,
 
295
      [GRUB_VGA_CR_OVERFLOW] = GRUB_SM712_CR_SHADOW_VGA_OVERFLOW,
 
296
      [GRUB_VGA_CR_BYTE_PANNING] = 0xff,
 
297
      [GRUB_VGA_CR_CELL_HEIGHT] = GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT,
 
298
      [GRUB_VGA_CR_CURSOR_START] = 0xff,
 
299
      [GRUB_VGA_CR_CURSOR_END] = 0xff,
 
300
      [GRUB_VGA_CR_START_ADDR_HIGH_REGISTER] = 0xff,
 
301
      [GRUB_VGA_CR_START_ADDR_LOW_REGISTER] = 0xff,
 
302
      [GRUB_VGA_CR_CURSOR_ADDR_HIGH] = 0xff,
 
303
      [GRUB_VGA_CR_CURSOR_ADDR_LOW] = 0xff,
 
304
      [GRUB_VGA_CR_VSYNC_START] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START,
 
305
      [GRUB_VGA_CR_VSYNC_END] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END,
 
306
      [GRUB_VGA_CR_VDISPLAY_END] = GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END,
 
307
      [GRUB_VGA_CR_PITCH] = GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END,
 
308
      [GRUB_VGA_CR_UNDERLINE_LOCATION] = 0xff,
 
309
 
 
310
      [GRUB_VGA_CR_VERTICAL_BLANK_START] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_START,
 
311
      [GRUB_VGA_CR_VERTICAL_BLANK_END] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_END,
 
312
      [GRUB_VGA_CR_MODE] = 0xff,
 
313
      [GRUB_VGA_CR_LINE_COMPARE] = 0xff
 
314
    };
 
315
  if (addr >= ARRAY_SIZE (mapping) || mapping[addr] == 0xff)
 
316
    return;
 
317
  grub_sm712_cr_write (val, mapping[addr]);
 
318
}
 
319
 
 
320
static inline void
 
321
grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda,
 
322
                             grub_uint8_t vcentering)
 
323
{
 
324
  grub_sm712_cr_write (((compare << SM712_DDA_REG3_COMPARE_SHIFT)
 
325
                        & SM712_DDA_REG3_COMPARE_MASK)
 
326
                       | ((dda >> SM712_DDA_REG3_DDA_SHIFT)
 
327
                          & SM712_DDA_REG3_DDA_MASK),
 
328
                       GRUB_SM712_CR_DDA_LOOKUP_REG3_START + 2 * idx);
 
329
  grub_sm712_cr_write (dda & SM712_DDA_REG2_DDA_MASK,
 
330
                       GRUB_SM712_CR_DDA_LOOKUP_REG2_START + 2 * idx);
 
331
  grub_sm712_cr_write (vcentering & SM712_DDA_REG2_VCENTER_MASK,
 
332
                       GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx);
 
333
}
 
334
 
 
335
static grub_err_t
 
336
grub_video_sm712_setup (unsigned int width, unsigned int height,
 
337
                        unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
 
338
{
 
339
  int depth;
 
340
  grub_err_t err;
 
341
  int found = 0;
 
342
  unsigned i;
 
343
 
 
344
#ifndef TEST
 
345
  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
 
346
  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
 
347
    {
 
348
      grub_pci_address_t addr;
 
349
      grub_uint32_t class;
 
350
 
 
351
      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
 
352
      class = grub_pci_read (addr);
 
353
 
 
354
      if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
 
355
          || pciid != GRUB_SM712_PCIID)
 
356
        return 0;
 
357
      
 
358
      found = 1;
 
359
 
 
360
      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
 
361
      framebuffer.base = grub_pci_read (addr);
 
362
      framebuffer.dev = dev;
 
363
 
 
364
      return 1;
 
365
    }
 
366
 
 
367
  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
 
368
  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
 
369
          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
 
370
 
 
371
  if ((width != 1024 && width != 0) || (height != 600 && height != 0)
 
372
      || (depth != 16 && depth != 0))
 
373
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
 
374
                       "Only 1024x600x16 is supported");
 
375
 
 
376
  grub_pci_iterate (find_card);
 
377
  if (!found)
 
378
    return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
 
379
#endif
 
380
  /* Fill mode info details.  */
 
381
  framebuffer.mode_info.width = 1024;
 
382
  framebuffer.mode_info.height = 600;
 
383
  framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
 
384
  framebuffer.mode_info.bpp = 16;
 
385
  framebuffer.mode_info.bytes_per_pixel = 2;
 
386
  framebuffer.mode_info.pitch = 1024 * 2;
 
387
  framebuffer.mode_info.number_of_colors = 256;
 
388
  framebuffer.mode_info.red_mask_size = 5;
 
389
  framebuffer.mode_info.red_field_pos = 11;
 
390
  framebuffer.mode_info.green_mask_size = 6;
 
391
  framebuffer.mode_info.green_field_pos = 5;
 
392
  framebuffer.mode_info.blue_mask_size = 5;
 
393
  framebuffer.mode_info.blue_field_pos = 0;
 
394
  framebuffer.mode_info.reserved_mask_size = 0;
 
395
  framebuffer.mode_info.reserved_field_pos = 0;
 
396
#ifndef TEST
 
397
  framebuffer.mode_info.blit_format
 
398
    = grub_video_get_blit_format (&framebuffer.mode_info);
 
399
#endif
 
400
 
 
401
#ifndef TEST
 
402
  if (found && framebuffer.base == 0)
 
403
    {
 
404
      grub_pci_address_t addr;
 
405
      /* FIXME: choose address dynamically if needed.   */
 
406
      framebuffer.base = 0x04000000;
 
407
 
 
408
      addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0);
 
409
      grub_pci_write (addr, framebuffer.base);
 
410
 
 
411
      /* Set latency.  */
 
412
      addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE);
 
413
      grub_pci_write (addr, 0x8);
 
414
 
 
415
      /* Enable address spaces.  */
 
416
      addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND);
 
417
      grub_pci_write (addr, 0x7);
 
418
    }
 
419
#endif
 
420
 
 
421
  /* We can safely discard volatile attribute.  */
 
422
#ifndef TEST
 
423
  framebuffer.ptr
 
424
    = (void *) grub_pci_device_map_range (framebuffer.dev,
 
425
                                          framebuffer.base,
 
426
                                          GRUB_SM712_TOTAL_MEMORY_SPACE);
 
427
#endif
 
428
  framebuffer.mapped = 1;
 
429
 
 
430
  /* Initialise SM712.  */
 
431
#ifndef TEST
 
432
  /* FIXME */
 
433
  grub_vga_sr_write (0x11, 0x18);
 
434
#endif
 
435
 
 
436
#ifndef TEST
 
437
  /* Prevent garbage from appearing on the screen.  */
 
438
  grub_memset (framebuffer.ptr, 0, 
 
439
               framebuffer.mode_info.height * framebuffer.mode_info.pitch);
 
440
#endif
 
441
 
 
442
  /* FIXME */
 
443
  grub_sm712_sr_write (0, 0x21);
 
444
  grub_sm712_sr_write (0x7a, 0x62);
 
445
  grub_sm712_sr_write (0x16, 0x6a);
 
446
  grub_sm712_sr_write (0x2, 0x6b);
 
447
  grub_sm712_write_reg (0, GRUB_VGA_IO_PIXEL_MASK);
 
448
  grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC, GRUB_VGA_SR_RESET);
 
449
  grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY 
 
450
                        | GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY
 
451
                        | GRUB_VGA_IO_MISC_UPPER_64K
 
452
                        | GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0
 
453
                        | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS
 
454
                        | GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE);
 
455
  grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC | GRUB_VGA_SR_RESET_SYNC,
 
456
                       GRUB_VGA_SR_RESET);
 
457
  grub_sm712_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK,
 
458
                       GRUB_VGA_SR_CLOCKING_MODE);
 
459
  grub_sm712_sr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_SR_MAP_MASK_REGISTER);
 
460
  grub_sm712_sr_write (0, GRUB_VGA_SR_CHAR_MAP_SELECT);
 
461
  grub_sm712_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4
 
462
                       | GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING
 
463
                       | GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY,
 
464
                       GRUB_VGA_SR_MEMORY_MODE);
 
465
 
 
466
  for (i = 0; i < ARRAY_SIZE (sm712_sr_seq1); i++)
 
467
    grub_sm712_sr_write (sm712_sr_seq1[i], 0x10 + i);
 
468
 
 
469
  for (i = 0; i < ARRAY_SIZE (sm712_sr_seq2); i++)
 
470
    grub_sm712_sr_write (sm712_sr_seq2[i], 0x30 + i);
 
471
 
 
472
  /* Undocumented.  */
 
473
  grub_sm712_sr_write (0x1a, 0x63);
 
474
  /* Undocumented.  */
 
475
  grub_sm712_sr_write (0x1a, 0x64);
 
476
 
 
477
  grub_sm712_sr_write (GRUB_SM712_SR_TV_CRT_SRAM | GRUB_SM712_SR_TV_ALT_CLOCK
 
478
                       | GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC
 
479
                       | GRUB_SM712_SR_TV_HSYNC,
 
480
                       GRUB_SM712_SR_TV_CONTROL);
 
481
 
 
482
  grub_sm712_sr_write (GRUB_SM712_SR_RAM_LUT_NORMAL, GRUB_SM712_SR_RAM_LUT);
 
483
 
 
484
  /* Undocumented.  */
 
485
  grub_sm712_sr_write (0x00, 0x67);
 
486
 
 
487
  grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR
 
488
                       | GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK,
 
489
                       GRUB_SM712_SR_CLOCK_CONTROL1);
 
490
  grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK,
 
491
                       GRUB_SM712_SR_CLOCK_CONTROL2);
 
492
 
 
493
  grub_sm712_sr_write (82, GRUB_SM712_SR_VCLK_NUM);
 
494
  grub_sm712_sr_write (137, GRUB_SM712_SR_VCLK_DENOM);
 
495
 
 
496
  grub_sm712_sr_write (9, GRUB_SM712_SR_VCLK2_NUM);
 
497
  grub_sm712_sr_write (2, GRUB_SM712_SR_VCLK2_DENOM);
 
498
  /* FIXME */
 
499
  grub_sm712_sr_write (0x04, 0x70);
 
500
  /* FIXME */
 
501
  grub_sm712_sr_write (0x45, 0x71);
 
502
  /* Undocumented */
 
503
  grub_sm712_sr_write (0x30, 0x72);
 
504
  /* Undocumented */
 
505
  grub_sm712_sr_write (0x30, 0x73);
 
506
  /* Undocumented */
 
507
  grub_sm712_sr_write (0x40, 0x74);
 
508
  /* Undocumented */
 
509
  grub_sm712_sr_write (0x20, 0x75);
 
510
 
 
511
  grub_sm712_sr_write (0xff, GRUB_SM712_SR_POPUP_ICON_LOW);
 
512
  grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_HIGH_MASK,
 
513
                       GRUB_SM712_SR_POPUP_ICON_HIGH);
 
514
  grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED,
 
515
                       GRUB_SM712_SR_POPUP_ICON_CTRL);
 
516
  /* Undocumented */
 
517
  grub_sm712_sr_write (0x0, 0x83);
 
518
 
 
519
  grub_sm712_sr_write (8, GRUB_SM712_SR_POPUP_ICON_COLOR1);
 
520
  grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_COLOR2);
 
521
  grub_sm712_sr_write (0x42, GRUB_SM712_SR_POPUP_ICON_COLOR3);
 
522
 
 
523
  /* Undocumented */
 
524
  grub_sm712_sr_write (0x3a, 0x87);
 
525
 
 
526
  /* Why theese coordinates?  */
 
527
  grub_sm712_sr_write (0x59, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW);
 
528
  grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH);
 
529
  grub_sm712_sr_write (0x44, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW);
 
530
  grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH);
 
531
 
 
532
  grub_sm712_sr_write (RGB332_BLACK, GRUB_SM712_SR_HW_CURSOR_FG_COLOR);
 
533
  grub_sm712_sr_write (RGB332_WHITE, GRUB_SM712_SR_HW_CURSOR_BG_COLOR);
 
534
 
 
535
  /* Undocumented */
 
536
  grub_sm712_sr_write (0x3a, 0x8e);
 
537
  grub_sm712_sr_write (0x3a, 0x8f);
 
538
 
 
539
  grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_LOW);
 
540
  grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_HIGH);
 
541
  grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_LOW);
 
542
  grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_HIGH);
 
543
 
 
544
  grub_sm712_sr_write (0, GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL);
 
545
  grub_sm712_sr_write (0x10, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW);
 
546
  grub_sm712_sr_write (0x08, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH);
 
547
  grub_sm712_sr_write (0x00, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW);
 
548
  grub_sm712_sr_write (0x02, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH);
 
549
  grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT);
 
550
  grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT);
 
551
  grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT);
 
552
 
 
553
  grub_sm712_sr_write (0x7b, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY);
 
554
  grub_sm712_sr_write (0xfb, GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY);
 
555
  grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY);
 
556
  grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY);
 
557
  /* Doesn't match documentation?  */
 
558
  grub_sm712_sr_write (0x97, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY);
 
559
  grub_sm712_sr_write (0xef, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY);
 
560
 
 
561
  grub_sm712_sr_write (0xbf, GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR);
 
562
  grub_sm712_sr_write (0xdf, GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR);
 
563
 
 
564
  grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE);
 
565
  grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE_ENABLE);
 
566
  grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_COLOR_COMPARE);
 
567
  grub_sm712_gr_write (GRUB_VGA_GR_DATA_ROTATE_NOP, GRUB_VGA_GR_DATA_ROTATE);
 
568
  grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_READ_MAP_REGISTER);
 
569
  grub_sm712_gr_write (GRUB_VGA_GR_MODE_256_COLOR, GRUB_VGA_GR_MODE);
 
570
  grub_sm712_gr_write (GRUB_VGA_GR_GR6_MMAP_A0
 
571
                       | GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6);
 
572
  grub_sm712_gr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_GR_COLOR_COMPARE_DISABLE);
 
573
  grub_sm712_gr_write (0xff, GRUB_VGA_GR_BITMASK);
 
574
 
 
575
  /* Write palette mapping.  */
 
576
  for (i = 0; i < 16; i++)
 
577
    grub_sm712_write_arx (i, i);
 
578
 
 
579
  grub_sm712_write_arx (GRUB_VGA_ARX_MODE_ENABLE_256COLOR
 
580
                        | GRUB_VGA_ARX_MODE_GRAPHICS, GRUB_VGA_ARX_MODE);
 
581
  grub_sm712_write_arx (0, GRUB_VGA_ARX_OVERSCAN);
 
582
  grub_sm712_write_arx (GRUB_VGA_ALL_PLANES, GRUB_VGA_ARX_COLOR_PLANE_ENABLE);
 
583
  grub_sm712_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING);
 
584
  grub_sm712_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT);
 
585
 
 
586
  /* FIXME: compute this generically.  */
 
587
  {
 
588
    struct grub_video_hw_config config =
 
589
      {
 
590
        .vertical_total = 806,
 
591
        .vertical_blank_start = 0x300,
 
592
        .vertical_blank_end = 0,
 
593
        .vertical_sync_start = 0x303,
 
594
        .vertical_sync_end = 0x9,
 
595
        .line_compare = 0x3ff,
 
596
        .vdisplay_end = 0x300,
 
597
        .pitch = 0x80,
 
598
        .horizontal_total = 164,
 
599
        .horizontal_end = 128,
 
600
        .horizontal_blank_start = 128,
 
601
        .horizontal_blank_end = 0,
 
602
        .horizontal_sync_pulse_start = 133,
 
603
        .horizontal_sync_pulse_end = 22
 
604
      };
 
605
    grub_vga_set_geometry (&config, grub_sm712_cr_write);
 
606
    config.horizontal_sync_pulse_start = 134;
 
607
    config.horizontal_sync_pulse_end = 21;
 
608
    config.vertical_sync_start = 0x301;
 
609
    config.vertical_sync_end = 0x0;
 
610
    config.line_compare = 0x0ff;
 
611
    config.vdisplay_end = 0x258;
 
612
    config.pitch = 0x7f;
 
613
    grub_vga_set_geometry (&config, grub_sm712_cr_shadow_write);
 
614
  }
 
615
 
 
616
  grub_sm712_cr_write (GRUB_VGA_CR_BYTE_PANNING_NORMAL,
 
617
                       GRUB_VGA_CR_BYTE_PANNING);
 
618
  grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_START);
 
619
  grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_END);
 
620
  grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
 
621
  grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
 
622
  grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_HIGH);
 
623
  grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_LOW);
 
624
  grub_sm712_cr_write (GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE,
 
625
                       GRUB_VGA_CR_UNDERLINE_LOCATION);
 
626
  grub_sm712_cr_write (GRUB_VGA_CR_MODE_ADDRESS_WRAP
 
627
                       | GRUB_VGA_CR_MODE_BYTE_MODE
 
628
                       | GRUB_VGA_CR_MODE_TIMING_ENABLE
 
629
                       | GRUB_VGA_CR_MODE_NO_CGA
 
630
                       | GRUB_VGA_CR_MODE_NO_HERCULES,
 
631
                       GRUB_VGA_CR_MODE);
 
632
 
 
633
  grub_sm712_cr_write (0, GRUB_SM712_CR_OVERFLOW_INTERLACE);
 
634
  grub_sm712_cr_write (0, GRUB_SM712_CR_INTERLACE_RETRACE);
 
635
  grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_START);
 
636
  grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_HIGH);
 
637
  grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_LOW);
 
638
  grub_sm712_cr_write (0x80, GRUB_SM712_CR_DDA_CONTROL_LOW);
 
639
  grub_sm712_cr_write (0x02, GRUB_SM712_CR_DDA_CONTROL_HIGH);
 
640
 
 
641
  /* Undocumented */
 
642
  grub_sm712_cr_write (0x20, 0x37);
 
643
 
 
644
  grub_sm712_cr_write (0, GRUB_SM712_CR_TV_EQUALIZER);
 
645
  grub_sm712_cr_write (0, GRUB_SM712_CR_TV_SERRATION);
 
646
  grub_sm712_cr_write (0, GRUB_SM712_CR_HSYNC_CTRL);
 
647
 
 
648
  /* Undocumented */
 
649
  grub_sm712_cr_write (0x40, 0x3b);
 
650
 
 
651
  grub_sm712_cr_write (GRUB_SM712_CR_DEBUG_NONE, GRUB_SM712_CR_DEBUG);
 
652
 
 
653
  /* Undocumented */
 
654
  grub_sm712_cr_write (0xff, 0x3d);
 
655
  grub_sm712_cr_write (0x46, 0x3e);
 
656
  grub_sm712_cr_write (0x91, 0x3f);
 
657
 
 
658
  for (i = 0; i < ARRAY_SIZE (dda_lookups); i++)
 
659
    grub_sm712_write_dda_lookup (i, dda_lookups[i].compare, dda_lookups[i].dda,
 
660
                                 dda_lookups[i].vcentering);
 
661
  
 
662
  /* Undocumented  */
 
663
  grub_sm712_cr_write (0, 0x9c);
 
664
  grub_sm712_cr_write (0, 0x9d);
 
665
  grub_sm712_cr_write (0, 0x9e);
 
666
  grub_sm712_cr_write (0, 0x9f);
 
667
 
 
668
  grub_sm712_cr_write (0, GRUB_SM712_CR_VCENTERING_OFFSET);
 
669
  grub_sm712_cr_write (0, GRUB_SM712_CR_HCENTERING_OFFSET);
 
670
 
 
671
  grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY
 
672
                        | GRUB_VGA_IO_MISC_UPPER_64K
 
673
                        | GRUB_VGA_IO_MISC_28MHZ
 
674
                        | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS
 
675
                        | GRUB_VGA_IO_MISC_COLOR,
 
676
                        GRUB_VGA_IO_MISC_WRITE);
 
677
 
 
678
#ifndef TEST
 
679
  /* Undocumented? */
 
680
  *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0;
 
681
  *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0;
 
682
  *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c000) = 0x20000;
 
683
  *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c010) = 0x1020100;
 
684
#endif
 
685
 
 
686
  (void) grub_sm712_sr_read (0x16);
 
687
 
 
688
#ifndef TEST
 
689
  err = grub_video_fb_create_render_target_from_pointer (&framebuffer
 
690
                                                         .render_target,
 
691
                                                         &framebuffer.mode_info,
 
692
                                                         framebuffer.ptr);
 
693
 
 
694
  if (err)
 
695
    return err;
 
696
 
 
697
  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
 
698
  
 
699
  if (err)
 
700
    return err;
 
701
 
 
702
  /* Copy default palette to initialize emulated palette.  */
 
703
  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
 
704
                                   grub_video_fbstd_colors);
 
705
#endif
 
706
  return err;
 
707
}
 
708
 
 
709
#ifndef TEST
 
710
 
 
711
static grub_err_t
 
712
grub_video_sm712_swap_buffers (void)
 
713
{
 
714
  /* TODO: Implement buffer swapping.  */
 
715
  return GRUB_ERR_NONE;
 
716
}
 
717
 
 
718
static grub_err_t
 
719
grub_video_sm712_set_active_render_target (struct grub_video_render_target *target)
 
720
{
 
721
  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
 
722
      target = framebuffer.render_target;
 
723
 
 
724
  return grub_video_fb_set_active_render_target (target);
 
725
}
 
726
 
 
727
static grub_err_t
 
728
grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info,
 
729
                                    void **framebuf)
 
730
{
 
731
  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
 
732
  *framebuf = (char *) framebuffer.ptr;
 
733
 
 
734
  grub_video_fb_fini ();
 
735
 
 
736
  return GRUB_ERR_NONE;
 
737
}
 
738
 
 
739
static struct grub_video_adapter grub_video_sm712_adapter =
 
740
  {
 
741
    .name = "SM712 Video Driver",
 
742
    .id = GRUB_VIDEO_DRIVER_SM712,
 
743
 
 
744
    .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE,
 
745
 
 
746
    .init = grub_video_sm712_video_init,
 
747
    .fini = grub_video_sm712_video_fini,
 
748
    .setup = grub_video_sm712_setup,
 
749
    .get_info = grub_video_fb_get_info,
 
750
    .get_info_and_fini = grub_video_sm712_get_info_and_fini,
 
751
    .set_palette = grub_video_fb_set_palette,
 
752
    .get_palette = grub_video_fb_get_palette,
 
753
    .set_viewport = grub_video_fb_set_viewport,
 
754
    .get_viewport = grub_video_fb_get_viewport,
 
755
    .map_color = grub_video_fb_map_color,
 
756
    .map_rgb = grub_video_fb_map_rgb,
 
757
    .map_rgba = grub_video_fb_map_rgba,
 
758
    .unmap_color = grub_video_fb_unmap_color,
 
759
    .fill_rect = grub_video_fb_fill_rect,
 
760
    .blit_bitmap = grub_video_fb_blit_bitmap,
 
761
    .blit_render_target = grub_video_fb_blit_render_target,
 
762
    .scroll = grub_video_fb_scroll,
 
763
    .swap_buffers = grub_video_sm712_swap_buffers,
 
764
    .create_render_target = grub_video_fb_create_render_target,
 
765
    .delete_render_target = grub_video_fb_delete_render_target,
 
766
    .set_active_render_target = grub_video_sm712_set_active_render_target,
 
767
    .get_active_render_target = grub_video_fb_get_active_render_target,
 
768
 
 
769
    .next = 0
 
770
  };
 
771
 
 
772
GRUB_MOD_INIT(video_sm712)
 
773
{
 
774
  grub_video_register (&grub_video_sm712_adapter);
 
775
}
 
776
 
 
777
GRUB_MOD_FINI(video_sm712)
 
778
{
 
779
  grub_video_unregister (&grub_video_sm712_adapter);
 
780
}
 
781
#else
 
782
int
 
783
main ()
 
784
{
 
785
  grub_video_sm712_setup (1024, 600, 0, 0);
 
786
}
 
787
#endif