2006-04-19 Yoshinori K. Okuji <okuji@enbug.org>

* DISTLIST: Added include/grub/efi/console.h,
        include/grub/efi/time.h, include/grub/i386/efi/kernel.h,
        kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.

        * include/grub/efi/console.h: New file.
        * include/grub/efi/time.h: Likewise.
        * include/grub/i386/efi/kernel.h: Likewise.
        * kern/efi/init.c: Likewise.
        * kern/efi/mm.c: Likewise.
        * term/efi/console.c: Likewise.

        * kern/i386/efi/init.c: Do not include grub/machine/time.h.
        (grub_stop): Removed.
        (grub_get_rtc): Likewise.
        (grub_machine_init): Simply call grub_efi_init.
        (grub_machine_fini): Call grub_efi_fini.

        * kern/efi/efi.c: Include grub/machine/time.h and grub/term.h.
        (grub_efi_output_string): Removed.
        (grub_efi_stall): New function.
        (grub_stop): Likewise.
        (grub_get_rtc): Likewise.

        * include/grub/efi/efi.h (grub_efi_output_string): Removed.
        (grub_efi_stall): New prototype.
        (grub_efi_allocate_pages): Likewise.
        (grub_efi_free_pages): Likewise.
        (grub_efi_get_memory_map): Likewise.
        (grub_efi_mm_init): Likewise.
        (grub_efi_mm_fini): Likewise.
        (grub_efi_init): Likewise.
        (grub_efi_fini): Likewise.

        * include/grub/i386/efi/time.h: Do not include
        grub/symbol.h. Include grub/efi/time.h.
        (GRUB_TICKS_PER_SECOND): Removed.
        (grub_get_rtc): Likewise.

        * include/grub/efi/api.h (struct grub_efi_memory_descriptor):
        Added padding. The EFI spec is buggy.
        (GRUB_EFI_BLACK): New macro.
        (GRUB_EFI_BLUE): Likewise.
        (GRUB_EFI_GREEN): Likewise.
        (GRUB_EFI_CYAN): Likewise.
        (GRUB_EFI_RED): Likewise.
        (GRUB_EFI_MAGENTA): Likewise.
        (GRUB_EFI_BROWN): Likewise.
        (GRUB_EFI_LIGHTGRAY): Likewise.
        (GRUB_EFI_BRIGHT): Likewise.
        (GRUB_EFI_DARKGRAY): Likewise.
        (GRUB_EFI_LIGHTBLUE): Likewise.
        (GRUB_EFI_LIGHTGREEN): Likewise.
        (GRUB_EFI_LIGHTCYAN): Likewise.
        (GRUB_EFI_LIGHTRED): Likewise.
        (GRUB_EFI_LIGHTMAGENTA): Likewise.
        (GRUB_EFI_YELLOW): Likewise.
        (GRUB_EFI_WHITE): Likewise.
        (GRUB_EFI_BACKGROUND_BLACK): Likewise.
        (GRUB_EFI_BACKGROUND_BLUE): Likewise.
        (GRUB_EFI_BACKGROUND_GREEN): Likewise.
        (GRUB_EFI_BACKGROUND_CYAN): Likewise.
        (GRUB_EFI_BACKGROUND_RED): Likewise.
        (GRUB_EFI_BACKGROUND_MAGENTA): Likewise.
        (GRUB_EFI_BACKGROUND_BROWN): Likewise.
        (GRUB_EFI_BACKGROUND_LIGHTGRAY): Likewise.
        (GRUB_EFI_TEXT_ATTR): Likewise.

        * conf/i386-efi.rmk (kernel_mod_SOURCES): Added kern/efi/efi.c,
        kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.
        (kernel_mod_HEADERS): Added efi/time.h.
This commit is contained in:
okuji 2006-04-19 08:59:44 +00:00
parent e2a8c90448
commit 976a4ea036
15 changed files with 1053 additions and 52 deletions

View file

