Merge mainline into usb

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-08-20 20:12:26 +02:00
commit 8161b08687
44 changed files with 2884 additions and 1049 deletions

View file

@ -40,6 +40,7 @@ grub-fstest
grub_fstest_init.c
grub_fstest_init.h
grub-install
grub-macho2img
grub-mk*
grub-pbkdf2
grub-pe2elf

372
ChangeLog
View file

@ -1,3 +1,354 @@
2010-08-20 Colin Watson <cjwatson@ubuntu.com>
* commands/i386/pc/sendkey.c (keysym_table): Rename "numlock" to
"numcenter" (I misunderstood the purpose of this entry).
* docs/grub.texi (sendkey): Likewise.
2010-08-20 Colin Watson <cjwatson@ubuntu.com>
* commands/i386/pc/sendkey.c (options): Remove "keep" from all
status flag options; simply omitting the option is equivalent and
simpler. Rename "wait" to "pause". Rename "sysreq" to "sysrq".
(keysym_table): Rename "num5numlock" to "numlock".
(grub_cmd_sendkey): Reinitialise `andmask' and `ormask', so that we
can uniformly say that only the last of multiple `sendkey'
invocations has any effect.
* docs/grub.texi (sendkey): New section.
2010-08-19 Colin Watson <cjwatson@ubuntu.com>
* commands/i386/pc/sendkey.c (options): Fix three typos.
2010-08-19 Vladimir Serbinenko <phcoder@gmail.com>
Implement sendkey support.
* commands/i386/pc/sendkey.c: New file.
* conf/i386-pc.rmk (pkglib_MODULES): Add sendkey.mod.
(sendkey_mod_SOURCES): New variable.
(sendkey_mod_CFLAGS): Likewise.
(sendkey_mod_LDFLAGS): Likewise.
2010-08-18 Colin Watson <cjwatson@ubuntu.com>
* configure.ac: Move AM_INIT_AUTOMAKE after AC_CANONICAL_TARGET to
fix warnings from Autoconf.
2010-08-18 Colin Watson <cjwatson@ubuntu.com>
* acinclude.m4 (grub_ASM_USCORE): Use a more accurate grep pattern,
to avoid false positives with some assemblers that output things
like "someprefix_func" as part of their output.
2010-08-15 Robert Millan <rmh@gnu.org>
* kern/emu/misc.c (grub_get_libzfs_handle): Handle libzfs_init()
errors.
* kern/emu/getroot.c (find_root_device_from_libzfs): Handle
grub_get_libzfs_handle() errors.
2010-08-14 Robert Millan <rmh@gnu.org>
* kern/emu/misc.c (grub_find_zpool_from_dir): Abort function if
filesystem is not ZFS.
2010-08-12 BVK Chaitanya <bvk.groups@gmail.com>
Fix for misspelled color names defaulting to black/black (bug
reported by Doug Nazar)
* include/grub/normal.h (grub_parse_color_name_pair): Add return
status to prototype.
* normal/color.c (grub_parse_color_name_pair): Return failure
status.
(grub_env_write_color_normal): Ignore bad color names.
(grub_env_write_color_highlight): Likewise.
* normal/main.c (GRUB_MOD_INIT): Set default color names.
2010-08-12 BVK Chaitanya <bvk.groups@gmail.com>
"shift" command support to GRUB script.
* include/grub/script_sh.h (grub_script_shift): New prototype.
* script/execute.c (grub_script_shift): New function.
* script/main.c (grub_script_init): Register shift command.
(grub_script_fini): Unregister shift command.
* util/grub-script-check.c (grub_script_cmd_shift): New function.
* tests/grub_script_shift.in: New testcase.
* conf/tests.rmk: Rules for new testcase.
2010-08-12 BVK Chaitanya <bvk.groups@gmail.com>
"continue" command support to GRUB script.
* script/execute.c (grub_script_execute_cmdwhile): Continue support.
(grub_script_break): Continue support.
* script/main.c (grub_script_init): Register continue command.
(grub_script_fini): Unregister continue command.
* tests/grub_script_continue.in: New testcase.
* conf/tests.rmk: Rules for new testcase.
2010-08-12 BVK Chaitanya <bvk@dbook>
"break" command support to GRUB script.
* conf/common.rmk: Rule updates to grub-script-check.
* include/grub/misc.h (grub_min): New function.
* include/grub/script_sh.h (grub_script_init): New prototype.
(grub_script_fini): New prototype.
(grub_script_break): New prototype.
* script/main.c (grub_script_init): New function.
(grub_script_fini): New function.
* script/execute.c (grub_script_break): New function.
* normal/main.c: Calls to grub_script_{init,fini}.
* util/grub-script-check.c (grub_script_break): New function.
* tests/grub_script_break.in: New testcase.
* conf/tests.rmk: Rules for new test case.
2010-08-12 BVK Chaitanya <bvk.groups@gmail.com>
Function parameters support to GRUB script.
* script/yylex.l (VARIABLE): Regular expression update.
* script/function.c (grub_script_function_call): Moved ...
* script/execute.c (grub_script_function_call): ... to here.
(grub_script_execute_arglist_to_argv): Removed.
(grub_script_arglist_to_argv): New function.
* script/argv.c: New file.
(grub_script_argv_free): New function.
(grub_script_argv_next): Likewise.
(grub_script_argv_append): Likewise.
(grub_script_argv_split_append): Likewise.
* include/grub/script_sh.h (grub_script_argv): New struct.
(grub_script_argv_free): New function.
(grub_script_argv_next): Likewise.
(grub_script_argv_append): Likewise.
(grub_script_argv_split_append): Likewise.
* conf/common.rmk (normal.mod): New source script/argv.c.
* tests/grub_script_echo1.in: More tests.
* tests/grub_script_vars1.in: Likewise.
* tests/grub_script_functions.in: New test case.
* conf/tests.rmk: Rules for new testcase.
2010-08-12 BVK Chaitanya <bvk.groups@gmail.com>
Remove grub_script_cmdblock struct.
* include/grub/script_sh.h: Remove grub_script_cmdblock.
* script/parser.y: Likewise.
* script/execute.c: Rename cmdblock suffix to cmdlist.
* script/script.c: Likewise.
* util/grub-script-check.c: Likewise.
2010-08-11 Yves Blusseau <blusseau@zetam.org>
* .bzrignore: add grub-macho2img
2010-08-11 Vladimir Serbinenko <phcoder@gmail.com>
* kern/i386/qemu/init.c (grub_qemu_init_cirrus): Fix compilation error.
2010-08-11 Vladimir Serbinenko <phcoder@gmail.com>
Remove the dump of sm712 initialisation sequence.
* include/grub/pci.h (GRUB_PCI_CLASS_SUBCLASS_VGA): New const.
* include/grub/vga.h (GRUB_VGA_IO_ARX_READ): New register.
(GRUB_VGA_IO_MISC_WRITE): Likewise.
(GRUB_VGA_CR_*): Added many registers.
(GRUB_VGA_SR_*): Likewise.
(GRUB_VGA_GR_*): Likewise.
(grub_vga_write_arx): New function.
(grub_video_hw_config): New struct.
(grub_vga_set_geometry): New function.
* kern/i386/qemu/init.c (load_palette): Use grub_vga_write_arx and
GRUB_PCI_CLASS_SUBCLASS_VGA.
* video/cirrus.c (grub_video_cirrus_setup): Use grub_vga_set_geometry.
* video/sm712.c (grub_sm712_write_reg): New function
(grub_sm712_read_reg): Likewise.
(grub_sm712_sr_write): Likewise.
(grub_sm712_gr_write): Likewise.
(grub_sm712_cr_write): Likewise.
(grub_sm712_write_arx): Likewise.
(grub_sm712_cr_shadow_write): Likewise.
(grub_sm712_write_dda_lookup): Likewise.
(grub_video_sm712_setup): Initialise the video rather then
blindly replay the dump.
(main) [TEST]: Add a routine to be able to compile as standalone for
tests.
* video/sm712_init.c (sm712_init): Removed.
(sm712_sr_seq1): New array.
(sm712_sr_seq2): Likewise.
2010-08-10 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/vga.h: Add missing grub/pci.h include.
2010-08-10 Yves Blusseau <blusseau@zetam.org>
* util/grub-macho2img.c (main): fix typo
2010-08-10 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/vga.h (grub_vga_gr_write): Add GRUB_MACHINE_PCI_IO_BASE.
(grub_vga_gr_read): Likewise.
(grub_vga_cr_write): Likewise.
(grub_vga_cr_read): Likewise.
(grub_vga_sr_write): Likewise.
(grub_vga_sr_read): Likewise.
(grub_vga_palette_read): Likewise.
(grub_vga_palette_write): Likewise.
* video/sm712.c (GRUB_SM712_REG_BASE): New definition.
(grub_sm712_sr_read): New function.
(grub_video_sm712_setup): Use grub_vga_sr_write and grub_sm712_sr_read.
* video/sm712_init.c (sm712_init): Substract GRUB_MACHINE_PCI_IO_BASE.
2010-08-09 Robert Millan <rmh@gnu.org>
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Filter
out unused variables on non-ZFS build.
2010-08-08 Robert Millan <rmh@gnu.org>
Fix path generation for sub-filesystems in ZFS.
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Add
missing slash.
2010-08-08 Robert Millan <rmh@gnu.org>
* util/grub-fstest.c (read_file, cmd_cmp): Improve error message.
2010-08-08 Robert Millan <rmh@gnu.org>
* util/grub.d/10_kfreebsd.in: When files required for ZFS do not
exist, issue a proper error message (rely on `ls' for translated
strings).
2010-08-08 Robert Millan <rmh@gnu.org>
Fix grub-probe invocation.
* util/grub.d/10_kfreebsd.in: s/label/fs_label/g.
2010-08-04 Robert Millan <rmh@gnu.org>
* configure.ac: Remove checks for getfsstat() and getmntany().
Add checks for `<sys/param.h>' and `<sys/mount.h>'.
* kern/emu/misc.c [HAVE_GETMNTANY]: Remove `<sys/mnttab.h>'.
[HAVE_SYS_PARAM_H]: Include `<sys/param.h>'.
[HAVE_SYS_MOUNT_H]: Include `<sys/mount.h>'.
[HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove
function.
(grub_find_zpool_from_dir): Use statfs() instead of indirect matching
via find_mount_point_from_dir() and getfsstat() / getmntany().
2010-08-04 Robert Millan <rmh@gnu.org>
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
(grub_find_zpool_from_mount_point): Merge into ...
(grub_find_zpool_from_dir): ... this.
* kern/emu/misc.c: Likewise.
* kern/emu/misc.c
(grub_make_system_path_relative_to_its_root): Replace
grub_find_mount_point_from_dir() / grub_find_zpool_from_mount_point()
with grub_find_zpool_from_dir().
* kern/emu/getroot.c (find_root_device_from_libzfs): Likewise.
2010-08-04 Robert Millan <rmh@gnu.org>
Support OpenSolaris in ZFS device resolution.
* configure.ac: Check for getmntany().
* kern/emu/misc.c [HAVE_GETMNTANY]: Include `<sys/mnttab.h>'.
[HAVE_GETMNTANY] (grub_find_zpool_from_mount_point): Add OpenSolaris
support.
2010-08-03 Robert Millan <rmh@gnu.org>
Fix grub-emu build.
* include/grub/util/misc.h: Move `<grub/util/libzfs.h>' to ...
* include/grub/emu/misc.h: ... here.
* include/grub/util/misc.h (grub_get_libzfs_handle): Move function ...
* include/grub/emu/misc.h (grub_get_libzfs_handle): ... here.
* util/misc.c: Remove `<grub/util/libzfs.h>'.
[HAVE_LIBZFS] (libzfs_handle, fini_libzfs)
(grub_get_libzfs_handle): Move to ...
* kern/emu/misc.c [HAVE_LIBZFS] (__libzfs_handle, fini_libzfs)
(grub_get_libzfs_handle): ... here.
2010-08-03 BVK Chaitanya <bvk.groups@gmail.com>
* script/execute.c (grub_script_execute_cmdline): Check for NULL
as command name case.
2010-08-02 Colin Watson <cjwatson@ubuntu.com>
* disk/raid.c (insert_array): Select unique numbers for named arrays
as well, for use as keys in the disk cache.
2010-08-01 Robert Millan <rmh@gnu.org>
* util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the
kFreeBSD device name, except on ZFS where the filesystem label is
used.
(kfreebsd_entry): On ZFS root, load `opensolaris.ko', `zfs.ko' and
`/boot/zfs/zpool.cache'.
Set mountfrom kernel variable using ${kfreebsd_device}.
2010-08-01 Robert Millan <rmh@gnu.org>
Make it even harder to use uninitialized `libzfs_handle' (and
make the interface a bit simpler).
* include/grub/util/misc.h (grub_util_init_libzfs)
(libzfs_handle): Remove.
(grub_get_libzfs_handle): New prototype.
* util/misc.c [HAVE_LIBZFS] (libzfs_handle): Add `static'
attribute.
(grub_util_init_libzfs): Remove.
(grub_get_libzfs_handle): New function.
* kern/emu/getroot.c (find_root_device_from_libzfs): Use
grub_get_libzfs_handle() to obtain a libzfs handle instead of
accessing `libzfs_handle' directly.
2010-08-01 Robert Millan <rmh@gnu.org>
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
(grub_find_zpool_from_mount_point): New function prototypes.
* kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
* kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
* kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
* kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove
`static' attribute.
* kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
finding zpool from mount point into ...
* kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
requested path is part of a ZFS pool, use
grub_find_zpool_from_mount_point() to detect its filesystem name,
and generate a path with `/fsname@path' syntax.
2010-08-01 Colin Watson <cjwatson@ubuntu.com>
* include/grub/util/libzfs.h (libzfs_init): Set argument list to
(void) rather than () so that this is a proper prototype.
2010-08-01 Vladimir Serbinenko <phcoder@gmail.com>
* lib/arg.c (grub_arg_show_help): Add the necessary spacing.
@ -34,6 +385,27 @@
* kern/misc.c (grub_memset): Optimise to reduce cache stalls.
2010-08-01 Robert Millan <rmh@gnu.org>
* include/grub/emu/misc.h (grub_find_mount_point_from_dir)
(grub_find_zpool_from_mount_point): New function prototypes.
* kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `<sys/mount.h>' to ...
* kern/emu/misc.c [HAVE_GETFSSTAT]: ... here.
* kern/emu/getroot.c (find_mount_point_from_dir): Move to ...
* kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove
`static' attribute.
* kern/emu/getroot.c (find_root_device_from_libzfs): Split code for
finding zpool from mount point into ...
* kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this.
* kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When
requested path is part of a ZFS pool, use
grub_find_zpool_from_mount_point() to detect its filesystem name,
and generate a path with `/fsname@path' syntax.
2010-08-01 Robert Millan <rmh@gnu.org>
Prevent accidental use of uninitialized libzfs_handle.

View file

@ -38,6 +38,7 @@ dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by
dnl Erich Boleyn and modified by Yoshinori K. Okuji.
AC_DEFUN([grub_ASM_USCORE],
[AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_EGREP])
AC_MSG_CHECKING([if C symbols get an underscore after compilation])
AC_CACHE_VAL(grub_cv_asm_uscore,
[cat > conftest.c <<\EOF
@ -56,7 +57,7 @@ else
AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
fi
if grep _func conftest.s >/dev/null 2>&1; then
if $EGREP '(^|[^_[:alnum]])_func' conftest.s >/dev/null 2>&1; then
grub_cv_asm_uscore=yes
else
grub_cv_asm_uscore=no

384
commands/i386/pc/sendkey.c Normal file
View file

@ -0,0 +1,384 @@
/* sendkey.c - fake keystroke. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/extcmd.h>
#include <grub/cpu/io.h>
#include <grub/loader.h>
static char sendkey[0x20];
/* Length of sendkey. */
static int keylen = 0;
static int noled = 0;
static const struct grub_arg_option options[] =
{
{"num", 'n', 0, "set numlock mode", "[on|off]", ARG_TYPE_STRING},
{"caps", 'c', 0, "set capslock mode", "[on|off]", ARG_TYPE_STRING},
{"scroll", 's', 0, "set scrolllock mode", "[on|off]", ARG_TYPE_STRING},
{"insert", 0, 0, "set insert mode", "[on|off]", ARG_TYPE_STRING},
{"pause", 0, 0, "set pause mode", "[on|off]", ARG_TYPE_STRING},
{"left-shift", 0, 0, "press left shift", "[on|off]", ARG_TYPE_STRING},
{"right-shift", 0, 0, "press right shift", "[on|off]", ARG_TYPE_STRING},
{"sysrq", 0, 0, "press SysRq", "[on|off]", ARG_TYPE_STRING},
{"numkey", 0, 0, "press NumLock key", "[on|off]", ARG_TYPE_STRING},
{"capskey", 0, 0, "press CapsLock key", "[on|off]", ARG_TYPE_STRING},
{"scrollkey", 0, 0, "press ScrollLock key", "[on|off]", ARG_TYPE_STRING},
{"insertkey", 0, 0, "press Insert key", "[on|off]", ARG_TYPE_STRING},
{"left-alt", 0, 0, "press left alt", "[on|off]", ARG_TYPE_STRING},
{"right-alt", 0, 0, "press right alt", "[on|off]", ARG_TYPE_STRING},
{"left-ctrl", 0, 0, "press left ctrl", "[on|off]", ARG_TYPE_STRING},
{"right-ctrl", 0, 0, "press right ctrl", "[on|off]", ARG_TYPE_STRING},
{"no-led", 0, 0, "don't update LED state", 0, 0},
{0, 0, 0, 0, 0, 0}
};
static int simple_flag_offsets[]
= {5, 6, 4, 7, 11, 1, 0, 10, 13, 14, 12, 15, 9, 3, 8, 2};
static grub_uint32_t andmask = 0xffffffff, ormask = 0;
struct
keysym
{
char *unshifted_name; /* the name in unshifted state */
char *shifted_name; /* the name in shifted state */
unsigned char unshifted_ascii; /* the ascii code in unshifted state */
unsigned char shifted_ascii; /* the ascii code in shifted state */
unsigned char keycode; /* keyboard scancode */
};
/* The table for key symbols. If the "shifted" member of an entry is
NULL, the entry does not have shifted state. Copied from GRUB Legacy setkey fuction */
static struct keysym keysym_table[] =
{
{"escape", 0, 0x1b, 0, 0x01},
{"1", "exclam", '1', '!', 0x02},
{"2", "at", '2', '@', 0x03},
{"3", "numbersign", '3', '#', 0x04},
{"4", "dollar", '4', '$', 0x05},
{"5", "percent", '5', '%', 0x06},
{"6", "caret", '6', '^', 0x07},
{"7", "ampersand", '7', '&', 0x08},
{"8", "asterisk", '8', '*', 0x09},
{"9", "parenleft", '9', '(', 0x0a},
{"0", "parenright", '0', ')', 0x0b},
{"minus", "underscore", '-', '_', 0x0c},
{"equal", "plus", '=', '+', 0x0d},
{"backspace", 0, '\b', 0, 0x0e},
{"tab", 0, '\t', 0, 0x0f},
{"q", "Q", 'q', 'Q', 0x10},
{"w", "W", 'w', 'W', 0x11},
{"e", "E", 'e', 'E', 0x12},
{"r", "R", 'r', 'R', 0x13},
{"t", "T", 't', 'T', 0x14},
{"y", "Y", 'y', 'Y', 0x15},
{"u", "U", 'u', 'U', 0x16},
{"i", "I", 'i', 'I', 0x17},
{"o", "O", 'o', 'O', 0x18},
{"p", "P", 'p', 'P', 0x19},
{"bracketleft", "braceleft", '[', '{', 0x1a},
{"bracketright", "braceright", ']', '}', 0x1b},
{"enter", 0, '\r', 0, 0x1c},
{"control", 0, 0, 0, 0x1d},
{"a", "A", 'a', 'A', 0x1e},
{"s", "S", 's', 'S', 0x1f},
{"d", "D", 'd', 'D', 0x20},
{"f", "F", 'f', 'F', 0x21},
{"g", "G", 'g', 'G', 0x22},
{"h", "H", 'h', 'H', 0x23},
{"j", "J", 'j', 'J', 0x24},
{"k", "K", 'k', 'K', 0x25},
{"l", "L", 'l', 'L', 0x26},
{"semicolon", "colon", ';', ':', 0x27},
{"quote", "doublequote", '\'', '"', 0x28},
{"backquote", "tilde", '`', '~', 0x29},
{"shift", 0, 0, 0, 0x2a},
{"backslash", "bar", '\\', '|', 0x2b},
{"z", "Z", 'z', 'Z', 0x2c},
{"x", "X", 'x', 'X', 0x2d},
{"c", "C", 'c', 'C', 0x2e},
{"v", "V", 'v', 'V', 0x2f},
{"b", "B", 'b', 'B', 0x30},
{"n", "N", 'n', 'N', 0x31},
{"m", "M", 'm', 'M', 0x32},
{"comma", "less", ',', '<', 0x33},
{"period", "greater", '.', '>', 0x34},
{"slash", "question", '/', '?', 0x35},
{"rshift", 0, 0, 0, 0x36},
{"numasterisk", 0, '*', 0, 0x37},
{"alt", 0, 0, 0, 0x38},
{"space", 0, ' ', 0, 0x39},
{"capslock", 0, 0, 0, 0x3a},
{"F1", 0, 0, 0, 0x3b},
{"F2", 0, 0, 0, 0x3c},
{"F3", 0, 0, 0, 0x3d},
{"F4", 0, 0, 0, 0x3e},
{"F5", 0, 0, 0, 0x3f},
{"F6", 0, 0, 0, 0x40},
{"F7", 0, 0, 0, 0x41},
{"F8", 0, 0, 0, 0x42},
{"F9", 0, 0, 0, 0x43},
{"F10", 0, 0, 0, 0x44},
{"num7", "numhome", '7', 0, 0x47},
{"num8", "numup", '8', 0, 0x48},
{"num9", "numpgup", '9', 0, 0x49},
{"numminus", 0, '-', 0, 0x4a},
{"num4", "numleft", '4', 0, 0x4b},
{"num5", "numcenter", '5', 0, 0x4c},
{"num6", "numright", '6', 0, 0x4d},
{"numplus", 0, '-', 0, 0x4e},
{"num1", "numend", '1', 0, 0x4f},
{"num2", "numdown", '2', 0, 0x50},
{"num3", "numpgdown", '3', 0, 0x51},
{"num0", "numinsert", '0', 0, 0x52},
{"numperiod", "numdelete", 0, 0x7f, 0x53},
{"F11", 0, 0, 0, 0x57},
{"F12", 0, 0, 0, 0x58},
{"numenter", 0, '\r', 0, 0xe0},
{"numslash", 0, '/', 0, 0xe0},
{"delete", 0, 0x7f, 0, 0xe0},
{"insert", 0, 0xe0, 0, 0x52},
{"home", 0, 0xe0, 0, 0x47},
{"end", 0, 0xe0, 0, 0x4f},
{"pgdown", 0, 0xe0, 0, 0x51},
{"pgup", 0, 0xe0, 0, 0x49},
{"down", 0, 0xe0, 0, 0x50},
{"up", 0, 0xe0, 0, 0x48},
{"left", 0, 0xe0, 0, 0x4b},
{"right", 0, 0xe0, 0, 0x4d}
};
/* Set a simple flag in flags variable
OUTOFFSET - offset of flag in FLAGS,
OP - action id
*/
static void
grub_sendkey_set_simple_flag (int outoffset, int op)
{
if (op == 2)
{
andmask |= (1 << outoffset);
ormask &= ~(1 << outoffset);
}
else
{
andmask &= (~(1 << outoffset));
if (op == 1)
ormask |= (1 << outoffset);
else
ormask &= ~(1 << outoffset);
}
}
static int
grub_sendkey_parse_op (struct grub_arg_list state)
{
if (! state.set)
return 2;
if (grub_strcmp (state.arg, "off") == 0 || grub_strcmp (state.arg, "0") == 0
|| grub_strcmp (state.arg, "unpress") == 0)
return 0;
if (grub_strcmp (state.arg, "on") == 0 || grub_strcmp (state.arg, "1") == 0
|| grub_strcmp (state.arg, "press") == 0)
return 1;
return 2;
}
static grub_uint32_t oldflags;
static grub_err_t
grub_sendkey_postboot (void)
{
/* For convention: pointer to flags. */
grub_uint32_t *flags = (grub_uint32_t *) 0x417;
*flags = oldflags;
*((char *) 0x41a) = 0x1e;
*((char *) 0x41c) = 0x1e;
return GRUB_ERR_NONE;
}
/* Set keyboard buffer to our sendkey */
static grub_err_t
grub_sendkey_preboot (int noret __attribute__ ((unused)))
{
/* For convention: pointer to flags. */
grub_uint32_t *flags = (grub_uint32_t *) 0x417;
oldflags = *flags;
/* Set the sendkey. */
*((char *) 0x41a) = 0x1e;
*((char *) 0x41c) = keylen + 0x1e;
grub_memcpy ((char *) 0x41e, sendkey, 0x20);
/* Transform "any ctrl" to "right ctrl" flag. */
if (*flags & (1 << 8))
*flags &= ~(1 << 2);
/* Transform "any alt" to "right alt" flag. */
if (*flags & (1 << 9))
*flags &= ~(1 << 3);
*flags = (*flags & andmask) | ormask;
/* Transform "right ctrl" to "any ctrl" flag. */
if (*flags & (1 << 8))
*flags |= (1 << 2);
/* Transform "right alt" to "any alt" flag. */
if (*flags & (1 << 9))
*flags |= (1 << 3);
/* Write new LED state */
if (!noled)
{
int value = 0;
int failed;
/* Try 5 times */
for (failed = 0; failed < 5; failed++)
{
value = 0;
/* Send command change LEDs */
grub_outb (0xed, 0x60);
/* Wait */
do
value = grub_inb (0x60);
while ((value != 0xfa) && (value != 0xfe));
if (value == 0xfa)
{
/* Set new LEDs*/
grub_outb ((*flags >> 4) & 7, 0x60);
break;
}
}
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_sendkey (grub_extcmd_t cmd, int argc, char **args)
{
struct grub_arg_list *state = cmd->state;
auto int find_key_code (char *key);
auto int find_ascii_code (char *key);
int find_key_code (char *key)
{
unsigned i;
for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
{
if (keysym_table[i].unshifted_name
&& grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
return keysym_table[i].keycode;
else if (keysym_table[i].shifted_name
&& grub_strcmp (key, keysym_table[i].shifted_name) == 0)
return keysym_table[i].keycode;
}
return 0;
}
int find_ascii_code (char *key)
{
unsigned i;
for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
{
if (keysym_table[i].unshifted_name
&& grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
return keysym_table[i].unshifted_ascii;
else if (keysym_table[i].shifted_name
&& grub_strcmp (key, keysym_table[i].shifted_name) == 0)
return keysym_table[i].shifted_ascii;
}
return 0;
}
andmask = 0xffffffff;
ormask = 0;
{
int i;
keylen = 0;
for (i = 0; i < argc && keylen < 0x20; i++)
{
int key_code;
key_code = find_key_code (args[i]);
if (key_code)
{
sendkey[keylen++] = find_ascii_code (args[i]);
sendkey[keylen++] = key_code;
}
}
}
{
unsigned i;
for (i = 0; i < sizeof (simple_flag_offsets)
/ sizeof (simple_flag_offsets[0]); i++)
grub_sendkey_set_simple_flag (simple_flag_offsets[i],
grub_sendkey_parse_op(state[i]));
}
/* Set noled. */
noled = (state[sizeof (simple_flag_offsets)
/ sizeof (simple_flag_offsets[0])].set);
return GRUB_ERR_NONE;
}
static grub_extcmd_t cmd;
static void *preboot_hook;
GRUB_MOD_INIT (sendkey)
{
cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey,
GRUB_COMMAND_FLAG_BOTH,
"sendkey [KEYSTROKE1] [KEYSTROKE2] ...",
"Emulate a keystroke", options);
preboot_hook
= grub_loader_register_preboot_hook (grub_sendkey_preboot,
grub_sendkey_postboot,
GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE);
}
GRUB_MOD_FINI (sendkey)
{
grub_unregister_extcmd (cmd);
grub_loader_unregister_preboot_hook (preboot_hook);
}

View file

@ -94,7 +94,7 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c
util/grub-script-check.c util/misc.c kern/emu/misc.c kern/emu/mm.c \
script/main.c script/script.c script/function.c script/lexer.c \
kern/err.c kern/list.c \
kern/misc.c kern/env.c grub_script.tab.c \
kern/command.c kern/misc.c kern/env.c grub_script.tab.c \
grub_script.yy.c
grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
grub_script_check_DEPENDENCIES = grub_script.tab.h
@ -636,7 +636,7 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c normal/charset.c \
normal/misc.c normal/crypto.c normal/term.c normal/context.c \
script/main.c script/script.c script/execute.c unidata.c \
script/main.c script/script.c script/execute.c script/argv.c unidata.c \
script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -253,6 +253,12 @@ datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For sendkey.mod
pkglib_MODULES += sendkey.mod
sendkey_mod_SOURCES = commands/i386/pc/sendkey.c
sendkey_mod_CFLAGS = $(COMMON_CFLAGS)
sendkey_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata_pthru.mod.
ata_pthru_mod_SOURCES = disk/ata_pthru.c
ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -71,6 +71,18 @@ grub_script_dollar_SOURCES = tests/grub_script_dollar.in
check_SCRIPTS += grub_script_comments
grub_script_comments_SOURCES = tests/grub_script_comments.in
check_SCRIPTS += grub_script_functions
grub_script_functions_SOURCES = tests/grub_script_functions.in
check_SCRIPTS += grub_script_break
grub_script_break_SOURCES = tests/grub_script_break.in
check_SCRIPTS += grub_script_continue
grub_script_continue_SOURCES = tests/grub_script_continue.in
check_SCRIPTS += grub_script_shift
grub_script_shift_SOURCES = tests/grub_script_shift.in
# List of tests to execute on "make check"
# SCRIPTED_TESTS = example_scripted_test
# SCRIPTED_TESTS += example_grub_script_test
@ -87,6 +99,10 @@ SCRIPTED_TESTS += grub_script_blanklines
SCRIPTED_TESTS += grub_script_final_semicolon
SCRIPTED_TESTS += grub_script_dollar
SCRIPTED_TESTS += grub_script_comments
SCRIPTED_TESTS += grub_script_functions
SCRIPTED_TESTS += grub_script_break
SCRIPTED_TESTS += grub_script_continue
SCRIPTED_TESTS += grub_script_shift
# dependencies between tests and testing-tools
$(SCRIPTED_TESTS): grub-shell grub-shell-tester

View file

@ -32,7 +32,6 @@ dnl type.
AC_INIT([GRUB],[1.98],[bug-grub@gnu.org])
AM_INIT_AUTOMAKE()
AC_PREREQ(2.60)
AC_CONFIG_SRCDIR([include/grub/dl.h])
AC_CONFIG_HEADER([config.h])
@ -41,6 +40,8 @@ AC_CONFIG_HEADER([config.h])
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE()
# Program name transformations
AC_ARG_PROGRAM
@ -247,8 +248,8 @@ else
fi
# Check for functions and headers.
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getfsstat)
AC_CHECK_HEADERS(libzfs.h libnvpair.h)
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h)
# For opendisk() and getrawpartition() on NetBSD.
# Used in util/deviceiter.c and in util/hostdisk.c.

View file

@ -528,25 +528,28 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
grub_memset (&array->device, 0, sizeof (array->device));
grub_memset (&array->start_sector, 0, sizeof (array->start_sector));
if (array->name)
goto skip_duplicate_check;
/* Check whether we don't have multiple arrays with the same number. */
for (p = array_list; p != NULL; p = p->next)
{
if (! p->name && p->number == array->number)
break;
}
if (! array->name)
{
for (p = array_list; p != NULL; p = p->next)
{
if (! p->name && p->number == array->number)
break;
}
}
if (p)
if (array->name || p)
{
/* The number is already in use, so we need to find a new one. */
int i = 0;
/* The number is already in use, so we need to find a new one.
(Or, in the case of named arrays, the array doesn't have its
own number, but we need one that doesn't clash for use as a key
in the disk cache. */
int i = array->name ? 0x40000000 : 0;
while (1)
{
for (p = array_list; p != NULL; p = p->next)
{
if (! p->name && p->number == i)
if (p->number == i)
break;
}
@ -560,7 +563,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
i++;
}
}
skip_duplicate_check:
/* mdraid 1.x superblocks have only a name stored not a number.
Use it directly as GRUB device. */
if (! array->name)

View file

@ -2094,6 +2094,7 @@ you forget a command, you can run the command @command{help}
* pxe_unload:: Unload the PXE environment
* reboot:: Reboot your computer
* search:: Search devices by file, label, or UUID
* sendkey:: Emulate keystrokes
* set:: Set an environment variable
* unset:: Unset an environment variable
* uppermem:: Set the upper memory size
@ -2604,6 +2605,154 @@ commands are aliases for @samp{search --file}, @samp{search --label}, and
@end deffn
@node sendkey
@subsection sendkey
@deffn Command sendkey @
[@option{--num}|@option{--caps}|@option{--scroll}|@option{--insert}|@
@option{--pause}|@option{--left-shift}|@option{--right-shift}|@
@option{--sysrq}|@option{--numkey}|@option{--capskey}|@option{--scrollkey}|@
@option{--insertkey}|@option{--left-alt}|@option{--right-alt}|@
@option{--left-ctrl}|@option{--right-ctrl} @
@samp{on}|@samp{off}]@dots{} @
[@option{no-led}] @
keystroke
Insert keystrokes into the keyboard buffer when booting. Sometimes an
operating system or chainloaded boot loader requires particular keys to be
pressed: for example, one might need to press a particular key to enter
"safe mode", or when chainloading another boot loader one might send
keystrokes to it to navigate its menu.
You may provide up to 16 keystrokes (the length of the BIOS keyboard
buffer). Keystroke names may be upper-case or lower-case letters, digits,
or taken from the following table:
@c Please keep this table in the same order as in
@c commands/i386/pc/sendkey.c, for ease of maintenance.
@c Exception: The function and numeric keys are sorted, for aesthetics.
@multitable @columnfractions .4 .5
@headitem Name @tab Key
@item escape @tab Escape
@item exclam @tab !
@item at @tab @@
@item numbersign @tab #
@item dollar @tab $
@item percent @tab %
@item caret @tab ^
@item ampersand @tab &
@item asterisk @tab *
@item parenleft @tab (
@item parenright @tab )
@item minus @tab -
@item underscore @tab _
@item equal @tab =
@item plus @tab +
@item backspace @tab Backspace
@item tab @tab Tab
@item bracketleft @tab [
@item braceleft @tab @{
@item bracketright @tab ]
@item braceright @tab @}
@item enter @tab Enter
@item control @tab press and release Control
@item semicolon @tab ;
@item colon @tab :
@item quote @tab '
@item doublequote @tab "
@item backquote @tab `
@item tilde @tab ~
@item shift @tab press and release left Shift
@item backslash @tab \
@item bar @tab |
@item comma @tab ,
@item less @tab <
@item period @tab .
@item greater @tab >
@item slash @tab /
@item question @tab ?
@item rshift @tab press and release right Shift
@item alt @tab press and release Alt
@item space @tab space bar
@item capslock @tab Caps Lock
@item F1 @tab F1
@item F2 @tab F2
@item F3 @tab F3
@item F4 @tab F4
@item F5 @tab F5
@item F6 @tab F6
@item F7 @tab F7
@item F8 @tab F8
@item F9 @tab F9
@item F10 @tab F10
@item F11 @tab F11
@item F12 @tab F12
@item num1 @tab 1 (numeric keypad)
@item num2 @tab 2 (numeric keypad)
@item num3 @tab 3 (numeric keypad)
@item num4 @tab 4 (numeric keypad)
@item num5 @tab 5 (numeric keypad)
@item num6 @tab 6 (numeric keypad)
@item num7 @tab 7 (numeric keypad)
@item num8 @tab 8 (numeric keypad)
@item num9 @tab 9 (numeric keypad)
@item num0 @tab 0 (numeric keypad)
@item numperiod @tab . (numeric keypad)
@item numend @tab End (numeric keypad)
@item numdown @tab Down (numeric keypad)
@item numpgdown @tab Page Down (numeric keypad)
@item numleft @tab Left (numeric keypad)
@item numcenter @tab 5 with Num Lock inactive (numeric keypad)
@item numright @tab Right (numeric keypad)
@item numhome @tab Home (numeric keypad)
@item numup @tab Up (numeric keypad)
@item numpgup @tab Page Up (numeric keypad)
@item numinsert @tab Insert (numeric keypad)
@item numdelete @tab Delete (numeric keypad)
@item numasterisk @tab * (numeric keypad)
@item numminus @tab - (numeric keypad)
@item numplus @tab + (numeric keypad)
@item numslash @tab / (numeric keypad)
@item numenter @tab Enter (numeric keypad)
@item delete @tab Delete
@item insert @tab Insert
@item home @tab Home
@item end @tab End
@item pgdown @tab Page Down
@item pgup @tab Page Up
@item down @tab Down
@item up @tab Up
@item left @tab Left
@item right @tab Right
@end multitable
As well as keystrokes, the @command{sendkey} command takes various options
that affect the BIOS keyboard status flags. These options take an @samp{on}
or @samp{off} parameter, specifying that the corresponding status flag be
set or unset; omitting the option for a given status flag will leave that
flag at its initial state at boot. The @option{--num}, @option{--caps},
@option{--scroll}, and @option{--insert} options emulate setting the
corresponding mode, while the @option{--numkey}, @option{--capskey},
@option{--scrollkey}, and @option{--insertkey} options emulate pressing and
holding the corresponding key. The other status flag options are
self-explanatory.
If the @option{--no-led} option is given, the status flag options will have
no effect on keyboard LEDs.
If the @command{sendkey} command is given multiple times, then only the last
invocation has any effect.
Since @command{sendkey} manipulates the BIOS keyboard buffer, it may cause
hangs, reboots, or other misbehaviour on some systems. If the operating
system or boot loader that runs after GRUB uses its own keyboard driver
rather than the BIOS keyboard functions, then @command{sendkey} will have no
effect.
This command is only available on PC BIOS systems.
@end deffn
@node set
@subsection set

View file

@ -21,6 +21,7 @@
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/util/libzfs.h>
#ifdef __CYGWIN__
# include <sys/fcntl.h>
@ -44,7 +45,11 @@ extern const char *program_name;
void grub_init_all (void);
void grub_fini_all (void);
char *grub_make_system_path_relative_to_its_root (const char *path) __attribute__ ((warn_unused_result));
void grub_find_zpool_from_dir (const char *dir,
char **poolname, char **poolfs);
char *grub_make_system_path_relative_to_its_root (const char *path)
__attribute__ ((warn_unused_result));
void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result));
void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result));
@ -69,4 +74,6 @@ extern char * canonicalize_file_name (const char *path);
int grub_device_mapper_supported (void);
#endif
libzfs_handle_t *grub_get_libzfs_handle (void);
#endif /* GRUB_EMU_MISC_H */

View file

@ -288,6 +288,15 @@ grub_abs (int x)
return (unsigned int) x;
}
static inline long
grub_min (long x, long y)
{
if (x < y)
return x;
else
return y;
}
static inline long
grub_max (long x, long y)
{

View file

@ -73,7 +73,7 @@ grub_err_t grub_normal_print_device_info (const char *name);
/* Defined in `color.c'. */
char *grub_env_write_color_normal (struct grub_env_var *var, const char *val);
char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val);
void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
/* Defined in `menu_text.c'. */
void grub_wait_after_message (void);

