From 548947916b74f8b4b66f88a4cf08b233fd31047c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 28 Jun 2011 17:05:41 +0100 Subject: [PATCH 1/3] * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use default_bg_color rather than black. (grub_gfxterm_fullscreen): Likewise. (grub_gfxterm_background_color_cmd): Save new background color in default_bg_color. --- ChangeLog | 8 ++++++++ grub-core/term/gfxterm.c | 16 +++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81d98716d..4b8d8f149 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-06-28 Colin Watson + + * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use + default_bg_color rather than black. + (grub_gfxterm_fullscreen): Likewise. + (grub_gfxterm_background_color_cmd): Save new background color in + default_bg_color. + 2011-06-27 Vladimir Serbinenko * grub-core/Makefile.core.def (chain): Fix coreboot filename. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 9e3d8eeb1..2f8deac18 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -131,6 +131,7 @@ static unsigned int bitmap_width; static unsigned int bitmap_height; static struct grub_video_bitmap *bitmap; static int blend_text_bg; +static grub_video_rgba_color_t default_bg_color = { 0, 0, 0, 0 }; static struct grub_dirty_region dirty_region; @@ -266,7 +267,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, grub_video_set_active_render_target (render_target); - virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0); + virtual_screen.bg_color_display = + grub_video_map_rgba_color (default_bg_color); /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) @@ -338,8 +340,8 @@ grub_gfxterm_fullscreen (void) double_redraw = mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - /* Make sure screen is black. */ - color = grub_video_map_rgb (0, 0, 0); + /* Make sure screen is set to the default background color. */ + color = grub_video_map_rgba_color (default_bg_color); grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); if (double_redraw) { @@ -1189,7 +1191,6 @@ static grub_err_t grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - grub_video_rgba_color_t color; struct grub_video_render_target *old_target; if (argc != 1) @@ -1199,7 +1200,7 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), if (grub_video_get_info (NULL) != GRUB_ERR_NONE) return grub_errno; - if (grub_video_parse_color (args[0], &color) != GRUB_ERR_NONE) + if (grub_video_parse_color (args[0], &default_bg_color) != GRUB_ERR_NONE) return grub_errno; /* Destroy existing background bitmap if loaded. */ @@ -1216,9 +1217,10 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), compatible with the text layer. */ grub_video_get_active_render_target (&old_target); grub_video_set_active_render_target (text_layer); - virtual_screen.bg_color = grub_video_map_rgba_color (color); + virtual_screen.bg_color = grub_video_map_rgba_color (default_bg_color); grub_video_set_active_render_target (old_target); - virtual_screen.bg_color_display = grub_video_map_rgba_color (color); + virtual_screen.bg_color_display = + grub_video_map_rgba_color (default_bg_color); blend_text_bg = 1; /* Mark whole screen as dirty. */ From 77546584e1466b4702a60b83df674ca4337b2627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 2 Jul 2011 21:22:19 +0200 Subject: [PATCH 2/3] Use @PACKAGE@ instead of hardcoded name when sourcing grub-mkconfig_lib. --- ChangeLog | 14 ++++++++++++++ util/grub-mkconfig.in | 2 +- util/grub.d/00_header.in | 2 +- util/grub.d/10_hurd.in | 2 +- util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- util/grub.d/10_netbsd.in | 2 +- util/grub.d/10_windows.in | 2 +- util/grub.d/20_linux_xen.in | 2 +- util/grub.d/30_os-prober.in | 2 +- util/update-grub_lib.in | 2 +- 11 files changed, 24 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b8d8f149..e091265d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-07-02 Grégoire Sutre + + * util/grub-mkconfig.in: Use @PACKAGE@ instead of hardcoded name when + sourcing grub-mkconfig_lib. + * util/update-grub_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + 2011-06-28 Colin Watson * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 4d627c057..cf94d1065 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -95,7 +95,7 @@ do esac done -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib if [ "x$EUID" = "x" ] ; then EUID=`id -u` diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 9da1511f5..7b8871d4d 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -25,7 +25,7 @@ libdir=@libdir@ locale_dir=`echo ${GRUB_PREFIX}/locale | sed ${transform}` grub_lang=`echo $LANG | cut -d . -f 1` -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib # Do this as early as possible, since other commands might depend on it. # (e.g. the `loadfont' command might need lvm or raid modules) diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8c54eab97..9ca01f0a8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -20,7 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib CLASS="--class gnu --class os" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 3600c74f9..2ade4ea35 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 1d1eb403f..97e7c6523 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index ffd31ad93..c257aeb3c 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index fd068dd2d..941267a9f 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -20,7 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib case "`uname 2>/dev/null`" in CYGWIN*) ;; diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 083391c40..c0b255598 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index d9d4b0a96..c0b5d7cd7 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then exit 0 diff --git a/util/update-grub_lib.in b/util/update-grub_lib.in index 998452e67..430ce1308 100644 --- a/util/update-grub_lib.in +++ b/util/update-grub_lib.in @@ -18,6 +18,6 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib grub_warn "update-grub_lib is deprecated, use grub-mkconfig_lib instead" From a07a81b33550ed050cbd70b18f8eb0d9177559fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 20:24:20 +0200 Subject: [PATCH 3/3] CMOS support on sparc. * gentpl.py (cmos): Add powerpc and sparc. * grub-core/Makefile.core.def (datetime): Add lib/ieee1275/cmos.c on powerpc and sparc. * grub-core/lib/cmos_datetime.c (grub_get_datetime) [__powerpc__ || __sparc__]: Rename to grub_get_datetime_cmos. (grub_set_datetime) [__powerpc__ || __sparc__]: Likewise to grub_set_datetime_cmos. * grub-core/lib/ieee1275/cmos.c: New file. * grub-core/lib/ieee1275/datetime.c (no_ieee1275_rtc): New vaiable. (find_rtc): Set no_ieee1275_rtc on error. (grub_get_datetime): Call grub_get_datetime_cmos on error. (grub_set_datetime): Call grub_set_datetime_cmos on error. * include/grub/cmos.h (grub_cmos_read): Return grub_err_t since it may fail. Move value to argument. All users updated (grub_cmos_write): Likewise. (grub_cmos_read) [__powerpc__ || __sparc__]: Rewritten. (grub_cmos_write) [__powerpc__ || __sparc__]: Likewise. * include/grub/datetime.h [__powerpc__ || __sparc__]: Declare grub_get_datetime_cmos and grub_set_datetime_cmos. --- ChangeLog | 24 ++++++++++ gentpl.py | 4 +- grub-core/Makefile.core.def | 3 ++ grub-core/commands/i386/cmostest.c | 14 ++++-- grub-core/lib/cmos_datetime.c | 68 ++++++++++++++++++++------- grub-core/lib/ieee1275/cmos.c | 75 ++++++++++++++++++++++++++++++ grub-core/lib/ieee1275/datetime.c | 14 +++++- include/grub/cmos.h | 48 +++++++++++++++++-- include/grub/datetime.h | 7 +++ 9 files changed, 231 insertions(+), 26 deletions(-) create mode 100644 grub-core/lib/ieee1275/cmos.c diff --git a/ChangeLog b/ChangeLog index e091265d4..694a97972 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2011-07-05 Vladimir Serbinenko + + CMOS support on sparc. + + * gentpl.py (cmos): Add powerpc and sparc. + * grub-core/Makefile.core.def (datetime): Add lib/ieee1275/cmos.c on + powerpc and sparc. + * grub-core/lib/cmos_datetime.c (grub_get_datetime) + [__powerpc__ || __sparc__]: Rename to grub_get_datetime_cmos. + (grub_set_datetime) [__powerpc__ || __sparc__]: Likewise to + grub_set_datetime_cmos. + * grub-core/lib/ieee1275/cmos.c: New file. + * grub-core/lib/ieee1275/datetime.c (no_ieee1275_rtc): New vaiable. + (find_rtc): Set no_ieee1275_rtc on error. + (grub_get_datetime): Call grub_get_datetime_cmos on error. + (grub_set_datetime): Call grub_set_datetime_cmos on error. + * include/grub/cmos.h (grub_cmos_read): Return grub_err_t since it may + fail. Move value to argument. All users updated + (grub_cmos_write): Likewise. + (grub_cmos_read) [__powerpc__ || __sparc__]: Rewritten. + (grub_cmos_write) [__powerpc__ || __sparc__]: Likewise. + * include/grub/datetime.h [__powerpc__ || __sparc__]: Declare + grub_get_datetime_cmos and grub_set_datetime_cmos. + 2011-07-02 Grégoire Sutre * util/grub-mkconfig.in: Use @PACKAGE@ instead of hardcoded name when diff --git a/gentpl.py b/gentpl.py index 6e2df076b..31cde1e81 100644 --- a/gentpl.py +++ b/gentpl.py @@ -30,7 +30,9 @@ GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") # Groups based on hardware features -GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", + "sparc64_ieee1275", "powerpc_ieee1275"] +GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] GROUPS["usb"] = GROUPS["pci"] diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fd69e9c22..16c940c61 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1192,6 +1192,9 @@ module = { efi = lib/efi/datetime.c; sparc64_ieee1275 = lib/ieee1275/datetime.c; powerpc_ieee1275 = lib/ieee1275/datetime.c; + sparc64_ieee1275 = lib/ieee1275/cmos.c; + powerpc_ieee1275 = lib/ieee1275/cmos.c; + mips_arc = lib/arc/datetime.c; enable = noemu; }; diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index c79bd0387..6439159bd 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -46,12 +46,17 @@ grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), { int byte, bit; grub_err_t err; + grub_uint8_t value; err = parse_args (argc, argv, &byte, &bit); if (err) return err; - if (grub_cmos_read (byte) & (1 << bit)) + err = grub_cmos_read (byte, &value); + if (err) + return err; + + if (value & (1 << bit)) return GRUB_ERR_NONE; return grub_error (GRUB_ERR_TEST_FAILURE, "false"); @@ -63,13 +68,16 @@ grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)), { int byte, bit; grub_err_t err; + grub_uint8_t value; err = parse_args (argc, argv, &byte, &bit); + if (err) + return err; + err = grub_cmos_read (byte, &value); if (err) return err; - grub_cmos_write (byte, grub_cmos_read (byte) & (~(1 << bit))); - return GRUB_ERR_NONE; + return grub_cmos_write (byte, value & (~(1 << bit))); } static grub_command_t cmd, cmd_clean; diff --git a/grub-core/lib/cmos_datetime.c b/grub-core/lib/cmos_datetime.c index 73c5a03c0..86cd91180 100644 --- a/grub-core/lib/cmos_datetime.c +++ b/grub-core/lib/cmos_datetime.c @@ -23,30 +23,44 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#if !defined (__powerpc__) && !defined (__sparc__) +#define grub_get_datetime_cmos grub_get_datetime +#define grub_set_datetime_cmos grub_set_datetime +#endif + grub_err_t -grub_get_datetime (struct grub_datetime *datetime) +grub_get_datetime_cmos (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; + grub_err_t err; - flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); + if (err) + return err; is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); - value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR); + err = grub_cmos_read (GRUB_CMOS_INDEX_YEAR, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); datetime->year = value; datetime->year += (value < 80) ? 2000 : 1900; - value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH); + err = grub_cmos_read (GRUB_CMOS_INDEX_MONTH, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); datetime->month = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH); + err = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); @@ -54,7 +68,9 @@ grub_get_datetime (struct grub_datetime *datetime) is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR); - value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR); + err = grub_cmos_read (GRUB_CMOS_INDEX_HOUR, &value); + if (err) + return err; if (is_12hour) { is_12hour = (value & 0x80); @@ -71,13 +87,18 @@ grub_get_datetime (struct grub_datetime *datetime) datetime->hour = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE); + err = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE, &value); + if (err) + return err; + if (is_bcd) value = grub_bcd_to_num (value); datetime->minute = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND); + err = grub_cmos_read (GRUB_CMOS_INDEX_SECOND, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); @@ -87,12 +108,15 @@ grub_get_datetime (struct grub_datetime *datetime) } grub_err_t -grub_set_datetime (struct grub_datetime *datetime) +grub_set_datetime_cmos (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; + grub_err_t err; - flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); + if (err) + return err; is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); @@ -102,21 +126,27 @@ grub_set_datetime (struct grub_datetime *datetime) if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); + if (err) + return err; value = datetime->month; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); + if (err) + return err; value = datetime->day; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); + if (err) + return err; value = datetime->hour; @@ -138,21 +168,27 @@ grub_set_datetime (struct grub_datetime *datetime) if (is_12hour) value |= 0x80; - grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); + if (err) + return err; value = datetime->minute; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); + if (err) + return err; value = datetime->second; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); + if (err) + return err; return 0; } diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c new file mode 100644 index 000000000..fa57db9e7 --- /dev/null +++ b/grub-core/lib/ieee1275/cmos.c @@ -0,0 +1,75 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 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 . + */ + +#include +#include +#include +#include +#include + +volatile grub_uint8_t *grub_cmos_port = 0; +grub_err_t +grub_cmos_find_port (void) +{ + auto int hook (struct grub_ieee1275_devalias *alias); + int hook (struct grub_ieee1275_devalias *alias) + { + grub_ieee1275_phandle_t dev; + grub_uint32_t addr[2]; + grub_ssize_t actual; + /* Enough to check if it's "m5819" */ + char compat[100]; + if (grub_ieee1275_finddevice (alias->path, &dev)) + return 0; + if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat), + 0)) + return 0; + if (grub_strcmp (compat, "m5819") != 0) + return 0; + if (grub_ieee1275_get_integer_property (dev, "address", + addr, sizeof (addr), &actual)) + return 0; + if (actual == 4) + { + grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0]; + return 1; + } + +#if GRUB_CPU_SIZEOF_VOID_P == 8 + if (actual == 8) + { + grub_cmos_port = (volatile grub_uint8_t *) + ((((grub_addr_t) addr[0]) << 32) | addr[1]); + return 1; + } +#else + if (actual == 8 && addr[0] == 0) + { + grub_cmos_port = (volatile grub_uint8_t *) addr[1]; + return 1; + } +#endif + return 0; + } + + grub_ieee1275_devices_iterate (hook); + if (!grub_cmos_port) + return grub_error (GRUB_ERR_IO, "no cmos found"); + + return GRUB_ERR_NONE; +} diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c index 4105c639b..1947135fe 100644 --- a/grub-core/lib/ieee1275/datetime.c +++ b/grub-core/lib/ieee1275/datetime.c @@ -21,10 +21,14 @@ #include #include #include +#if defined (__powerpc__) || defined (__sparc__) +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); static char *rtc = 0; +static int no_ieee1275_rtc = 0; static void find_rtc (void) @@ -42,6 +46,8 @@ find_rtc (void) } grub_ieee1275_devices_iterate (hook); + if (!rtc) + no_ieee1275_rtc = 1; } grub_err_t @@ -64,10 +70,12 @@ grub_get_datetime (struct grub_datetime *datetime) int status; grub_ieee1275_ihandle_t ihandle; + if (no_ieee1275_rtc) + return grub_get_datetime_cmos (datetime); if (!rtc) find_rtc (); if (!rtc) - return grub_error (GRUB_ERR_IO, "no RTC found"); + return grub_get_datetime_cmos (datetime); status = grub_ieee1275_open (rtc, &ihandle); if (status == -1) @@ -114,10 +122,12 @@ grub_set_datetime (struct grub_datetime *datetime) int status; grub_ieee1275_ihandle_t ihandle; + if (no_ieee1275_rtc) + return grub_set_datetime_cmos (datetime); if (!rtc) find_rtc (); if (!rtc) - return grub_error (GRUB_ERR_IO, "no RTC found"); + return grub_set_datetime_cmos (datetime); status = grub_ieee1275_open (rtc, &ihandle); if (status == -1) diff --git a/include/grub/cmos.h b/include/grub/cmos.h index f508e3bf6..331513cd7 100644 --- a/include/grub/cmos.h +++ b/include/grub/cmos.h @@ -20,8 +20,10 @@ #define GRUB_CMOS_H 1 #include +#if !defined (__powerpc__) && !defined (__sparc__) #include #include +#endif #define GRUB_CMOS_INDEX_SECOND 0 #define GRUB_CMOS_INDEX_SECOND_ALARM 1 @@ -55,18 +57,56 @@ grub_num_to_bcd (grub_uint8_t a) return (((a / 10) << 4) + (a % 10)); } -static inline grub_uint8_t -grub_cmos_read (grub_uint8_t index) +#if !defined (__powerpc__) && !defined (__sparc__) +static inline grub_err_t +grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) { grub_outb (index, GRUB_CMOS_ADDR_REG); - return grub_inb (GRUB_CMOS_DATA_REG); + *val = grub_inb (GRUB_CMOS_DATA_REG); + return GRUB_ERR_NONE; } -static inline void +static inline grub_err_t grub_cmos_write (grub_uint8_t index, grub_uint8_t value) { grub_outb (index, GRUB_CMOS_ADDR_REG); grub_outb (value, GRUB_CMOS_DATA_REG); + return GRUB_ERR_NONE; +} +#else +grub_err_t grub_cmos_find_port (void); +extern volatile grub_uint8_t *grub_cmos_port; + +static inline grub_err_t +grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) +{ + if (!grub_cmos_port) + { + grub_err_t err; + err = grub_cmos_find_port (); + if (err) + return err; + } + grub_cmos_port[0] = index; + *val = grub_cmos_port[1]; + return GRUB_ERR_NONE; } +static inline grub_err_t +grub_cmos_write (grub_uint8_t index, grub_uint8_t val) +{ + if (!grub_cmos_port) + { + grub_err_t err; + err = grub_cmos_find_port (); + if (err) + return err; + } + grub_cmos_port[0] = index; + grub_cmos_port[1] = val; + return GRUB_ERR_NONE; +} + +#endif + #endif /* GRUB_CMOS_H */ diff --git a/include/grub/datetime.h b/include/grub/datetime.h index c20fc8c36..dea0f8ea9 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -125,4 +125,11 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) return 1; } +#if defined (__powerpc__) || defined (__sparc__) +grub_err_t +grub_get_datetime_cmos (struct grub_datetime *datetime); +grub_err_t +grub_set_datetime_cmos (struct grub_datetime *datetime); +#endif + #endif /* ! KERNEL_DATETIME_HEADER */