@ -1,3 +1,76 @@
2006-04-19 Yoshinori K. Okuji <okuji@enbug.org>
* DISTLIST: Added include/grub/efi/console.h,
include/grub/efi/time.h, include/grub/i386/efi/kernel.h,
kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.
* include/grub/efi/console.h: New file.
* include/grub/efi/time.h: Likewise.
* include/grub/i386/efi/kernel.h: Likewise.
* kern/efi/init.c: Likewise.
* kern/efi/mm.c: Likewise.
* term/efi/console.c: Likewise.
* kern/i386/efi/init.c: Do not include grub/machine/time.h.
(grub_stop): Removed.
(grub_get_rtc): Likewise.
(grub_machine_init): Simply call grub_efi_init.
(grub_machine_fini): Call grub_efi_fini.
* kern/efi/efi.c: Include grub/machine/time.h and grub/term.h.
(grub_efi_output_string): Removed.
(grub_efi_stall): New function.
(grub_stop): Likewise.
(grub_get_rtc): Likewise.
* include/grub/efi/efi.h (grub_efi_output_string): Removed.
(grub_efi_stall): New prototype.
(grub_efi_allocate_pages): Likewise.
(grub_efi_free_pages): Likewise.
(grub_efi_get_memory_map): Likewise.
(grub_efi_mm_init): Likewise.
(grub_efi_mm_fini): Likewise.
(grub_efi_init): Likewise.
(grub_efi_fini): Likewise.
* include/grub/i386/efi/time.h: Do not include
grub/symbol.h. Include grub/efi/time.h.
(GRUB_TICKS_PER_SECOND): Removed.
(grub_get_rtc): Likewise.
* include/grub/efi/api.h (struct grub_efi_memory_descriptor):
Added padding. The EFI spec is buggy.
(GRUB_EFI_BLACK): New macro.
(GRUB_EFI_BLUE): Likewise.
(GRUB_EFI_GREEN): Likewise.
(GRUB_EFI_CYAN): Likewise.
(GRUB_EFI_RED): Likewise.
(GRUB_EFI_MAGENTA): Likewise.
(GRUB_EFI_BROWN): Likewise.
(GRUB_EFI_LIGHTGRAY): Likewise.
(GRUB_EFI_BRIGHT): Likewise.
(GRUB_EFI_DARKGRAY): Likewise.
(GRUB_EFI_LIGHTBLUE): Likewise.
(GRUB_EFI_LIGHTGREEN): Likewise.
(GRUB_EFI_LIGHTCYAN): Likewise.
(GRUB_EFI_LIGHTRED): Likewise.
(GRUB_EFI_LIGHTMAGENTA): Likewise.
(GRUB_EFI_YELLOW): Likewise.
(GRUB_EFI_WHITE): Likewise.
(GRUB_EFI_BACKGROUND_BLACK): Likewise.
(GRUB_EFI_BACKGROUND_BLUE): Likewise.
(GRUB_EFI_BACKGROUND_GREEN): Likewise.
(GRUB_EFI_BACKGROUND_CYAN): Likewise.
(GRUB_EFI_BACKGROUND_RED): Likewise.
(GRUB_EFI_BACKGROUND_MAGENTA): Likewise.
(GRUB_EFI_BACKGROUND_BROWN): Likewise.
(GRUB_EFI_BACKGROUND_LIGHTGRAY): Likewise.
(GRUB_EFI_TEXT_ATTR): Likewise.
* conf/i386-efi.rmk (kernel_mod_SOURCES): Added kern/efi/efi.c,
kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.
(kernel_mod_HEADERS): Added efi/time.h.
2006-04-18 Yoshinori K. Okuji <okuji@enbug.org>
* DISTLIST: Added conf/i386-efi.mk, conf/i386-efi.rmk,

View file

@ -112,11 +112,14 @@ include/grub/tparm.h
include/grub/types.h
include/grub/video.h
include/grub/efi/api.h
include/grub/efi/console.h
include/grub/efi/console_control.h
include/grub/efi/efi.h
include/grub/efi/pe32.h
include/grub/efi/time.h
include/grub/i386/setjmp.h
include/grub/i386/types.h
include/grub/i386/efi/kernel.h
include/grub/i386/efi/time.h
include/grub/i386/pc/biosdisk.h
include/grub/i386/pc/boot.h
@ -173,7 +176,9 @@ kern/parser.c
kern/partition.c
kern/rescue.c
kern/term.c
kern/efi/init.c
kern/efi/efi.c
kern/efi/mm.c
kern/i386/dl.c
kern/i386/efi/init.c
kern/i386/efi/startup.S
@ -224,6 +229,7 @@ partmap/sun.c
term/terminfo.c
term/tparm.c
term/gfxterm.c
term/efi/console.c
term/i386/pc/console.c
term/i386/pc/serial.c
term/i386/pc/vesafb.c