View file

@ -80,6 +80,7 @@
#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9
#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600
#define GRUB_PCI_CLASS_SUBCLASS_VGA 0x0300
#ifndef ASM_FILE
typedef grub_uint32_t grub_pci_id_t;

View file

@ -23,6 +23,7 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/parser.h>
#include <grub/command.h>
struct grub_script_mem;
@ -63,6 +64,13 @@ struct grub_script_arg
struct grub_script_arg *next;
};
/* An argument vector. */
struct grub_script_argv
{
unsigned argc;
char **args;
};
/* A complete argument. It consists of a list of one or more `struct
grub_script_arg's. */
struct grub_script_arglist
@ -82,15 +90,6 @@ struct grub_script_cmdline
struct grub_script_arglist *arglist;
};
/* A block of commands, this can be used to group commands. */
struct grub_script_cmdblock
{
struct grub_script_cmd cmd;
/* A chain of commands. */
struct grub_script_cmd *cmdlist;
};
/* An if statement. */
struct grub_script_cmdif
{
@ -224,6 +223,14 @@ struct grub_parser_param
struct grub_lexer_param *lexerstate;
};
void grub_script_init (void);
void grub_script_fini (void);
void grub_script_argv_free (struct grub_script_argv *argv);
int grub_script_argv_next (struct grub_script_argv *argv);
int grub_script_argv_append (struct grub_script_argv *argv, const char *s);
int grub_script_argv_split_append (struct grub_script_argv *argv, char *s);
struct grub_script_arglist *
grub_script_create_arglist (struct grub_parser_param *state);
@ -234,8 +241,6 @@ grub_script_add_arglist (struct grub_parser_param *state,
struct grub_script_cmd *
grub_script_create_cmdline (struct grub_parser_param *state,
struct grub_script_arglist *arglist);
struct grub_script_cmd *
grub_script_create_cmdblock (struct grub_parser_param *state);
struct grub_script_cmd *
grub_script_create_cmdif (struct grub_parser_param *state,
@ -262,9 +267,9 @@ grub_script_create_cmdmenu (struct grub_parser_param *state,
int options);
struct grub_script_cmd *
grub_script_add_cmd (struct grub_parser_param *state,
struct grub_script_cmdblock *cmdblock,
struct grub_script_cmd *cmd);
grub_script_append_cmd (struct grub_parser_param *state,
struct grub_script_cmd *list,
struct grub_script_cmd *last);
struct grub_script_arg *
grub_script_arg_add (struct grub_parser_param *state,
struct grub_script_arg *arg,
@ -301,7 +306,7 @@ void grub_script_yyerror (struct grub_parser_param *, char const *);
/* Commands to execute, don't use these directly. */
grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
grub_err_t grub_script_execute_cmdlist (struct grub_script_cmd *cmd);
grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd);
grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd);
@ -310,6 +315,12 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
/* Execute any GRUB pre-parsed command or script. */
grub_err_t grub_script_execute (struct grub_script *script);
/* Break command for loops. */
grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]);
/* SHIFT command for GRUB script. */
grub_err_t grub_script_shift (grub_command_t cmd, int argc, char *argv[]);
/* This variable points to the parsed command. This is used to
communicate with the bison code. */
extern struct grub_script_cmd *grub_script_parsed;
@ -344,8 +355,9 @@ grub_script_function_t grub_script_function_create (struct grub_script_arg *func
struct grub_script *cmd);
void grub_script_function_remove (const char *name);
grub_script_function_t grub_script_function_find (char *functionname);
int grub_script_function_call (grub_script_function_t func,
int argc, char **args);
grub_err_t grub_script_function_call (grub_script_function_t func,
int argc, char **args);
char **
grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);

