From f9e4ed6a45f73a3bbc4b1201db16c3f3ba1e4e8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 14:26:07 +0100 Subject: [PATCH 01/24] Index of BMP for faster font lookup --- font/font.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/font/font.c b/font/font.c index a81291916..82e0d88e7 100644 --- a/font/font.c +++ b/font/font.c @@ -58,6 +58,7 @@ struct grub_font short leading; grub_uint32_t num_chars; struct char_index_entry *char_index; + grub_uint16_t *bmp_idx; }; /* Definition of font registry. */ @@ -180,6 +181,7 @@ font_init (grub_font_t font) font->descent = 0; font->num_chars = 0; font->char_index = 0; + font->bmp_idx = 0; } /* Open the next section in the file. @@ -273,6 +275,14 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct * sizeof (struct char_index_entry)); if (! font->char_index) return 1; + font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); + if (! font->bmp_idx) + { + grub_free (font->char_index); + return 1; + } + grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); + #if FONT_DEBUG >= 2 grub_printf("num_chars=%d)\n", font->num_chars); @@ -299,6 +309,9 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct return 1; } + if (entry->code < 0x10000) + font->bmp_idx[entry->code] = i; + last_code = entry->code; /* Read storage flags byte. */ @@ -594,7 +607,7 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) /* Return a pointer to the character index entry for the glyph corresponding to the codepoint CODE in the font FONT. If not found, return zero. */ -static struct char_index_entry * +static inline struct char_index_entry * find_glyph (const grub_font_t font, grub_uint32_t code) { struct char_index_entry *table; @@ -602,8 +615,17 @@ find_glyph (const grub_font_t font, grub_uint32_t code) grub_size_t hi; grub_size_t mid; - /* Do a binary search in `char_index', which is ordered by code point. */ table = font->char_index; + + /* Use BMP index if possible. */ + if (code < 0x10000) + { + if (font->bmp_idx[code] == 0xffff) + return 0; + return &table[font->bmp_idx[code]]; + } + + /* Do a binary search in `char_index', which is ordered by code point. */ lo = 0; hi = font->num_chars - 1; From 26625973e14613858d9fef3afe9913b065935800 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 15:17:18 +0100 Subject: [PATCH 02/24] ChangeLog --- ChangeLog.bmpidx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.bmpidx diff --git a/ChangeLog.bmpidx b/ChangeLog.bmpidx new file mode 100644 index 000000000..bae879596 --- /dev/null +++ b/ChangeLog.bmpidx @@ -0,0 +1,9 @@ +2009-11-29 Vladimir Serbinenko + + Optimise glyph lookup by Basic Multilingual Plane lookup array. + + * font/font.c (struct grub_font): New member 'bmp_idx'. + (font_init): Initialise 'bmp_idx'. + (load_font_index): Fill 'bmp_idx'. + (find_glyph): Make inline. Use bmp_idx for BMP characters. + From 3e29c69a8ddf5e5641d35a55a01def964fd89f72 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Nov 2009 10:58:06 +0100 Subject: [PATCH 03/24] 2009-11-30 Vladimir Serbinenko * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding unnecessary calls. --- ChangeLog.scrollopt | 4 ++ video/fb/video_fb.c | 93 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 ChangeLog.scrollopt diff --git a/ChangeLog.scrollopt b/ChangeLog.scrollopt new file mode 100644 index 000000000..c677a2372 --- /dev/null +++ b/ChangeLog.scrollopt @@ -0,0 +1,4 @@ +2009-11-30 Vladimir Serbinenko + + * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding + unnecessary calls. diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 5f2917da6..15c30c23b 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -974,32 +974,83 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) { /* 3. Move data in render target. */ struct grub_video_fbblit_info target; - grub_uint8_t *src; - grub_uint8_t *dst; - int j; + int i, j; + int linedelta, linelen; target.mode_info = &render_target->mode_info; target.data = render_target->data; - /* Check vertical direction of the move. */ - if (dy <= 0) - /* 3a. Move data upwards. */ - for (j = 0; j < height; j++) - { - dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); - src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); - grub_memmove (dst, src, - width * target.mode_info->bytes_per_pixel); - } + linedelta = target.mode_info->pitch + - width * target.mode_info->bytes_per_pixel; + linelen = width * target.mode_info->bytes_per_pixel; +#define DO_SCROLL \ + /* Check vertical direction of the move. */ \ + if (dy < 0 || (dy == 0 && dx < 0)) \ + { \ + dst = (void *) grub_video_fb_get_video_ptr (&target, \ + dst_x, dst_y); \ + src = (void *) grub_video_fb_get_video_ptr (&target, \ + src_x, src_y); \ + /* 3a. Move data upwards. */ \ + for (j = 0; j < height; j++) \ + { \ + for (i = 0; i < linelen; i++) \ + *(dst++) = *(src++); \ + dst += linedelta; \ + src += linedelta; \ + } \ + } \ + else \ + { \ + /* 3b. Move data downwards. */ \ + dst = (void *) grub_video_fb_get_video_ptr (&target, \ + dst_x + width - 1, \ + dst_y + height - 1); \ + src = (void *) grub_video_fb_get_video_ptr (&target, \ + src_x + width - 1, \ + src_y + height - 1); \ + for (j = 0; j < height; j++) \ + { \ + for (i = 0; i < linelen; i++) \ + *(dst--) = *(src--); \ + dst -= linedelta; \ + src -= linedelta; \ + } \ + } + + /* If everything is aligned on 32-bit use 32-bit copy. */ + if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y) + % sizeof (grub_uint32_t) == 0 + && (grub_addr_t) grub_video_fb_get_video_ptr (&target, dst_x, dst_y) + % sizeof (grub_uint32_t) == 0 + && linelen % sizeof (grub_uint32_t) == 0 + && linedelta % sizeof (grub_uint32_t) == 0) + { + grub_uint32_t *src, *dst; + linelen /= sizeof (grub_uint32_t); + linedelta /= sizeof (grub_uint32_t); + DO_SCROLL + } + /* If everything is aligned on 16-bit use 16-bit copy. */ + else if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y) + % sizeof (grub_uint16_t) == 0 + && (grub_addr_t) grub_video_fb_get_video_ptr (&target, + dst_x, dst_y) + % sizeof (grub_uint16_t) == 0 + && linelen % sizeof (grub_uint16_t) == 0 + && linedelta % sizeof (grub_uint16_t) == 0) + { + grub_uint16_t *src, *dst; + linelen /= sizeof (grub_uint16_t); + linedelta /= sizeof (grub_uint16_t); + DO_SCROLL + } + /* If not aligned at all use 8-bit copy. */ else - /* 3b. Move data downwards. */ - for (j = (height - 1); j >= 0; j--) - { - dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); - src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); - grub_memmove (dst, src, - width * target.mode_info->bytes_per_pixel); - } + { + grub_uint8_t *src, *dst; + DO_SCROLL + } } /* 4. Fill empty space with specified color. In this implementation From 0d48a435a0370bd30920bb507c301b67e218145e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 19 Dec 2009 21:30:00 +0100 Subject: [PATCH 04/24] 2009-12-19 Vladimir Serbinenko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * include/grub/types.h (UNUSED): Removed since it conflicts with NetBSD headers. All users changed to direct __attribute__ ((unused)). Reported by Grégoire Sutre. --- ChangeLog | 6 ++++++ commands/read.c | 2 +- fs/i386/pc/pxe.c | 6 ++++-- include/grub/types.h | 2 -- kern/elf.c | 8 ++++++-- loader/i386/pc/multiboot2.c | 9 ++++++--- loader/ieee1275/multiboot2.c | 6 ++++-- loader/machoXX.c | 19 ++++++++++--------- loader/multiboot2.c | 3 ++- util/getroot.c | 2 +- util/ieee1275/devicemap.c | 6 ++++-- util/ieee1275/ofpath.c | 17 ++++++++++------- 12 files changed, 54 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc616c078..d386f7b71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-19 Vladimir Serbinenko + + * include/grub/types.h (UNUSED): Removed since it conflicts with + NetBSD headers. All users changed to direct __attribute__ ((unused)). + Reported by Grégoire Sutre. + 2009-12-19 Carles Pina i Estany * normal/menu_text.c (STANDARD_MARGIN): New macro. diff --git a/commands/read.c b/commands/read.c index 82b30b461..aa6af37b5 100644 --- a/commands/read.c +++ b/commands/read.c @@ -62,7 +62,7 @@ grub_getline (void) } static grub_err_t -grub_cmd_read (grub_command_t cmd UNUSED, int argc, char **args) +grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { char *line = grub_getline (); if (! line) diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 6c41d4298..dec3b91bf 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -107,9 +107,11 @@ static struct grub_disk_dev grub_pxe_dev = }; static grub_err_t -grub_pxefs_dir (grub_device_t device UNUSED, const char *path UNUSED, +grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), + const char *path __attribute__ ((unused)), int (*hook) (const char *filename, - const struct grub_dirhook_info *info) UNUSED) + const struct grub_dirhook_info *info) + __attribute__ ((unused))) { return GRUB_ERR_NONE; } diff --git a/include/grub/types.h b/include/grub/types.h index 8e2ad15ef..5f6b7ec62 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -22,8 +22,6 @@ #include #include -#define UNUSED __attribute__ ((unused)) - #ifdef GRUB_UTIL # define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P # define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG diff --git a/kern/elf.c b/kern/elf.c index f14161060..951049e73 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -181,7 +181,9 @@ grub_elf32_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf32_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) @@ -360,7 +362,9 @@ grub_elf64_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf64_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c index e2d649613..6ef8c70ca 100644 --- a/loader/i386/pc/multiboot2.c +++ b/loader/i386/pc/multiboot2.c @@ -27,7 +27,8 @@ #include grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf32_Addr paddr = phdr->p_paddr; @@ -48,7 +49,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, } grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf64_Addr paddr = phdr->p_paddr; @@ -82,7 +84,8 @@ grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) } grub_err_t -grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size) +grub_mb2_arch_module_free (grub_addr_t addr, + grub_size_t size __attribute__ ((unused))) { grub_free((void *) addr); return GRUB_ERR_NONE; diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c index 3646e8091..3b0ab758e 100644 --- a/loader/ieee1275/multiboot2.c +++ b/loader/ieee1275/multiboot2.c @@ -36,7 +36,8 @@ typedef void (*kernel_entry_t) (unsigned long, void *, int (void *), /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; @@ -61,7 +62,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; diff --git a/loader/machoXX.c b/loader/machoXX.c index d42dd8b55..8441e0128 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -123,8 +123,9 @@ SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, struct grub_macho_cmd *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr0, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr0, + void *_arg __attribute__ ((unused))) { grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) @@ -166,10 +167,10 @@ SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags) grub_err_t err = 0; auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, struct grub_macho_cmd *hdr0, - void UNUSED *_arg); + void *_arg __attribute__ ((unused))); int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, struct grub_macho_cmd *hdr0, - void UNUSED *_arg) + void *_arg __attribute__ ((unused))) { grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; @@ -223,11 +224,11 @@ SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho) { grub_macho_addr_t entry_point = 0; auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg); - int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg) + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))); + int NESTED_FUNC_ATTR hook(grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))) { if (hdr->cmd == GRUB_MACHO_CMD_THREAD) entry_point = ((grub_macho_thread_t *) hdr)->entry_point; diff --git a/loader/multiboot2.c b/loader/multiboot2.c index 976285b85..4c73a2f17 100644 --- a/loader/multiboot2.c +++ b/loader/multiboot2.c @@ -222,7 +222,8 @@ grub_mb2_unload (void) } static grub_err_t -grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer) +grub_mb2_load_other (grub_file_t file __attribute__ ((unused)), + void *buffer __attribute__ ((unused))) { /* XXX Create module tag here. */ return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported"); diff --git a/util/getroot.c b/util/getroot.c index c6c229967..db772b968 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -488,7 +488,7 @@ grub_util_is_dmraid (const char *os_dev) } int -grub_util_get_dev_abstraction (const char *os_dev UNUSED) +grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { #ifdef __linux__ /* Check for LVM. */ diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c index bddfc17e7..19ab746ef 100644 --- a/util/ieee1275/devicemap.c +++ b/util/ieee1275/devicemap.c @@ -35,8 +35,10 @@ escape_of_path (const char *orig_path) } void -grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED, - int *num_fd UNUSED, int *num_hd UNUSED) +grub_util_emit_devicemap_entry (FILE *fp, char *name, + int is_floppy __attribute__((unused)), + int *num_fd __attribute__((unused)), + int *num_hd __attribute__((unused))) { const char *orig_path = grub_util_devname_to_ofpath (name); char *ofpath = escape_of_path (orig_path); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 7b464bf09..e90488fc3 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -39,7 +39,6 @@ #include #ifdef OFPATH_STANDALONE -#define UNUSED __attribute__((unused)) #define xmalloc malloc void grub_util_error (const char *fmt, ...) @@ -199,8 +198,10 @@ get_basename(char *p) static void of_path_of_vdisk(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), + const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int devno, junk; @@ -217,8 +218,9 @@ of_path_of_vdisk(char *of_path, static void of_path_of_ide(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int chan, devno; @@ -299,8 +301,9 @@ check_sas (char *sysfs_path, int *tgt) static void of_path_of_scsi(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { const char *p, *digit_string, *disk_name; int host, bus, tgt, lun; From 2fbcbbc3895142f5ddc17518eacc7a5b7fbeb575 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Dec 2009 02:52:39 +0100 Subject: [PATCH 05/24] Save 314 bytes on not handling contexts in core --- conf/any-emu.rmk | 2 +- conf/common.rmk | 2 +- conf/i386-coreboot.rmk | 3 +- conf/i386-efi.rmk | 3 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 3 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/x86_64-efi.rmk | 2 +- include/grub/env.h | 30 ++---- include/grub/env_private.h | 46 +++++++++ include/grub/normal.h | 2 + kern/corecmd.c | 14 --- kern/env.c | 203 ++----------------------------------- kern/main.c | 2 - normal/context.c | 172 +++++++++++++++++++++++++++++++ normal/main.c | 12 ++- 17 files changed, 259 insertions(+), 243 deletions(-) create mode 100644 include/grub/env_private.h create mode 100644 normal/context.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index fb97de0a0..066bb52ba 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -27,7 +27,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ normal/handler.c normal/auth.c normal/autofs.c \ normal/completion.c normal/main.c normal/color.c \ normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ - normal/menu_text.c \ + normal/menu_text.c normal/context.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ diff --git a/conf/common.rmk b/conf/common.rmk index 1ed30a404..74e2b5bc4 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -543,7 +543,7 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \ - normal/misc.c + normal/misc.c normal/context.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index e597328e7..1efea8afb 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -35,7 +35,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 261fe4092..2de0e9304 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -51,7 +51,8 @@ kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 8d9577844..08c6c8f37 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -33,7 +33,7 @@ kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \ - list.h handler.h command.h i18n.h + list.h handler.h command.h i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 046c71641..8cec19f19 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -64,7 +64,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ - machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i18n.h + machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 85b1fa211..9c16299d1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ - command.h i18n.h + command.h i18n.h env_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index d19e927a5..d34adeb3c 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -31,7 +31,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ list.h handler.h command.h i18n.h \ sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ - sparc64/ieee1275/ieee1275.h + sparc64/ieee1275/ieee1275.h env_private.h kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 0d1289c6f..f5f0db25e 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -51,7 +51,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ - handler.h command.h i18n.h + handler.h command.h i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/env.h b/include/grub/env.h index 440185a59..ae4fd8745 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -22,6 +22,7 @@ #include #include #include +#include struct grub_env_var; @@ -30,18 +31,6 @@ typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var, typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, const char *val); -enum grub_env_var_type - { - /* The default variable type which is local in current context. */ - GRUB_ENV_VAR_LOCAL, - - /* The exported type, which is passed to new contexts. */ - GRUB_ENV_VAR_GLOBAL, - - /* The data slot type, which is used to store arbitrary data. */ - GRUB_ENV_VAR_DATA - }; - struct grub_env_var { char *name; @@ -50,23 +39,24 @@ struct grub_env_var grub_env_write_hook_t write_hook; struct grub_env_var *next; struct grub_env_var **prevp; - enum grub_env_var_type type; + int global; }; grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var)); +struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name); grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, grub_env_read_hook_t read_hook, grub_env_write_hook_t write_hook); -grub_err_t EXPORT_FUNC(grub_env_context_open) (int export); -grub_err_t EXPORT_FUNC(grub_env_context_close) (void); -grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); -grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name, - const void *ptr); -void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name); -void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name); +grub_err_t grub_env_context_open (int export); +grub_err_t grub_env_context_close (void); +grub_err_t grub_env_export (const char *name); + +void grub_env_unset_menu (void); +grub_menu_t grub_env_get_menu (void); +void grub_env_set_menu (grub_menu_t nmenu); #endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/env_private.h b/include/grub/env_private.h new file mode 100644 index 000000000..bb001533f --- /dev/null +++ b/include/grub/env_private.h @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2009 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 . + */ + +#ifndef GRUB_ENV_PRIVATE_HEADER +#define GRUB_ENV_PRIVATE_HEADER 1 + +#include + +/* The size of the hash table. */ +#define HASHSZ 13 + +/* A hashtable for quick lookup of variables. */ +struct grub_env_context +{ + /* A hash table for variables. */ + struct grub_env_var *vars[HASHSZ]; + + /* One level deeper on the stack. */ + struct grub_env_context *prev; +}; + +/* This is used for sorting only. */ +struct grub_env_sorted_var +{ + struct grub_env_var *var; + struct grub_env_sorted_var *next; +}; + +extern struct grub_env_context *EXPORT_VAR(grub_current_context); + +#endif /* ! GRUB_ENV_PRIVATE_HEADER */ diff --git a/include/grub/normal.h b/include/grub/normal.h index feebc85b1..15f4671d2 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -84,6 +84,8 @@ void read_command_list (void); /* Defined in `autofs.c'. */ void read_fs_list (void); +void grub_context_init (void); +void grub_context_fini (void); #ifdef GRUB_UTIL void grub_normal_init (void); diff --git a/kern/corecmd.c b/kern/corecmd.c index 03944f2df..7e8a3b4f6 100644 --- a/kern/corecmd.c +++ b/kern/corecmd.c @@ -73,18 +73,6 @@ grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)), return 0; } -static grub_err_t -grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "no environment variable specified"); - - grub_env_export (args[0]); - return 0; -} - /* insmod MODULE */ static grub_err_t grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), @@ -193,8 +181,6 @@ grub_register_core_commands (void) "set [ENVVAR=VALUE]", "set an environment variable"); grub_register_command ("unset", grub_core_cmd_unset, "unset ENVVAR", "remove an environment variable"); - grub_register_command ("export", grub_core_cmd_export, - "export ENVVAR", "Export a variable."); grub_register_command ("ls", grub_core_cmd_ls, "ls [ARG]", "list devices or files"); grub_register_command ("insmod", grub_core_cmd_insmod, diff --git a/kern/env.c b/kern/env.c index 750902af8..fdb3c9a34 100644 --- a/kern/env.c +++ b/kern/env.c @@ -18,34 +18,15 @@ */ #include +#include #include #include -/* The size of the hash table. */ -#define HASHSZ 13 - -/* A hashtable for quick lookup of variables. */ -struct grub_env_context -{ - /* A hash table for variables. */ - struct grub_env_var *vars[HASHSZ]; - - /* One level deeper on the stack. */ - struct grub_env_context *prev; -}; - -/* This is used for sorting only. */ -struct grub_env_sorted_var -{ - struct grub_env_var *var; - struct grub_env_sorted_var *next; -}; - /* The initial context. */ static struct grub_env_context initial_context; /* The current context. */ -static struct grub_env_context *current_context = &initial_context; +struct grub_env_context *grub_current_context = &initial_context; /* Return the hash representation of the string S. */ static unsigned int @@ -60,87 +41,20 @@ grub_env_hashval (const char *s) return i % HASHSZ; } -static struct grub_env_var * +struct grub_env_var * grub_env_find (const char *name) { struct grub_env_var *var; int idx = grub_env_hashval (name); /* Look for the variable in the current context. */ - for (var = current_context->vars[idx]; var; var = var->next) + for (var = grub_current_context->vars[idx]; var; var = var->next) if (grub_strcmp (var->name, name) == 0) return var; return 0; } -grub_err_t -grub_env_context_open (int export) -{ - struct grub_env_context *context; - int i; - - context = grub_zalloc (sizeof (*context)); - if (! context) - return grub_errno; - - context->prev = current_context; - current_context = context; - - /* Copy exported variables. */ - for (i = 0; i < HASHSZ; i++) - { - struct grub_env_var *var; - - for (var = context->prev->vars[i]; var; var = var->next) - { - if (export && var->type == GRUB_ENV_VAR_GLOBAL) - { - if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) - { - grub_env_context_close (); - return grub_errno; - } - grub_register_variable_hook (var->name, var->read_hook, var->write_hook); - } - } - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_env_context_close (void) -{ - struct grub_env_context *context; - int i; - - if (! current_context->prev) - grub_fatal ("cannot close the initial context"); - - /* Free the variables associated with this context. */ - for (i = 0; i < HASHSZ; i++) - { - struct grub_env_var *p, *q; - - for (p = current_context->vars[i]; p; p = q) - { - q = p->next; - grub_free (p->name); - if (p->type != GRUB_ENV_VAR_DATA) - grub_free (p->value); - grub_free (p); - } - } - - /* Restore the previous context. */ - context = current_context->prev; - grub_free (current_context); - current_context = context; - - return GRUB_ERR_NONE; -} - static void grub_env_insert (struct grub_env_context *context, struct grub_env_var *var) @@ -164,18 +78,6 @@ grub_env_remove (struct grub_env_var *var) var->next->prevp = var->prevp; } -grub_err_t -grub_env_export (const char *name) -{ - struct grub_env_var *var; - - var = grub_env_find (name); - if (var) - var->type = GRUB_ENV_VAR_GLOBAL; - - return GRUB_ERR_NONE; -} - grub_err_t grub_env_set (const char *name, const char *val) { @@ -207,9 +109,8 @@ grub_env_set (const char *name, const char *val) if (! var) return grub_errno; - /* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave - this for readability. */ - var->type = GRUB_ENV_VAR_LOCAL; + /* This is not necessary. But leave this for readability. */ + var->global = 0; var->name = grub_strdup (name); if (! var->name) @@ -219,7 +120,7 @@ grub_env_set (const char *name, const char *val) if (! var->value) goto fail; - grub_env_insert (current_context, var); + grub_env_insert (grub_current_context, var); return GRUB_ERR_NONE; @@ -263,8 +164,7 @@ grub_env_unset (const char *name) grub_env_remove (var); grub_free (var->name); - if (var->type != GRUB_ENV_VAR_DATA) - grub_free (var->value); + grub_free (var->value); grub_free (var); } @@ -280,14 +180,10 @@ grub_env_iterate (int (*func) (struct grub_env_var *var)) { struct grub_env_var *var; - for (var = current_context->vars[i]; var; var = var->next) + for (var = grub_current_context->vars[i]; var; var = var->next) { struct grub_env_sorted_var *p, **q; - /* Ignore data slots. */ - if (var->type == GRUB_ENV_VAR_DATA) - continue; - sorted_var = grub_malloc (sizeof (*sorted_var)); if (! sorted_var) goto fail; @@ -343,84 +239,3 @@ grub_register_variable_hook (const char *name, return GRUB_ERR_NONE; } - -static char * -mangle_data_slot_name (const char *name) -{ - char *mangled_name; - - mangled_name = grub_malloc (grub_strlen (name) + 2); - if (! mangled_name) - return 0; - - grub_sprintf (mangled_name, "\e%s", name); - return mangled_name; -} - -grub_err_t -grub_env_set_data_slot (const char *name, const void *ptr) -{ - char *mangled_name; - struct grub_env_var *var; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - /* If the variable does already exist, just update the variable. */ - var = grub_env_find (mangled_name); - if (var) - { - var->value = (char *) ptr; - return GRUB_ERR_NONE; - } - - /* The variable does not exist, so create a new one. */ - var = grub_zalloc (sizeof (*var)); - if (! var) - goto fail; - - var->type = GRUB_ENV_VAR_DATA; - var->name = mangled_name; - var->value = (char *) ptr; - - grub_env_insert (current_context, var); - - return GRUB_ERR_NONE; - - fail: - - grub_free (mangled_name); - return grub_errno; -} - -void * -grub_env_get_data_slot (const char *name) -{ - char *mangled_name; - void *ptr = 0; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - ptr = grub_env_get (mangled_name); - grub_free (mangled_name); - - fail: - - return ptr; -} - -void -grub_env_unset_data_slot (const char *name) -{ - char *mangled_name; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - return; - - grub_env_unset (mangled_name); - grub_free (mangled_name); -} diff --git a/kern/main.c b/kern/main.c index 9215d55e7..b76d2d20e 100644 --- a/kern/main.c +++ b/kern/main.c @@ -114,7 +114,6 @@ grub_set_root_dev (void) const char *prefix; grub_register_variable_hook ("root", 0, grub_env_write_root); - grub_env_export ("root"); prefix = grub_env_get ("prefix"); @@ -164,7 +163,6 @@ grub_main (void) /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); - grub_env_export ("prefix"); grub_set_root_dev (); grub_register_core_commands (); diff --git a/normal/context.c b/normal/context.c new file mode 100644 index 000000000..d9ad3b61d --- /dev/null +++ b/normal/context.c @@ -0,0 +1,172 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 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 + +struct menu_pointer +{ + grub_menu_t menu; + struct menu_pointer *prev; +}; + +struct menu_pointer initial_menu; +struct menu_pointer *current_menu = &initial_menu; + +void +grub_env_unset_menu (void) +{ + current_menu->menu = NULL; +} + +grub_menu_t +grub_env_get_menu (void) +{ + return current_menu->menu; +} + +void +grub_env_set_menu (grub_menu_t nmenu) +{ + current_menu->menu = nmenu; +} + +grub_err_t +grub_env_context_open (int export) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + context = grub_zalloc (sizeof (*context)); + if (! context) + return grub_errno; + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return grub_errno; + + context->prev = grub_current_context; + grub_current_context = context; + + menu->prev = current_menu; + current_menu = menu; + + /* Copy exported variables. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = context->prev->vars[i]; var; var = var->next) + { + if (export && var->global) + { + if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_register_variable_hook (var->name, var->read_hook, var->write_hook); + } + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_context_close (void) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + if (! grub_current_context->prev) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "cannot close the initial context"); + + /* Free the variables associated with this context. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *p, *q; + + for (p = grub_current_context->vars[i]; p; p = q) + { + q = p->next; + grub_free (p->name); + grub_free (p->value); + grub_free (p); + } + } + + /* Restore the previous context. */ + context = grub_current_context->prev; + grub_free (grub_current_context); + grub_current_context = context; + + menu = current_menu->prev; + grub_free (current_menu); + current_menu = menu; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (var) + var->global = 1; + + return GRUB_ERR_NONE; +} + +static grub_command_t export_cmd; + +static grub_err_t +grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no environment variable specified"); + + grub_env_export (args[0]); + return 0; +} + +void +grub_context_init (void) +{ + grub_env_export ("root"); + grub_env_export ("prefix"); + + export_cmd = grub_register_command ("export", grub_cmd_export, + "export ENVVAR", "Export a variable."); +} + +void +grub_context_fini (void) +{ + grub_unregister_command (export_cmd); +} diff --git a/normal/main.c b/normal/main.c index f080a6971..52581613a 100644 --- a/normal/main.c +++ b/normal/main.c @@ -133,7 +133,7 @@ free_menu (grub_menu_t menu) } grub_free (menu); - grub_env_unset_data_slot ("menu"); + grub_env_unset_menu (); } static void @@ -174,7 +174,7 @@ grub_normal_add_menu_entry (int argc, const char **args, return grub_errno; classes_tail = classes_head; - menu = grub_env_get_data_slot ("menu"); + menu = grub_env_get_menu (); if (! menu) return grub_error (GRUB_ERR_MENU, "no menu context"); @@ -357,14 +357,14 @@ read_config_file (const char *config) grub_menu_t newmenu; - newmenu = grub_env_get_data_slot ("menu"); + newmenu = grub_env_get_menu (); if (! newmenu) { newmenu = grub_zalloc (sizeof (*newmenu)); if (! newmenu) return 0; - grub_env_set_data_slot ("menu", newmenu); + grub_env_set_menu (newmenu); } /* Try to open the config file. */ @@ -562,6 +562,8 @@ grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), GRUB_MOD_INIT(normal) { + grub_context_init (); + /* Normal mode shouldn't be unloaded. */ if (mod) grub_dl_ref (mod); @@ -589,6 +591,8 @@ GRUB_MOD_INIT(normal) GRUB_MOD_FINI(normal) { + grub_context_fini (); + grub_set_history (0); grub_reader_unregister (&grub_normal_reader); grub_register_variable_hook ("pager", 0, 0); From 4011be3b1a647596572e2c79349bd70adcaecc42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Dec 2009 14:21:04 +0100 Subject: [PATCH 06/24] ChangeLog --- ChangeLog.newenv | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 ChangeLog.newenv diff --git a/ChangeLog.newenv b/ChangeLog.newenv new file mode 100644 index 000000000..3c1b09cfc --- /dev/null +++ b/ChangeLog.newenv @@ -0,0 +1,55 @@ +2009-12-20 Vladimir Serbinenko + + Move context handling out of the kernel. + + * conf/any-emu.rmk (grub_emu_SOURCES): Add normal/context.c. + * conf/common.rmk (normal_mod_SOURCES): Add normal/context.c. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add env_private.h. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/env.h: Include grub/menu.h. + (grub_env_var_type): Removed. + (grub_env_var): Replaced field 'type' with 'global'. + (grub_env_find): New prototype. + (grub_env_context_open): Remove EXPORT_FUNC. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (grub_env_set_data_slot): Removed. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + (grub_env_unset_menu): New prototype. + (grub_env_set_menu): Likewise. + (grub_env_get_menu): Likewise. + * include/grub/env_private.h: New file. + * include/grub/normal.h (grub_context_init): New prototype. + (grub_context_fini): Likewise. + * kern/corecmd.c (grub_core_cmd_export): Moved from here ... + * normal/context.c (grub_cmd_export): ... to here. + * kern/env.c: Include env_private.h. + (HASHSZ): Moved to include/grub/env_private.h. + (grub_env_context): Likewise. + (grub_env_sorted_var): Likewise. + (current_context): Renamed from this ... + (grub_current_context): ...to this. 'static' removed. All users updated. + (grub_env_find): Removed 'static'. + (grub_env_context_open): Moved to normal/context.c. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (mangle_data_slot_name): Removed. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + * kern/main.c (grub_set_root_dev): Don't export root. + It will be done later. + (grub_main): Don't export prefix. + It will be done later. + * normal/context.c: New file. + * normal/main.c (free_menu): Use grub_env_unset_menu. + (grub_normal_add_menu_entry): Use grub_env_get_menu. + (read_config_file): Use grub_env_get_menu and grub_env_set_menu. + (GRUB_MOD_INIT(normal)): Call grub_context_init. + (GRUB_MOD_FINI(normal)): Call grub_context_fini. From fbb8a88714844a34b9a817e2af8960bda6e4ce58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 22 Dec 2009 15:09:25 +0100 Subject: [PATCH 07/24] Byte-addressable PCI config space --- ChangeLog.pciclean | 52 +++++++++++++++++++++++++++++++++++++++++ bus/pci.c | 6 ++--- bus/usb/ohci.c | 4 ++-- bus/usb/uhci.c | 4 ++-- commands/efi/fixvideo.c | 2 +- commands/efi/loadbios.c | 4 ++-- commands/lspci.c | 22 ++++++++++------- disk/ata.c | 9 ++++--- include/grub/pci.h | 31 ++++++++++++++++++++++++ loader/i386/efi/linux.c | 2 +- loader/i386/efi/xnu.c | 2 +- util/pci.c | 2 +- video/efi_uga.c | 2 +- 13 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 ChangeLog.pciclean diff --git a/ChangeLog.pciclean b/ChangeLog.pciclean new file mode 100644 index 000000000..f50a48875 --- /dev/null +++ b/ChangeLog.pciclean @@ -0,0 +1,52 @@ +2009-12-22 Vladimir Serbinenko + + Byte-addressable PCI configuration space. + + * bus/pci.c (grub_pci_make_address): Use byte address instead of + dword address. + (grub_pci_iterate): Use macroses GRUB_PCI_REG_PCI_ID and + GRUB_PCI_REG_CACHELINE. + * bus/usb/ohci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG0. + * bus/usb/uhci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG4. + * commands/efi/fixvideo.c (scan_card): Use macros GRUB_PCI_REG_CLASS. + * commands/efi/loadbios.c (enable_rom_area): Pass byte-address to + grub_pci_make_address. + (lock_rom_area): Likewise. + * commands/lspci.c (grub_lspci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESSES. Handle byte-addressing + of grub_pci_make_address. + * disk/ata.c (grub_ata_pciinit): Likewise. + * include/grub/pci.h (GRUB_PCI_REG_PCI_ID): New macro. + (GRUB_PCI_REG_VENDOR): Likewise. + (GRUB_PCI_REG_DEVICE): Likewise. + (GRUB_PCI_REG_COMMAND): Likewise. + (GRUB_PCI_REG_STATUS): Likewise. + (GRUB_PCI_REG_REVISION): Likewise. + (GRUB_PCI_REG_CLASS): Likewise. + (GRUB_PCI_REG_CACHELINE): Likewise. + (GRUB_PCI_REG_LAT_TIMER): Likewise. + (GRUB_PCI_REG_HEADER_TYPE): Likewise. + (GRUB_PCI_REG_BIST): Likewise. + (GRUB_PCI_REG_ADDRESSES): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_CIS_POINTER): Likewise. + (GRUB_PCI_REG_SUBVENDOR): Likewise. + (GRUB_PCI_REG_SUBSYSTEM): Likewise. + (GRUB_PCI_REG_ROM_ADDRESS): Likewise. + (GRUB_PCI_REG_CAP_POINTER): Likewise. + (GRUB_PCI_REG_IRQ_LINE): Likewise. + (GRUB_PCI_REG_IRQ_PIN): Likewise. + (GRUB_PCI_REG_MIN_GNT): Likewise. + (GRUB_PCI_REG_MAX_LAT): Likewise. + * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. + * loader/i386/efi/xnu.c (find_framebuf): Likewise. + * video/efi_uga.c (find_framebuf): Likewise. + * util/pci.c (grub_pci_make_address): Use byte-addressed configuration + space. diff --git a/bus/pci.c b/bus/pci.c index fe4cad181..13b67c908 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -24,7 +24,7 @@ grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) { return (1 << 31) | (dev.bus << 16) | (dev.device << 11) - | (dev.function << 8) | (reg << 2); + | (dev.function << 8) | reg; } void @@ -41,7 +41,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) { for (dev.function = 0; dev.function < 8; dev.function++) { - addr = grub_pci_make_address (dev, 0); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID); id = grub_pci_read (addr); /* Check if there is a device present. */ @@ -54,7 +54,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) /* Probe only func = 0 if the device if not multifunction */ if (dev.function == 0) { - addr = grub_pci_make_address (dev, 3); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE); hdr = grub_pci_read (addr); if (!(hdr & 0x800000)) break; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 5fe9c9507..6d185bc7f 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -126,7 +126,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_uint32_t revision; grub_uint32_t frame_interval; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -138,7 +138,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 4); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); base = grub_pci_read (addr); #if 0 diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index e83fccc1d..947f2367b 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -150,7 +150,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, struct grub_uhci *u; int i; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -162,7 +162,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 8); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4); base = grub_pci_read (addr); /* Stop if there is no IO space base address defined. */ if (! (base & 1)) diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c index 685662237..dea69c8b1 100644 --- a/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -42,7 +42,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index d7ad42690..183ba7e85 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -50,7 +50,7 @@ enable_rom_area (void) return 0; } - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); grub_pci_write_byte (addr++, 0x33); @@ -76,7 +76,7 @@ lock_rom_area (void) grub_pci_address_t addr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); grub_pci_write_byte (addr++, 0x11); diff --git a/commands/lspci.c b/commands/lspci.c index 559bb8242..c515da762 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -134,7 +134,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), pciid & 0xFFFF, pciid >> 16); - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Lookup the class name, if there isn't a specific one, @@ -155,14 +155,14 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (iospace) { - reg = 4; - while (reg < 10) + reg = GRUB_PCI_REG_ADDRESSES; + while (reg < GRUB_PCI_REG_CIS_POINTER) { grub_uint64_t space; addr = grub_pci_make_address (dev, reg); space = grub_pci_read (addr); - reg++; + reg += sizeof (grub_uint32_t); if (space == 0) continue; @@ -170,7 +170,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) switch (space & GRUB_PCI_ADDR_SPACE_MASK) { case GRUB_PCI_ADDR_SPACE_IO: - grub_printf ("\tIO space %d at 0x%llx\n", (reg - 1) - 4, + grub_printf ("\tIO space %d at 0x%llx\n", + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_IO_MASK)); break; @@ -180,9 +182,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { addr = grub_pci_make_address (dev, reg); space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; - reg++; + reg += sizeof (grub_uint32_t); grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", - (reg - 2) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 2, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); @@ -190,7 +194,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } else grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", - (reg - 1) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); diff --git a/disk/ata.c b/disk/ata.c index af8c87180..bc8383d4e 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -402,7 +402,7 @@ grub_ata_pciinit (grub_pci_device_t dev, static int controller = 0; /* Read class. */ - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Check if this class ID matches that of a PCI IDE Controller. */ @@ -429,9 +429,12 @@ grub_ata_pciinit (grub_pci_device_t dev, { /* Read the BARs, which either contain a mmapped IO address or the IO port address. */ - addr = grub_pci_make_address (dev, 4 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i); bar1 = grub_pci_read (addr); - addr = grub_pci_make_address (dev, 5 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i + + sizeof (grub_uint32_t)); bar2 = grub_pci_read (addr); /* Check if the BARs describe an IO region. */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 2bea05410..1f3ac7fc7 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -35,6 +35,37 @@ #define GRUB_PCI_ADDR_MEM_MASK ~0xf #define GRUB_PCI_ADDR_IO_MASK ~0x03 +#define GRUB_PCI_REG_PCI_ID 0x00 +#define GRUB_PCI_REG_VENDOR 0x00 +#define GRUB_PCI_REG_DEVICE 0x02 +#define GRUB_PCI_REG_COMMAND 0x04 +#define GRUB_PCI_REG_STATUS 0x06 +#define GRUB_PCI_REG_REVISION 0x08 +#define GRUB_PCI_REG_CLASS 0x08 +#define GRUB_PCI_REG_CACHELINE 0x0c +#define GRUB_PCI_REG_LAT_TIMER 0x0d +#define GRUB_PCI_REG_HEADER_TYPE 0x0e +#define GRUB_PCI_REG_BIST 0x0f +#define GRUB_PCI_REG_ADDRESSES 0x10 + +/* Beware that 64-bit address takes 2 registers. */ +#define GRUB_PCI_REG_ADDRESS_REG0 0x10 +#define GRUB_PCI_REG_ADDRESS_REG1 0x14 +#define GRUB_PCI_REG_ADDRESS_REG2 0x18 +#define GRUB_PCI_REG_ADDRESS_REG3 0x1c +#define GRUB_PCI_REG_ADDRESS_REG4 0x20 +#define GRUB_PCI_REG_ADDRESS_REG5 0x24 + +#define GRUB_PCI_REG_CIS_POINTER 0x28 +#define GRUB_PCI_REG_SUBVENDOR 0x2c +#define GRUB_PCI_REG_SUBSYSTEM 0x2e +#define GRUB_PCI_REG_ROM_ADDRESS 0x30 +#define GRUB_PCI_REG_CAP_POINTER 0x34 +#define GRUB_PCI_REG_IRQ_LINE 0x3c +#define GRUB_PCI_REG_IRQ_PIN 0x3d +#define GRUB_PCI_REG_MIN_GNT 0x3e +#define GRUB_PCI_REG_MAX_LAT 0x3f + typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_UTIL diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 8cd4d23f2..ad09f7c36 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -477,7 +477,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 236732804..af54ac5c1 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -79,7 +79,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/util/pci.c b/util/pci.c index a0c1867be..420ae320b 100644 --- a/util/pci.c +++ b/util/pci.c @@ -26,7 +26,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) { grub_pci_address_t ret; ret.dev = dev; - ret.pos = reg << 2; + ret.pos = reg; return ret; } diff --git a/video/efi_uga.c b/video/efi_uga.c index 9bca64306..959b266a9 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -92,7 +92,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; From adc89895e05a4cdd5cd69bfc313fd09633f900f9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 22 Dec 2009 16:42:45 +0100 Subject: [PATCH 08/24] setpci implementation --- commands/setpci.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++ conf/i386.rmk | 6 + 2 files changed, 346 insertions(+) create mode 100644 commands/setpci.c diff --git a/commands/setpci.c b/commands/setpci.c new file mode 100644 index 000000000..aa5e51de9 --- /dev/null +++ b/commands/setpci.c @@ -0,0 +1,340 @@ +/* lspci.c - List PCI devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 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 +#include + +struct pci_register +{ + const char *name; + grub_uint16_t addr; + unsigned size; +}; + +struct pci_register pci_registers[] = + { + {"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2}, + {"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2}, + {"COMMAND", GRUB_PCI_REG_COMMAND , 2}, + {"STATUS", GRUB_PCI_REG_STATUS , 2}, + {"REVISION", GRUB_PCI_REG_REVISION , 1}, + {"CLASS_PROG", GRUB_PCI_REG_CLASS + 1 , 1}, + {"CLASS_DEVICE", GRUB_PCI_REG_CLASS + 2 , 2}, + {"CACHE_LINE_SIZE", GRUB_PCI_REG_CACHELINE , 1}, + {"LATENCY_TIMER", GRUB_PCI_REG_LAT_TIMER , 1}, + {"HEADER_TYPE", GRUB_PCI_REG_HEADER_TYPE , 1}, + {"BIST", GRUB_PCI_REG_BIST , 1}, + {"BASE_ADDRESS_0", GRUB_PCI_REG_ADDRESS_REG0, 4}, + {"BASE_ADDRESS_1", GRUB_PCI_REG_ADDRESS_REG1, 4}, + {"BASE_ADDRESS_2", GRUB_PCI_REG_ADDRESS_REG2, 4}, + {"BASE_ADDRESS_3", GRUB_PCI_REG_ADDRESS_REG3, 4}, + {"BASE_ADDRESS_4", GRUB_PCI_REG_ADDRESS_REG4, 4}, + {"BASE_ADDRESS_5", GRUB_PCI_REG_ADDRESS_REG5, 4}, + {"CARDBUS_CIS", GRUB_PCI_REG_CIS_POINTER , 4}, + {"SUBVENDOR_ID", GRUB_PCI_REG_SUBVENDOR , 2}, + {"SUBSYSTEM_ID", GRUB_PCI_REG_SUBSYSTEM , 2}, + {"ROM_ADDRESS", GRUB_PCI_REG_ROM_ADDRESS , 4}, + {"CAP_POINTER", GRUB_PCI_REG_CAP_POINTER , 1}, + {"INTERRUPT_LINE", GRUB_PCI_REG_IRQ_LINE , 1}, + {"INTERRUPT_PIN", GRUB_PCI_REG_IRQ_PIN , 1}, + {"MIN_GNT", GRUB_PCI_REG_MIN_GNT , 1}, + {"MAX_LAT", GRUB_PCI_REG_MIN_GNT , 1}, + }; + +static const struct grub_arg_option options[] = + { + {0, 'd', 0, "Select device by vendor and device IDs.", + "[vendor]:[device]", ARG_TYPE_STRING}, + {0, 's', 0, "Select device by its position on the bus.", + "[bus]:[slot][.func]", ARG_TYPE_STRING}, + {0, 'v', 0, "Save read value into variable VARNAME.", + "VARNAME", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_uint32_t pciid_check_mask, pciid_check_value; +static int bus, device, function; +static int check_bus, check_device, check_function; +static grub_uint32_t write_mask, regwrite; +static int regsize; +static grub_uint16_t regaddr; +static const char *varname; + +static int NESTED_FUNC_ATTR +grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) +{ + grub_uint32_t regval = 0; + grub_pci_address_t addr; + + if ((pciid & pciid_check_mask) != pciid_check_value) + return 0; + + if (check_bus && grub_pci_get_bus (dev) != bus) + return 0; + + if (check_device && grub_pci_get_device (dev) != device) + return 0; + + if (check_function && grub_pci_get_function (dev) != device) + return 0; + + addr = grub_pci_make_address (dev, regaddr); + + switch (regsize) + { + case 1: + regval = grub_pci_read_byte (addr); + break; + + case 2: + regval = grub_pci_read_word (addr); + break; + + case 4: + regval = grub_pci_read (addr); + break; + } + + if (varname) + { + char buf[sizeof ("XXXXXXXX")]; + grub_sprintf (buf, "%x", regval); + grub_env_set (varname, buf); + return 1; + } + + if (!write_mask) + { + grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr, + grub_pci_get_bus (dev), + grub_pci_get_device (dev), + grub_pci_get_function (dev), + regval); + return 0; + } + + regval = (regval & ~write_mask) | regwrite; + + switch (regsize) + { + case 1: + grub_pci_write_byte (addr, regval); + break; + + case 2: + grub_pci_write_word (addr, regval); + break; + + case 4: + grub_pci_write (addr, regval); + break; + } + + return 0; +} + +static grub_err_t +grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) +{ + const char *ptr; + unsigned i; + + pciid_check_value = 0; + pciid_check_mask = 0; + + if (cmd->state[0].set) + { + ptr = cmd->state[0].arg; + pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = cmd->state[0].arg; + } + else + pciid_check_mask |= 0xffff; + if (grub_errno) + return grub_errno; + if (*ptr != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); + ptr++; + pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) + << 16; + if (grub_errno == GRUB_ERR_BAD_NUMBER) + grub_errno = GRUB_ERR_NONE; + else + pciid_check_mask |= 0xffff0000; + } + + pciid_check_value &= pciid_check_mask; + + check_bus = check_device = check_function = 0; + + if (cmd->state[1].set) + { + const char *optr; + + ptr = cmd->state[1].arg; + optr = ptr; + bus = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = optr; + } + else + check_bus = 1; + if (grub_errno) + return grub_errno; + if (*ptr != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); + ptr++; + optr = ptr; + device = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = optr; + } + else + check_device = 1; + if (*ptr == '.') + { + ptr++; + function = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + check_function = 1; + } + } + + if (cmd->state[2].set) + varname = cmd->state[2].arg; + else + varname = NULL; + + write_mask = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Command expected."); + + if (argc > 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one command is supported."); + + ptr = argv[0]; + + for (i = 0; i < ARRAY_SIZE (pci_registers); i++) + { + if (grub_strncmp (ptr, pci_registers[i].name, + grub_strlen (pci_registers[i].name)) == 0) + break; + } + if (i == ARRAY_SIZE (pci_registers)) + { + regsize = 0; + regaddr = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register"); + } + else + { + regaddr = pci_registers[i].addr; + regsize = pci_registers[i].size; + ptr += grub_strlen (pci_registers[i].name); + } + + if (grub_errno) + return grub_errno; + + if (*ptr == '+') + { + ptr++; + regaddr += grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + } + + if (grub_memcmp (ptr, ".L", sizeof (".L") - 1) == 0 + || grub_memcmp (ptr, ".l", sizeof (".l") - 1) == 0) + { + regsize = 4; + ptr += sizeof (".l") - 1; + } + else if (grub_memcmp (ptr, ".W", sizeof (".W") - 1) == 0 + || grub_memcmp (ptr, ".w", sizeof (".w") - 1) == 0) + { + regsize = 2; + ptr += sizeof (".w") - 1; + } + else if (grub_memcmp (ptr, ".B", sizeof (".B") - 1) == 0 + || grub_memcmp (ptr, ".b", sizeof (".b") - 1) == 0) + { + regsize = 1; + ptr += sizeof (".b") - 1; + } + + if (!regsize) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unknown register size."); + + write_mask = 0; + if (*ptr == '=') + { + ptr++; + regwrite = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + write_mask = 0xffffffff; + if (*ptr == ':') + { + ptr++; + write_mask = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + write_mask = 0xffffffff; + } + regwrite &= write_mask; + } + + if (write_mask && varname) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Option -v isn't valid for writes."); + + grub_pci_iterate (grub_setpci_iter); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(setpci) +{ + cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH, + "setpci [-s POSITION] [-d DEVICE] [-v VAR] " + "[REGISTER][=VALUE[:MASK]]", + "Manipulate PCI devices.", options); +} + +GRUB_MOD_FINI(setpci) +{ + grub_unregister_extcmd (cmd); +} diff --git a/conf/i386.rmk b/conf/i386.rmk index c3f036d0f..2c1edf62f 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -25,3 +25,9 @@ pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For setpci.mod +pkglib_MODULES += setpci.mod +setpci_mod_SOURCES = commands/setpci.c +setpci_mod_CFLAGS = $(COMMON_CFLAGS) +setpci_mod_LDFLAGS = $(COMMON_LDFLAGS) From 281d82347e4c6fdfe31e5c3a18196f373651af4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Dec 2009 17:02:03 +0100 Subject: [PATCH 09/24] ChangeLog --- ChangeLog.setpci | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.setpci diff --git a/ChangeLog.setpci b/ChangeLog.setpci new file mode 100644 index 000000000..e488379ce --- /dev/null +++ b/ChangeLog.setpci @@ -0,0 +1,9 @@ +2009-12-27 Vladimir Serbinenko + + setpci support. + + * commands/setpci.c: New file. + * conf/i386.rmk (pkglib_MODULES): Add setpci.mod. + (setpci_mod_SOURCES): New variable. + (setpci_mod_CFLAGS): Likewise. + (setpci_mod_LDFLAGS): Likewise. From aa2209101c1f140c562a83449e9c443c2e6c448f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 22:23:28 +0100 Subject: [PATCH 10/24] Fix i386-qemu compilation --- conf/i386-coreboot.rmk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 1efea8afb..6f078a256 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -80,7 +80,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) From dccad19408df39cdde9a4c9422bc25dfacfa303c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 22:37:36 +0100 Subject: [PATCH 11/24] Fix compilation on x86_64-efi --- commands/lspci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/lspci.c b/commands/lspci.c index c515da762..ab756616a 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -171,7 +171,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { case GRUB_PCI_ADDR_SPACE_IO: grub_printf ("\tIO space %d at 0x%llx\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_IO_MASK)); @@ -184,7 +184,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; reg += sizeof (grub_uint32_t); grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 2, (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), @@ -194,7 +194,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } else grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), From 07e727f751028b3f9cdfa2c0ab892b8307e41d2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 17:53:10 +0100 Subject: [PATCH 12/24] Add missing include --- normal/context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/normal/context.c b/normal/context.c index 412dbd84c..08a841699 100644 --- a/normal/context.c +++ b/normal/context.c @@ -22,6 +22,7 @@ #include #include #include +#include struct menu_pointer { From 02cf98ca8d6d7663864adbb5e44a8c76c9ab4096 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 13:27:23 +0100 Subject: [PATCH 13/24] 2010-01-20 Vladimir Serbinenko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz as possible unifont location (Gentoo). Reported by: Alexander Brüning --- ChangeLog | 6 ++++++ configure.ac | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f814b940d..9883b5f02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-20 Vladimir Serbinenko + + * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz + as possible unifont location (Gentoo). + Reported by: Alexander Brüning + 2010-01-20 Vladimir Serbinenko Don't try to generate lists for kernel.img. diff --git a/configure.ac b/configure.ac index a8e137b90..b1435de44 100644 --- a/configure.ac +++ b/configure.ac @@ -168,7 +168,7 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi -for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz ; do +for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do if test -e $file ; then AC_SUBST([FONT_SOURCE], [$file]) break From 94fabf587a791d77daf7eeee4c2442d469348e06 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 13:55:30 +0000 Subject: [PATCH 14/24] 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix handling of locale_dir. --- ChangeLog | 4 ++++ util/grub.d/00_header.in | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9883b5f02..fbd2a37db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix handling of locale_dir. + 2010-01-20 Vladimir Serbinenko * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0048ebed1..0610792c6 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,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 @@ -122,7 +122,9 @@ esac # Gettext variables and module if [ "x${LANG}" != "xC" ] ; then + prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF +set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) set locale_dir=${locale_dir} set lang=${grub_lang} insmod gettext From 34a66d995b3fc6222cdbfaa2c3cf48398de3034c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 14:10:46 +0000 Subject: [PATCH 15/24] 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix stupid mistake from last commit. --- ChangeLog | 4 ++++ util/grub.d/00_header.in | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fbd2a37db..547070e8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix stupid mistake from last commit. + 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix handling of locale_dir. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0610792c6..23e0cb569 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -125,7 +125,6 @@ if [ "x${LANG}" != "xC" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) -set locale_dir=${locale_dir} set lang=${grub_lang} insmod gettext EOF From cbca0ada6273773415e192fb53e9e987f17b05f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 15:26:31 +0100 Subject: [PATCH 16/24] 2010-01-20 Vladimir Serbinenko Fix any-emu compilation. * conf/any-emu.rmk (bin_UTILITIES): Add grub-bin2h. * grub_bin2h_SOURCES: New variable. --- ChangeLog | 7 +++++++ conf/any-emu.rmk | 3 +++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 547070e8a..7274a9920 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-20 Vladimir Serbinenko + + Fix any-emu compilation. + + * conf/any-emu.rmk (bin_UTILITIES): Add grub-bin2h. + * grub_bin2h_SOURCES: New variable. + 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix stupid mistake from last commit. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index cee9e8338..5aa923893 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -98,3 +98,6 @@ endif grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h + +bin_UTILITIES += grub-bin2h +grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c From f66924a414b5440c06d73d0a4d74ded3cb580637 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 14:40:00 +0000 Subject: [PATCH 17/24] 2010-01-20 Robert Millan * util/misc.c (make_system_path_relative_to_its_root): Work around special-casing of "/", as previous incarnation of this routine did. --- ChangeLog | 5 +++++ util/misc.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7274a9920..c4048a66e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Robert Millan + + * util/misc.c (make_system_path_relative_to_its_root): Work around + special-casing of "/", as previous incarnation of this routine did. + 2010-01-20 Vladimir Serbinenko Fix any-emu compilation. diff --git a/util/misc.c b/util/misc.c index 0b682c445..c5ab62e42 100644 --- a/util/misc.c +++ b/util/misc.c @@ -577,6 +577,13 @@ make_system_path_relative_to_its_root (const char *path) len--; } + /* This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ + if (!strcmp (buf3, "/")) + buf3[0] = '\0'; + return buf3; } From 00308ecfe8d536340a319ae5a33dc001589bf843 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 15:43:21 +0100 Subject: [PATCH 18/24] 2010-01-20 Vladimir Serbinenko * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. --- ChangeLog | 4 ++++ conf/common.rmk | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index c4048a66e..c6b4d7baf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. + 2010-01-20 Robert Millan * util/misc.c (make_system_path_relative_to_its_root): Work around diff --git a/conf/common.rmk b/conf/common.rmk index 956ed8ec3..4e5ed9c73 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -638,7 +638,9 @@ png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += font.mod +ifneq (, $(FONT_SOURCE)) font/font.c_DEPENDENCIES = ascii.h +endif font_mod_SOURCES = font/font_cmd.c font/font.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) From d44844828a137c0325c46aedb56c2946ccb30aa0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 16:30:20 +0000 Subject: [PATCH 19/24] 2010-01-20 Robert Millan * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down that VESA is supported. (grub_linux_boot): Use generic framebuffer unless VESA is known to be supported. --- ChangeLog | 7 +++++++ loader/i386/linux.c | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6b4d7baf..f96b99f77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-20 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down + that VESA is supported. + (grub_linux_boot): Use generic framebuffer unless VESA is known to be + supported. + 2010-01-20 Vladimir Serbinenko * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 5d9edbe7d..831d8b25a 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -536,7 +536,11 @@ grub_linux_boot (void) } if (! grub_linux_setup_video (params)) - params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + { + /* Use generic framebuffer unless VESA is known to be supported. */ + if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA) + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + } else { params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; @@ -794,6 +798,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), break; } + /* We can't detect VESA, but user is implicitly telling us that it + is built-in because `vga=' parameter was used. */ + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + linux_mode = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START]; From 96d73208a17dea7455a9dee49fc57270bd41919c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 17:01:12 +0000 Subject: [PATCH 20/24] 2010-01-20 Robert Millan * util/grub.d/10_linux.in (linux_entry): Set gfxpayload=keep when it can be reliably determined to be supported. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index f96b99f77..4ef13e931 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Robert Millan + + * util/grub.d/10_linux.in (linux_entry): Set gfxpayload=keep when it + can be reliably determined to be supported. + 2010-01-20 Robert Millan * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 3ecf454e2..90a6e83e7 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -60,6 +60,15 @@ linux_entry () fi printf "menuentry \"${title}\" {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" + + # Use ELILO's generic "efifb" when it's known to be available. + # FIXME: We need an interface to select vesafb in case efifb can't be used. + if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null ; then + cat << EOF + set gfxpayload=keep +EOF + fi + if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi From 61c8e880e455d4c129ab06cae7f79f98e1014256 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:33:01 +0100 Subject: [PATCH 21/24] Add comments to loadbios.c --- commands/efi/loadbios.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index 183ba7e85..f48e4c5cb 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -50,6 +50,7 @@ enable_rom_area (void) return 0; } + /* FIXME: should be macroified. */ addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); @@ -76,6 +77,7 @@ lock_rom_area (void) grub_pci_address_t addr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; + /* FIXME: should be macroified. */ addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); From fdb1b2ea4e9eba8272b47e07029b05ffa6af5984 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:49:18 +0100 Subject: [PATCH 22/24] 2010-01-20 Vladimir Serbinenko * video/sm712.c (grub_video_sm712_setup): Use GRUB_PCI_REG_CLASS. --- ChangeLog | 1 + video/sm712.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b54f6aeec..d789f821e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,6 +48,7 @@ * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. * loader/i386/efi/xnu.c (find_framebuf): Likewise. * video/efi_uga.c (find_framebuf): Likewise. + * video/sm712.c (grub_video_sm712_setup): Likewise. * util/pci.c (grub_pci_make_address): Use byte-addressed configuration space. diff --git a/video/sm712.c b/video/sm712.c index 1e0f59b9d..a86470b7d 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -74,7 +74,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, grub_pci_address_t addr; grub_uint32_t class; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f) @@ -82,7 +82,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, found = 1; - addr = grub_pci_make_address (dev, 4); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); framebuffer.base = grub_pci_read (addr); framebuffer.dev = dev; From baccdb23a716413b74faaae556e7fbad5eb2c951 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:54:58 +0100 Subject: [PATCH 23/24] Use grub_snprintf in commands/setpci.c --- commands/setpci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/setpci.c b/commands/setpci.c index aa5e51de9..f780547a2 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -118,7 +118,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (varname) { char buf[sizeof ("XXXXXXXX")]; - grub_sprintf (buf, "%x", regval); + grub_snprintf (buf, sizeof (buf), "%x", regval); grub_env_set (varname, buf); return 1; } From a9ed4ff36fde7c285cdeb80879dd70659190b7a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 22:21:08 +0100 Subject: [PATCH 24/24] 2010-01-20 Vladimir Serbinenko * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h --- ChangeLog | 6 +++++- conf/mips.rmk | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb66685b1..64aa9d593 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2009-11-29 Vladimir Serbinenko +2010-01-20 Vladimir Serbinenko + + * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h + +2010-01-20 Vladimir Serbinenko Optimise glyph lookup by Basic Multilingual Plane lookup array. diff --git a/conf/mips.rmk b/conf/mips.rmk index d0b1c484c..1ef4fc395 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h + command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h env_private.h ifeq ($(platform), yeeloong) kernel_img_HEADERS += pci.h