View file

@ -119,13 +119,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c
CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o und-kernel.lst
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c
CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o und-kernel.lst
ifneq ($(kernel_mod_EXPORTS),no)
CLEANFILES += def-kernel.lst
DEFSYMFILES += def-kernel.lst
endif
MOSTLYCLEANFILES += kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_i386_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d
MOSTLYCLEANFILES += kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_i386_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-term_efi_console.d
UNDSYMFILES += und-kernel.lst
kernel.mod: pre-kernel.o mod-kernel.o
@ -133,7 +134,7 @@ kernel.mod: pre-kernel.o mod-kernel.o
$(LD) $(kernel_mod_LDFLAGS) $(LDFLAGS) -r -d -o $@ $^
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
pre-kernel.o: kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o
pre-kernel.o: kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o
-rm -f $@
$(LD) $(kernel_mod_LDFLAGS) -r -d -o $@ $^
@ -532,10 +533,67 @@ fs-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c genfslist.sh
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
kernel_mod-kern_efi_init.o: kern/efi/init.c
$(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
kernel_mod-kern_efi_init.d: kern/efi/init.c
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -M $< | sed 's,init\.o[ :]*,kernel_mod-kern_efi_init.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
-include kernel_mod-kern_efi_init.d
CLEANFILES += cmd-kernel_mod-kern_efi_init.lst fs-kernel_mod-kern_efi_init.lst
COMMANDFILES += cmd-kernel_mod-kern_efi_init.lst
FSFILES += fs-kernel_mod-kern_efi_init.lst
cmd-kernel_mod-kern_efi_init.lst: kern/efi/init.c gencmdlist.sh
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
fs-kernel_mod-kern_efi_init.lst: kern/efi/init.c genfslist.sh
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
kernel_mod-kern_efi_mm.o: kern/efi/mm.c
$(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
kernel_mod-kern_efi_mm.d: kern/efi/mm.c
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -M $< | sed 's,mm\.o[ :]*,kernel_mod-kern_efi_mm.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
-include kernel_mod-kern_efi_mm.d
CLEANFILES += cmd-kernel_mod-kern_efi_mm.lst fs-kernel_mod-kern_efi_mm.lst
COMMANDFILES += cmd-kernel_mod-kern_efi_mm.lst
FSFILES += fs-kernel_mod-kern_efi_mm.lst
cmd-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c gencmdlist.sh
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
fs-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c genfslist.sh
set -e; $(CC) -Ikern/efi -I$(srcdir)/kern/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
kernel_mod-term_efi_console.o: term/efi/console.c
$(CC) -Iterm/efi -I$(srcdir)/term/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
kernel_mod-term_efi_console.d: term/efi/console.c
set -e; $(CC) -Iterm/efi -I$(srcdir)/term/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -M $< | sed 's,console\.o[ :]*,kernel_mod-term_efi_console.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@
-include kernel_mod-term_efi_console.d
CLEANFILES += cmd-kernel_mod-term_efi_console.lst fs-kernel_mod-term_efi_console.lst
COMMANDFILES += cmd-kernel_mod-term_efi_console.lst
FSFILES += fs-kernel_mod-term_efi_console.lst
cmd-kernel_mod-term_efi_console.lst: term/efi/console.c gencmdlist.sh
set -e; $(CC) -Iterm/efi -I$(srcdir)/term/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
fs-kernel_mod-term_efi_console.lst: term/efi/console.c genfslist.sh
set -e; $(CC) -Iterm/efi -I$(srcdir)/term/efi $(CPPFLAGS) $(CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
pc_partition.h rescue.h symbol.h term.h types.h \
i386/efi/time.h efi/efi.h
i386/efi/time.h efi/efi.h efi/time.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -75,11 +75,12 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c
kernel_mod_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \
file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h partition.h \
pc_partition.h rescue.h symbol.h term.h types.h \
i386/efi/time.h efi/efi.h
i386/efi/time.h efi/efi.h efi/time.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -213,9 +213,12 @@ struct grub_efi_guid
} __attribute__ ((aligned(8)));
typedef struct grub_efi_guid grub_efi_guid_t;
/* XXX although the spec does not specify the padding, this actually
must have the padding! */
struct grub_efi_memory_descriptor
{
grub_efi_uint32_t type;
grub_efi_uint32_t padding;
grub_efi_physical_address_t physical_start;
grub_efi_virtual_address_t virtual_start;
grub_efi_uint64_t num_pages;
@ -632,6 +635,35 @@ struct grub_efi_simple_text_output_interface
};
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
#define GRUB_EFI_BLACK 0x00
#define GRUB_EFI_BLUE 0x01
#define GRUB_EFI_GREEN 0x02
#define GRUB_EFI_CYAN 0x03
#define GRUB_EFI_RED 0x04
#define GRUB_EFI_MAGENTA 0x05
#define GRUB_EFI_BROWN 0x06
#define GRUB_EFI_LIGHTGRAY 0x07
#define GRUB_EFI_BRIGHT 0x08
#define GRUB_EFI_DARKGRAY 0x08
#define GRUB_EFI_LIGHTBLUE 0x09
#define GRUB_EFI_LIGHTGREEN 0x0A
#define GRUB_EFI_LIGHTCYAN 0x0B
#define GRUB_EFI_LIGHTRED 0x0C
#define GRUB_EFI_LIGHTMAGENTA 0x0D
#define GRUB_EFI_YELLOW 0x0E
#define GRUB_EFI_WHITE 0x0F
#define GRUB_EFI_BACKGROUND_BLACK 0x00
#define GRUB_EFI_BACKGROUND_BLUE 0x10
#define GRUB_EFI_BACKGROUND_GREEN 0x20
#define GRUB_EFI_BACKGROUND_CYAN 0x30
#define GRUB_EFI_BACKGROUND_RED 0x40
#define GRUB_EFI_BACKGROUND_MAGENTA 0x50
#define GRUB_EFI_BACKGROUND_BROWN 0x60
#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70
#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg) << 4))
struct grub_efi_system_table
{
grub_efi_table_header_t hdr;

View file

@ -0,0 +1,45 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2005,2006 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.
*/
#ifndef GRUB_EFI_CONSOLE_HEADER
#define GRUB_EFI_CONSOLE_HEADER 1
/* Define scan codes. */
#define GRUB_CONSOLE_KEY_LEFT 0x4B00
#define GRUB_CONSOLE_KEY_RIGHT 0x4D00
#define GRUB_CONSOLE_KEY_UP 0x4800
#define GRUB_CONSOLE_KEY_DOWN 0x5000
#define GRUB_CONSOLE_KEY_IC 0x5200
#define GRUB_CONSOLE_KEY_DC 0x5300
#define GRUB_CONSOLE_KEY_BACKSPACE 0x0008
#define GRUB_CONSOLE_KEY_HOME 0x4700
#define GRUB_CONSOLE_KEY_END 0x4F00
#define GRUB_CONSOLE_KEY_NPAGE 0x4900
#define GRUB_CONSOLE_KEY_PPAGE 0x5100
#include <grub/types.h>
#include <grub/symbol.h>
/* Initialize the console system. */
void grub_console_init (void);
/* Finish the console system. */
void grub_console_fini (void);
#endif /* ! GRUB_EFI_CONSOLE_HEADER */

View file

@ -30,7 +30,21 @@ void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
void *registration);
int EXPORT_FUNC(grub_efi_set_text_mode) (int on);
void EXPORT_FUNC(grub_efi_exit) (void) __attribute__((noreturn));
int EXPORT_FUNC(grub_efi_output_string) (const char *str);
void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
void *EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
grub_efi_uintn_t pages);
int EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *descriptor_size,
grub_efi_uint32_t *descriptor_version);
void grub_efi_mm_init (void);
void grub_efi_mm_fini (void);
void grub_efi_init (void);
void grub_efi_fini (void);
/* Variables. */
extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table);