View file

@ -30,7 +30,7 @@
typedef void libzfs_handle_t;
typedef void zpool_handle_t;
extern libzfs_handle_t *libzfs_init ();
extern libzfs_handle_t *libzfs_init (void);
extern void libzfs_fini (libzfs_handle_t *);
extern zpool_handle_t *zpool_open (libzfs_handle_t *, const char *);

View file

@ -29,7 +29,6 @@
#include <grub/types.h>
#include <grub/symbol.h>
#include <grub/emu/misc.h>
#include <grub/util/libzfs.h>
char *grub_util_get_path (const char *dir, const char *file);
size_t grub_util_get_fp_size (FILE *fp);
@ -61,7 +60,4 @@ char *canonicalize_file_name (const char *path);
void grub_util_init_nls (void);
void grub_util_init_libzfs (void);
extern libzfs_handle_t *libzfs_handle;
#endif /* ! GRUB_UTIL_MISC_HEADER */

View file

@ -19,9 +19,13 @@
#ifndef GRUB_VGA_HEADER
#define GRUB_VGA_HEADER 1
#include <grub/pci.h>
enum
{
GRUB_VGA_IO_ARX = 0x3c0,
GRUB_VGA_IO_ARX_READ = 0x3c1,
GRUB_VGA_IO_MISC_WRITE = 0x3c2,
GRUB_VGA_IO_SR_INDEX = 0x3c4,
GRUB_VGA_IO_SR_DATA = 0x3c5,
GRUB_VGA_IO_PIXEL_MASK = 0x3c6,
@ -39,8 +43,15 @@ enum
enum
{
GRUB_VGA_CR_WIDTH = 0x01,
GRUB_VGA_CR_HTOTAL = 0x00,
GRUB_VGA_CR_HORIZ_END = 0x01,
GRUB_VGA_CR_HBLANK_START = 0x02,
GRUB_VGA_CR_HBLANK_END = 0x03,
GRUB_VGA_CR_HORIZ_SYNC_PULSE_START = 0x04,
GRUB_VGA_CR_HORIZ_SYNC_PULSE_END = 0x05,
GRUB_VGA_CR_VERT_TOTAL = 0x06,
GRUB_VGA_CR_OVERFLOW = 0x07,
GRUB_VGA_CR_BYTE_PANNING = 0x08,
GRUB_VGA_CR_CELL_HEIGHT = 0x09,
GRUB_VGA_CR_CURSOR_START = 0x0a,
GRUB_VGA_CR_CURSOR_END = 0x0b,
@ -48,14 +59,71 @@ enum
GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d,
GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e,
GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f,
GRUB_VGA_CR_VSYNC_START = 0x10,
GRUB_VGA_CR_VSYNC_END = 0x11,
GRUB_VGA_CR_HEIGHT = 0x12,
GRUB_VGA_CR_VDISPLAY_END = 0x12,
GRUB_VGA_CR_PITCH = 0x13,
GRUB_VGA_CR_UNDERLINE_LOCATION = 0x14,
GRUB_VGA_CR_VERTICAL_BLANK_START = 0x15,
GRUB_VGA_CR_VERTICAL_BLANK_END = 0x16,
GRUB_VGA_CR_MODE = 0x17,
GRUB_VGA_CR_LINE_COMPARE = 0x18,
};
enum
{
GRUB_VGA_CR_BYTE_PANNING_NORMAL = 0
};
enum
{
GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE = 0x40
};
enum
{
GRUB_VGA_IO_MISC_COLOR = 0x01,
GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS = 0x02,
GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08,
GRUB_VGA_IO_MISC_28MHZ = 0x04,
GRUB_VGA_IO_MISC_UPPER_64K = 0x20,
GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY = 0x40,
GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY = 0x80,
};
enum
{
GRUB_VGA_ARX_MODE = 0x10,
GRUB_VGA_ARX_OVERSCAN = 0x11,
GRUB_VGA_ARX_COLOR_PLANE_ENABLE = 0x12,
GRUB_VGA_ARX_HORIZONTAL_PANNING = 0x13,
GRUB_VGA_ARX_COLOR_SELECT = 0x14
};
enum
{
GRUB_VGA_ARX_MODE_TEXT = 0x00,
GRUB_VGA_ARX_MODE_GRAPHICS = 0x01,
GRUB_VGA_ARX_MODE_ENABLE_256COLOR = 0x40
};
#define GRUB_VGA_CR_WIDTH_DIVISOR 8
#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT 7
#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK 0x02
#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT 3
#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK 0x40
#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT 8
#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK 0x01
#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT 4
#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK 0x20
#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT 6
#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK 0x04
#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT 2
#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK 0x80
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7
#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02
#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3
@ -65,7 +133,9 @@ enum
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40
#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3
#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK 0x20
#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT 4
#define GRUB_VGA_CR_CELL_HEIGHT_DOUBLE_SCAN 0x80
enum
{
GRUB_VGA_CR_CURSOR_START_DISABLE = (1 << 5)
@ -77,17 +147,26 @@ enum
{
GRUB_VGA_CR_MODE_NO_CGA = 0x01,
GRUB_VGA_CR_MODE_NO_HERCULES = 0x02,
GRUB_VGA_CR_MODE_ADDRESS_WRAP = 0x20,
GRUB_VGA_CR_MODE_BYTE_MODE = 0x40,
GRUB_VGA_CR_MODE_TIMING_ENABLE = 0x80
};
enum
{
GRUB_VGA_SR_RESET = 0,
GRUB_VGA_SR_CLOCKING_MODE = 1,
GRUB_VGA_SR_MAP_MASK_REGISTER = 2,
GRUB_VGA_SR_CHAR_MAP_SELECT = 3,
GRUB_VGA_SR_MEMORY_MODE = 4,
};
enum
{
GRUB_VGA_SR_RESET_ASYNC = 1,
GRUB_VGA_SR_RESET_SYNC = 2
};
enum
{
GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK = 1
@ -96,19 +175,33 @@ enum
enum
{
GRUB_VGA_SR_MEMORY_MODE_NORMAL = 0,
GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8
GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY = 2,
GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING = 4,
GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8,
};
enum
{
GRUB_VGA_GR_SET_RESET_PLANE = 0,
GRUB_VGA_GR_SET_RESET_PLANE_ENABLE = 1,
GRUB_VGA_GR_COLOR_COMPARE = 2,
GRUB_VGA_GR_DATA_ROTATE = 3,
GRUB_VGA_GR_READ_MAP_REGISTER = 4,
GRUB_VGA_GR_MODE = 5,
GRUB_VGA_GR_GR6 = 6,
GRUB_VGA_GR_COLOR_COMPARE_DISABLE = 7,
GRUB_VGA_GR_BITMASK = 8,
GRUB_VGA_GR_MAX
};
#define GRUB_VGA_ALL_PLANES 0xf
#define GRUB_VGA_NO_PLANES 0x0
enum
{
GRUB_VGA_GR_DATA_ROTATE_NOP = 0
};
enum
{
GRUB_VGA_TEXT_TEXT_PLANE = 0,
@ -119,6 +212,7 @@ enum
enum
{
GRUB_VGA_GR_GR6_GRAPHICS_MODE = 1,
GRUB_VGA_GR_GR6_MMAP_A0 = (1 << 2),
GRUB_VGA_GR_GR6_MMAP_CGA = (3 << 2)
};
@ -126,70 +220,152 @@ enum
{
GRUB_VGA_GR_MODE_READ_MODE1 = 0x08,
GRUB_VGA_GR_MODE_ODD_EVEN = 0x10,
GRUB_VGA_GR_MODE_ODD_EVEN_SHIFT = 0x20,
GRUB_VGA_GR_MODE_256_COLOR = 0x40
};
static inline void
grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
grub_outb (val, GRUB_VGA_IO_GR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA);
}
static inline grub_uint8_t
grub_vga_gr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_GR_INDEX);
return grub_inb (GRUB_VGA_IO_GR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX);
return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA);
}
static inline void
grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
grub_outb (val, GRUB_VGA_IO_CR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA);
}
static inline grub_uint8_t
grub_vga_cr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_CR_INDEX);
return grub_inb (GRUB_VGA_IO_CR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX);
return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA);
}
static inline void
grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
grub_outb (val, GRUB_VGA_IO_SR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA);
}
static inline grub_uint8_t
grub_vga_sr_read (grub_uint8_t addr)
{
grub_outb (addr, GRUB_VGA_IO_SR_INDEX);
return grub_inb (GRUB_VGA_IO_SR_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX);
return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA);
}
static inline void
grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g,
grub_uint8_t *b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_READ_INDEX);
*r = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*g = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
*b = grub_inb (GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_READ_INDEX);
*r = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
*g = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
*b = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
}
static inline void
grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g,
grub_uint8_t b)
{
grub_outb (addr, GRUB_VGA_IO_PALLETTE_WRITE_INDEX);
grub_outb (r, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (g, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (b, GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_WRITE_INDEX);
grub_outb (r, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (g, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
grub_outb (b, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA);
}
static inline void
grub_vga_write_arx (grub_uint8_t val, grub_uint8_t addr)
{
grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
}
struct grub_video_hw_config
{
unsigned vertical_total;
unsigned vertical_blank_start;
unsigned vertical_blank_end;
unsigned vertical_sync_start;
unsigned vertical_sync_end;
unsigned line_compare;
unsigned vdisplay_end;
unsigned pitch;
unsigned horizontal_total;
unsigned horizontal_blank_start;
unsigned horizontal_blank_end;
unsigned horizontal_sync_pulse_start;
unsigned horizontal_sync_pulse_end;
unsigned horizontal_end;
};
static inline void
grub_vga_set_geometry (struct grub_video_hw_config *config,
void (*cr_write) (grub_uint8_t val, grub_uint8_t addr))
{
unsigned vertical_total = config->vertical_total - 2;
unsigned vertical_blank_start = config->vertical_blank_start - 1;
unsigned vdisplay_end = config->vdisplay_end - 1;
grub_uint8_t overflow, cell_height_reg;
/* Disable CR0-7 write protection. */
cr_write (0, GRUB_VGA_CR_VSYNC_END);
overflow = ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK)
| ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK)
| ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK)
| ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK)
| ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK)
| ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK)
| ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK)
| ((config->line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK);
cell_height_reg = ((vertical_blank_start
>> GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT)
& GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK)
| ((config->line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK);
cr_write (config->horizontal_total - 1, GRUB_VGA_CR_HTOTAL);
cr_write (config->horizontal_end - 1, GRUB_VGA_CR_HORIZ_END);
cr_write (config->horizontal_blank_start - 1, GRUB_VGA_CR_HBLANK_START);
cr_write (config->horizontal_blank_end, GRUB_VGA_CR_HBLANK_END);
cr_write (config->horizontal_sync_pulse_start,
GRUB_VGA_CR_HORIZ_SYNC_PULSE_START);
cr_write (config->horizontal_sync_pulse_end,
GRUB_VGA_CR_HORIZ_SYNC_PULSE_END);
cr_write (vertical_total & 0xff, GRUB_VGA_CR_VERT_TOTAL);
cr_write (overflow, GRUB_VGA_CR_OVERFLOW);
cr_write (cell_height_reg, GRUB_VGA_CR_CELL_HEIGHT);
cr_write (config->vertical_sync_start & 0xff, GRUB_VGA_CR_VSYNC_START);
cr_write (config->vertical_sync_end & 0x0f, GRUB_VGA_CR_VSYNC_END);
cr_write (vdisplay_end & 0xff, GRUB_VGA_CR_VDISPLAY_END);
cr_write (config->pitch & 0xff, GRUB_VGA_CR_PITCH);
cr_write (vertical_blank_start & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_START);
cr_write (config->vertical_blank_end & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_END);
cr_write (config->line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE);
}
#endif

View file

@ -49,10 +49,6 @@
# include <grub/util/libnvpair.h>
#endif
#ifdef HAVE_GETFSSTAT
# include <sys/mount.h>
#endif
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/emu/misc.h>
@ -98,66 +94,6 @@ xgetcwd (void)
return path;
}
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
static char *
find_mount_point_from_dir (const char *dir)
{
struct stat st;
typeof (st.st_dev) fs;
char *prev, *next, *slash, *statdir;
if (stat (dir, &st) == -1)
error (1, errno, "stat (%s)", dir);
fs = st.st_dev;
prev = xstrdup (dir);
while (1)
{
/* Remove last slash. */
next = xstrdup (prev);
slash = strrchr (next, '/');
if (! slash)
{
free (next);
free (prev);
return NULL;
}
*slash = '\0';
/* A next empty string counts as /. */
if (next[0] == '\0')
statdir = "/";
else
statdir = next;
if (stat (statdir, &st) == -1)
error (1, errno, "stat (%s)", next);
if (st.st_dev != fs)
{
/* Found mount point. */
free (next);
return prev;
}
free (prev);
prev = next;
/* We've already seen an empty string, which means we
reached /. Nothing left to do. */
if (prev[0] == '\0')
{
free (prev);
return xstrdup ("/");
}
}
}
#endif
#ifdef __linux__
/* Statting something on a btrfs filesystem always returns a virtual device
@ -239,63 +175,29 @@ find_root_device_from_mountinfo (const char *dir)
#endif /* __linux__ */
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
/* ZFS has similar problems to those of btrfs (see above). */
static char *
find_root_device_from_libzfs (const char *dir)
{
char *device = NULL;
char *poolname = NULL;
char *poolfs = NULL;
char *mnt_point;
char *slash;
mnt_point = find_mount_point_from_dir (dir);
#ifdef HAVE_GETFSSTAT
{
int mnt_count = getfsstat (NULL, 0, MNT_WAIT);
if (mnt_count == -1)
error (1, errno, "getfsstat");
struct statfs *mnt = xmalloc (mnt_count * sizeof (*mnt));
mnt_count = getfsstat (mnt, mnt_count * sizeof (*mnt), MNT_WAIT);
if (mnt_count == -1)
error (1, errno, "getfsstat");
unsigned int i;
for (i = 0; i < (unsigned) mnt_count; i++)
if (!strcmp (mnt[i].f_fstypename, "zfs")
&& !strcmp (mnt[i].f_mntonname, mnt_point))
{
poolname = xstrdup (mnt[i].f_mntfromname);
break;
}
free (mnt);
}
#endif
char *device;
char *poolname;
char *poolfs;
grub_find_zpool_from_dir (dir, &poolname, &poolfs);
if (! poolname)
return NULL;
slash = strchr (poolname, '/');
if (slash)
{
*slash = '\0';
poolfs = slash + 1;
}
{
zpool_handle_t *zpool;
libzfs_handle_t *libzfs;
nvlist_t *nvlist;
nvlist_t **nvlist_array;
unsigned int nvlist_count;
grub_util_init_libzfs ();
libzfs = grub_get_libzfs_handle ();
if (! libzfs)
return NULL;
zpool = zpool_open (libzfs_handle, poolname);
zpool = zpool_open (libzfs, poolname);
nvlist = zpool_get_config (zpool, NULL);
if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0)
@ -317,6 +219,8 @@ find_root_device_from_libzfs (const char *dir)
}
free (poolname);
if (poolfs)
free (poolfs);
return device;
}

