Bean <[EMAIL PROTECTED]> writes: > On Mon, Aug 11, 2008 at 2:04 AM, Marco Gerards <[EMAIL PROTECTED]> wrote: >> Hi, >> >> Bean <[EMAIL PROTECTED]> writes: >> >>> I implement this command for grub4dos some time ago, now it's ported to >>> grub2. >>> >>> Usage: >>> >>> checktime min hour day_of_month month day_of_week >> >> Personally I would prefer it if it worked a bit more GRUB2/bash like. >> So can you make this variables? >> >> For example: >> >> if ($WEEKDAY = Sunday); then >> ... >> fi >> >> The same can be done for all week number, day number, year, etc, etc. >> >> The advantage of this is that many users are familiar with such syntax >> and it will give them more control. Furthermore, this is what I >> intended with the scripting support in the first place. So can you >> please follow such scheme? > > Hi, > > As suggested by marco, this patch replaces the crontab command with > variable hook. Now you can retrive current date/time with variable > $YEAR, $MONTH, $DAY, $HOUR, $MINUTE, $SECOND and $WEEKDAY. > > 2008-08-11 Bean <[EMAIL PROTECTED]> > > * conf/i386-pc.rmk (pkglib_MODULES): Add datetime.mod and date.mod. > (datetime_mod_SOURCES): New macro. > (datetime_mod_CFLAGS): Likewise. > (datetime_mod_LDFLAGS): Likewise. > (date_mod_SOURCES): Likewise. > (date_mod_CFLAGS): Likewise. > (date_mod_LDFLAGS): Likewise. > > * conf/i386-coreboot.rmk (pkglib_MODULES): Add datetime.mod and > date.mod. > (datetime_mod_SOURCES): New macro. > (datetime_mod_CFLAGS): Likewise. > (datetime_mod_LDFLAGS): Likewise. > (date_mod_SOURCES): Likewise. > (date_mod_CFLAGS): Likewise. > (date_mod_LDFLAGS): Likewise. > > * conf/i386-ieee1275.rmk (pkglib_MODULES): Add datetime.mod and > date.mod. > (datetime_mod_SOURCES): New macro. > (datetime_mod_CFLAGS): Likewise. > (datetime_mod_LDFLAGS): Likewise. > (date_mod_SOURCES): Likewise. > (date_mod_CFLAGS): Likewise. > (date_mod_LDFLAGS): Likewise. > > * conf/i386-efi.rmk (pkglib_MODULES): Add datetime.mod and date.mod. > (datetime_mod_SOURCES): New macro. > (datetime_mod_CFLAGS): Likewise. > (datetime_mod_LDFLAGS): Likewise. > (date_mod_SOURCES): Likewise. > (date_mod_CFLAGS): Likewise. > (date_mod_LDFLAGS): Likewise. > > * conf/x86_64-efi.rmk (pkglib_MODULES): Add datetime.mod and date.mod. > (datetime_mod_SOURCES): New macro. > (datetime_mod_CFLAGS): Likewise. > (datetime_mod_LDFLAGS): Likewise. > (date_mod_SOURCES): Likewise. > (date_mod_CFLAGS): Likewise. > (date_mod_LDFLAGS): Likewise.
Robert is right, we need an i386.rmk or similar file. > * commands/date.c: New file. > > * commands/datetime.c: Likewise. This is not a command. But I do not really know a good place for this module... > * include/grub/datetime.h: Likewise. > > * include/grub/i386/cmos.h: Likewise. > > * kern/i386/datetime.c: Likewise. > > * kern/efi/datetime.c: Likewise. Does this really belong in the kernel? You created lib/ (which I still not might agree with, but ok ;)). But that might be a better place than here. > -- > Bean > > diff --git a/commands/date.c b/commands/date.c > new file mode 100644 > index 0000000..1e11e61 > --- /dev/null > +++ b/commands/date.c > @@ -0,0 +1,124 @@ > +/* date.c - command to display/set current datetime. */ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/normal.h> > +#include <grub/dl.h> > +#include <grub/arg.h> > +#include <grub/err.h> > +#include <grub/misc.h> > +#include <grub/datetime.h> > + > +static grub_err_t > +grub_cmd_date (struct grub_arg_list *state __attribute__ ((unused)), > + int argc, char **args) > +{ > + struct grub_datetime datetime; > + int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, > 59}}; > + int value[6], mask; > + > + if (argc == 0) > + { > + if (grub_get_datetime (&datetime)) > + return grub_errno; > + > + grub_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n", > + datetime.year, datetime.month, datetime.day, > + datetime.hour, datetime.minute, datetime.second, > + grub_get_weekday_name (&datetime)); > + > + return 0; > + } Can you somehow use the argument parser here? This will give us --help for free :-) > + grub_memset (&value, 0, sizeof (value)); > + mask = 0; > + > + for (; argc; argc--, args++) > + { > + char *p, c; > + int m1, ofs, n, cur_mask; > + > + p = args[0]; > + m1 = grub_strtoul (p, &p, 10); > + > + c = *p; > + if (c == '-') > + ofs = 0; > + else if (c == ':') > + ofs = 3; > + else > + goto fail; > + > + value[ofs] = m1; > + cur_mask = (1 << ofs); > + mask &= ~(cur_mask * (1 + 2 + 4)); > + > + for (n = 1; (n < 3) && (*p); n++) > + { > + if (*p != c) > + goto fail; > + > + value[ofs + n] = grub_strtoul (p + 1, &p, 10); > + cur_mask |= (1 << (ofs + n)); > + } > + > + if (*p) > + goto fail; > + > + if ((ofs == 0) && (n == 2)) > + { > + value[ofs + 2] = value[ofs + 1]; > + value[ofs + 1] = value[ofs]; > + ofs++; > + cur_mask <<= 1; > + } > + > + for (; n; n--, ofs++) > + if ((value [ofs] < limit[ofs][0]) || > + (value [ofs] > limit[ofs][1])) > + goto fail; > + > + mask |= cur_mask; > + } > + > + datetime.year = value[0]; > + datetime.month = value[1]; > + datetime.day = value[2]; > + datetime.hour = value[3]; > + datetime.minute = value[4]; > + datetime.second = value[5]; > + > + return grub_set_datetime (&datetime, mask); > + > +fail: > + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid datetime"); > +} > + > +GRUB_MOD_INIT(date) > +{ > + (void) mod; /* To stop warning. */ > + grub_register_command ("date", grub_cmd_date, > + GRUB_COMMAND_FLAG_BOTH, > + "date [[year-]month-day] [hour:minute[:second]]", This help string will not be shown if you do not use the argument parser to generate a --help Furthermore, I can imagine more arguments should be added in the future. > + "Command to display/set current datetime.", 0); > +} > + > +GRUB_MOD_FINI(date) > +{ > + grub_unregister_command ("date"); > +} > diff --git a/commands/datetime.c b/commands/datetime.c > new file mode 100644 > index 0000000..a681f96 > --- /dev/null > +++ b/commands/datetime.c > @@ -0,0 +1,132 @@ > +/* datetime.c - Module to export datetime variables. */ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/types.h> > +#include <grub/dl.h> > +#include <grub/env.h> > +#include <grub/misc.h> > +#include <grub/normal.h> > +#include <grub/datetime.h> > + > +static char *grub_weekday_names[] = > +{ > + "Sunday", > + "Monday", > + "Tueday", Tuesday > + "Wednesday", > + "Thusday", Thursday > + "Friday", > + "Saturday", > +}; Please notice that, depending on the country, the week either starts on sunday or monday. Altough I am quite clueless about the specifics ;) > +static char *grub_datetime_names[] = > +{ > + "YEAR", > + "MONTH", > + "DAY", > + "HOUR", > + "MINUTE", > + "SECOND", > + "WEEKDAY", > +}; > + > +int > +grub_get_weekday (struct grub_datetime *datetime) > +{ > + int a, y, m; > + > + a = (14 - datetime->month) / 12; > + y = datetime->year - a; > + m = datetime->month + 12 * a - 2; > + > + return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7; Wow ;-) Does this deal with leap years? > +} > + > +char * > +grub_get_weekday_name (struct grub_datetime *datetime) > +{ > + return grub_weekday_names[grub_get_weekday (datetime)]; > +} Shoudn't this be static? Or is this intentional? > +static char * > +grub_read_hook_datetime (struct grub_env_var *var, > + const char *val __attribute__ ((unused))) > +{ > + struct grub_datetime datetime; > + static char buf[6]; > + > + buf[0] = 0; > + if (! grub_get_datetime (&datetime)) > + { > + int i; > + > + for (i = 0; i < 7; i++) > + if (! grub_strcmp (var->name, grub_datetime_names[i])) > + { > + int n; > + > + switch (i) > + { > + case 0: > + n = datetime.year; > + break; > + case 1: > + n = datetime.month; > + break; > + case 2: > + n = datetime.day; > + break; > + case 3: > + n = datetime.hour; > + break; > + case 4: > + n = datetime.minute; > + break; > + case 5: > + n = datetime.second; > + break; > + default: > + return grub_get_weekday_name (&datetime); > + } > + > + grub_sprintf (buf, "%d", n); > + break; > + } > + } > + > + return buf; > +} > + > +GRUB_MOD_INIT(datetime) > +{ > + (void)mod; /* To stop warning. */ > + int i; > + > + for (i = 0; i < 7; i++) > + grub_register_variable_hook (grub_datetime_names[i], > + grub_read_hook_datetime, 0); > +} > + > +GRUB_MOD_FINI(datetime) > +{ > + int i; > + > + for (i = 0; i < 7; i++) > + grub_register_variable_hook (grub_datetime_names[i], 0, 0); Perhaps it is even wise to unset the variables? As the contents are no longer valid. > +} > diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk > index 4827c0f..2ec34a6 100644 > --- a/conf/i386-coreboot.rmk > +++ b/conf/i386-coreboot.rmk > @@ -101,7 +101,7 @@ pkglib_MODULES = _linux.mod linux.mod normal.mod \ > _multiboot.mod multiboot.mod aout.mod \ > play.mod cpuid.mod serial.mod ata.mod \ > memdisk.mod pci.mod lspci.mod reboot.mod \ > - halt.mod > + halt.mod datetime.mod date.mod > > # For _linux.mod. > _linux_mod_SOURCES = loader/i386/pc/linux.c > @@ -186,4 +186,14 @@ lspci_mod_SOURCES = commands/lspci.c > lspci_mod_CFLAGS = $(COMMON_CFLAGS) > lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) > > +# For datetime.mod > +datetime_mod_SOURCES = commands/datetime.c kern/i386/datetime.c > +datetime_mod_CFLAGS = $(COMMON_CFLAGS) > +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > +# For date.mod > +date_mod_SOURCES = commands/date.c > +date_mod_CFLAGS = $(COMMON_CFLAGS) > +date_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > include $(srcdir)/conf/common.mk > diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk > index 2ce21b1..8556954 100644 > --- a/conf/i386-efi.rmk > +++ b/conf/i386-efi.rmk > @@ -75,7 +75,8 @@ grub_install_SOURCES = util/i386/efi/grub-install.in > > # Modules. > pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ > - _linux.mod linux.mod cpuid.mod halt.mod reboot.mod pci.mod lspci.mod > + _linux.mod linux.mod cpuid.mod halt.mod reboot.mod pci.mod lspci.mod \ > + datetime.mod date.mod > > # For kernel.mod. > kernel_mod_EXPORTS = no > @@ -167,4 +168,14 @@ lspci_mod_SOURCES = commands/lspci.c > lspci_mod_CFLAGS = $(COMMON_CFLAGS) > lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) > > +# For datetime.mod > +datetime_mod_SOURCES = commands/datetime.c kern/efi/datetime.c > +datetime_mod_CFLAGS = $(COMMON_CFLAGS) > +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > +# For date.mod > +date_mod_SOURCES = commands/date.c > +date_mod_CFLAGS = $(COMMON_CFLAGS) > +date_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > include $(srcdir)/conf/common.mk > diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk > index a93845e..5728c5c 100644 > --- a/conf/i386-ieee1275.rmk > +++ b/conf/i386-ieee1275.rmk > @@ -104,7 +104,8 @@ grub_install_SOURCES = util/ieee1275/grub-install.in > # Modules. > pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod cpuid.mod > \ > multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \ > - _linux.mod nand.mod memdisk.mod pci.mod lspci.mod > + _linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ > + date.mod > > # For normal.mod. > normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ > @@ -188,4 +189,14 @@ lspci_mod_SOURCES = commands/lspci.c > lspci_mod_CFLAGS = $(COMMON_CFLAGS) > lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) > > +# For datetime.mod > +datetime_mod_SOURCES = commands/datetime.c kern/i386/datetime.c > +datetime_mod_CFLAGS = $(COMMON_CFLAGS) > +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > +# For date.mod > +date_mod_SOURCES = commands/date.c > +date_mod_CFLAGS = $(COMMON_CFLAGS) > +date_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > include $(srcdir)/conf/common.mk > diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk > index c1e4ac4..f9c6b4f 100644 > --- a/conf/i386-pc.rmk > +++ b/conf/i386-pc.rmk > @@ -163,7 +163,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod > linux.mod normal.mod \ > vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \ > videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \ > ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \ > - aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod > + aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod > > # For biosdisk.mod. > biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c > @@ -340,4 +340,14 @@ pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c > pxecmd_mod_CFLAGS = $(COMMON_CFLAGS) > pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS) > > +# For datetime.mod > +datetime_mod_SOURCES = commands/datetime.c kern/i386/datetime.c > +datetime_mod_CFLAGS = $(COMMON_CFLAGS) > +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > +# For date.mod > +date_mod_SOURCES = commands/date.c > +date_mod_CFLAGS = $(COMMON_CFLAGS) > +date_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > include $(srcdir)/conf/common.mk > diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk > index 4f8abba..4fdfa9a 100644 > --- a/conf/x86_64-efi.rmk > +++ b/conf/x86_64-efi.rmk > @@ -77,7 +77,8 @@ grub_install_SOURCES = util/i386/efi/grub-install.in > > # Modules. > pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ > - cpuid.mod halt.mod reboot.mod _linux.mod linux.mod pci.mod lspci.mod > + cpuid.mod halt.mod reboot.mod _linux.mod linux.mod pci.mod lspci.mod \ > + datetime.mod date.mod > > # For kernel.mod. > kernel_mod_EXPORTS = no > @@ -169,4 +170,14 @@ lspci_mod_SOURCES = commands/lspci.c > lspci_mod_CFLAGS = $(COMMON_CFLAGS) > lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) > > +# For datetime.mod > +datetime_mod_SOURCES = commands/datetime.c kern/efi/datetime.c > +datetime_mod_CFLAGS = $(COMMON_CFLAGS) > +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > +# For date.mod > +date_mod_SOURCES = commands/date.c > +date_mod_CFLAGS = $(COMMON_CFLAGS) > +date_mod_LDFLAGS = $(COMMON_LDFLAGS) > + > include $(srcdir)/conf/common.mk > diff --git a/include/grub/datetime.h b/include/grub/datetime.h > new file mode 100644 > index 0000000..3fb5e50 > --- /dev/null > +++ b/include/grub/datetime.h > @@ -0,0 +1,58 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/>. > + */ > + > +#ifndef KERNEL_DATETIME_HEADER > +#define KERNEL_DATETIME_HEADER 1 > + > +#include <grub/types.h> > +#include <grub/err.h> > + > +#define GRUB_DATETIME_SET_YEAR 1 > +#define GRUB_DATETIME_SET_MONTH 2 > +#define GRUB_DATETIME_SET_DAY 4 > +#define GRUB_DATETIME_SET_DATE (GRUB_DATETIME_SET_YEAR | \ > + GRUB_DATETIME_SET_MONTH | \ > + GRUB_DATETIME_SET_DAY) > + > +#define GRUB_DATETIME_SET_HOUR 8 > +#define GRUB_DATETIME_SET_MINUTE 16 > +#define GRUB_DATETIME_SET_SECOND 32 > +#define GRUB_DATETIME_SET_TIME (GRUB_DATETIME_SET_HOUR | \ > + GRUB_DATETIME_SET_MINUTE | \ > + GRUB_DATETIME_SET_SECOND) > + > +struct grub_datetime > +{ > + grub_uint16_t year; > + grub_uint8_t month; > + grub_uint8_t day; > + grub_uint8_t hour; > + grub_uint8_t minute; > + grub_uint8_t second; > +}; > + > +/* Return date and time. */ > +grub_err_t grub_get_datetime (struct grub_datetime *datetime); > + > +/* Set date and time. */ > +grub_err_t grub_set_datetime (struct grub_datetime *datetime, int mask); > + > +int grub_get_weekday (struct grub_datetime *datetime); > +char *grub_get_weekday_name (struct grub_datetime *datetime); > + > +#endif /* ! KERNEL_DATETIME_HEADER */ > diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h > new file mode 100644 > index 0000000..d482a7d > --- /dev/null > +++ b/include/grub/i386/cmos.h > @@ -0,0 +1,74 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/>. > + */ > + > +#ifndef GRUB_CPU_CMOS_H > +#define GRUB_CPU_CMOS_H 1 > + > +#include <grub/types.h> > +#include <grub/i386/io.h> > + > +#define GRUB_CMOS_ADDR_REG 0x70 > +#define GRUB_CMOS_DATA_REG 0x71 > + > +#define GRUB_CMOS_INDEX_SECOND 0 > +#define GRUB_CMOS_INDEX_SECOND_ALARM 1 > +#define GRUB_CMOS_INDEX_MINUTE 2 > +#define GRUB_CMOS_INDEX_MINUTE_ALARM 3 > +#define GRUB_CMOS_INDEX_HOUR 4 > +#define GRUB_CMOS_INDEX_HOUR_ALARM 5 > +#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6 > +#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7 > +#define GRUB_CMOS_INDEX_MONTH 8 > +#define GRUB_CMOS_INDEX_YEAR 9 > + > +#define GRUB_CMOS_INDEX_STATUS_A 0xA > +#define GRUB_CMOS_INDEX_STATUS_B 0xB > +#define GRUB_CMOS_INDEX_STATUS_C 0xC > +#define GRUB_CMOS_INDEX_STATUS_D 0xD > + > +#define GRUB_CMOS_STATUS_B_DAYLIGHT 1 > +#define GRUB_CMOS_STATUS_B_24HOUR 2 > +#define GRUB_CMOS_STATUS_B_BINARY 4 > + > +static inline grub_uint8_t > +grub_bcd_to_num (grub_uint8_t a) > +{ > + return ((a >> 4) * 10 + (a & 0xF)); > +} > + > +static inline grub_uint8_t > +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) > +{ > + grub_outb (index, GRUB_CMOS_ADDR_REG); > + return grub_inb (GRUB_CMOS_DATA_REG); > +} > + > +static inline void > +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); > +} > + > +#endif /* GRUB_CPU_PCI_H */ PCI? :-) > diff --git a/kern/efi/datetime.c b/kern/efi/datetime.c > new file mode 100644 > index 0000000..4ba38be > --- /dev/null > +++ b/kern/efi/datetime.c > @@ -0,0 +1,87 @@ > +/* kern/efi/datetime.c - efi datetime function. > + * > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/types.h> > +#include <grub/symbol.h> > +#include <grub/efi/api.h> > +#include <grub/efi/efi.h> > +#include <grub/datetime.h> > + > +grub_err_t > +grub_get_datetime (struct grub_datetime *datetime) > +{ > + grub_efi_status_t status; > + struct grub_efi_time efi_time; > + > + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, > + &efi_time, 0); > + > + if (status) > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "can\'t get datetime"); You implemented the function here! > + else > + { > + datetime->year = efi_time.year; > + datetime->month = efi_time.month; > + datetime->day = efi_time.day; > + datetime->hour = efi_time.hour; > + datetime->minute = efi_time.minute; > + datetime->second = efi_time.second; > + } > + > + return 0; > +} > + > +grub_err_t > +grub_set_datetime (struct grub_datetime *datetime, int mask) > +{ > + grub_efi_status_t status; > + struct grub_efi_time efi_time; Why do you use a mask? Isn't it better to let the caller to deal with this by calling grub_get_datetime? Perhaps I do not see the results of dealing with this either way. > + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, > + &efi_time, 0); > + > + if (status) > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "can\'t get datetime"); > + > + if (mask & GRUB_DATETIME_SET_YEAR) > + efi_time.year = datetime->year; > + > + if (mask & GRUB_DATETIME_SET_MONTH) > + efi_time.month = datetime->month; > + > + if (mask & GRUB_DATETIME_SET_DAY) > + efi_time.day = datetime->day; > + > + if (mask & GRUB_DATETIME_SET_HOUR) > + efi_time.hour = datetime->hour; > + > + if (mask & GRUB_DATETIME_SET_MINUTE) > + efi_time.minute = datetime->minute; > + > + if (mask & GRUB_DATETIME_SET_SECOND) > + efi_time.second = datetime->second; > + > + status = efi_call_1 (grub_efi_system_table->runtime_services->set_time, > + &efi_time); > + > + if (status) > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "can\'t set datetime"); > + > + return 0; > +} > diff --git a/kern/i386/datetime.c b/kern/i386/datetime.c > new file mode 100644 > index 0000000..466a404 > --- /dev/null > +++ b/kern/i386/datetime.c > @@ -0,0 +1,175 @@ > +/* kern/i386/datetime.c - x86 CMOS datetime function. > + * > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2008 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/datetime.h> > +#include <grub/i386/cmos.h> > + > +grub_err_t > +grub_get_datetime (struct grub_datetime *datetime) > +{ > + int is_bcd, is_12hour; > + grub_uint8_t value, flag; > + > + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); > + > + is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); > + > + value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR); > + 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); > + if (is_bcd) > + value = grub_bcd_to_num (value); > + > + datetime->month = value; > + > + value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH); > + if (is_bcd) > + value = grub_bcd_to_num (value); > + > + datetime->day = value; > + > + is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR); > + > + value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR); > + if (is_12hour) > + { > + is_12hour = (value & 0x80); > + > + value &= 0x7F; > + value--; > + } > + > + if (is_bcd) > + value = grub_bcd_to_num (value); > + > + if (is_12hour) > + value += 12; > + > + datetime->hour = value; > + > + value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE); > + if (is_bcd) > + value = grub_bcd_to_num (value); > + > + datetime->minute = value; > + > + value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND); > + if (is_bcd) > + value = grub_bcd_to_num (value); > + > + datetime->second = value; > + > + return 0; > +} > + > +grub_err_t > +grub_set_datetime (struct grub_datetime *datetime, int mask) > +{ > + int is_bcd; > + grub_uint8_t value, flag; > + > + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); > + > + is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); > + > + if (mask & GRUB_DATETIME_SET_YEAR) > + { > + value = ((datetime->year >= 2000) ? datetime->year - 2000 : > + datetime->year - 1900); > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); > + } > + > + if (mask & GRUB_DATETIME_SET_MONTH) > + { > + value = datetime->month; > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); > + } > + > + if (mask & GRUB_DATETIME_SET_DAY) > + { > + value = datetime->day; > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); > + } > + > + if (mask & GRUB_DATETIME_SET_HOUR) > + { > + int is_12hour; > + > + value = datetime->hour; > + > + is_12hour = (! (flag & GRUB_CMOS_STATUS_B_24HOUR)); > + > + if (is_12hour) > + { > + value++; > + > + if (value > 12) > + value -= 12; > + else > + is_12hour = 0; > + } > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + if (is_12hour) > + value |= 0x80; > + > + grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); > + } > + > + if (mask & GRUB_DATETIME_SET_MINUTE) > + { > + value = datetime->minute; > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); > + } > + > + if (mask & GRUB_DATETIME_SET_SECOND) > + { > + value = datetime->second; > + > + if (is_bcd) > + value = grub_num_to_bcd (value); > + > + grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); > + } > + > + return 0; > +} > _______________________________________________ > Grub-devel mailing list > [email protected] > http://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list [email protected] http://lists.gnu.org/mailman/listinfo/grub-devel