32
include/grub/efi/time.h Normal file
View file

@ -0,0 +1,32 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef GRUB_EFI_TIME_HEADER
#define GRUB_EFI_TIME_HEADER 1
#include <grub/symbol.h>
/* This is destined to overflow when one minute passes by. */
#define GRUB_TICKS_PER_SECOND ((1UL << 31) / 60 / 60 * 2)
/* Return the real time in ticks. */
grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
#endif /* ! GRUB_EFI_TIME_HEADER */

View file

@ -0,0 +1,28 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003 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.
*/
#ifndef GRUB_MACHINE_KERNEL_HEADER
#define GRUB_MACHINE_KERNEL_HEADER 1
/* The prefix which points to the directory where GRUB modules and its
configuration file are located. */
extern char grub_prefix[];
#endif /* ! GRUB_MACHINE_KERNEL_HEADER */

View file

@ -18,14 +18,9 @@
* MA 02110-1301, USA.
*/
#ifndef KERNEL_TIME_HEADER
#define KERNEL_TIME_HEADER 1
#ifndef GRUB_MACHINE_TIME_HEADER
#define GRUB_MACHINE_TIME_HEADER 1
#include <grub/symbol.h>
#include <grub/efi/time.h>
#define GRUB_TICKS_PER_SECOND 1193
/* Return the real time in ticks. */
grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
#endif /* ! KERNEL_TIME_HEADER */
#endif /* ! GRUB_MACHINE_TIME_HEADER */