View file

@ -19,6 +19,7 @@
#include <config.h>
#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@ -44,6 +45,22 @@
# include <libdevmapper.h>
#endif
#ifdef HAVE_LIBZFS
# include <grub/util/libzfs.h>
#endif
#ifdef HAVE_LIBNVPAIR
# include <grub/util/libnvpair.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
int verbosity;
void
@ -236,23 +253,87 @@ get_win32_path (const char *path)
}
#endif
#ifdef HAVE_LIBZFS
static libzfs_handle_t *__libzfs_handle;
static void
fini_libzfs (void)
{
libzfs_fini (__libzfs_handle);
}
libzfs_handle_t *
grub_get_libzfs_handle (void)
{
if (! __libzfs_handle)
{
__libzfs_handle = libzfs_init ();
if (__libzfs_handle)
atexit (fini_libzfs);
}
return __libzfs_handle;
}
#endif /* HAVE_LIBZFS */
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
/* ZFS has similar problems to those of btrfs (see above). */
void
grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs)
{
struct statfs mnt;
char *slash;
*poolname = *poolfs = NULL;
if (statfs (dir, &mnt) != 0)
return;
if (strcmp (mnt.f_fstypename, "zfs") != 0)
return;
*poolname = xstrdup (mnt.f_mntfromname);
slash = strchr (*poolname, '/');
if (slash)
{
*slash = '\0';
*poolfs = xstrdup (slash + 1);
}
else
*poolfs = xstrdup ("");
}
#endif
/* This function never prints trailing slashes (so that its output
can be appended a slash unconditionally). */
char *
grub_make_system_path_relative_to_its_root (const char *path)
{
struct stat st;
char *p, *buf, *buf2, *buf3;
char *p, *buf, *buf2, *buf3, *ret;
uintptr_t offset = 0;
dev_t num;
size_t len;
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
char *poolfs = NULL;
#endif
/* canonicalize. */
p = canonicalize_file_name (path);
if (p == NULL)
grub_util_error ("failed to get canonical path of %s", path);
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
/* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */
{
char *dummy;
grub_find_zpool_from_dir (p, &dummy, &poolfs);
}
#endif
len = strlen (p) + 1;
buf = xstrdup (p);
free (p);
@ -331,7 +412,17 @@ grub_make_system_path_relative_to_its_root (const char *path)
len--;
}
return buf3;
#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR)
if (poolfs)
{
ret = xasprintf ("/%s/@%s", poolfs, buf3);
free (buf3);
}
else
#endif
ret = buf3;
return ret;
}
#ifdef HAVE_DEVICE_MAPPER

View file

@ -69,10 +69,7 @@ load_palette (void)
{
unsigned i;
for (i = 0; i < 16; i++)
{
grub_outb (i, GRUB_VGA_IO_ARX);
grub_outb (i, GRUB_VGA_IO_ARX);
}
grub_vga_write_arx (i, i);
for (i = 0; i < ARRAY_SIZE (colors); i++)
grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b);
@ -90,7 +87,7 @@ grub_qemu_init_cirrus (void)
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class = grub_pci_read (addr);
if (((class >> 16) & 0xffff) != 0x0300)
if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA)
return 0;
/* FIXME: chooose addresses dynamically. */
@ -110,7 +107,7 @@ grub_qemu_init_cirrus (void)
grub_pci_iterate (find_card);
grub_outb (1, 0x3c2);
grub_outb (GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE);
load_font ();
@ -124,11 +121,11 @@ grub_qemu_init_cirrus (void)
GRUB_VGA_SR_MAP_MASK_REGISTER);
grub_vga_cr_write (15, GRUB_VGA_CR_CELL_HEIGHT);
grub_vga_cr_write (79, GRUB_VGA_CR_WIDTH);
grub_vga_cr_write (79, GRUB_VGA_CR_HORIZ_END);
grub_vga_cr_write (40, GRUB_VGA_CR_PITCH);
int vert = 25 * 16;
grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_HEIGHT);
grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_VDISPLAY_END);
grub_vga_cr_write (((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT)
& GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK)
| ((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT)
@ -137,10 +134,8 @@ grub_qemu_init_cirrus (void)
load_palette ();
grub_outb (0x10, 0x3c0);
grub_outb (0, 0x3c1);
grub_outb (0x14, 0x3c0);
grub_outb (0, 0x3c1);
grub_vga_write_arx (GRUB_VGA_ARX_MODE_TEXT, GRUB_VGA_ARX_MODE);
grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT);
grub_vga_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK,
GRUB_VGA_SR_CLOCKING_MODE);

View file

@ -56,22 +56,23 @@ parse_color_name (grub_uint8_t *ret, char *name)
return -1;
}
void
grub_parse_color_name_pair (grub_uint8_t *ret, const char *name)
int
grub_parse_color_name_pair (grub_uint8_t *color, const char *name)
{
int result = 1;
grub_uint8_t fg, bg;
char *fg_name, *bg_name;
/* nothing specified by user */
if (name == NULL)
return;
return result;
fg_name = grub_strdup (name);
if (fg_name == NULL)
{
/* "out of memory" message was printed by grub_strdup() */
grub_wait_after_message ();
return;
return result;
}
bg_name = grub_strchr (fg_name, '/');
@ -97,10 +98,12 @@ grub_parse_color_name_pair (grub_uint8_t *ret, const char *name)
goto free_and_return;
}
*ret = (bg << 4) | fg;
*color = (bg << 4) | fg;
result = 0;
free_and_return:
grub_free (fg_name);
return result;
}
static grub_uint8_t color_normal, color_highlight;
@ -122,10 +125,10 @@ set_colors (void)
/* Replace default `normal' colors with the ones specified by user (if any). */
char *
grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
grub_env_write_color_normal (struct grub_env_var *var, const char *val)
{
grub_parse_color_name_pair (&color_normal, val);
if (grub_parse_color_name_pair (&color_normal, val))
return 0;
set_colors ();
@ -134,10 +137,10 @@ grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
/* Replace default `highlight' colors with the ones specified by user (if any). */
char *
grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
grub_env_write_color_highlight (struct grub_env_var *var, const char *val)
{
grub_parse_color_name_pair (&color_highlight, val);
if (grub_parse_color_name_pair (&color_highlight, val))
return 0;
set_colors ();

View file

@ -675,6 +675,7 @@ static void (*grub_xputs_saved) (const char *str);
GRUB_MOD_INIT(normal)
{
grub_context_init ();
grub_script_init ();
grub_xputs_saved = grub_xputs;
grub_xputs = grub_xputs_normal;
@ -704,11 +705,16 @@ GRUB_MOD_INIT(normal)
/* Preserve hooks after context changes. */
grub_env_export ("color_normal");
grub_env_export ("color_highlight");
/* Set default color names. */
grub_env_set ("color_normal", "white/black");
grub_env_set ("color_highlight", "black/white");
}
GRUB_MOD_FINI(normal)
{
grub_context_fini ();
grub_script_fini ();
grub_xputs = grub_xputs_saved;

133
script/argv.c Normal file
View file

@ -0,0 +1,133 @@
/* argv.c - methods for constructing argument vector */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/mm.h>
#include <grub/script_sh.h>
/* Return nearest power of two that is >= v. */
static unsigned
round_up_exp (unsigned v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
if (sizeof (v) > 4)
v |= v >> 32;
v++;
v += (v == 0);
return v;
}
void
grub_script_argv_free (struct grub_script_argv *argv)
{
unsigned i;
if (argv->args)
{
for (i = 0; i < argv->argc; i++)
grub_free (argv->args[i]);
grub_free (argv->args);
}
argv->argc = 0;
argv->args = 0;
}
/* Prepare for next argc. */
int
grub_script_argv_next (struct grub_script_argv *argv)
{
char **p = argv->args;
if (argv->args && argv->args[argv->argc - 1] == 0)
return 0;
p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
if (! p)
return 1;
argv->argc++;
argv->args = p;
if (argv->argc == 1)
argv->args[0] = 0;
argv->args[argv->argc] = 0;
return 0;
}
/* Append `s' to the last argument. */
int
grub_script_argv_append (struct grub_script_argv *argv, const char *s)
{
int a, b;
char *p = argv->args[argv->argc - 1];
if (! s)
return 0;
a = p ? grub_strlen (p) : 0;
b = grub_strlen (s);
p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char)));
if (! p)
return 1;
grub_strcpy (p + a, s);
argv->args[argv->argc - 1] = p;
return 0;
}
/* Split `s' and append words as multiple arguments. */
int
grub_script_argv_split_append (struct grub_script_argv *argv, char *s)
{
char ch;
char *p;
int errors = 0;
if (! s)
return 0;
while (! errors && *s)
{
p = s;
while (*s && ! grub_isspace (*s))
s++;
ch = *s;
*s = '\0';
errors += grub_script_argv_append (argv, p);
*s = ch;
while (*s && grub_isspace (*s))
s++;
if (*s)
errors += grub_script_argv_next (argv);
}
return errors;
}

View file

@ -30,6 +30,252 @@
is sizeof (int) * 3, and one extra for a possible -ve sign. */
#define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1)
static unsigned long is_continue;
static unsigned long active_loops;
static unsigned long active_breaks;
/* Scope for grub script functions. */
struct grub_script_scope
{
struct grub_script_argv argv;
};
static struct grub_script_scope *scope = 0;
grub_err_t
grub_script_break (grub_command_t cmd, int argc, char *argv[])
{
char *p = 0;
unsigned long count;
if (argc == 0)
count = 1;
else if ((argc > 1) || (count = grub_strtoul (argv[0], &p, 10)) == 0 ||
(*p != '\0'))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break");
is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0;
active_breaks = grub_min (active_loops, count);
return GRUB_ERR_NONE;
}
grub_err_t
grub_script_shift (grub_command_t cmd __attribute__((unused)),
int argc, char *argv[])
{
char *p = 0;
unsigned long n = 0;
if (! scope)
return GRUB_ERR_NONE;
if (argc == 0)
n = 1;
else if (argc > 1)
return GRUB_ERR_BAD_ARGUMENT;
else
{
n = grub_strtoul (argv[0], &p, 10);
if (*p != '\0')
return GRUB_ERR_BAD_ARGUMENT;
}
if (n > scope->argv.argc)
return GRUB_ERR_BAD_ARGUMENT;
scope->argv.argc -= n;
scope->argv.args += n;
return GRUB_ERR_NONE;
}
static int
grub_env_special (const char *name)
{
if (grub_isdigit (name[0]) ||
grub_strcmp (name, "#") == 0 ||
grub_strcmp (name, "*") == 0 ||
grub_strcmp (name, "@") == 0)
return 1;
return 0;
}
static char **
grub_script_env_get (const char *name, grub_script_arg_type_t type)
{
struct grub_script_argv result = { 0, 0 };
if (grub_script_argv_next (&result))
goto fail;
if (! grub_env_special (name))
{
char *v = grub_env_get (name);
if (v && v[0])
{
if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
{
if (grub_script_argv_split_append (&result, v))
goto fail;
}
else
if (grub_script_argv_append (&result, v))
goto fail;
}
}
else if (! scope)
{
if (grub_script_argv_append (&result, 0))
goto fail;
}
else if (grub_strcmp (name, "#") == 0)
{
char buffer[ERRNO_DIGITS_MAX + 1];
grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc);
if (grub_script_argv_append (&result, buffer))
goto fail;
}
else if (grub_strcmp (name, "*") == 0)
{
unsigned i;
for (i = 0; i < scope->argv.argc; i++)
if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
{
if (i != 0 && grub_script_argv_next (&result))
goto fail;
if (grub_script_argv_split_append (&result, scope->argv.args[i]))
goto fail;
}
else
{
if (i != 0 && grub_script_argv_append (&result, " "))
goto fail;
if (grub_script_argv_append (&result, scope->argv.args[i]))
goto fail;
}
}
else if (grub_strcmp (name, "@") == 0)
{
unsigned i;
for (i = 0; i < scope->argv.argc; i++)
{
if (i != 0 && grub_script_argv_next (&result))
goto fail;
if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
{
if (grub_script_argv_split_append (&result, scope->argv.args[i]))
goto fail;
}
else
if (grub_script_argv_append (&result, scope->argv.args[i]))
goto fail;
}
}
else
{
unsigned long num = grub_strtoul (name, 0, 10);
if (num == 0)
; /* XXX no file name, for now. */
else if (num <= scope->argv.argc)
{
if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
{
if (grub_script_argv_split_append (&result,
scope->argv.args[num - 1]))
goto fail;
}
else
if (grub_script_argv_append (&result, scope->argv.args[num - 1]))
goto fail;
}
}
return result.args;
fail:
grub_script_argv_free (&result);
return 0;
}
static grub_err_t
grub_script_env_set (const char *name, const char *val)
{
if (grub_env_special (name))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variable name");
return grub_env_set (name, val);
}
/* Expand arguments in ARGLIST into multiple arguments. */
static int
grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
struct grub_script_argv *argv)
{
int i;
char **values = 0;
struct grub_script_arg *arg = 0;
struct grub_script_argv result = { 0, 0 };
for (; arglist && arglist->arg; arglist = arglist->next)
{
if (grub_script_argv_next (&result))
goto fail;
arg = arglist->arg;
while (arg)
{
switch (arg->type)
{
case GRUB_SCRIPT_ARG_TYPE_VAR:
case GRUB_SCRIPT_ARG_TYPE_DQVAR:
values = grub_script_env_get (arg->str, arg->type);
for (i = 0; values && values[i]; i++)
{
if (i != 0 && grub_script_argv_next (&result))
goto fail;
if (grub_script_argv_append (&result, values[i]))
goto fail;
}
grub_free (values);
break;
case GRUB_SCRIPT_ARG_TYPE_TEXT:
if (grub_strlen (arg->str) &&
grub_script_argv_append (&result, arg->str))
goto fail;
break;
case GRUB_SCRIPT_ARG_TYPE_DQSTR:
case GRUB_SCRIPT_ARG_TYPE_SQSTR:
if (grub_script_argv_append (&result, arg->str))
goto fail;
break;
}
arg = arg->next;
}
}
if (! result.args[result.argc - 1])
result.argc--;
*argv = result;
return 0;
fail:
grub_script_argv_free (&result);
return 1;
}
static grub_err_t
grub_script_execute_cmd (struct grub_script_cmd *cmd)
{
@ -46,149 +292,27 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd)
return ret;
}
#define ARG_ALLOCATION_UNIT (32 * sizeof (char))
#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*))
/* Expand arguments in ARGLIST into multiple arguments. */
char **
grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count)
/* Execute a function call. */
grub_err_t
grub_script_function_call (grub_script_function_t func, int argc, char **args)
{
int i;
int oom;
int argc;
int empty;
char *ptr;
char **argv;
char *value;
struct grub_script_arg *arg;
grub_err_t ret = 0;
unsigned long loops = active_loops;
struct grub_script_scope *old_scope;
struct grub_script_scope new_scope;
auto void push (char *str);
void push (char *str)
{
char **p;
active_loops = 0;
new_scope.argv.argc = argc;
new_scope.argv.args = args;
if (oom)
return;
old_scope = scope;
scope = &new_scope;
p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT));
if (!p)
oom = 1;
else
{
p[argc++] = str;
argv = p;
}
}
ret = grub_script_execute (func->func);
auto char* append (const char *str, grub_size_t nchar);
char* append (const char *str, grub_size_t nchar)
{
int len;
int old;
char *p;
if (oom || !str)
return 0;
len = nchar ?: grub_strlen (str);
old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0;
p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT));
if (p)
{
grub_strncpy (p + old, str, len);
p[old + len] = '\0';
}
else
{
oom = 1;
grub_free (argv[argc - 1]);
}
argv[argc - 1] = p;
return argv[argc - 1];
}
/* Move *STR to the begining of next word, but return current word. */
auto char* move_to_next (char **str);
char* move_to_next (char **str)
{
char *end;
char *start;
if (oom || !str || !*str)
return 0;
start = *str;
while (*start && grub_isspace (*start)) start++;
if (*start == '\0')
return 0;
end = start + 1;
while (*end && !grub_isspace (*end)) end++;
*str = end;
return start;
}
oom = 0;
argv = 0;
argc = 0;
push (0);
for (; arglist; arglist = arglist->next)
{
empty = 1;
arg = arglist->arg;
while (arg)
{
switch (arg->type)
{
case GRUB_SCRIPT_ARG_TYPE_VAR:
value = grub_env_get (arg->str);
while (value && *value && (ptr = move_to_next(&value)))
{
empty = 0;
append (ptr, value - ptr);
if (*value) push(0);
}
break;
case GRUB_SCRIPT_ARG_TYPE_TEXT:
if (grub_strlen (arg->str) > 0)
{
empty = 0;
append (arg->str, 0);
}
break;
case GRUB_SCRIPT_ARG_TYPE_DQSTR:
case GRUB_SCRIPT_ARG_TYPE_SQSTR:
empty = 0;
append (arg->str, 0);
break;
case GRUB_SCRIPT_ARG_TYPE_DQVAR:
empty = 0;
append (grub_env_get (arg->str), 0);
break;
}
arg = arg->next;
}
if (!empty)
push (0);
}
if (oom)
{
for (i = 0; i < argc; i++)
grub_free (argv[i]);
grub_free (argv);
argv = 0;
}
if (argv)
*count = argc - 1;
return argv;
active_loops = loops;
scope = old_scope;
return ret;
}
/* Execute a single command line. */
@ -196,21 +320,18 @@ grub_err_t
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
{
struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
char **args = 0;
int i = 0;
grub_command_t grubcmd;
grub_err_t ret = 0;
int argcount = 0;
grub_script_function_t func = 0;
char errnobuf[18];
char *cmdname;
struct grub_script_argv argv = { 0, 0 };
/* Lookup the command. */
args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount);
if (!args)
if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
return grub_errno;
cmdname = args[0];
cmdname = argv.args[0];
grubcmd = grub_command_find (cmdname);
if (! grubcmd)
{
@ -232,13 +353,14 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
/* Create two strings and set the variable. */
*eq = '\0';
eq++;
grub_env_set (assign, eq);
grub_script_env_set (assign, eq);
}
grub_free (assign);
grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno);
grub_env_set ("?", errnobuf);
grub_script_env_set ("?", errnobuf);
grub_script_argv_free (&argv);
grub_print_error ();
return 0;
@ -247,14 +369,12 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
/* Execute the GRUB command or function. */
if (grubcmd)
ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1);
ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1);
else
ret = grub_script_function_call (func, argcount - 1, args + 1);
ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1);
/* Free arguments. */
for (i = 0; i < argcount; i++)
grub_free (args[i]);
grub_free (args);
grub_script_argv_free (&argv);
if (grub_errno == GRUB_ERR_TEST_FAILURE)
grub_errno = GRUB_ERR_NONE;
@ -269,13 +389,13 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
/* Execute a block of one or more commands. */
grub_err_t
grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
grub_script_execute_cmdlist (struct grub_script_cmd *list)
{
int ret = 0;
struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
struct grub_script_cmd *cmd;
/* Loop over every command and execute it. */
for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
for (cmd = list->next; cmd && ! active_breaks; cmd = cmd->next)
ret = grub_script_execute_cmd (cmd);
return ret;
@ -307,25 +427,34 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd)
grub_err_t
grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
{
int i;
int result;
char **args;
int argcount;
unsigned i;
grub_err_t result;
struct grub_script_argv argv = { 0, 0 };
struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount);
if (!args)
if (grub_script_arglist_to_argv (cmdfor->words, &argv))
return grub_errno;
active_loops++;
result = 0;
for (i = 0; i < argcount; i++)
for (i = 0; i < argv.argc; i++)
{
grub_env_set (cmdfor->name->str, args[i]);
result = grub_script_execute_cmd (cmdfor->list);
grub_free (args[i]);
if (is_continue && active_breaks == 1)
active_breaks = 0;
if (! active_breaks)
{
grub_script_env_set (cmdfor->name->str, argv.args[i]);
result = grub_script_execute_cmd (cmdfor->list);
}
}
grub_free (args);
if (active_breaks)
active_breaks--;
active_loops--;
grub_script_argv_free (&argv);
return result;
}
@ -337,6 +466,7 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
int result;
struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
active_loops++;
result = 0;
do {
cond = grub_script_execute_cmd (cmdwhile->cond);
@ -344,8 +474,19 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
break;
result = grub_script_execute_cmd (cmdwhile->list);
if (active_breaks == 1 && is_continue)
active_breaks = 0;
if (active_breaks)
break;
} while (1); /* XXX Put a check for ^C here */
if (active_breaks)
active_breaks--;
active_loops--;
return result;
}
@ -354,26 +495,20 @@ grub_err_t
grub_script_execute_menuentry (struct grub_script_cmd *cmd)
{
struct grub_script_cmd_menuentry *cmd_menuentry;
char **args = 0;
int argcount = 0;
int i = 0;
struct grub_script_argv argv = { 0, 0 };
cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
if (cmd_menuentry->arglist)
{
args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount);
if (!args)
if (grub_script_arglist_to_argv (cmd_menuentry->arglist, &argv))
return grub_errno;
}
grub_normal_add_menu_entry (argcount, (const char **) args,
grub_normal_add_menu_entry (argv.argc, (const char **) argv.args,
cmd_menuentry->sourcecode);
/* Free arguments. */
for (i = 0; i < argcount; i++)
grub_free (args[i]);
grub_free (args);
grub_script_argv_free (&argv);
return grub_errno;
}

View file

@ -103,12 +103,3 @@ grub_script_function_find (char *functionname)
return func;
}
int
grub_script_function_call (grub_script_function_t func,
int argc __attribute__((unused)),
char **args __attribute__((unused)))
{
/* XXX: Arguments are not supported yet. */
return grub_script_execute (func->func);
}

View file

@ -17,6 +17,7 @@
*/
#include <grub/dl.h>
#include <grub/i18n.h>
#include <grub/parser.h>
#include <grub/script_sh.h>
@ -39,3 +40,34 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline)
return grub_errno;
}
static grub_command_t cmd_break;
static grub_command_t cmd_continue;
static grub_command_t cmd_shift;
void
grub_script_init (void)
{
cmd_break = grub_register_command ("break", grub_script_break,
N_("[n]"), N_("Exit from loops"));
cmd_continue = grub_register_command ("continue", grub_script_break,
N_("[n]"), N_("Continue loops"));
cmd_shift = grub_register_command ("shift", grub_script_shift,
N_("[n]"), N_("Shift positional parameters."));
}
void
grub_script_fini (void)
{
if (cmd_break)
grub_unregister_command (cmd_break);
cmd_break = 0;
if (cmd_continue)
grub_unregister_command (cmd_continue);
cmd_continue = 0;
if (cmd_shift)
grub_unregister_command (cmd_shift);
cmd_shift = 0;
}

View file