View file

@ -22,6 +22,8 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/console_control.h>
#include <grub/machine/time.h>
#include <grub/term.h>
/* The handle of GRUB itself. Filled in by the startup code. */
grub_efi_handle_t grub_efi_image_handle;
@ -75,23 +77,34 @@ grub_efi_exit (void)
0, 0);
}
int
grub_efi_output_string (const char *str)
void
grub_efi_stall (grub_efi_uintn_t microseconds)
{
grub_efi_simple_text_output_interface_t *o;
grub_size_t len = grub_strlen (str);
grub_efi_char16_t utf16_str[len + 1];
grub_efi_status_t status;
/* XXX Assume that STR is all ASCII characters. */
do
{
utf16_str[len] = str[len];
}
while (len--);
o = grub_efi_system_table->con_out;
status = o->output_string (o, utf16_str);
return status >= 0;
grub_efi_system_table->boot_services->stall (microseconds);
}
void
grub_stop (void)
{
grub_printf ("\nPress any key to abort.\n");
grub_getkey ();
grub_efi_fini ();
grub_efi_exit ();
}
grub_uint32_t
grub_get_rtc (void)
{
grub_efi_time_t time;
grub_efi_runtime_services_t *r;
r = grub_efi_system_table->runtime_services;
if (r->get_time (&time, 0) != GRUB_EFI_SUCCESS)
/* What is possible in this case? */
return 0;
return (((time.minute * 60 + time.second) * 1000
+ time.nanosecond / 1000000)
* GRUB_TICKS_PER_SECOND / 1000);
}

47
kern/efi/init.c Normal file
View file

@ -0,0 +1,47 @@
/* init.c - generic EFI initialization and finalization */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <grub/efi/efi.h>
#include <grub/efi/console.h>
#include <grub/term.h>
#include <grub/misc.h>
#include <grub/machine/kernel.h>
void
grub_efi_init (void)
{
/* First of all, initialize the console so that GRUB can display
messages. */
grub_console_init ();
/* Initialize the memory management system. */
grub_efi_mm_init ();
/* FIXME: this must be set to something meaningful. */
grub_env_set ("prefix", grub_prefix);
}
void
grub_efi_fini (void)
{
grub_efi_mm_fini ();
grub_console_fini ();
}

391
kern/efi/mm.c Normal file
View file