@ -97,9 +97,7 @@ script: newlines0
}
| script statement delimiter newlines0
{
struct grub_script_cmdblock *cmdblock;
cmdblock = (struct grub_script_cmdblock *) $1;
$$ = grub_script_add_cmd (state, cmdblock, $2);
$$ = grub_script_append_cmd (state, $1, $2);
}
| error
{
@ -185,13 +183,11 @@ command: grubcmd { $$ = $1; }
/* A list of commands. */
commands1: newlines0 command
{
$$ = grub_script_add_cmd (state, 0, $2);
$$ = grub_script_append_cmd (state, 0, $2);
}
| commands1 delimiters1 command
{
struct grub_script_cmdblock *cmdblock;
cmdblock = (struct grub_script_cmdblock *) $1;
$$ = grub_script_add_cmd (state, cmdblock, $3);
$$ = grub_script_append_cmd (state, $1, $3);
}
;

View file

@ -291,46 +291,40 @@ grub_script_create_cmdmenu (struct grub_parser_param *state,
return (struct grub_script_cmd *) cmd;
}
/* Create a block of commands. CMD contains the command that should
be added at the end of CMDBLOCK's list. If CMDBLOCK is zero, a new
cmdblock will be created. */
/* Create a chain of commands. LAST contains the command that should
be added at the end of LIST's list. If LIST is zero, a new list
will be created. */
struct grub_script_cmd *
grub_script_add_cmd (struct grub_parser_param *state,
struct grub_script_cmdblock *cmdblock,
struct grub_script_cmd *cmd)
grub_script_append_cmd (struct grub_parser_param *state,
struct grub_script_cmd *list,
struct grub_script_cmd *last)
{
struct grub_script_cmd *ptr;
grub_dprintf ("scripting", "cmdblock\n");
grub_dprintf ("scripting", "append command\n");
if (!cmd)
return (struct grub_script_cmd *) cmdblock;
if (! last)
return list;
if (!cmdblock)
if (! list)
{
cmdblock = grub_script_malloc (state, sizeof (*cmdblock));
if (!cmdblock)
list = grub_script_malloc (state, sizeof (*list));
if (! list)
return 0;
cmdblock->cmd.exec = grub_script_execute_cmdblock;
cmdblock->cmd.next = 0;
cmdblock->cmdlist = cmd;
cmd->next = 0;
list->exec = grub_script_execute_cmdlist;
list->next = last;
}
else
{
if (!cmdblock->cmdlist)
cmdblock->cmdlist = cmd;
else
{
ptr = cmdblock->cmdlist;
while (ptr->next)
ptr = ptr->next;
ptr->next = cmd;
}
ptr = list;
while (ptr->next)
ptr = ptr->next;
ptr->next = last;
}
return (struct grub_script_cmd *) cmdblock;
return list;
}

View file

@ -119,7 +119,8 @@ DIGITS [[:digit:]]+
NAME [[:alpha:]_][[:alnum:]_]*
ESC \\.
VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\}
SPECIAL \?|\#|\*|\@
VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\}
DQSTR \"([^\\\"]|{ESC})*\"
SQSTR \'[^\']*\'
WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
@ -221,7 +222,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
}
<VAR>{
\? |
{SPECIAL} |
{DIGITS} |
{NAME} {
COPY (yytext, yyleng);
@ -231,7 +232,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
else
ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
}
\{\?\} |
\{{SPECIAL}\} |
\{{DIGITS}\} |
\{{NAME}\} {
yytext[yyleng - 1] = '\0';

View file

@ -0,0 +1,86 @@
#! @builddir@/grub-shell-tester
#
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# break without any arguments
for i in 1 2 3 4 5 6 7 8 9 10
do
echo $i
if test "$i" = 5
then
break
fi
done
# break with one
for i in 1 2 3 4 5 6 7 8 9 10
do
echo $i
if test "$i" = 5
then
break 1
fi
done
# break with loop count
for i in 1 2 3 4 5
do
for j in a b c d e f
do
echo "$i $j"
if test "$i" = 3
then
if test "$j" = d
then
break 2
fi
fi
done
done
# break into middle loop
for i in 1 2 3 4 5
do
for j in a b c d e f
do
echo "$i $j"
if test "$i" = 3
then
if test "$j" = d
then
break 1
fi
fi
done
done
# while and until loops
a=
while test "$a" != "aaaaaaa"
do
a="a$a"
for i in 1 2 3 4
do
b=
until test "$b" = "bbbbb"
do
b="b$b"
echo "$a $i $b"
if test "$i" = 3; then echo "break 2"; break 2; fi
done
done
done

View file

@ -0,0 +1,86 @@
#! @builddir@/grub-shell-tester
#
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# continue without any arguments
for i in 1 2 3 4 5 6 7 8 9 10
do
if test "$i" = 5
then
continue
fi
echo $i
done
# continue with one
for i in 1 2 3 4 5 6 7 8 9 10
do
if test "$i" = 5
then
continue 1
fi
echo $i
done
# continue with loop count
for i in 1 2 3 4 5
do
for j in a b c d e f
do
if test "$i" = 3
then
if test "$j" = d
then
continue 2
fi
echo "$i $j"
fi
done
done
# continue into middle loop
for i in 1 2 3 4 5
do
for j in a b c d e f
do
if test "$i" = 3
then
if test "$j" = d
then
continue 1
fi
echo "$i $j"
fi
done
done
# while and until loops
a=
while test "$a" != "aaaaaaa"
do
a="a$a"
for i in 1 2 3 4
do
b=
until test "$b" = "bbbbb"
do
b="b$b"
if test "$i" = 3; then echo "continue 2"; continue 2; fi
echo "$a $i $b"
done
done
done

View file

@ -16,6 +16,33 @@
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# simple arguments
echo one two three
echo "one two three"
echo 'one two three'
# empty arguments
echo a "" b
echo a '' b
echo a $foo b
echo a ${foo} b
echo a "$foo" b
echo a "${foo}" b
# multi-part arguments
echo one"two"three
echo one${two}three
echo one"two"$three
echo one'two'three
echo one${two}three
echo one'two'$three
echo one'two'three"four"five${six}seven$eight
foo=bar
echo $foo ${foo}
echo "$foo" "${foo}"

View file

@ -0,0 +1,147 @@
#! @builddir@/grub-shell-tester
# Run GRUB script in a Qemu instance
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
echo parameter count
function fcount {
echo fcount "$#"
}
fcount
fcount a
fcount a b
echo parameter count, with nesting
function ffcount {
echo ffcount "$#"
fcount
fcount a
fcount a b
}
ffcount
ffcount 1
ffcount 1 2
echo parameters
function fparam {
echo fparam 1 $1
echo fparam 2 $2
echo fparam 3 $3
}
fparam
fparam a
fparam a b
echo parameters, with nesting
function ffparam {
echo ffparam 1 $1
echo ffparam 2 $2
echo ffparam 3 $3
fparam
fparam a
fparam a b
}
ffparam
ffparam 1
ffparam 1 2
echo parameter expansion with specials
function fstar {
for f in $*
do
echo fstar $f
done
for f in aaa$*bbb
do
echo fstar $f
done
}
fstar
fstar a
fstar a "1 2"
fstar a "1 2" b
function fdqstar {
for f in "$*"
do
echo fdqstar $f
done
for f in aaa"$*"bbb
do
echo fdqstar $f
done
for f in "aaa$*bbb"
do
echo fdqstar $f
done
}
fdqstar
fdqstar a
fdqstar a "1 2"
fdqstar a "1 2" b
function fat {
for f in $@
do
echo fat $f
done
for f in aaa$@bbb
do
echo fat $f
done
}
fat
fat a
fat a "1 2"
fat a "1 2" b
fat a "1 2" b "c d"
fat a "1 2" b "c d" e
function fdqat {
for f in "$@"
do
echo fdqat $f
done
for f in aaa"$@"bbb
do
echo fdqat $f
done
for f in "aaa$@bbb"
do
echo fdqat $f
done
}
# fdqat # this case needs special handling, lets ignore till we really need it.
fdqat a
fdqat a "1 2"
fdqat a "1 2" b
fdqat a "1 2" b "c d"
fdqat a "1 2" b "c d" e

View file

@ -0,0 +1,85 @@
#! @builddir@/grub-shell-tester
# Run GRUB script in a Qemu instance
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
function f1 {
echo f1 '$@' $@
echo f1 '$*' $*
echo f1 $# $1 $2 $3
shift
echo f1 '$@' $@
echo f1 '$*' $*
echo f1 $# $1 $2 $3
}
f1
f1 a
f1 a b
f1 a b c
f1 a b c d
f1 a b c d e
function f2 {
echo f1 '$@' $@
echo f1 '$*' $*
echo f2 $# $1 $2 $3
shift 1
echo f1 '$@' $@
echo f1 '$*' $*
echo f2 $# $1 $2 $3
}
f2
f2 a
f2 a b
f2 a b c
f2 a b c d
f2 a b c d e
function f3 {
echo f1 '$@' $@
echo f1 '$*' $*
echo f3 $# $1 $2 $3
shift 3
echo f1 '$@' $@
echo f1 '$*' $*
echo f3 $# $1 $2 $3
}
f3
f3 a
f3 a b
f3 a b c
f3 a b c d
f3 a b c d e
function f4 {
echo f1 '$@' $@
echo f1 '$*' $*
echo f4 $# $1 $2 $3
shift 100
echo f1 '$@' $@
echo f1 '$*' $*
echo f4 $# $1 $2 $3
}
f4
f4 a
f4 a b
f4 a b c
f4 a b c d
f4 a b c d e

View file

@ -157,7 +157,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
if (sz < 0)
{
grub_util_error ("read error at offset %llu", ofs);
grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
break;
}
@ -211,7 +211,7 @@ cmd_cmp (char *src, char *dest)
{
if ((int) fread (buf_1, 1, len, ff) != len)
{
grub_util_error ("read error at offset %llu", ofs);
grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg);
return 1;
}

View file

@ -79,7 +79,7 @@ main (int argc, char **argv)
fclose (in);
fclose (out);
free (buf);
printf ("Invalid Mach-O fle\n");
printf ("Invalid Mach-O file\n");
return 4;
}
curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head));

View file

@ -57,6 +57,22 @@ grub_refresh (void)
fflush (stdout);
}
grub_err_t
grub_script_break (grub_command_t cmd __attribute__((unused)),
int argc __attribute__((unused)),
char *argv[] __attribute__((unused)))
{
return 0;
}
grub_err_t
grub_script_shift (grub_command_t cmd __attribute__((unused)),
int argc __attribute__((unused)),
char *argv[] __attribute__((unused)))
{
return 0;
}
char *
grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused)))
{
@ -70,7 +86,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused)
}
grub_err_t
grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused)))
grub_script_execute_cmdlist (struct grub_script_cmd *cmd __attribute__ ((unused)))
{
return 0;
}

View file

@ -74,8 +74,28 @@ EOF
EOF
fi
case "${kfreebsd_fs}" in
zfs)
for i in "${module_dir}/opensolaris.ko" "${module_dir}/zfs.ko" \
"${dirname}/zfs/zpool.cache" ; do
ls "$i" > /dev/null
done
printf '%s\n' "${prepare_module_dir_cache}"
cat << EOF
kfreebsd_module_elf ${module_dir_rel}/opensolaris.ko
kfreebsd_module_elf ${module_dir_rel}/zfs.ko
EOF
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE}
kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache
EOF
;;
esac
cat << EOF
set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${kfreebsd_device}
set kFreeBSD.vfs.root.mountfrom.options=rw
}
EOF
@ -105,6 +125,11 @@ while [ "x$list" != "x" ] ; do
*) kfreebsd_fs=${GRUB_FS} ;;
esac
case ${GRUB_FS} in
zfs) kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) ;;
*) kfreebsd_device=${GRUB_DEVICE} ;;
esac
version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`

View file

@ -36,7 +36,6 @@
#include <grub/misc.h>
#include <grub/cache.h>
#include <grub/util/misc.h>
#include <grub/util/libzfs.h>
#include <grub/mm.h>
#include <grub/term.h>
#include <grub/time.h>
@ -295,28 +294,7 @@ grub_util_init_nls (void)
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
}
#ifdef HAVE_LIBZFS
libzfs_handle_t *libzfs_handle;
static void
fini_libzfs (void)
{
libzfs_fini (libzfs_handle);
}
#endif
void
grub_util_init_libzfs (void)
{
#ifdef HAVE_LIBZFS
if (! libzfs_handle)
{
libzfs_handle = libzfs_init ();
atexit (fini_libzfs);
}
#endif
}
#endif
#endif /* GRUB_UTIL */
int
grub_dl_ref (grub_dl_t mod)

View file

@ -334,10 +334,15 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
}
{
int pitch_reg, overflow_reg = 0, line_compare = 0x3ff;
struct grub_video_hw_config config = {
.pitch = pitch / GRUB_VGA_CR_PITCH_DIVISOR,
.line_compare = 0x3ff,
.vdisplay_end = height - 1,
.horizontal_end = width / GRUB_VGA_CR_WIDTH_DIVISOR
};
grub_uint8_t sr_ext = 0, hidden_dac = 0;
pitch_reg = pitch / GRUB_VGA_CR_PITCH_DIVISOR;
grub_vga_set_geometry (&config, grub_vga_cr_write);
grub_vga_gr_write (GRUB_VGA_GR_MODE_256_COLOR | GRUB_VGA_GR_MODE_READ_MODE1,
GRUB_VGA_GR_MODE);
@ -345,32 +350,10 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE);
/* Disable CR0-7 write protection. */
grub_vga_cr_write (0, GRUB_VGA_CR_VSYNC_END);
grub_vga_cr_write (width / GRUB_VGA_CR_WIDTH_DIVISOR - 1,
GRUB_VGA_CR_WIDTH);
grub_vga_cr_write ((height - 1) & 0xff, GRUB_VGA_CR_HEIGHT);
overflow_reg |= (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) &
GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK)
| (((height - 1) >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) &
GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK);
grub_vga_cr_write (pitch_reg & 0xff, GRUB_VGA_CR_PITCH);
grub_vga_cr_write (line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE);
overflow_reg |= (line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK;
grub_vga_cr_write (overflow_reg, GRUB_VGA_CR_OVERFLOW);
grub_vga_cr_write ((pitch_reg >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT)
grub_vga_cr_write ((config.pitch >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT)
& CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK,
CIRRUS_CR_EXTENDED_DISPLAY);
grub_vga_cr_write ((line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT)
& GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK, GRUB_VGA_CR_CELL_HEIGHT);
grub_vga_cr_write (GRUB_VGA_CR_MODE_TIMING_ENABLE
| GRUB_VGA_CR_MODE_BYTE_MODE
| GRUB_VGA_CR_MODE_NO_HERCULES | GRUB_VGA_CR_MODE_NO_CGA,

View file

@ -26,10 +26,168 @@
#include <grub/video.h>
#include <grub/video_fb.h>
#include <grub/pci.h>
#include <grub/vga.h>
#include "sm712_init.c"
#define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400
#define GRUB_SM712_REG_BASE 0x700000
#define GRUB_SM712_PCIID 0x0712126f
enum
{
GRUB_SM712_SR_TV_CONTROL = 0x65,
GRUB_SM712_SR_RAM_LUT = 0x66,
GRUB_SM712_SR_CLOCK_CONTROL1 = 0x68,
GRUB_SM712_SR_CLOCK_CONTROL2 = 0x69,
GRUB_SM712_SR_VCLK_NUM = 0x6c,
GRUB_SM712_SR_VCLK_DENOM = 0x6d,
GRUB_SM712_SR_VCLK2_NUM = 0x6e,
GRUB_SM712_SR_VCLK2_DENOM = 0x6f,
GRUB_SM712_SR_POPUP_ICON_LOW = 0x80,
GRUB_SM712_SR_POPUP_ICON_HIGH = 0x81,
GRUB_SM712_SR_POPUP_ICON_CTRL = 0x82,
GRUB_SM712_SR_POPUP_ICON_COLOR1 = 0x84,
GRUB_SM712_SR_POPUP_ICON_COLOR2 = 0x85,
GRUB_SM712_SR_POPUP_ICON_COLOR3 = 0x86,
GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW = 0x88,
GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH = 0x89,
GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW = 0x8a,
GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH = 0x8b,
GRUB_SM712_SR_HW_CURSOR_FG_COLOR = 0x8c,
GRUB_SM712_SR_HW_CURSOR_BG_COLOR = 0x8d,
GRUB_SM712_SR_POPUP_ICON_X_LOW = 0x90,
GRUB_SM712_SR_POPUP_ICON_X_HIGH = 0x91,
GRUB_SM712_SR_POPUP_ICON_Y_LOW = 0x92,
GRUB_SM712_SR_POPUP_ICON_Y_HIGH = 0x93,
GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL = 0xa0,
GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW = 0xa1,
GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH = 0xa2,
GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW = 0xa3,
GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH = 0xa4,
GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT = 0xa5,
GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT = 0xa6,
GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT = 0xa7,
GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY = 0xa8,
GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY = 0xa9,
GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY = 0xaa,
GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY = 0xab,
GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY = 0xac,
GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY = 0xad,
GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR = 0xae,
GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR = 0xaf,
};
enum
{
GRUB_SM712_SR_TV_CRT_SRAM = 0x00,
GRUB_SM712_SR_TV_LCD_SRAM = 0x08
};
enum
{
GRUB_SM712_SR_TV_ALT_CLOCK = 0x00,
GRUB_SM712_SR_TV_FREE_RUN_CLOCK = 0x04
};
enum
{
GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC = 0x00,
GRUB_SM712_SR_TV_CLOCK_REFCLK_PAL = 0x04
};
enum
{
GRUB_SM712_SR_TV_HSYNC = 0x00,
GRUB_SM712_SR_TV_COMPOSITE_HSYNC = 0x01
};
enum
{
GRUB_SM712_SR_RAM_LUT_NORMAL = 0,
GRUB_SM712_SR_RAM_LUT_LCD_RAM_OFF = 0x80,
GRUB_SM712_SR_RAM_LUT_CRT_RAM_OFF = 0x40,
GRUB_SM712_SR_RAM_LUT_LCD_RAM_NO_WRITE = 0x20,
GRUB_SM712_SR_RAM_LUT_CRT_RAM_NO_WRITE = 0x10,
GRUB_SM712_SR_RAM_LUT_CRT_8BIT = 0x08,
GRUB_SM712_SR_RAM_LUT_CRT_GAMMA = 0x04
};
enum
{
GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR = 0x40,
GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK = 0x10,
};
enum
{
GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK = 0x03
};
#define GRUB_SM712_SR_POPUP_ICON_HIGH_MASK 0x7
#define GRUB_SM712_SR_POPUP_ICON_HIGH_HW_CURSOR_EN 0x80
enum
{
GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED = 0,
GRUB_SM712_SR_POPUP_ICON_CTRL_ZOOM_ENABLED = 0x40,
GRUB_SM712_SR_POPUP_ICON_CTRL_ENABLED = 0x80
};
#define RGB332_BLACK 0
#define RGB332_WHITE 0xff
enum
{
GRUB_SM712_CR_OVERFLOW_INTERLACE = 0x30,
GRUB_SM712_CR_INTERLACE_RETRACE = 0x31,
GRUB_SM712_CR_TV_VDISPLAY_START = 0x32,
GRUB_SM712_CR_TV_VDISPLAY_END_HIGH = 0x33,
GRUB_SM712_CR_TV_VDISPLAY_END_LOW = 0x34,
GRUB_SM712_CR_DDA_CONTROL_LOW = 0x35,
GRUB_SM712_CR_DDA_CONTROL_HIGH = 0x36,
GRUB_SM712_CR_TV_EQUALIZER = 0x38,
GRUB_SM712_CR_TV_SERRATION = 0x39,
GRUB_SM712_CR_HSYNC_CTRL = 0x3a,
GRUB_SM712_CR_DEBUG = 0x3c,
GRUB_SM712_CR_SHADOW_VGA_HTOTAL = 0x40,
GRUB_SM712_CR_SHADOW_VGA_HBLANK_START = 0x41,
GRUB_SM712_CR_SHADOW_VGA_HBLANK_END = 0x42,
GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START = 0x43,
GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END = 0x44,
GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL = 0x45,
GRUB_SM712_CR_SHADOW_VGA_VBLANK_START = 0x46,
GRUB_SM712_CR_SHADOW_VGA_VBLANK_END = 0x47,
GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START = 0x48,
GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END = 0x49,
GRUB_SM712_CR_SHADOW_VGA_OVERFLOW = 0x4a,
GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT = 0x4b,
GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END = 0x4c,
GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END = 0x4d,
GRUB_SM712_CR_DDA_LOOKUP_REG3_START = 0x90,
GRUB_SM712_CR_DDA_LOOKUP_REG2_START = 0x91,
GRUB_SM712_CR_DDA_LOOKUP_REG1_START = 0xa0,
GRUB_SM712_CR_VCENTERING_OFFSET = 0xa6,
GRUB_SM712_CR_HCENTERING_OFFSET = 0xa7,
};
#define GRUB_SM712_CR_DEBUG_NONE 0
#define SM712_DDA_REG3_COMPARE_SHIFT 2
#define SM712_DDA_REG3_COMPARE_MASK 0xfc
#define SM712_DDA_REG3_DDA_SHIFT 8
#define SM712_DDA_REG3_DDA_MASK 0x3
#define SM712_DDA_REG2_DDA_MASK 0xff
#define SM712_DDA_REG2_VCENTER_MASK 0x3f
static struct
{
grub_uint8_t compare;
grub_uint16_t dda;
grub_uint8_t vcentering;
} dda_lookups[] = {
{ 21, 469, 2},
{ 23, 477, 2},
{ 33, 535, 2},
{ 35, 682, 21},
{ 34, 675, 2},
{ 55, 683, 6},
};
static struct
{
@ -42,6 +200,7 @@ static struct
grub_pci_device_t dev;
} framebuffer;
#ifndef TEST
static grub_err_t
grub_video_sm712_video_init (void)
{
@ -60,6 +219,118 @@ grub_video_sm712_video_fini (void)
return grub_video_fb_fini ();
}
#endif
static inline void
grub_sm712_write_reg (grub_uint8_t val, grub_uint16_t addr)
{
#ifdef TEST
printf (" {1, 0x%x, 0x%x},\n", addr, val);
#else
*(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
+ addr) = val;
#endif
}
static inline grub_uint8_t
grub_sm712_read_reg (grub_uint16_t addr)
{
#ifdef TEST
printf (" {-1, 0x%x, 0x5},\n", addr);
#else
return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE
+ addr);
#endif
}
static inline grub_uint8_t
grub_sm712_sr_read (grub_uint8_t addr)
{
grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX);
return grub_sm712_read_reg (GRUB_VGA_IO_SR_DATA);
}
static inline void
grub_sm712_sr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX);
grub_sm712_write_reg (val, GRUB_VGA_IO_SR_DATA);
}
static inline void
grub_sm712_gr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_sm712_write_reg (addr, GRUB_VGA_IO_GR_INDEX);
grub_sm712_write_reg (val, GRUB_VGA_IO_GR_DATA);
}
static inline void
grub_sm712_cr_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_sm712_write_reg (addr, GRUB_VGA_IO_CR_INDEX);
grub_sm712_write_reg (val, GRUB_VGA_IO_CR_DATA);
}
static inline void
grub_sm712_write_arx (grub_uint8_t val, grub_uint8_t addr)
{
grub_sm712_read_reg (GRUB_VGA_IO_INPUT_STATUS1_REGISTER);
grub_sm712_write_reg (addr, GRUB_VGA_IO_ARX);
grub_sm712_read_reg (GRUB_VGA_IO_ARX_READ);
grub_sm712_write_reg (val, GRUB_VGA_IO_ARX);
}
static inline void
grub_sm712_cr_shadow_write (grub_uint8_t val, grub_uint8_t addr)
{
grub_uint8_t mapping[] =
{
[GRUB_VGA_CR_HTOTAL] = GRUB_SM712_CR_SHADOW_VGA_HTOTAL,
[GRUB_VGA_CR_HORIZ_END] = 0xff,
[GRUB_VGA_CR_HBLANK_START] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_START,
[GRUB_VGA_CR_HBLANK_END] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_END,
[GRUB_VGA_CR_HORIZ_SYNC_PULSE_START] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START,
[GRUB_VGA_CR_HORIZ_SYNC_PULSE_END] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END,
[GRUB_VGA_CR_VERT_TOTAL] = GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL,
[GRUB_VGA_CR_OVERFLOW] = GRUB_SM712_CR_SHADOW_VGA_OVERFLOW,
[GRUB_VGA_CR_BYTE_PANNING] = 0xff,
[GRUB_VGA_CR_CELL_HEIGHT] = GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT,
[GRUB_VGA_CR_CURSOR_START] = 0xff,
[GRUB_VGA_CR_CURSOR_END] = 0xff,
[GRUB_VGA_CR_START_ADDR_HIGH_REGISTER] = 0xff,
[GRUB_VGA_CR_START_ADDR_LOW_REGISTER] = 0xff,
[GRUB_VGA_CR_CURSOR_ADDR_HIGH] = 0xff,
[GRUB_VGA_CR_CURSOR_ADDR_LOW] = 0xff,
[GRUB_VGA_CR_VSYNC_START] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START,
[GRUB_VGA_CR_VSYNC_END] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END,
[GRUB_VGA_CR_VDISPLAY_END] = GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END,
[GRUB_VGA_CR_PITCH] = GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END,
[GRUB_VGA_CR_UNDERLINE_LOCATION] = 0xff,
[GRUB_VGA_CR_VERTICAL_BLANK_START] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_START,
[GRUB_VGA_CR_VERTICAL_BLANK_END] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_END,
[GRUB_VGA_CR_MODE] = 0xff,
[GRUB_VGA_CR_LINE_COMPARE] = 0xff
};
if (addr >= ARRAY_SIZE (mapping) || mapping[addr] == 0xff)
return;
grub_sm712_cr_write (val, mapping[addr]);
}
static inline void
grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda,
grub_uint8_t vcentering)
{
grub_sm712_cr_write (((compare << SM712_DDA_REG3_COMPARE_SHIFT)
& SM712_DDA_REG3_COMPARE_MASK)
| ((dda >> SM712_DDA_REG3_DDA_SHIFT)
& SM712_DDA_REG3_DDA_MASK),
GRUB_SM712_CR_DDA_LOOKUP_REG3_START + 2 * idx);
grub_sm712_cr_write (dda & SM712_DDA_REG2_DDA_MASK,
GRUB_SM712_CR_DDA_LOOKUP_REG2_START + 2 * idx);
grub_sm712_cr_write (vcentering & SM712_DDA_REG2_VCENTER_MASK,
GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx);
}
static grub_err_t
grub_video_sm712_setup (unsigned int width, unsigned int height,
@ -70,6 +341,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
int found = 0;
unsigned i;
#ifndef TEST
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
{
@ -79,7 +351,8 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class = grub_pci_read (addr);
if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f)
if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA
|| pciid != GRUB_SM712_PCIID)
return 0;
found = 1;
@ -103,7 +376,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
grub_pci_iterate (find_card);
if (!found)
return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
#endif
/* Fill mode info details. */
framebuffer.mode_info.width = 1024;
framebuffer.mode_info.height = 600;
@ -120,8 +393,12 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
framebuffer.mode_info.blue_field_pos = 0;
framebuffer.mode_info.reserved_mask_size = 0;
framebuffer.mode_info.reserved_field_pos = 0;
framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
#ifndef TEST
framebuffer.mode_info.blit_format
= grub_video_get_blit_format (&framebuffer.mode_info);
#endif
#ifndef TEST
if (found && framebuffer.base == 0)
{
grub_pci_address_t addr;
@ -139,47 +416,280 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND);
grub_pci_write (addr, 0x7);
}
#endif
/* We can safely discard volatile attribute. */
#ifndef TEST
framebuffer.ptr
= (void *) grub_pci_device_map_range (framebuffer.dev,
framebuffer.base,
GRUB_SM712_TOTAL_MEMORY_SPACE);
#endif
framebuffer.mapped = 1;
/* Initialise SM712. */
grub_outb (0x18, GRUB_MACHINE_PCI_IO_BASE + 0x3c4);
grub_outb (0x11, GRUB_MACHINE_PCI_IO_BASE + 0x3c5);
#ifndef TEST
/* FIXME */
grub_vga_sr_write (0x11, 0x18);
#endif
#ifndef TEST
/* Prevent garbage from appearing on the screen. */
grub_memset (framebuffer.ptr, 0,
framebuffer.mode_info.height * framebuffer.mode_info.pitch);
#endif
for (i = 0; i < ARRAY_SIZE (sm712_init); i++)
switch (sm712_init[i].directive)
/* FIXME */
grub_sm712_sr_write (0, 0x21);
grub_sm712_sr_write (0x7a, 0x62);
grub_sm712_sr_write (0x16, 0x6a);
grub_sm712_sr_write (0x2, 0x6b);
grub_sm712_write_reg (0, GRUB_VGA_IO_PIXEL_MASK);
grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC, GRUB_VGA_SR_RESET);
grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY
| GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY
| GRUB_VGA_IO_MISC_UPPER_64K
| GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0
| GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS
| GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE);
grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC | GRUB_VGA_SR_RESET_SYNC,
GRUB_VGA_SR_RESET);
grub_sm712_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK,
GRUB_VGA_SR_CLOCKING_MODE);
grub_sm712_sr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_SR_MAP_MASK_REGISTER);
grub_sm712_sr_write (0, GRUB_VGA_SR_CHAR_MAP_SELECT);
grub_sm712_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4
| GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING
| GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY,
GRUB_VGA_SR_MEMORY_MODE);
for (i = 0; i < ARRAY_SIZE (sm712_sr_seq1); i++)
grub_sm712_sr_write (sm712_sr_seq1[i], 0x10 + i);
for (i = 0; i < ARRAY_SIZE (sm712_sr_seq2); i++)
grub_sm712_sr_write (sm712_sr_seq2[i], 0x30 + i);
/* Undocumented. */
grub_sm712_sr_write (0x1a, 0x63);
/* Undocumented. */
grub_sm712_sr_write (0x1a, 0x64);
grub_sm712_sr_write (GRUB_SM712_SR_TV_CRT_SRAM | GRUB_SM712_SR_TV_ALT_CLOCK
| GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC
| GRUB_SM712_SR_TV_HSYNC,
GRUB_SM712_SR_TV_CONTROL);
grub_sm712_sr_write (GRUB_SM712_SR_RAM_LUT_NORMAL, GRUB_SM712_SR_RAM_LUT);
/* Undocumented. */
grub_sm712_sr_write (0x00, 0x67);
grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR
| GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK,
GRUB_SM712_SR_CLOCK_CONTROL1);
grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK,
GRUB_SM712_SR_CLOCK_CONTROL2);
grub_sm712_sr_write (82, GRUB_SM712_SR_VCLK_NUM);
grub_sm712_sr_write (137, GRUB_SM712_SR_VCLK_DENOM);
grub_sm712_sr_write (9, GRUB_SM712_SR_VCLK2_NUM);
grub_sm712_sr_write (2, GRUB_SM712_SR_VCLK2_DENOM);
/* FIXME */
grub_sm712_sr_write (0x04, 0x70);
/* FIXME */
grub_sm712_sr_write (0x45, 0x71);
/* Undocumented */
grub_sm712_sr_write (0x30, 0x72);
/* Undocumented */
grub_sm712_sr_write (0x30, 0x73);
/* Undocumented */
grub_sm712_sr_write (0x40, 0x74);
/* Undocumented */
grub_sm712_sr_write (0x20, 0x75);
grub_sm712_sr_write (0xff, GRUB_SM712_SR_POPUP_ICON_LOW);
grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_HIGH_MASK,
GRUB_SM712_SR_POPUP_ICON_HIGH);
grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED,
GRUB_SM712_SR_POPUP_ICON_CTRL);
/* Undocumented */
grub_sm712_sr_write (0x0, 0x83);
grub_sm712_sr_write (8, GRUB_SM712_SR_POPUP_ICON_COLOR1);
grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_COLOR2);
grub_sm712_sr_write (0x42, GRUB_SM712_SR_POPUP_ICON_COLOR3);
/* Undocumented */
grub_sm712_sr_write (0x3a, 0x87);
/* Why theese coordinates? */
grub_sm712_sr_write (0x59, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW);
grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH);
grub_sm712_sr_write (0x44, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW);
grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH);
grub_sm712_sr_write (RGB332_BLACK, GRUB_SM712_SR_HW_CURSOR_FG_COLOR);
grub_sm712_sr_write (RGB332_WHITE, GRUB_SM712_SR_HW_CURSOR_BG_COLOR);
/* Undocumented */
grub_sm712_sr_write (0x3a, 0x8e);
grub_sm712_sr_write (0x3a, 0x8f);
grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_LOW);
grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_HIGH);
grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_LOW);
grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_HIGH);
grub_sm712_sr_write (0, GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL);
grub_sm712_sr_write (0x10, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW);
grub_sm712_sr_write (0x08, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH);
grub_sm712_sr_write (0x00, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW);
grub_sm712_sr_write (0x02, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH);
grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT);
grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT);
grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT);
grub_sm712_sr_write (0x7b, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY);
grub_sm712_sr_write (0xfb, GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY);
grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY);
grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY);
/* Doesn't match documentation? */
grub_sm712_sr_write (0x97, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY);
grub_sm712_sr_write (0xef, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY);
grub_sm712_sr_write (0xbf, GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR);
grub_sm712_sr_write (0xdf, GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR);
grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE);
grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE_ENABLE);
grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_COLOR_COMPARE);
grub_sm712_gr_write (GRUB_VGA_GR_DATA_ROTATE_NOP, GRUB_VGA_GR_DATA_ROTATE);
grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_READ_MAP_REGISTER);
grub_sm712_gr_write (GRUB_VGA_GR_MODE_256_COLOR, GRUB_VGA_GR_MODE);
grub_sm712_gr_write (GRUB_VGA_GR_GR6_MMAP_A0
| GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6);
grub_sm712_gr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_GR_COLOR_COMPARE_DISABLE);
grub_sm712_gr_write (0xff, GRUB_VGA_GR_BITMASK);
/* Write palette mapping. */
for (i = 0; i < 16; i++)
grub_sm712_write_arx (i, i);
grub_sm712_write_arx (GRUB_VGA_ARX_MODE_ENABLE_256COLOR
| GRUB_VGA_ARX_MODE_GRAPHICS, GRUB_VGA_ARX_MODE);
grub_sm712_write_arx (0, GRUB_VGA_ARX_OVERSCAN);
grub_sm712_write_arx (GRUB_VGA_ALL_PLANES, GRUB_VGA_ARX_COLOR_PLANE_ENABLE);
grub_sm712_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING);
grub_sm712_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT);
/* FIXME: compute this generically. */
{
struct grub_video_hw_config config =
{
case 1:
*(volatile grub_uint8_t *) ((char *) framebuffer.ptr
+ sm712_init[i].addr) = sm712_init[i].val;
break;
case -1:
{
grub_uint8_t val = *(volatile grub_uint8_t *)
((char *) framebuffer.ptr + sm712_init[i].addr);
(void) val;
}
break;
case 2:
*(volatile grub_uint16_t *) ((char *) framebuffer.ptr
+ sm712_init[i].addr) = sm712_init[i].val;
break;
case 4:
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr
+ sm712_init[i].addr) = sm712_init[i].val;
break;
}
.vertical_total = 806,
.vertical_blank_start = 0x300,
.vertical_blank_end = 0,
.vertical_sync_start = 0x303,
.vertical_sync_end = 0x9,
.line_compare = 0x3ff,
.vdisplay_end = 0x300,
.pitch = 0x80,
.horizontal_total = 164,
.horizontal_end = 128,
.horizontal_blank_start = 128,
.horizontal_blank_end = 0,
.horizontal_sync_pulse_start = 133,
.horizontal_sync_pulse_end = 22
};
grub_vga_set_geometry (&config, grub_sm712_cr_write);
config.horizontal_sync_pulse_start = 134;
config.horizontal_sync_pulse_end = 21;
config.vertical_sync_start = 0x301;
config.vertical_sync_end = 0x0;
config.line_compare = 0x0ff;
config.vdisplay_end = 0x258;
config.pitch = 0x7f;
grub_vga_set_geometry (&config, grub_sm712_cr_shadow_write);
}
err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
grub_sm712_cr_write (GRUB_VGA_CR_BYTE_PANNING_NORMAL,
GRUB_VGA_CR_BYTE_PANNING);
grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_START);
grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_END);
grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_HIGH);
grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_LOW);
grub_sm712_cr_write (GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE,
GRUB_VGA_CR_UNDERLINE_LOCATION);
grub_sm712_cr_write (GRUB_VGA_CR_MODE_ADDRESS_WRAP
| GRUB_VGA_CR_MODE_BYTE_MODE
| GRUB_VGA_CR_MODE_TIMING_ENABLE
| GRUB_VGA_CR_MODE_NO_CGA
| GRUB_VGA_CR_MODE_NO_HERCULES,
GRUB_VGA_CR_MODE);
grub_sm712_cr_write (0, GRUB_SM712_CR_OVERFLOW_INTERLACE);
grub_sm712_cr_write (0, GRUB_SM712_CR_INTERLACE_RETRACE);
grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_START);
grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_HIGH);
grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_LOW);
grub_sm712_cr_write (0x80, GRUB_SM712_CR_DDA_CONTROL_LOW);
grub_sm712_cr_write (0x02, GRUB_SM712_CR_DDA_CONTROL_HIGH);
/* Undocumented */
grub_sm712_cr_write (0x20, 0x37);
grub_sm712_cr_write (0, GRUB_SM712_CR_TV_EQUALIZER);
grub_sm712_cr_write (0, GRUB_SM712_CR_TV_SERRATION);
grub_sm712_cr_write (0, GRUB_SM712_CR_HSYNC_CTRL);
/* Undocumented */
grub_sm712_cr_write (0x40, 0x3b);
grub_sm712_cr_write (GRUB_SM712_CR_DEBUG_NONE, GRUB_SM712_CR_DEBUG);
/* Undocumented */
grub_sm712_cr_write (0xff, 0x3d);
grub_sm712_cr_write (0x46, 0x3e);
grub_sm712_cr_write (0x91, 0x3f);
for (i = 0; i < ARRAY_SIZE (dda_lookups); i++)
grub_sm712_write_dda_lookup (i, dda_lookups[i].compare, dda_lookups[i].dda,
dda_lookups[i].vcentering);
/* Undocumented */
grub_sm712_cr_write (0, 0x9c);
grub_sm712_cr_write (0, 0x9d);
grub_sm712_cr_write (0, 0x9e);
grub_sm712_cr_write (0, 0x9f);
grub_sm712_cr_write (0, GRUB_SM712_CR_VCENTERING_OFFSET);
grub_sm712_cr_write (0, GRUB_SM712_CR_HCENTERING_OFFSET);
grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY
| GRUB_VGA_IO_MISC_UPPER_64K
| GRUB_VGA_IO_MISC_28MHZ
| GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS
| GRUB_VGA_IO_MISC_COLOR,
GRUB_VGA_IO_MISC_WRITE);
#ifndef TEST
/* Undocumented? */
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0;
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0;
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c000) = 0x20000;
*(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c010) = 0x1020100;
#endif
(void) grub_sm712_sr_read (0x16);
#ifndef TEST
err = grub_video_fb_create_render_target_from_pointer (&framebuffer
.render_target,
&framebuffer.mode_info,
framebuffer.ptr);
if (err)
return err;
@ -192,9 +702,12 @@ grub_video_sm712_setup (unsigned int width, unsigned int height,
/* Copy default palette to initialize emulated palette. */
err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_fbstd_colors);
#endif
return err;
}
#ifndef TEST
static grub_err_t
grub_video_sm712_swap_buffers (void)
{
@ -223,7 +736,6 @@ grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info,
return GRUB_ERR_NONE;
}
static struct grub_video_adapter grub_video_sm712_adapter =
{
.name = "SM712 Video Driver",
@ -266,3 +778,10 @@ GRUB_MOD_FINI(video_sm712)
{
grub_video_unregister (&grub_video_sm712_adapter);
}
#else
int
main ()
{
grub_video_sm712_setup (1024, 600, 0, 0);
}
#endif

View file

@ -1,546 +1,14 @@
/* Following sequence is a capture of sm712 initialisation sequence. */
static struct
{
int directive;
grub_uint32_t addr;
grub_uint32_t val;
} sm712_init[] =
{
{1, 0x7003c4, 0x21},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x62},
{1, 0x7003c5, 0x7a},
{1, 0x7003c4, 0x6a},
{1, 0x7003c5, 0x16},
{1, 0x7003c4, 0x6b},
{1, 0x7003c5, 0x2},
{1, 0x7003c6, 0x0},
{1, 0x7003c4, 0x0},
{1, 0x7003c5, 0x1},
{1, 0x7003c2, 0xeb},
{1, 0x7003c4, 0x0},
{1, 0x7003c5, 0x3},
{1, 0x7003c4, 0x1},
{1, 0x7003c5, 0x1},
{1, 0x7003c4, 0x2},
{1, 0x7003c5, 0xf},
{1, 0x7003c4, 0x3},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x4},
{1, 0x7003c5, 0xe},
{1, 0x7003c4, 0x10},
{1, 0x7003c5, 0xc8},
{1, 0x7003c4, 0x11},
{1, 0x7003c5, 0x40},
{1, 0x7003c4, 0x12},
{1, 0x7003c5, 0x14},
{1, 0x7003c4, 0x13},
{1, 0x7003c5, 0x60},
{1, 0x7003c4, 0x14},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x15},
{1, 0x7003c5, 0xa},
{1, 0x7003c4, 0x16},
{1, 0x7003c5, 0x92},
{1, 0x7003c4, 0x17},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x18},
{1, 0x7003c5, 0x51},
{1, 0x7003c4, 0x19},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x1a},
{1, 0x7003c5, 0x1},
{1, 0x7003c4, 0x1b},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x1c},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x1d},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x1e},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x1f},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x20},
{1, 0x7003c5, 0xc4},
{1, 0x7003c4, 0x21},
{1, 0x7003c5, 0x30},
{1, 0x7003c4, 0x22},
{1, 0x7003c5, 0x2},
{1, 0x7003c4, 0x23},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x24},
{1, 0x7003c5, 0x1},
{1, 0x7003c4, 0x30},
{1, 0x7003c5, 0x28},
{1, 0x7003c4, 0x31},
{1, 0x7003c5, 0x3},
{1, 0x7003c4, 0x32},
{1, 0x7003c5, 0x24},
{1, 0x7003c4, 0x33},
{1, 0x7003c5, 0x9},
{1, 0x7003c4, 0x34},
{1, 0x7003c5, 0xc0},
{1, 0x7003c4, 0x35},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x36},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x37},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x38},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x39},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x3a},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x3b},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x3c},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x3d},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x3e},
{1, 0x7003c5, 0x3},
{1, 0x7003c4, 0x3f},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0x40},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x41},
{1, 0x7003c5, 0xfc},
{1, 0x7003c4, 0x42},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x43},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x44},
{1, 0x7003c5, 0x20},
{1, 0x7003c4, 0x45},
{1, 0x7003c5, 0x18},
{1, 0x7003c4, 0x46},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x47},
{1, 0x7003c5, 0xfc},
{1, 0x7003c4, 0x48},
{1, 0x7003c5, 0x20},
{1, 0x7003c4, 0x49},
{1, 0x7003c5, 0xc},
{1, 0x7003c4, 0x4a},
{1, 0x7003c5, 0x44},
{1, 0x7003c4, 0x4b},
{1, 0x7003c5, 0x20},
{1, 0x7003c4, 0x4c},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x4d},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x4e},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x4f},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x50},
{1, 0x7003c5, 0x6},
{1, 0x7003c4, 0x51},
{1, 0x7003c5, 0x68},
{1, 0x7003c4, 0x52},
{1, 0x7003c5, 0xa7},
{1, 0x7003c4, 0x53},
{1, 0x7003c5, 0x7f},
{1, 0x7003c4, 0x54},
{1, 0x7003c5, 0x83},
{1, 0x7003c4, 0x55},
{1, 0x7003c5, 0x24},
{1, 0x7003c4, 0x56},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0x57},
{1, 0x7003c5, 0x3},
{1, 0x7003c4, 0x58},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x59},
{1, 0x7003c5, 0x60},
{1, 0x7003c4, 0x5a},
{1, 0x7003c5, 0x59},
{1, 0x7003c4, 0x5b},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x5c},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x5d},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x5e},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x5f},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x60},
{1, 0x7003c5, 0x1},
{1, 0x7003c4, 0x61},
{1, 0x7003c5, 0x80},
{1, 0x7003c4, 0x63},
{1, 0x7003c5, 0x1a},
{1, 0x7003c4, 0x64},
{1, 0x7003c5, 0x1a},
{1, 0x7003c4, 0x65},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x66},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x67},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x68},
{1, 0x7003c5, 0x50},
{1, 0x7003c4, 0x69},
{1, 0x7003c5, 0x3},
{1, 0x7003c4, 0x6c},
{1, 0x7003c5, 0x52},
{1, 0x7003c4, 0x6d},
{1, 0x7003c5, 0x89},
{1, 0x7003c4, 0x6e},
{1, 0x7003c5, 0x9},
{1, 0x7003c4, 0x6f},
{1, 0x7003c5, 0x2},
{1, 0x7003c4, 0x70},
{1, 0x7003c5, 0x4},
{1, 0x7003c4, 0x71},
{1, 0x7003c5, 0x45},
{1, 0x7003c4, 0x72},
{1, 0x7003c5, 0x30},
{1, 0x7003c4, 0x73},
{1, 0x7003c5, 0x30},
{1, 0x7003c4, 0x74},
{1, 0x7003c5, 0x40},
{1, 0x7003c4, 0x75},
{1, 0x7003c5, 0x20},
{1, 0x7003c4, 0x80},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0x81},
{1, 0x7003c5, 0x7},
{1, 0x7003c4, 0x82},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x83},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x84},
{1, 0x7003c5, 0x8},
{1, 0x7003c4, 0x85},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x86},
{1, 0x7003c5, 0x42},
{1, 0x7003c4, 0x87},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x88},
{1, 0x7003c5, 0x59},
{1, 0x7003c4, 0x89},
{1, 0x7003c5, 0x2},
{1, 0x7003c4, 0x8a},
{1, 0x7003c5, 0x44},
{1, 0x7003c4, 0x8b},
{1, 0x7003c5, 0x2},
{1, 0x7003c4, 0x8c},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x8d},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0x8e},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x8f},
{1, 0x7003c5, 0x3a},
{1, 0x7003c4, 0x90},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x91},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x92},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0x93},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0xa0},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0xa1},
{1, 0x7003c5, 0x10},
{1, 0x7003c4, 0xa2},
{1, 0x7003c5, 0x8},
{1, 0x7003c4, 0xa3},
{1, 0x7003c5, 0x0},
{1, 0x7003c4, 0xa4},
{1, 0x7003c5, 0x2},
{1, 0x7003c4, 0xa5},
{1, 0x7003c5, 0xed},
{1, 0x7003c4, 0xa6},
{1, 0x7003c5, 0xed},
{1, 0x7003c4, 0xa7},
{1, 0x7003c5, 0xed},
{1, 0x7003c4, 0xa8},
{1, 0x7003c5, 0x7b},
{1, 0x7003c4, 0xa9},
{1, 0x7003c5, 0xfb},
{1, 0x7003c4, 0xaa},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0xab},
{1, 0x7003c5, 0xff},
{1, 0x7003c4, 0xac},
{1, 0x7003c5, 0x97},
{1, 0x7003c4, 0xad},
{1, 0x7003c5, 0xef},
{1, 0x7003c4, 0xae},
{1, 0x7003c5, 0xbf},
{1, 0x7003c4, 0xaf},
{1, 0x7003c5, 0xdf},
{1, 0x7003ce, 0x0},
{1, 0x7003cf, 0x0},
{1, 0x7003ce, 0x1},
{1, 0x7003cf, 0x0},
{1, 0x7003ce, 0x2},
{1, 0x7003cf, 0x0},
{1, 0x7003ce, 0x3},
{1, 0x7003cf, 0x0},
{1, 0x7003ce, 0x4},
{1, 0x7003cf, 0x0},
{1, 0x7003ce, 0x5},
{1, 0x7003cf, 0x40},
{1, 0x7003ce, 0x6},
{1, 0x7003cf, 0x5},
{1, 0x7003ce, 0x7},
{1, 0x7003cf, 0xf},
{1, 0x7003ce, 0x8},
{1, 0x7003cf, 0xff},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x0},
{-1, 0x7003c1, 0x3e},
{1, 0x7003c0, 0x0},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x1},
{-1, 0x7003c1, 0x3b},
{1, 0x7003c0, 0x1},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x2},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0x2},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x3},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0x3},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x4},
{-1, 0x7003c1, 0x3b},
{1, 0x7003c0, 0x4},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x5},
{-1, 0x7003c1, 0x2f},
{1, 0x7003c0, 0x5},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x6},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0x6},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x7},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0x7},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x8},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0x8},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x9},
{-1, 0x7003c1, 0x3d},
{1, 0x7003c0, 0x9},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xa},
{-1, 0x7003c1, 0x1f},
{1, 0x7003c0, 0xa},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xb},
{-1, 0x7003c1, 0x1f},
{1, 0x7003c0, 0xb},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xc},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0xc},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xd},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0xd},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xe},
{-1, 0x7003c1, 0x3f},
{1, 0x7003c0, 0xe},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0xf},
{-1, 0x7003c1, 0x2e},
{1, 0x7003c0, 0xf},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x10},
{-1, 0x7003c1, 0x0},
{1, 0x7003c0, 0x41},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x11},
{-1, 0x7003c1, 0x0},
{1, 0x7003c0, 0x0},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x12},
{-1, 0x7003c1, 0x0},
{1, 0x7003c0, 0xf},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x13},
{-1, 0x7003c1, 0x0},
{1, 0x7003c0, 0x0},
{-1, 0x7003da, 0x5},
{1, 0x7003c0, 0x14},
{-1, 0x7003c1, 0x0},
{1, 0x7003c0, 0x0},
{1, 0x7003d4, 0x0},
{1, 0x7003d5, 0xa3},
{1, 0x7003d4, 0x1},
{1, 0x7003d5, 0x7f},
{1, 0x7003d4, 0x2},
{1, 0x7003d5, 0x7f},
{1, 0x7003d4, 0x3},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x4},
{1, 0x7003d5, 0x85},
{1, 0x7003d4, 0x5},
{1, 0x7003d5, 0x16},
{1, 0x7003d4, 0x6},
{1, 0x7003d5, 0x24},
{1, 0x7003d4, 0x7},
{1, 0x7003d5, 0xf5},
{1, 0x7003d4, 0x8},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x9},
{1, 0x7003d5, 0x60},
{1, 0x7003d4, 0xa},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xb},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xc},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xd},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xe},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xf},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x10},
{1, 0x7003d5, 0x3},
{1, 0x7003d4, 0x11},
{1, 0x7003d5, 0x9},
{1, 0x7003d4, 0x12},
{1, 0x7003d5, 0xff},
{1, 0x7003d4, 0x13},
{1, 0x7003d5, 0x80},
{1, 0x7003d4, 0x14},
{1, 0x7003d5, 0x40},
{1, 0x7003d4, 0x15},
{1, 0x7003d5, 0xff},
{1, 0x7003d4, 0x16},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x17},
{1, 0x7003d5, 0xe3},
{1, 0x7003d4, 0x18},
{1, 0x7003d5, 0xff},
{1, 0x7003d4, 0x30},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x31},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x32},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x33},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x34},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x35},
{1, 0x7003d5, 0x80},
{1, 0x7003d4, 0x36},
{1, 0x7003d5, 0x2},
{1, 0x7003d4, 0x37},
{1, 0x7003d5, 0x20},
{1, 0x7003d4, 0x38},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x39},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x3a},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x3b},
{1, 0x7003d5, 0x40},
{1, 0x7003d4, 0x3c},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x3d},
{1, 0x7003d5, 0xff},
{1, 0x7003d4, 0x3e},
{1, 0x7003d5, 0x46},
{1, 0x7003d4, 0x3f},
{1, 0x7003d5, 0x91},
{1, 0x7003d4, 0x40},
{1, 0x7003d5, 0xa3},
{1, 0x7003d4, 0x41},
{1, 0x7003d5, 0x7f},
{1, 0x7003d4, 0x42},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x43},
{1, 0x7003d5, 0x86},
{1, 0x7003d4, 0x44},
{1, 0x7003d5, 0x15},
{1, 0x7003d4, 0x45},
{1, 0x7003d5, 0x24},
{1, 0x7003d4, 0x46},
{1, 0x7003d5, 0xff},
{1, 0x7003d4, 0x47},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x48},
{1, 0x7003d5, 0x1},
{1, 0x7003d4, 0x49},
{1, 0x7003d5, 0x7},
{1, 0x7003d4, 0x4a},
{1, 0x7003d5, 0xe5},
{1, 0x7003d4, 0x4b},
{1, 0x7003d5, 0x20},
{1, 0x7003d4, 0x4c},
{1, 0x7003d5, 0x7f},
{1, 0x7003d4, 0x4d},
{1, 0x7003d5, 0x57},
{1, 0x7003d4, 0x90},
{1, 0x7003d5, 0x55},
{1, 0x7003d4, 0x91},
{1, 0x7003d5, 0xd5},
{1, 0x7003d4, 0x92},
{1, 0x7003d5, 0x5d},
{1, 0x7003d4, 0x93},
{1, 0x7003d5, 0xdd},
{1, 0x7003d4, 0x94},
{1, 0x7003d5, 0x86},
{1, 0x7003d4, 0x95},
{1, 0x7003d5, 0x17},
{1, 0x7003d4, 0x96},
{1, 0x7003d5, 0x8e},
{1, 0x7003d4, 0x97},
{1, 0x7003d5, 0xaa},
{1, 0x7003d4, 0x98},
{1, 0x7003d5, 0x8a},
{1, 0x7003d4, 0x99},
{1, 0x7003d5, 0xa3},
{1, 0x7003d4, 0x9a},
{1, 0x7003d5, 0xde},
{1, 0x7003d4, 0x9b},
{1, 0x7003d5, 0xab},
{1, 0x7003d4, 0x9c},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x9d},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x9e},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0x9f},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xa0},
{1, 0x7003d5, 0x2},
{1, 0x7003d4, 0xa1},
{1, 0x7003d5, 0x2},
{1, 0x7003d4, 0xa2},
{1, 0x7003d5, 0x2},
{1, 0x7003d4, 0xa3},
{1, 0x7003d5, 0x15},
{1, 0x7003d4, 0xa4},
{1, 0x7003d5, 0x2},
{1, 0x7003d4, 0xa5},
{1, 0x7003d5, 0x6},
{1, 0x7003d4, 0xa6},
{1, 0x7003d5, 0x0},
{1, 0x7003d4, 0xa7},
{1, 0x7003d5, 0x0},
{1, 0x7003c2, 0x67},
{4, 0x40c00c, 0x0},
{4, 0x40c040, 0x0},
{4, 0x40c000, 0x20000},
{4, 0x40c010, 0x1020100},
{1, 0x7003c4, 0x16},
{-1, 0x7003c5, 0x17}
};
static grub_uint8_t sm712_sr_seq1[] =
{ 0xc8, 0x40, 0x14, 0x60, 0x0, 0xa, 0x92, 0x0,
0x51, 0x00, 0x01, 0x00, 0x0, 0x0, 0x00, 0x0,
0xc4, 0x30, 0x02, 0x00, 0x1 };
static grub_uint8_t sm712_sr_seq2[] =
{ 0x28, 0x03, 0x24, 0x09, 0xc0, 0x3a, 0x3a, 0x3a,
0x3a, 0x3a, 0x3a, 0x3a, 0x00, 0x00, 0x03, 0xff,
0x00, 0xfc, 0x00, 0x00, 0x20, 0x18, 0x00, 0xfc,
0x20, 0x0c, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3a,
0x06, 0x68, 0xa7, 0x7f, 0x83, 0x24, 0xff, 0x03,
0x00, 0x60, 0x59, 0x3a, 0x3a, 0x00, 0x00, 0x3a,
0x01, 0x80 };