@ -0,0 +1,391 @@
/* mm.c - generic EFI memory management */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#define NEXT_MEMORY_DESCRIPTOR(desc, size) \
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
#define BYTES_TO_PAGES(bytes) ((bytes) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
/* The size of a memory map obtained from the firmware. This must be
a multiplier of 4KB. */
#define MEMORY_MAP_SIZE 0x1000
/* Maintain the list of allocated pages. */
struct allocated_page
{
grub_efi_physical_address_t addr;
grub_efi_uint64_t num_pages;
};
#define ALLOCATED_PAGES_SIZE 0x1000
#define MAX_ALLOCATED_PAGES \
(ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page))
static struct allocated_page *allocated_pages = 0;
/* The minimum and maximum heap size for GRUB itself. */
#define MIN_HEAP_SIZE 0x100000
#define MAX_HEAP_SIZE (16 * 0x100000)
/* Allocate pages. Return the pointer to the first of allocated pages. */
void *
grub_efi_allocate_pages (grub_efi_physical_address_t address,
grub_efi_uintn_t pages)
{
grub_efi_allocate_type_t type;
grub_efi_status_t status;
grub_efi_boot_services_t *b;
#if GRUB_HOST_SIZEOF_VOID_P < 8
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff)
return 0;
if (address == 0)
{
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
address = 0xffffffff;
}
else
type = GRUB_EFI_ALLOCATE_ADDRESS;
#else
if (address == 0)
type = GRUB_EFI_ALLOCATE_ANY_PAGES;
else
type = GRUB_EFI_ALLOCATE_ADDRESS;
#endif
b = grub_efi_system_table->boot_services;
status = b->allocate_pages (type, GRUB_EFI_LOADER_DATA, pages, &address);
if (status != GRUB_EFI_SUCCESS)
return 0;
if (address == 0)
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
address = 0xffffffff;
status = b->allocate_pages (type, GRUB_EFI_LOADER_DATA, pages, &address);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
return 0;
}
if (allocated_pages)
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
if (allocated_pages[i].addr == 0)
{
allocated_pages[i].addr = address;
allocated_pages[i].num_pages = pages;
break;
}
if (i == MAX_ALLOCATED_PAGES)
grub_fatal ("too many page allocations");
}
return (void *) ((grub_addr_t) address);
}
/* Free pages starting from ADDRESS. */
void
grub_efi_free_pages (grub_efi_physical_address_t address,
grub_efi_uintn_t pages)
{
grub_efi_boot_services_t *b;
if (allocated_pages
&& ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
!= address))
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
if (allocated_pages[i].addr == address)
{
allocated_pages[i].addr = 0;
break;
}
}
b = grub_efi_system_table->boot_services;
b->free_pages (address, pages);
}
/* Get the memory map as defined in the EFI spec. Return 1 if successful,
return 0 if partial, or return -1 if an error occurs. */
int
grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *descriptor_size,
grub_efi_uint32_t *descriptor_version)
{
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_efi_uintn_t key;
grub_efi_uint32_t version;
/* Allow some parameters to be missing. */
if (! map_key)
map_key = &key;
if (! descriptor_version)
descriptor_version = &version;
b = grub_efi_system_table->boot_services;
status = b->get_memory_map (memory_map_size, memory_map, map_key,
descriptor_size, descriptor_version);
if (status == GRUB_EFI_SUCCESS)
return 1;
else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
return 0;
else
return -1;
}
/* Sort the memory map in place. */
static void
sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t desc_size,
grub_efi_memory_descriptor_t *memory_map_end)
{
grub_efi_memory_descriptor_t *d1;
grub_efi_memory_descriptor_t *d2;
for (d1 = memory_map;
d1 < memory_map_end;
d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
{
grub_efi_memory_descriptor_t *min_desc = d1;
for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
d2 < memory_map_end;
d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
{
if (min_desc->num_pages > d2->num_pages)
min_desc = d2;
}
if (min_desc != d1)
{
grub_efi_memory_descriptor_t tmp;
tmp = *d1;
*d1 = *min_desc;
*min_desc = tmp;
}
}
}
/* Filter the descriptors. GRUB needs only available memory. */
static grub_efi_memory_descriptor_t *
filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
grub_efi_memory_descriptor_t *filtered_memory_map,
grub_efi_uintn_t desc_size,
grub_efi_memory_descriptor_t *memory_map_end)
{
grub_efi_memory_descriptor_t *desc;
grub_efi_memory_descriptor_t *filtered_desc;
for (desc = memory_map, filtered_desc = filtered_memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if GRUB_HOST_SIZEOF_VOID_P < 8
&& desc->physical_start <= 0xffffffff
#endif
&& desc->num_pages != 0)
{
grub_memcpy (filtered_desc, desc, desc_size);
/* Avoid the page at the address zero, because this is really
confusing for C programs. */
if (filtered_desc->physical_start == 0)
{
filtered_desc->physical_start = 0x1000;
filtered_desc->num_pages--;
}
#if GRUB_HOST_SIZEOF_VOID_P < 8
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL))
filtered_desc->num_pages
= (BYTES_TO_PAGES (0x100000000LL)
- BYTES_TO_PAGES (filtered_desc->physical_start));
#endif
if (filtered_desc->num_pages == 0)
continue;
filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
}
}
return filtered_desc;
}
/* Return the total number of pages. */
static grub_efi_uint64_t
get_total_pages (grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t desc_size,
grub_efi_memory_descriptor_t *memory_map_end)
{
grub_efi_memory_descriptor_t *desc;
grub_efi_uint64_t total = 0;
for (desc = memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
total += desc->num_pages;
return total;
}
/* Add memory regions. */
static void
add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t desc_size,
grub_efi_memory_descriptor_t *memory_map_end,
grub_efi_uint64_t required_pages)
{
grub_efi_memory_descriptor_t *desc;
for (desc = memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
grub_efi_uint64_t pages;
void *addr;
pages = desc->num_pages;
if (pages > required_pages)
pages = required_pages;
addr = grub_efi_allocate_pages (desc->physical_start, pages);
if (! addr)
grub_fatal ("cannot allocate conventional memory %p with %u pages",
(void *) ((grub_addr_t) desc->physical_start),
(unsigned) pages);
grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
required_pages -= pages;
if (required_pages == 0)
break;
}
if (required_pages > 0)
grub_fatal ("too little memory");
}
void
grub_efi_mm_init (void)
{
grub_efi_memory_descriptor_t *memory_map;
grub_efi_memory_descriptor_t *memory_map_end;
grub_efi_memory_descriptor_t *filtered_memory_map;
grub_efi_memory_descriptor_t *filtered_memory_map_end;
grub_efi_uintn_t map_size;
grub_efi_uintn_t desc_size;
grub_efi_uint64_t total_pages;
grub_efi_uint64_t required_pages;
/* First of all, allocate pages to maintain allocations. */
allocated_pages
= grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
if (! allocated_pages)
grub_fatal ("cannot allocate memory");
grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
/* Prepare a memory region to store two memory maps. */
memory_map = grub_efi_allocate_pages (0,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
if (! memory_map)
grub_fatal ("cannot allocate memory");
filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
/* Obtain descriptors for available memory. */
map_size = MEMORY_MAP_SIZE;
if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
grub_fatal ("cannot get memory map");
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
desc_size, memory_map_end);
/* By default, request a quarter of the available memory. */
total_pages = get_total_pages (filtered_memory_map, desc_size,
filtered_memory_map_end);
required_pages = (total_pages >> 2);
if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
/* Sort the filtered descriptors, so that GRUB can allocate pages
from smaller regions. */
sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
/* Allocate memory regions for GRUB's memory management. */
add_memory_regions (filtered_memory_map, desc_size,
filtered_memory_map_end, required_pages);
/* Release the memory maps. */
grub_efi_free_pages ((grub_addr_t) memory_map,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
}
void
grub_efi_mm_fini (void)
{
if (allocated_pages)
{
unsigned i;
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
{
struct allocated_page *p;
p = allocated_pages + i;
if (p->addr != 0)
grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
}
grub_efi_free_pages ((grub_addr_t) allocated_pages,
BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
}
}

View file

@ -27,33 +27,17 @@
#include <grub/cache.h>
#include <grub/kernel.h>
#include <grub/efi/efi.h>
#include <grub/machine/time.h>
void
grub_stop (void)
{
grub_efi_exit ();
}
grub_uint32_t
grub_get_rtc (void)
{
return 0; /* FIXME */
}
void
grub_machine_init (void)
{
grub_efi_set_text_mode (1);
grub_efi_output_string ("test!\r\n");
/* Stop immediately at the moment... */
grub_stop ();
grub_efi_init ();
}
void
grub_machine_fini (void)
{
grub_efi_fini ();
}
void

282
term/efi/console.c Normal file
View file

@ -0,0 +1,282 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006 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/term.h>
#include <grub/types.h>
#include <grub/err.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
#include <grub/efi/console.h>
static grub_uint8_t
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
GRUB_EFI_BACKGROUND_BLACK);
static grub_uint8_t
grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
GRUB_EFI_BACKGROUND_BLACK);
static grub_uint8_t
grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_WHITE,
GRUB_EFI_BACKGROUND_BLACK);
static int read_key = -1;
static void
grub_console_putchar (grub_uint32_t c)
{
grub_efi_char16_t str[2];
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
/* For now, do not try to use a surrogate pair. */
if (c > 0xffff)
c = '?';
str[0] = (grub_efi_char16_t) (c & 0xffff);
str[1] = 0;
/* Should this test be cached? */
if (c > 0x7f && o->test_string (o, str) != GRUB_EFI_SUCCESS)
return;
o->output_string (o, str);
}
static grub_ssize_t
grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
{
/* For now, every printable character has the width 1. */
return 1;
}
static int
grub_console_checkkey (void)
{
grub_efi_simple_input_interface_t *i;
grub_efi_input_key_t key;
if (read_key >= 0)
return 1;
i = grub_efi_system_table->con_in;
if (i->read_key_stroke (i, &key) == GRUB_EFI_SUCCESS)
{
switch (key.scan_code)
{
case 0x00:
read_key = key.unicode_char;
break;
case 0x01:
read_key = GRUB_CONSOLE_KEY_UP;
break;
case 0x02:
read_key = GRUB_CONSOLE_KEY_DOWN;
break;
case 0x03:
read_key = GRUB_CONSOLE_KEY_RIGHT;
break;
case 0x04:
read_key = GRUB_CONSOLE_KEY_LEFT;
break;
case 0x05:
read_key = GRUB_CONSOLE_KEY_HOME;
break;
case 0x06:
read_key = GRUB_CONSOLE_KEY_END;
break;
case 0x07:
read_key = GRUB_CONSOLE_KEY_IC;
break;
case 0x08:
read_key = GRUB_CONSOLE_KEY_DC;
break;
case 0x09:
read_key = GRUB_CONSOLE_KEY_PPAGE;
break;
case 0x0a:
read_key = GRUB_CONSOLE_KEY_NPAGE;
case 0x17:
read_key = '\e';
break;
default:
return 0;
}
return 1;
}
return 0;
}
static int
grub_console_getkey (void)
{
grub_efi_simple_input_interface_t *i;
grub_efi_boot_services_t *b;
grub_efi_uintn_t index;
grub_efi_status_t status;
int key;
if (read_key >= 0)
{
key = read_key;
read_key = -1;
return key;
}
i = grub_efi_system_table->con_in;
b = grub_efi_system_table->boot_services;
do
{
status = b->wait_for_event (1, &(i->wait_for_key), &index);
if (status != GRUB_EFI_SUCCESS)
return -1;
grub_console_checkkey ();
}
while (read_key < 0);
key = read_key;
read_key = -1;
return key;
}
static grub_uint16_t
grub_console_getwh (void)
{
grub_efi_simple_text_output_interface_t *o;
grub_efi_uintn_t columns, rows;
o = grub_efi_system_table->con_out;
if (o->query_mode (o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
{
/* Why does this fail? */
columns = 80;
rows = 25;
}
return ((columns << 8) | rows);
}
static grub_uint16_t
grub_console_getxy (void)
{
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
}
static void
grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
o->set_cursor_position (o, x, y);
}
static void
grub_console_cls (void)
{
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
o->clear_screen (o);
}
static void
grub_console_setcolorstate (grub_term_color_state state)
{
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
switch (state) {
case GRUB_TERM_COLOR_STANDARD:
o->set_attributes (o, grub_console_standard_color);
break;
case GRUB_TERM_COLOR_NORMAL:
o->set_attributes (o, grub_console_normal_color);
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
o->set_attributes (o, grub_console_highlight_color);
break;
default:
break;
}
}
static void
grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
static void
grub_console_setcursor (int on)
{
grub_efi_simple_text_output_interface_t *o;
o = grub_efi_system_table->con_out;
o->enable_cursor (o, on);
}
static struct grub_term grub_console_term =
{
.name = "console",
.init = 0,
.fini = 0,
.putchar = grub_console_putchar,
.getcharwidth = grub_console_getcharwidth,
.checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
.getwh = grub_console_getwh,
.getxy = grub_console_getxy,
.gotoxy = grub_console_gotoxy,
.cls = grub_console_cls,
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.setcursor = grub_console_setcursor,
.flags = 0,
.next = 0
};
void
grub_console_init (void)
{
/* FIXME: it is necessary to consider the case where no console control
is present but the default is already in text mode. */
if (! grub_efi_set_text_mode (1))
{
grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
return;
}
grub_term_register (&grub_console_term);
grub_term_set_current (&grub_console_term);
}
void
grub_console_fini (void)
{
grub_term_unregister (&grub_console_term);
}