aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:41:12 +0200
committerFathi Boudra <fathi.boudra@linaro.org>2013-03-30 17:41:12 +0200
commite7f59a65345484ede230500400b774db8c9a6d6f (patch)
tree6c5c4e16d85820f6efa92dddb61e8fec47a9f528
parentf4243e63fd6e9588757edb1cca3cc3d88bc22faf (diff)
Imported Upstream version 2.00+bzr4618+20130322upstream/2.00+bzr4618+20130322upstream
-rw-r--r--ChangeLog384
-rw-r--r--config.h.in5
-rw-r--r--configure.ac19
-rw-r--r--grub-core/Makefile.am27
-rw-r--r--grub-core/Makefile.core.def47
-rw-r--r--grub-core/bus/usb/ehci.c8
-rw-r--r--grub-core/bus/usb/serial/common.c15
-rw-r--r--grub-core/bus/usb/serial/ftdi.c6
-rw-r--r--grub-core/bus/usb/serial/pl2303.c6
-rw-r--r--grub-core/bus/usb/serial/usbdebug_late.c93
-rw-r--r--grub-core/bus/usb/usb.c78
-rw-r--r--grub-core/bus/usb/usbhub.c355
-rw-r--r--grub-core/bus/usb/usbtrans.c60
-rw-r--r--grub-core/commands/boottime.c65
-rw-r--r--grub-core/commands/i386/cmosdump.c64
-rw-r--r--grub-core/commands/i386/coreboot/cb_timestamps.c118
-rw-r--r--grub-core/commands/i386/coreboot/cbls.c128
-rw-r--r--grub-core/commands/keystatus.c2
-rw-r--r--grub-core/commands/lsacpi.c77
-rw-r--r--grub-core/commands/terminal.c12
-rw-r--r--grub-core/commands/usbtest.c2
-rw-r--r--grub-core/commands/verify.c5
-rw-r--r--grub-core/disk/cryptodisk.c5
-rw-r--r--grub-core/disk/ieee1275/ofdisk.c59
-rw-r--r--grub-core/disk/usbms.c27
-rw-r--r--grub-core/fs/fshelp.c8
-rw-r--r--grub-core/fs/xfs.c4
-rw-r--r--grub-core/kern/dl.c3
-rw-r--r--grub-core/kern/elfXX.c144
-rw-r--r--grub-core/kern/i386/coreboot/mmap.c2
-rw-r--r--grub-core/kern/i386/pit.c49
-rw-r--r--grub-core/kern/main.c81
-rw-r--r--grub-core/kern/misc.c39
-rw-r--r--grub-core/kern/term.c4
-rw-r--r--grub-core/normal/main.c13
-rw-r--r--grub-core/normal/term.c19
-rw-r--r--grub-core/term/i386/coreboot/cbmemc.c127
-rw-r--r--grub-core/term/usb_keyboard.c4
-rw-r--r--include/grub/acpi.h31
-rw-r--r--include/grub/boottime.h0
-rw-r--r--include/grub/i386/coreboot/lbio.h30
-rw-r--r--include/grub/ieee1275/ofdisk.h3
-rw-r--r--include/grub/kernel.h25
-rw-r--r--include/grub/misc.h20
-rw-r--r--include/grub/normal.h3
-rw-r--r--include/grub/term.h2
-rw-r--r--include/grub/usb.h31
-rw-r--r--include/grub/usbdesc.h9
-rw-r--r--include/grub/usbserial.h7
-rw-r--r--po/POTFILES.in1
50 files changed, 2004 insertions, 322 deletions
diff --git a/ChangeLog b/ChangeLog
index 74ef434..bcc2f92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,387 @@
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/verify.c (hashes): Add several hashes
+ from the spec.
+
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Slight improve in USB-related boot-time checkpoints.
+
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/boottime.c: Fix copyright header.
+
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ New commands cbmemc, lscoreboot, coreboot_boottime to inspect
+ coreboot tables content. Support for cbmemc.
+
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Fix a conflict between ports structures with 2 controllers of
+ same kind.
+
+2013-03-20 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * include/grub/boottime.h: Add missing file.
+
+2013-03-19 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Initialize USB ports in parallel to speed-up boot.
+
+2013-03-19 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Fix USB devices not being detected when requested
+ due to delayed attach.
+
+2013-03-19 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Implement boot time analysis framework.
+
+2013-03-19 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Remove get_endpoint_descriptor and change all functions needing
+ descriptor to just receive it as argument rather than endpoint
+ address.
+
+2013-03-19 Aleš Nesrsta <starous@volny.cz>
+
+ Better estimate the maximum USB transfer size.
+
+2013-03-17 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Resend a packet if we got the wrong buffer in status.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Use
+ multiplication rather than division.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/arg.c (grub_arg_list_alloc): Use shifts rather
+ than divisions.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/verify.c (grub_verify_signature): Use unsigned
+ operations to have intended shifts and not divisions.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/loader/i386/pc/plan9.c (fill_disk): Fix types to use
+ intended shifts rather than division.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * include/grub/datetime.h (grub_datetime2unixtime): Fix unixtime
+ computation for some years before epoch. Avode confusing division
+ while on it.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/video/i386/pc/vbe.c
+ (grub_video_vbe_print_adapter_specific_info): Replace division by
+ shifts.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Adjust types in gdb module to have intended unsigned shifts rather than
+ signed divisions.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/hfs.c (grub_hfs_read_file): Avoid divmod64 since the
+ maximum size is 4G - 1 on hfs
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Avoid costly 64-bit division in grub_get_time_ms on most platforms.
+
+2013-03-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/fshelp.c (grub_fshelp_log2blksize): Remove now unused
+ function.
+
+2013-03-07 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * grub-core/fs/iso9660.c (add_part): Remove always_inline attribute
+ causing gcc error with gcc 4.7.1.
+
+2013-03-07 Nickolai Zeldovich <nickolai@csail.mit.edu>
+
+ * grub-core/commands/acpi.c (grub_acpi_create_ebda): Don't
+ dereference null pointer. While the code is technically correct, gcc
+ may eliminate a null check if pointer is already dereferenced.
+
+2013-03-07 Nickolai Zeldovich <nickolai@csail.mit.edu>
+
+ * grub-core/normal/crypto.c (read_crypto_list): Fix incorrect
+ OOM check.
+ * grub-core/normal/term.c (read_terminal_list): Likewise.
+
+2013-03-07 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Lift up core size limits on some platforms. Fix potential memory
+ corruption with big core on small memory systems. Document remaining
+ limits.
+
+2013-03-05 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/term/terminfo.c (grub_terminfo_cls): Issue an explicit
+ gotoxy to 0,0.
+
+2013-03-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Remove all trampoline support. Add -Wtrampolines when
+ present. Remove symbols used for trampolines to make
+ link fail if trampolines are present.
+
+2013-03-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/script/execute.c (grub_script_arglist_to_argv): Move
+ append out of its parent.
+
+2013-03-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/regexp.c (set_matches): Move setvar out of its
+ parent.
+
+2013-03-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/env.c, include/grub/env.h: Change iterator through
+ all vars to a macro. All users updated.
+
+2013-03-03 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/disk/ieee1275/nand.c: Fix compilation on
+ i386-ieee1275.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * include/grub/cmos.h: Handle high CMOS addresses on sparc64.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * include/grub/mips/loongson/cmos.h: Fix high CMOS addresses.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Move to more hookless approach in IEEE1275 devices handling.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/term.c (grub_term_normal_color),
+ (grub_term_highlight_color): Add back lost defaults.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Make elfload not use hooks. Opt for flags and iterators instead.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/ia64/longjmp.S: Fix the name of longjmp function.
+ * grub-core/lib/ia64/setjmp.S: Fix the name of setjmp function.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/script/execute.c (gettext_append): Remove nested functions.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/normal/charset.c (grub_bidi_logical_to_visual): Add
+ hook pass-through parameter. All users updated and unnested.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/loadenv.c (grub_cmd_list_env): Move print_var
+ out of its parent.
+
+2013-03-02 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/hfs.c: Remove nested functions.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/hfsplus.c (grub_hfsplus_btree_iterate_node): Pass
+ the context through.
+ (grub_hfsplus_iterate_dir): Move nested function out of its parent.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * util/grub-editenv.c (list_variables): Move print_var out of its
+ parent.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/emu/hostdisk.c (read_device_map): Remove nested
+ function.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/gentrigtables.c: Make tables const.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Remove nested functions from videoinfo iterators.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Fix compilation
+ for 64-bit platforms.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/disk/efi/efidisk.c: Transform iterate_child_devices into
+ a FOR_CHILDREN macro.
+
+2013-03-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/main.c (grub_set_prefix_and_root): Strip trailing
+ platform from firmware path.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Enable linux16 on non-BIOS systems for i.a. memtest.
+
+ * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0
+ correctly.
+ * grub-core/Makefile.core.def (linux16): Enable on all x86 flavours.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate):
+ Fix end of table condition.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/arg.c (grub_arg_show_help): Move showargs
+ out of its parent.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/jfs.c: Remove nested functions.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/minix.c: Remove nested functions.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/iso9660.c: Remove nested functions.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/parttool.c (grub_cmd_parttool): Move show_help out
+ of parent function.
+
+2013-02-28 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * util/grub-fstest.c: Remove nested functions.
+
+2013-02-27 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/loader/machoXX.c: Remove nested functions.
+
+2013-02-27 Colin Watson <cjwatson@ubuntu.com>
+
+ Remove nested functions from disk and file read hooks.
+
+ * include/grub/disk.h (grub_disk_read_hook_t): New type.
+ (struct grub_disk): Add read_hook_data member.
+ * include/grub/file.h (struct grub_file): Likewise.
+ * include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data
+ argument.
+
+ Update all callers.
+
+2012-02-27 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * grub-core/partmap/msdos.c (grub_partition_msdos_iterate):
+ Fix off by one error in enumerating extended partitions.
+
+2013-02-26 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * grub-core/disk/efi/efidisk.c(grub_efidisk_get_device_name): Fix
+ memory leak if device name is not found.
+
+2013-02-25 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * grub-core/normal/menu_entry.c (update_screen): remove
+ unused variable `off' which caused scroll down arrow to be always shown.
+
+2013-02-25 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * grub-core/normal/menu_entry.c (insert_string): fix off by one
+ access to unallocated memory.
+
+2013-02-25 Andrey Borzenkov <arvidjaar@gmail.com>
+
+ * Makefile.util.def: Add partmap/msdos.c to common library.
+ * include/grub/msdos_partition.h: Add GRUB_PC_PARTITION_TYPE_LDM
+ * grub-core/disk/ldm.c: Check for existence of
+ GRUB_PC_PARTITION_TYPE_LDM.
+
+2013-02-25 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/normal/misc.c (grub_normal_print_device_info): Use KiB to display
+ sizes and display sector size.
+
+2013-02-24 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Implement new command cmosdump.
+
+2013-02-19 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
+
+ Support Openfirmware disks with non-512B sectors.
+
+ * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block
+ size of the disk.
+ * (grub_ofdisk_get_block_size): New function.
+ * (grub_ofdisk_prepare): Use the correct block size.
+ * (grub_ofdisk_read): Likewise.
+ * (grub_ofdisk_write): Likewise.
+ * include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size):
+ New proto.
+
+2013-02-06 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/lsacpi.c: Fix types on 64-bit platform.
+
+2013-02-04 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/disk/cryptodisk.c (grub_cryptodisk_scan_device): Don't stop
+ on first error.
+
+2013-02-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/fshelp.c (find_file): Set oldnode to zero after
+ freeing it.
+
+2013-02-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Implement USBDebug (full USB stack variant).
+
+2013-02-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/commands/lsacpi.c: Show more info. Hide some boring parts
+ unless they have unexpected values.
+
+2013-02-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/bus/usb/usb.c (grub_usb_device_attach): Add missing
+ grub_print_error.
+
+2013-02-01 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): Fix missing
+ zero-out of port structure.
+
+2013-01-30 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/fs/xfs.c (grub_xfs_read_block): Fix computation in presence
+ of extended attributes.
+
2013-01-27 Andrey Borzenkov <arvidjaar@gmail.com>
* util/grub-install.in: change misleading comment about
diff --git a/config.h.in b/config.h.in
index a7eaf19..e965615 100644
--- a/config.h.in
+++ b/config.h.in
@@ -5,6 +5,11 @@
#if defined(__PPC__) && !defined(__powerpc__)
#define __powerpc__ 1
#endif
+
+/* Define to 1 to enable disk cache statistics. */
+#define DISK_CACHE_STATS @DISK_CACHE_STATS@
+#define BOOT_TIME_STATS @BOOT_TIME_STATS@
+
#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
#include <config-util.h>
#define NESTED_FUNC_ATTR
diff --git a/configure.ac b/configure.ac
index 45a3289..b78fe9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -815,6 +815,17 @@ else
fi
AC_SUBST([DISK_CACHE_STATS])
+AC_ARG_ENABLE([boot-time],
+ AS_HELP_STRING([--enable-boot-time],
+ [enable boot time statistics collection]))
+
+if test x$enable_boot_time = xyes; then
+ BOOT_TIME_STATS=1
+else
+ BOOT_TIME_STATS=0
+fi
+AC_SUBST([BOOT_TIME_STATS])
+
AC_ARG_ENABLE([grub-emu-usb],
[AS_HELP_STRING([--enable-grub-emu-usb],
[build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
@@ -1178,6 +1189,7 @@ AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x])
AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1])
+AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1])
AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin])
@@ -1250,6 +1262,13 @@ echo With disk cache statistics: Yes
else
echo With disk cache statistics: No
fi
+
+if [ x"$enable_boot_time" = xyes ]; then
+echo With boot time statistics: Yes
+else
+echo With boot time statistics: No
+fi
+
if [ x"$efiemu_excuse" = x ]; then
echo efiemu runtime: Yes
else
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 5624f9e..6fa0a14 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -98,29 +98,30 @@ if COND_i386_pc
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
endif
if COND_i386_coreboot
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h
endif
if COND_i386_multiboot
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h
endif
if COND_i386_qemu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_ieee1275
@@ -128,13 +129,13 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_x86_64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
endif
@@ -143,11 +144,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
-if COND_arm_uboot
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h
-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h
-endif
-
if COND_mips
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
endif
@@ -215,6 +211,13 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
endif
+if COND_arm_uboot
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 6bdd53c..dce64f9 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -106,7 +106,6 @@ kernel = {
noemu_nodist = symlist.c;
- i386_pc = kern/generic/rtc_get_time_ms.c;
mips = kern/generic/rtc_get_time_ms.c;
ieee1275 = disk/ieee1275/ofdisk.c;
@@ -127,8 +126,6 @@ kernel = {
i386_coreboot_multiboot_qemu = kern/i386/coreboot/init.c;
i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c;
- x86 = kern/i386/pit.c;
-
efi = disk/efi/efidisk.c;
efi = kern/efi/efi.c;
efi = kern/efi/init.c;
@@ -461,6 +458,12 @@ module = {
};
module = {
+ name = usbserial_usbdebug;
+ common = bus/usb/serial/usbdebug_late.c;
+ enable = usb;
+};
+
+module = {
name = uhci;
common = bus/usb/uhci.c;
enable = x86;
@@ -517,12 +520,36 @@ module = {
};
module = {
+ name = cmosdump;
+ common = commands/i386/cmosdump.c;
+ enable = cmos;
+};
+
+module = {
name = iorw;
common = commands/iorw.c;
enable = x86;
};
module = {
+ name = cbtime;
+ common = commands/i386/coreboot/cb_timestamps.c;
+ enable = i386_coreboot;
+};
+
+module = {
+ name = cbls;
+ common = commands/i386/coreboot/cbls.c;
+ enable = i386_coreboot;
+};
+
+module = {
+ name = cbmemc;
+ common = term/i386/coreboot/cbmemc.c;
+ enable = i386_coreboot;
+};
+
+module = {
name = regexp;
common = commands/regexp.c;
common = commands/wildcard.c;
@@ -608,8 +635,6 @@ module = {
module = {
name = cat;
common = commands/cat.c;
- arm_uboot = lib/arg.c;
- arm_uboot = commands/extcmd.c;
};
module = {
@@ -1397,9 +1422,9 @@ module = {
module = {
name = linux16;
- i386_pc = loader/i386/pc/linux.c;
- i386_pc = lib/cmdline.c;
- enable = i386_pc;
+ common = loader/i386/pc/linux.c;
+ common = lib/cmdline.c;
+ enable = x86;
};
module = {
@@ -1883,6 +1908,12 @@ module = {
};
module = {
+ name = boottime;
+ common = commands/boottime.c;
+ condition = COND_ENABLE_BOOT_TIME_STATS;
+};
+
+module = {
name = adler32;
common = lib/adler32.c;
};
diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c
index 9215866..41d29cb 100644
--- a/grub-core/bus/usb/ehci.c
+++ b/grub-core/bus/usb/ehci.c
@@ -715,6 +715,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
usblegsup = grub_pci_read (pciaddr_eecp);
if (usblegsup & GRUB_EHCI_BIOS_OWNED)
{
+ grub_boot_time ("Taking ownership of EHCI port");
grub_dprintf ("ehci",
"EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n");
/* Ownership change - set OS_OWNED bit */
@@ -741,6 +742,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
/* Ensure PCI register is written */
grub_pci_read (pciaddr_eecp);
}
+ grub_boot_time ("Ownership of EHCI port taken");
}
else if (usblegsup & GRUB_EHCI_OS_OWNED)
/* XXX: What to do in this case - nothing ? Can it happen ? */
@@ -1697,6 +1699,8 @@ grub_ehci_portstatus (grub_usb_controller_t dev,
grub_dprintf ("ehci", "portstatus: enable\n");
+ grub_boot_time ("Resetting port %d", port);
+
/* Now we will do reset - if HIGH speed device connected, it will
* result in Enabled state, otherwise port remains disabled. */
/* Set RESET bit for 50ms */
@@ -1710,6 +1714,7 @@ grub_ehci_portstatus (grub_usb_controller_t dev,
if (grub_get_time_ms () > endtime)
return grub_error (GRUB_ERR_IO,
"portstatus: EHCI Timed out - reset port");
+ grub_boot_time ("Port %d reset", port);
/* Remember "we did the reset" - needed by detect_dev */
e->reset |= (1 << port);
/* Test if port enabled, i.e. HIGH speed device connected */
@@ -1909,8 +1914,11 @@ GRUB_MOD_INIT (ehci)
{
COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_td) == 64);
COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_qh) == 96);
+ grub_boot_time ("Initing EHCI hardware");
grub_ehci_inithw ();
+ grub_boot_time ("Registering EHCI driver");
grub_usb_controller_dev_register (&usb_controller);
+ grub_boot_time ("EHCI driver registered");
grub_loader_register_preboot_hook (grub_ehci_fini_hw, grub_ehci_restore_hw,
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
}
diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c
index 55d1884..8e94c7d 100644
--- a/grub-core/bus/usb/serial/common.c
+++ b/grub-core/bus/usb/serial/common.c
@@ -42,7 +42,8 @@ static int usbnum = 0;
int
grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
- struct grub_serial_driver *driver)
+ struct grub_serial_driver *driver, int in_endp,
+ int out_endp)
{
struct grub_serial_port *port;
int j;
@@ -51,7 +52,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
interf = usbdev->config[configno].interf[interfno].descif;
- port = grub_malloc (sizeof (*port));
+ port = grub_zalloc (sizeof (*port));
if (!port)
{
grub_print_error ();
@@ -73,12 +74,16 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
struct grub_usb_desc_endp *endp;
endp = &usbdev->config[0].interf[interfno].descendp[j];
- if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+ if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2
+ && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
+ || in_endp == endp->endp_addr))
{
/* Bulk IN endpoint. */
port->in_endp = endp;
}
- else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+ else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2
+ && (out_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
+ || out_endp == endp->endp_addr))
{
/* Bulk OUT endpoint. */
port->out_endp = endp;
@@ -119,7 +124,7 @@ grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size)
if (port->bufstart < port->bufend)
return port->buf[port->bufstart++];
- err = grub_usb_bulk_read_extended (port->usbdev, port->in_endp->endp_addr,
+ err = grub_usb_bulk_read_extended (port->usbdev, port->in_endp,
sizeof (port->buf), port->buf, 10,
&actual);
if (err != GRUB_USB_ERR_NONE)
diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c
index 15ea8fb..25c1d6f 100644
--- a/grub-core/bus/usb/serial/ftdi.c
+++ b/grub-core/bus/usb/serial/ftdi.c
@@ -128,7 +128,7 @@ ftdi_hw_put (struct grub_serial_port *port, const int c)
real_config (port);
- grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc);
+ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
}
static grub_err_t
@@ -193,7 +193,9 @@ grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno)
return 0;
return grub_usbserial_attach (usbdev, configno, interfno,
- &grub_ftdi_driver);
+ &grub_ftdi_driver,
+ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING,
+ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING);
}
static struct grub_usb_attach_desc attach_hook =
diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c
index 5433763..92b00ef 100644
--- a/grub-core/bus/usb/serial/pl2303.c
+++ b/grub-core/bus/usb/serial/pl2303.c
@@ -146,7 +146,7 @@ pl2303_hw_put (struct grub_serial_port *port, const int c)
real_config (port);
- grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc);
+ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
}
static grub_err_t
@@ -208,7 +208,9 @@ grub_pl2303_attach (grub_usb_device_t usbdev, int configno, int interfno)
return 0;
return grub_usbserial_attach (usbdev, configno, interfno,
- &grub_pl2303_driver);
+ &grub_pl2303_driver,
+ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING,
+ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING);
}
static struct grub_usb_attach_desc attach_hook =
diff --git a/grub-core/bus/usb/serial/usbdebug_late.c b/grub-core/bus/usb/serial/usbdebug_late.c
new file mode 100644
index 0000000..e88ba13
--- /dev/null
+++ b/grub-core/bus/usb/serial/usbdebug_late.c
@@ -0,0 +1,93 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/serial.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/usbserial.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+
+/* Fetch a key. */
+static int
+usbdebug_late_hw_fetch (struct grub_serial_port *port)
+{
+ return grub_usbserial_fetch (port, 0);
+}
+
+/* Put a character. */
+static void
+usbdebug_late_hw_put (struct grub_serial_port *port, const int c)
+{
+ char cc = c;
+
+ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
+}
+
+static grub_err_t
+usbdebug_late_hw_configure (struct grub_serial_port *port __attribute__ ((unused)),
+ struct grub_serial_config *config __attribute__ ((unused)))
+{
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_serial_driver grub_usbdebug_late_driver =
+ {
+ .configure = usbdebug_late_hw_configure,
+ .fetch = usbdebug_late_hw_fetch,
+ .put = usbdebug_late_hw_put,
+ .fini = grub_usbserial_fini
+ };
+
+static int
+grub_usbdebug_late_attach (grub_usb_device_t usbdev, int configno, int interfno)
+{
+ grub_usb_err_t err;
+ struct grub_usb_desc_debug debugdesc;
+
+ err = grub_usb_get_descriptor (usbdev, GRUB_USB_DESCRIPTOR_DEBUG, configno,
+ sizeof (debugdesc), (char *) &debugdesc);
+ if (err)
+ return 0;
+
+ return grub_usbserial_attach (usbdev, configno, interfno,
+ &grub_usbdebug_late_driver,
+ debugdesc.in_endp, debugdesc.out_endp);
+}
+
+static struct grub_usb_attach_desc attach_hook =
+{
+ .class = 0xff,
+ .hook = grub_usbdebug_late_attach
+};
+
+GRUB_MOD_INIT(usbserial_usbdebug_late)
+{
+ grub_usb_register_attach_hook_class (&attach_hook);
+}
+
+GRUB_MOD_FINI(usbserial_usbdebug_late)
+{
+ grub_serial_unregister_driver (&grub_usbdebug_late_driver);
+ grub_usb_unregister_attach_hook_class (&attach_hook);
+}
diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c
index 6fbf134..024190e 100644
--- a/grub-core/bus/usb/usb.c
+++ b/grub-core/bus/usb/usb.c
@@ -26,46 +26,8 @@
GRUB_MOD_LICENSE ("GPLv3+");
-static grub_usb_controller_dev_t grub_usb_list;
static struct grub_usb_attach_desc *attach_hooks;
-/* Iterate over all controllers found by the driver. */
-static int
-grub_usb_controller_dev_register_iter (grub_usb_controller_t dev, void *data)
-{
- grub_usb_controller_dev_t usb = data;
-
- dev->dev = usb;
-
- /* Enable the ports of the USB Root Hub. */
- grub_usb_root_hub (dev);
-
- return 0;
-}
-
-void
-grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
-{
- usb->next = grub_usb_list;
- grub_usb_list = usb;
-
- if (usb->iterate)
- usb->iterate (grub_usb_controller_dev_register_iter, usb);
-}
-
-void
-grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
-{
- grub_usb_controller_dev_t *p, q;
-
- for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
- if (q == usb)
- {
- *p = q->next;
- break;
- }
-}
-
#if 0
/* Context for grub_usb_controller_iterate. */
struct grub_usb_controller_iterate_ctx
@@ -147,31 +109,6 @@ grub_usb_get_descriptor (grub_usb_device_t dev,
0, size, data);
}
-struct grub_usb_desc_endp *
-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
-{
- int i;
-
- for (i = 0; i < usbdev->config[0].descconf->numif; i++)
- {
- struct grub_usb_desc_if *interf;
- int j;
-
- interf = usbdev->config[0].interf[i].descif;
-
- for (j = 0; j < interf->endpointcnt; j++)
- {
- struct grub_usb_desc_endp *endp;
- endp = &usbdev->config[0].interf[i].descendp[j];
-
- if (endp->endp_addr == addr)
- return endp;
- }
- }
-
- return NULL;
-}
-
grub_usb_err_t
grub_usb_device_initialize (grub_usb_device_t dev)
{
@@ -287,8 +224,13 @@ void grub_usb_device_attach (grub_usb_device_t dev)
continue;
for (desc = attach_hooks; desc; desc = desc->next)
- if (interf->class == desc->class && desc->hook (dev, 0, i))
- dev->config[0].interf[i].attached = 1;
+ if (interf->class == desc->class)
+ {
+ grub_boot_time ("Probing USB device driver class %x", desc->class);
+ if (desc->hook (dev, 0, i))
+ dev->config[0].interf[i].attached = 1;
+ grub_boot_time ("Probed USB device driver class %x", desc->class);
+ }
if (dev->config[0].interf[i].attached)
continue;
@@ -297,14 +239,20 @@ void grub_usb_device_attach (grub_usb_device_t dev)
{
case GRUB_USB_CLASS_MASS_STORAGE:
grub_dl_load ("usbms");
+ grub_print_error ();
break;
case GRUB_USB_CLASS_HID:
grub_dl_load ("usb_keyboard");
+ grub_print_error ();
break;
case 0xff:
/* FIXME: don't load useless modules. */
grub_dl_load ("usbserial_ftdi");
+ grub_print_error ();
grub_dl_load ("usbserial_pl2303");
+ grub_print_error ();
+ grub_dl_load ("usbserial_usbdebug");
+ grub_print_error ();
break;
}
}
diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
index 3927f51..6fc9d02 100644
--- a/grub-core/bus/usb/usbhub.c
+++ b/grub-core/bus/usb/usbhub.c
@@ -29,6 +29,7 @@
static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
static int rescan = 0;
+static int npending = 0;
struct grub_usb_hub
{
@@ -36,10 +37,12 @@ struct grub_usb_hub
grub_usb_controller_t controller;
int nports;
struct grub_usb_device **devices;
+ struct grub_usb_hub_port *ports;
grub_usb_device_t dev;
};
static struct grub_usb_hub *hubs;
+static grub_usb_controller_dev_t grub_usb_list;
/* Add a device that currently has device number 0 and resides on
CONTROLLER, the Hub reported that the device speed is SPEED. */
@@ -52,6 +55,8 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
int i;
grub_usb_err_t err;
+ grub_boot_time ("Attaching USB device");
+
dev = grub_zalloc (sizeof (struct grub_usb_device));
if (! dev)
return NULL;
@@ -108,8 +113,12 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
/* Wait "recovery interval", spec. says 2ms */
grub_millisleep (2);
+
+ grub_boot_time ("Probing USB device driver");
grub_usb_device_attach (dev);
+
+ grub_boot_time ("Attached USB device");
return dev;
}
@@ -139,10 +148,15 @@ grub_usb_add_hub (grub_usb_device_t dev)
grub_dprintf ("usb", "Hub set configuration\n");
grub_usb_set_configuration (dev, 1);
- dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
- if (!dev->children)
- return GRUB_USB_ERR_INTERNAL;
dev->nports = hubdesc.portcnt;
+ dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
+ dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0]));
+ if (!dev->children || !dev->ports)
+ {
+ grub_free (dev->children);
+ grub_free (dev->ports);
+ return GRUB_USB_ERR_INTERNAL;
+ }
/* Power on all Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++)
@@ -173,7 +187,7 @@ grub_usb_add_hub (grub_usb_device_t dev)
if (len > sizeof (dev->statuschange))
len = sizeof (dev->statuschange);
dev->hub_transfer
- = grub_usb_bulk_read_background (dev, endp->endp_addr, len,
+ = grub_usb_bulk_read_background (dev, endp, len,
(char *) &dev->statuschange);
break;
}
@@ -190,47 +204,24 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
{
grub_usb_device_t dev;
grub_err_t err;
- int total, i;
- grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE;
- int changed=0;
-
-#if 0
-/* Specification does not say about disabling of port when device
- * connected. If disabling is really necessary for some devices,
- * delete this #if 0 and related #endif */
- /* Disable the port. XXX: Why? */
- err = hub->controller->dev->portstatus (hub->controller, portno, 0);
- if (err)
- return;
-#endif
- /* Wait for completion of insertion and stable power (USB spec.)
- * Should be at least 100ms, some devices requires more...
- * There is also another thing - some devices have worse contacts
- * and connected signal is unstable for some time - we should handle
- * it - but prevent deadlock in case when device is too faulty... */
- for (total = i = 0; (i < 250) && (total < 2000); i++, total++)
- {
- grub_millisleep (1);
- current_speed = hub->controller->dev->detect_dev
- (hub->controller, portno, &changed);
- if (current_speed == GRUB_USB_SPEED_NONE)
- i = 0;
- }
- grub_dprintf ("usb", "total=%d\n", total);
- if (total >= 2000)
- return;
+
+ grub_boot_time ("After detect_dev");
/* Enable the port. */
err = hub->controller->dev->portstatus (hub->controller, portno, 1);
if (err)
return;
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
+ npending++;
grub_millisleep (10);
+ grub_boot_time ("Port enabled");
+
/* Enable the port and create a device. */
dev = grub_usb_hub_add_dev (hub->controller, speed, portno, 0);
hub->controller->dev->pending_reset = 0;
+ npending--;
if (! dev)
return;
@@ -239,14 +230,20 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
/* If the device is a Hub, scan it for more devices. */
if (dev->descdev.class == 0x09)
grub_usb_add_hub (dev);
+
+ grub_boot_time ("Attached root port");
}
-grub_usb_err_t
-grub_usb_root_hub (grub_usb_controller_t controller)
+/* Iterate over all controllers found by the driver. */
+static int
+grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *data)
{
- int i;
+ grub_usb_controller_dev_t usb = data;
struct grub_usb_hub *hub;
- int changed=0;
+
+ controller->dev = usb;
+
+ grub_boot_time ("Registering USB root hub");
hub = grub_malloc (sizeof (*hub));
if (!hub)
@@ -267,27 +264,122 @@ grub_usb_root_hub (grub_usb_controller_t controller)
/* Query the number of ports the root Hub has. */
hub->nports = controller->dev->hubports (controller);
hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports);
- if (!hub->devices)
+ hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports);
+ if (!hub->devices || !hub->ports)
{
+ grub_free (hub->devices);
+ grub_free (hub->ports);
grub_free (hub->controller);
grub_free (hub);
- return GRUB_USB_ERR_INTERNAL;
+ grub_print_error ();
+ return 0;
}
- for (i = 0; i < hub->nports; i++)
+ return 0;
+}
+
+void
+grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
+{
+ grub_usb_controller_dev_t *p, q;
+
+ for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
+ if (q == usb)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+void
+grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+{
+ int portno;
+ int continue_waiting = 0;
+ struct grub_usb_hub *hub;
+
+ usb->next = grub_usb_list;
+ grub_usb_list = usb;
+
+ if (usb->iterate)
+ usb->iterate (grub_usb_controller_dev_register_iter, usb);
+
+ grub_boot_time ("waiting for stable power on USB root\n");
+
+ while (1)
{
- grub_usb_speed_t speed;
- if (!controller->dev->pending_reset)
- {
- speed = controller->dev->detect_dev (hub->controller, i,
- &changed);
-
- if (speed != GRUB_USB_SPEED_NONE)
- attach_root_port (hub, i, speed);
- }
+ for (hub = hubs; hub; hub = hub->next)
+ if (hub->controller->dev == usb)
+ {
+ /* Wait for completion of insertion and stable power (USB spec.)
+ * Should be at least 100ms, some devices requires more...
+ * There is also another thing - some devices have worse contacts
+ * and connected signal is unstable for some time - we should handle
+ * it - but prevent deadlock in case when device is too faulty... */
+ for (portno = 0; portno < hub->nports; portno++)
+ {
+ grub_usb_speed_t speed;
+ int changed = 0;
+
+ speed = hub->controller->dev->detect_dev (hub->controller, portno,
+ &changed);
+
+ if (hub->ports[portno].state == PORT_STATE_NORMAL
+ && speed != GRUB_USB_SPEED_NONE)
+ {
+ hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250;
+ hub->ports[portno].hard_limit_time = hub->ports[portno].soft_limit_time + 1750;
+ hub->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER;
+ grub_boot_time ("Scheduling stable power wait for port %p:%d",
+ usb, portno);
+ continue_waiting++;
+ continue;
+ }
+
+ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
+ && speed == GRUB_USB_SPEED_NONE)
+ {
+ hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250;
+ continue;
+ }
+ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
+ && grub_get_time_ms () > hub->ports[portno].soft_limit_time)
+ {
+ hub->ports[portno].state = PORT_STATE_STABLE_POWER;
+ grub_boot_time ("Got stable power wait for port %p:%d",
+ usb, portno);
+ continue_waiting--;
+ continue;
+ }
+ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
+ && grub_get_time_ms () > hub->ports[portno].hard_limit_time)
+ {
+ hub->ports[portno].state = PORT_STATE_FAILED_DEVICE;
+ continue_waiting--;
+ continue;
+ }
+ }
+ }
+ if (!continue_waiting)
+ break;
+ grub_millisleep (1);
}
- return GRUB_USB_ERR_NONE;
+ grub_boot_time ("After the stable power wait on USB root");
+
+ for (hub = hubs; hub; hub = hub->next)
+ if (hub->controller->dev == usb)
+ for (portno = 0; portno < hub->nports; portno++)
+ if (hub->ports[portno].state == PORT_STATE_STABLE_POWER)
+ {
+ grub_usb_speed_t speed;
+ int changed = 0;
+ hub->ports[portno].state = PORT_STATE_NORMAL;
+ speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed);
+ attach_root_port (hub, portno, speed);
+ }
+
+ grub_boot_time ("USB root hub registered");
}
static void detach_device (grub_usb_device_t dev);
@@ -319,6 +411,71 @@ detach_device (grub_usb_device_t dev)
grub_usb_devs[dev->addr] = 0;
}
+static int
+wait_power_nonroot_hub (grub_usb_device_t dev)
+{
+ grub_usb_err_t err;
+ int continue_waiting = 0;
+ unsigned i;
+
+ for (i = 1; i <= dev->nports; i++)
+ if (dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER)
+ {
+ grub_uint64_t tm;
+ grub_uint32_t current_status = 0;
+
+ /* Get the port status. */
+ err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+ | GRUB_USB_REQTYPE_CLASS
+ | GRUB_USB_REQTYPE_TARGET_OTHER),
+ GRUB_USB_REQ_GET_STATUS,
+ 0, i,
+ sizeof (current_status),
+ (char *) &current_status);
+ if (err)
+ {
+ dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE;
+ continue;
+ }
+ tm = grub_get_time_ms ();
+ if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
+ dev->ports[i - 1].soft_limit_time = tm + 250;
+ if (tm >= dev->ports[i - 1].soft_limit_time)
+ {
+ if (dev->controller.dev->pending_reset)
+ continue;
+ /* Now do reset of port. */
+ grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+ | GRUB_USB_REQTYPE_CLASS
+ | GRUB_USB_REQTYPE_TARGET_OTHER),
+ GRUB_USB_REQ_SET_FEATURE,
+ GRUB_USB_HUB_FEATURE_PORT_RESET,
+ i, 0, 0);
+ dev->ports[i - 1].state = PORT_STATE_NORMAL;
+ grub_boot_time ("Resetting port %p:%d", dev, i - 1);
+
+ rescan = 1;
+ /* We cannot reset more than one device at the same time !
+ * Resetting more devices together results in very bad
+ * situation: more than one device has default address 0
+ * at the same time !!!
+ * Additionaly, we cannot perform another reset
+ * anywhere on the same OHCI controller until
+ * we will finish addressing of reseted device ! */
+ dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
+ npending++;
+ continue;
+ }
+ if (tm >= dev->ports[i - 1].hard_limit_time)
+ {
+ dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE;
+ continue;
+ }
+ continue_waiting = 1;
+ }
+ return continue_waiting && dev->controller.dev->pending_reset == 0;
+}
+
static void
poll_nonroot_hub (grub_usb_device_t dev)
{
@@ -326,7 +483,6 @@ poll_nonroot_hub (grub_usb_device_t dev)
unsigned i;
grub_uint8_t changed;
grub_size_t actual, len;
- int j, total;
if (!dev->hub_transfer)
return;
@@ -342,7 +498,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
if (len > sizeof (dev->statuschange))
len = sizeof (dev->statuschange);
dev->hub_transfer
- = grub_usb_bulk_read_background (dev, dev->hub_endpoint->endp_addr, len,
+ = grub_usb_bulk_read_background (dev, dev->hub_endpoint, len,
(char *) &dev->statuschange);
if (err || actual == 0 || changed == 0)
@@ -352,9 +508,9 @@ poll_nonroot_hub (grub_usb_device_t dev)
for (i = 1; i <= dev->nports; i++)
{
grub_uint32_t status;
- grub_uint32_t current_status = 0;
- if (!(changed & (1 << i)))
+ if (!(changed & (1 << i))
+ || dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER)
continue;
/* Get the port status. */
@@ -407,52 +563,19 @@ poll_nonroot_hub (grub_usb_device_t dev)
/* Connected and status of connection changed ? */
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
{
+ grub_boot_time ("Before the stable power wait portno=%d", i);
/* A device is actually connected to this port. */
- /* Wait for completion of insertion and stable power (USB spec.)
- * Should be at least 100ms, some devices requires more...
- * There is also another thing - some devices have worse contacts
- * and connected signal is unstable for some time - we should handle
- * it - but prevent deadlock in case when device is too faulty... */
- for (total = j = 0; (j < 250) && (total < 2000); j++, total++)
- {
- grub_millisleep (1);
- /* Get the port status. */
- err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
- | GRUB_USB_REQTYPE_CLASS
- | GRUB_USB_REQTYPE_TARGET_OTHER),
- GRUB_USB_REQ_GET_STATUS,
- 0, i,
- sizeof (current_status),
- (char *) &current_status);
- if (err)
- {
- total = 2000;
- break;
- }
- if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
- j = 0;
- }
- grub_dprintf ("usb", "(non-root) total=%d\n", total);
- if (total >= 2000)
- continue;
-
- /* Now do reset of port. */
- grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
- | GRUB_USB_REQTYPE_CLASS
- | GRUB_USB_REQTYPE_TARGET_OTHER),
- GRUB_USB_REQ_SET_FEATURE,
- GRUB_USB_HUB_FEATURE_PORT_RESET,
- i, 0, 0);
- rescan = 1;
- /* We cannot reset more than one device at the same time !
- * Resetting more devices together results in very bad
- * situation: more than one device has default address 0
- * at the same time !!!
- * Additionaly, we cannot perform another reset
- * anywhere on the same OHCI controller until
- * we will finish addressing of reseted device ! */
- dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
- return;
+ /* Wait for completion of insertion and stable power (USB spec.)
+ * Should be at least 100ms, some devices requires more...
+ * There is also another thing - some devices have worse contacts
+ * and connected signal is unstable for some time - we should handle
+ * it - but prevent deadlock in case when device is too faulty... */
+ dev->ports[i - 1].soft_limit_time = grub_get_time_ms () + 250;
+ dev->ports[i - 1].hard_limit_time = dev->ports[i - 1].soft_limit_time + 1750;
+ dev->ports[i - 1].state = PORT_STATE_WAITING_FOR_STABLE_POWER;
+ grub_boot_time ("Scheduling stable power wait for port %p:%d",
+ dev, i - 1);
+ continue;
}
}
@@ -464,6 +587,8 @@ poll_nonroot_hub (grub_usb_device_t dev)
GRUB_USB_REQ_CLEAR_FEATURE,
GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0);
+ grub_boot_time ("Port %d reset", i);
+
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
{
grub_usb_speed_t speed;
@@ -485,7 +610,11 @@ poll_nonroot_hub (grub_usb_device_t dev)
/* Add the device and assign a device address to it. */
next_dev = grub_usb_hub_add_dev (&dev->controller, speed, i, dev->addr);
- dev->controller.dev->pending_reset = 0;
+ if (dev->controller.dev->pending_reset)
+ {
+ dev->controller.dev->pending_reset = 0;
+ npending--;
+ }
if (! next_dev)
continue;
@@ -500,7 +629,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
}
void
-grub_usb_poll_devices (void)
+grub_usb_poll_devices (int wait_for_completion)
{
struct grub_usb_hub *hub;
int i;
@@ -514,7 +643,7 @@ grub_usb_poll_devices (void)
grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
int changed = 0;
- if (!hub->controller->dev->pending_reset)
+ if (hub->controller->dev->pending_reset)
{
/* Check for possible timeout */
if (grub_get_time_ms () > hub->controller->dev->pending_reset)
@@ -522,6 +651,7 @@ grub_usb_poll_devices (void)
/* Something went wrong, reset device was not
* addressed properly, timeout happened */
hub->controller->dev->pending_reset = 0;
+ npending--;
speed = hub->controller->dev->detect_dev (hub->controller,
i, &changed);
}
@@ -548,11 +678,26 @@ grub_usb_poll_devices (void)
if (dev && dev->descdev.class == 0x09)
poll_nonroot_hub (dev);
}
- if (!rescan)
+
+ while (1)
+ {
+ int continue_waiting = 0;
+ for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
+ {
+ grub_usb_device_t dev = grub_usb_devs[i];
+
+ if (dev && dev->descdev.class == 0x09)
+ continue_waiting = continue_waiting || wait_power_nonroot_hub (dev);
+ }
+ if (!continue_waiting)
+ break;
+ grub_millisleep (1);
+ }
+
+ if (!(rescan || (npending && wait_for_completion)))
break;
- grub_millisleep (50);
+ grub_millisleep (25);
}
-
}
int
diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c
index 154c72d..4b6a32e 100644
--- a/grub-core/bus/usb/usbtrans.c
+++ b/grub-core/bus/usb/usbtrans.c
@@ -25,6 +25,19 @@
#include <grub/usbtrans.h>
#include <grub/time.h>
+
+static inline unsigned int
+grub_usb_bulk_maxpacket (grub_usb_device_t dev,
+ struct grub_usb_desc_endp *endpoint)
+{
+ /* Use the maximum packet size given in the endpoint descriptor. */
+ if (dev->initialized && endpoint)
+ return endpoint->maxpacket;
+
+ return 64;
+}
+
+
static grub_usb_err_t
grub_usb_execute_and_wait_transfer (grub_usb_device_t dev,
grub_usb_transfer_t transfer,
@@ -199,7 +212,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
static grub_usb_transfer_t
grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
- int endpoint, grub_size_t size0, char *data_in,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size0, char *data_in,
grub_transfer_type_t type)
{
int i;
@@ -210,7 +224,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
grub_uint32_t data_addr;
struct grub_pci_dma_chunk *data_chunk;
grub_size_t size = size0;
- int toggle = dev->toggle[endpoint];
+ int toggle = dev->toggle[endpoint->endp_addr];
grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size,
type);
@@ -249,7 +263,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
datablocks = ((size + max - 1) / max);
transfer->transcnt = datablocks;
transfer->size = size - 1;
- transfer->endpoint = endpoint;
+ transfer->endpoint = endpoint->endp_addr;
transfer->devaddr = dev->addr;
transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
transfer->dir = type;
@@ -315,7 +329,8 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
static grub_usb_err_t
grub_usb_bulk_readwrite (grub_usb_device_t dev,
- int endpoint, grub_size_t size0, char *data_in,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size0, char *data_in,
grub_transfer_type_t type, int timeout,
grub_size_t *actual)
{
@@ -333,6 +348,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
return err;
}
+<<<<<<< TREE
grub_usb_err_t
grub_usb_bulk_write (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
@@ -350,6 +366,13 @@ grub_usb_bulk_write (grub_usb_device_t dev,
grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
+=======
+static grub_usb_err_t
+grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev,
+ struct grub_usb_desc_endp *endpoint,
+ grub_transfer_type_t type,
+ grub_size_t size, char *data)
+>>>>>>> MERGE-SOURCE
{
grub_size_t actual, transferred;
grub_usb_err_t err;
@@ -373,6 +396,29 @@ grub_usb_bulk_read (grub_usb_device_t dev,
}
grub_usb_err_t
+<<<<<<< TREE
+=======
+grub_usb_bulk_write (grub_usb_device_t dev,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data)
+{
+ return grub_usb_bulk_readwrite_packetize (dev, endpoint,
+ GRUB_USB_TRANSFER_TYPE_OUT,
+ size, data);
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data)
+{
+ return grub_usb_bulk_readwrite_packetize (dev, endpoint,
+ GRUB_USB_TRANSFER_TYPE_IN,
+ size, data);
+}
+
+grub_usb_err_t
+>>>>>>> MERGE-SOURCE
grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual)
{
grub_usb_err_t err;
@@ -390,7 +436,8 @@ grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual)
grub_usb_transfer_t
grub_usb_bulk_read_background (grub_usb_device_t dev,
- int endpoint, grub_size_t size, void *data)
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, void *data)
{
grub_usb_err_t err;
grub_usb_transfer_t transfer;
@@ -417,7 +464,8 @@ grub_usb_cancel_transfer (grub_usb_transfer_t transfer)
grub_usb_err_t
grub_usb_bulk_read_extended (grub_usb_device_t dev,
- int endpoint, grub_size_t size, char *data,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data,
int timeout, grub_size_t *actual)
{
return grub_usb_bulk_readwrite (dev, endpoint, size, data,
diff --git a/grub-core/commands/boottime.c b/grub-core/commands/boottime.c
new file mode 100644
index 0000000..7370d27
--- /dev/null
+++ b/grub-core/commands/boottime.c
@@ -0,0 +1,65 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+
+static grub_err_t
+grub_cmd_boottime (struct grub_command *cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char *argv[] __attribute__ ((unused)))
+{
+ struct grub_boot_time *cur;
+ grub_uint64_t last_time = 0, start_time = 0;
+ if (!grub_boot_time_head)
+ {
+ grub_puts_ (N_("No boot time statistics is available\n"));
+ return 0;
+ }
+ start_time = last_time = grub_boot_time_head->tp;
+ for (cur = grub_boot_time_head; cur; cur = cur->next)
+ {
+ grub_uint32_t tmabs = cur->tp - start_time;
+ grub_uint32_t tmrel = cur->tp - last_time;
+ last_time = cur->tp;
+
+ grub_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n",
+ tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, cur->file, cur->line,
+ cur->msg);
+ }
+ return 0;
+}
+
+static grub_command_t cmd_boottime;
+
+GRUB_MOD_INIT(boottime)
+{
+ cmd_boottime =
+ grub_register_command ("boottime", grub_cmd_boottime,
+ 0, N_("Get boot time statistics."));
+}
+
+GRUB_MOD_FINI(boottime)
+{
+ grub_unregister_command (cmd_boottime);
+}
diff --git a/grub-core/commands/i386/cmosdump.c b/grub-core/commands/i386/cmosdump.c
new file mode 100644
index 0000000..952d200
--- /dev/null
+++ b/grub-core/commands/i386/cmosdump.c
@@ -0,0 +1,64 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009,2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/misc.h>
+#include <grub/cmos.h>
+#include <grub/i18n.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_err_t
+grub_cmd_cmosdump (struct grub_command *cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ {
+ grub_err_t err;
+ grub_uint8_t value;
+ if ((i & 0xf) == 0)
+ grub_printf ("%02x: ", i);
+
+ err = grub_cmos_read (i, &value);
+ if (err)
+ return err;
+
+ grub_printf ("%02x ", value);
+ if ((i & 0xf) == 0xf)
+ grub_printf ("\n");
+ }
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+
+GRUB_MOD_INIT(cmosdump)
+{
+ cmd = grub_register_command ("cmosdump", grub_cmd_cmosdump,
+ 0,
+ N_("Dump CMOS contents."));
+}
+
+GRUB_MOD_FINI(cmosdump)
+{
+ grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/i386/coreboot/cb_timestamps.c b/grub-core/commands/i386/coreboot/cb_timestamps.c
new file mode 100644
index 0000000..5299ad4
--- /dev/null
+++ b/grub-core/commands/i386/coreboot/cb_timestamps.c
@@ -0,0 +1,118 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/i386/coreboot/lbio.h>
+#include <grub/i386/tsc.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static grub_uint32_t
+tsc2ms (grub_uint64_t tsc)
+{
+ grub_uint64_t ah = tsc >> 32;
+ grub_uint64_t al = tsc & 0xffffffff;
+
+ return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate;
+}
+
+static const char *descs[] = {
+ [1] = "romstage",
+ [2] = "before RAM init",
+ [3] = "after RAM init",
+ [4] = "end of romstage",
+ [8] = "start of RAM copy",
+ [9] = "end of RAM copy",
+ [10] = "start of ramstage",
+ [30] = "device enumerate",
+ [40] = "device configure",
+ [50] = "device enable",
+ [60] = "device initialize",
+ [70] = "device done",
+ [75] = "CBMEM POST",
+ [80] = "writing tables",
+ [90] = "loading payload",
+ [98] = "wake jump",
+ [99] = "selfboot jump",
+};
+
+static int
+iterate_linuxbios_table (grub_linuxbios_table_item_t table_item,
+ void *data)
+{
+ int *available = data;
+ grub_uint64_t last_tsc = 0;
+ struct grub_linuxbios_timestamp_table *ts_table;
+ unsigned i;
+
+ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_TIMESTAMPS)
+ return 0;
+
+ *available = 1;
+ ts_table = (struct grub_linuxbios_timestamp_table *) (grub_addr_t)
+ *(grub_uint64_t *) (table_item + 1);
+
+ for (i = 0; i < ts_table->used; i++)
+ {
+ grub_uint32_t tmabs = tsc2ms (ts_table->entries[i].tsc);
+ grub_uint32_t tmrel = tsc2ms (ts_table->entries[i].tsc - last_tsc);
+ last_tsc = ts_table->entries[i].tsc;
+
+ grub_printf ("%3d.%03ds %2d.%03ds %02d %s\n",
+ tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000,
+ ts_table->entries[i].id,
+ (ts_table->entries[i].id < ARRAY_SIZE (descs)
+ && descs[ts_table->entries[i].id])
+ ? descs[ts_table->entries[i].id] : "");
+ }
+ return 1;
+}
+
+
+static grub_err_t
+grub_cmd_coreboot_boottime (struct grub_command *cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char *argv[] __attribute__ ((unused)))
+{
+ int available = 0;
+
+ grub_linuxbios_table_iterate (iterate_linuxbios_table, &available);
+ if (!available)
+ {
+ grub_puts_ (N_("No boot time statistics is available\n"));
+ return 0;
+ }
+ return 0;
+}
+
+static grub_command_t cmd_boottime;
+
+GRUB_MOD_INIT(cbtime)
+{
+ cmd_boottime =
+ grub_register_command ("coreboot_boottime", grub_cmd_coreboot_boottime,
+ 0, N_("Get coreboot boot time statistics."));
+}
+
+GRUB_MOD_FINI(cbtime)
+{
+ grub_unregister_command (cmd_boottime);
+}
diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c
new file mode 100644
index 0000000..dc46d55
--- /dev/null
+++ b/grub-core/commands/i386/coreboot/cbls.c
@@ -0,0 +1,128 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/i386/coreboot/lbio.h>
+#include <grub/i386/tsc.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const char *console_descs[] = {
+ "8250 UART",
+ "VGA",
+ "BTEXT",
+ "CBMEM console",
+ "SROM",
+ "EHCI debug",
+ "memory-mapped 8250 UART"
+};
+
+static const char *descs[] = {
+ [GRUB_LINUXBIOS_MEMBER_MEMORY] = "memory map (`lsmmap' to list)",
+ [GRUB_LINUXBIOS_MEMBER_MAINBOARD] = "mainboard",
+ [4] = "version",
+ [5] = "extra version",
+ [6] = "build",
+ [7] = "compile time",
+ [8] = "compile by",
+ [9] = "compile host",
+ [0xa] = "compile domain",
+ [0xb] = "compiler",
+ [0xc] = "linker",
+ [0xd] = "assembler",
+ [0xf] = "serial",
+ [GRUB_LINUXBIOS_MEMBER_CONSOLE] = "console",
+ [0x12] = "framebuffer",
+ [0x13] = "GPIO",
+ [0x15] = "VDAT",
+ [GRUB_LINUXBIOS_MEMBER_TIMESTAMPS] = "timestamps (`coreboot_boottime' to list)",
+ [GRUB_LINUXBIOS_MEMBER_CBMEMC] = "CBMEM console (`cbmem' to list)",
+ [0x18] = "MRC cache",
+ [0x19] = "VBNV",
+ [0xc8] = "CMOS option table",
+ [0xc9] = "CMOS option",
+ [0xca] = "CMOS option enum",
+ [0xcb] = "CMOS option defaults",
+ [0xcc] = "CMOS checksum",
+};
+
+static int
+iterate_linuxbios_table (grub_linuxbios_table_item_t table_item,
+ void *data __attribute__ ((unused)))
+{
+ if (table_item->tag < ARRAY_SIZE (descs) && descs[table_item->tag])
+ grub_printf ("tag=%02x size=%02x %s",
+ table_item->tag, table_item->size, descs[table_item->tag]);
+ else
+ grub_printf ("tag=%02x size=%02x",
+ table_item->tag, table_item->size);
+
+ switch (table_item->tag)
+ {
+ case GRUB_LINUXBIOS_MEMBER_MAINBOARD:
+ {
+ struct grub_linuxbios_mainboard *mb;
+ mb = (struct grub_linuxbios_mainboard *) (table_item + 1);
+ grub_printf (": vendor=`%s' part_number=`%s'",
+ mb->strings + mb->vendor,
+ mb->strings + mb->part_number);
+ break;
+ }
+ case 0x04 ... 0x0d:
+ grub_printf (": `%s'", (char *) (table_item + 1));
+ break;
+ case GRUB_LINUXBIOS_MEMBER_CONSOLE:
+ {
+ grub_uint16_t *val = (grub_uint16_t *) (table_item + 1);
+ grub_printf (": id=%d", *val);
+ if (*val < ARRAY_SIZE (console_descs)
+ && console_descs[*val])
+ grub_printf (" %s", console_descs[*val]);
+ }
+ }
+ grub_printf ("\n");
+
+ return 0;
+}
+
+
+static grub_err_t
+grub_cmd_lscoreboot (struct grub_command *cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char *argv[] __attribute__ ((unused)))
+{
+ grub_linuxbios_table_iterate (iterate_linuxbios_table, 0);
+ return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(cbls)
+{
+ cmd =
+ grub_register_command ("lscoreboot", grub_cmd_lscoreboot,
+ 0, N_("List coreboot tables."));
+}
+
+GRUB_MOD_FINI(cbls)
+{
+ grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c
index 0925c6a..460cf4e 100644
--- a/grub-core/commands/keystatus.c
+++ b/grub-core/commands/keystatus.c
@@ -42,7 +42,7 @@ grub_getkeystatus (void)
grub_term_input_t term;
if (grub_term_poll_usb)
- grub_term_poll_usb ();
+ grub_term_poll_usb (0);
FOR_ACTIVE_TERM_INPUTS(term)
{
diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c
index 07c3f0d..0824914 100644
--- a/grub-core/commands/lsacpi.c
+++ b/grub-core/commands/lsacpi.c
@@ -44,7 +44,8 @@ static void
disp_acpi_table (struct grub_acpi_table_header *t)
{
print_field (t->signature);
- grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision);
+ grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum,
+ grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid");
print_field (t->oemid);
print_field (t->oemtable);
grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev);
@@ -66,39 +67,87 @@ disp_madt_table (struct grub_acpi_madt *t)
d = t->entries;
for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
{
- grub_printf (" type=%x l=%u ", d->type, d->len);
-
switch (d->type)
{
+ case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC:
+ {
+ struct grub_acpi_madt_entry_lapic *dt = (void *) d;
+ grub_printf (" LAPIC ACPI_ID=%02x APIC_ID=%02x Flags=%08x\n",
+ dt->acpiid, dt->apicid, dt->flags);
+ if (dt->hdr.len != sizeof (*dt))
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
+ break;
+ }
+
+ case GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC:
+ {
+ struct grub_acpi_madt_entry_ioapic *dt = (void *) d;
+ grub_printf (" IOAPIC ID=%02x address=%08x GSI=%08x\n",
+ dt->id, dt->address, dt->global_sys_interrupt);
+ if (dt->hdr.len != sizeof (*dt))
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
+ if (dt->pad)
+ grub_printf (" non-zero pad: %02x\n", dt->pad);
+ break;
+ }
+
case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
{
struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d;
- grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
+ grub_printf (" Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
dt->bus, dt->source, dt->global_sys_interrupt,
dt->flags);
+ if (dt->hdr.len != sizeof (*dt))
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
}
break;
+
+ case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI:
+ {
+ struct grub_acpi_madt_entry_lapic_nmi *dt = (void *) d;
+ grub_printf (" LAPIC_NMI ACPI_ID=%02x Flags=%04x lint=%02x\n",
+ dt->acpiid, dt->flags, dt->lint);
+ if (dt->hdr.len != sizeof (*dt))
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
+ break;
+ }
+
case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
{
struct grub_acpi_madt_entry_sapic *dt = (void *) d;
- grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
+ grub_printf (" IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
"\n",
dt->id, dt->global_sys_interrupt_base,
dt->addr);
+ if (dt->hdr.len != sizeof (*dt))
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
+ if (dt->pad)
+ grub_printf (" non-zero pad: %02x\n", dt->pad);
+
}
break;
case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
{
struct grub_acpi_madt_entry_lsapic *dt = (void *) d;
- grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
+ grub_printf (" LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
dt->cpu_id, dt->id, dt->eid, dt->flags);
if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED)
grub_printf (" Enabled\n");
else
grub_printf (" Disabled\n");
if (d->len > sizeof (struct grub_acpi_madt_entry_sapic))
- grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid,
+ grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid,
dt->cpu_uid_str);
+ if (dt->hdr.len != sizeof (*dt) + grub_strlen ((char *) dt->cpu_uid_str) + 1)
+ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len,
+ (int) sizeof (*dt));
+ if (dt->pad[0] || dt->pad[1] || dt->pad[2])
+ grub_printf (" non-zero pad: %02x%02x%02x\n", dt->pad[0], dt->pad[1], dt->pad[2]);
}
break;
case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
@@ -107,17 +156,18 @@ disp_madt_table (struct grub_acpi_madt *t)
static const char * const platint_type[] =
{"Nul", "PMI", "INIT", "CPEI"};
- grub_printf ("Platform INT flags=%04x type=%02x (%s)"
+ grub_printf (" Platform INT flags=%04x type=%02x (%s)"
" ID=%02x EID=%02x\n",
dt->flags, dt->inttype,
(dt->inttype < ARRAY_SIZE (platint_type))
? platint_type[dt->inttype] : "??", dt->cpu_id,
dt->cpu_eid);
- grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
+ grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
dt->sapic_vector, dt->global_sys_int, dt->src_flags);
}
break;
default:
+ grub_printf (" type=%x l=%u ", d->type, d->len);
grub_printf (" ??\n");
}
}
@@ -182,7 +232,7 @@ static void
disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
{
print_field (rsdp->signature);
- grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum);
+ grub_printf ("chksum:%02x (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid");
print_field (rsdp->oemid);
grub_printf ("rev=%d\n", rsdp->revision);
grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
@@ -192,8 +242,13 @@ static void
disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
{
disp_acpi_rsdpv1 (&rsdp->rsdpv1);
- grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
+ grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid",
rsdp->xsdt_addr);
+ if (rsdp->length != sizeof (*rsdp))
+ grub_printf (" length mismatch %d != %d\n", rsdp->length,
+ (int) sizeof (*rsdp));
+ if (rsdp->reserved[0] || rsdp->reserved[1] || rsdp->reserved[2])
+ grub_printf (" non-zero reserved %02x%02x%02x\n", rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]);
}
static const struct grub_arg_option options[] = {
diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c
index 425a411..3002186 100644
--- a/grub-core/commands/terminal.c
+++ b/grub-core/commands/terminal.c
@@ -108,9 +108,9 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
if (term)
break;
if (again)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("terminal `%s' isn't found"),
- args[i]);
+ args[i]);
for (aut = autoloads; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0
|| (grub_strcmp (args[i], "ofconsole") == 0
@@ -126,6 +126,14 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled,
grub_errno = GRUB_ERR_NONE;
break;
}
+ if (grub_memcmp (args[i], "serial_usb",
+ sizeof ("serial_usb") - 1) == 0
+ && grub_term_poll_usb)
+ {
+ grub_term_poll_usb (1);
+ again = 1;
+ continue;
+ }
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("terminal `%s' isn't found"),
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
index af35b8c..01cdca9 100644
--- a/grub-core/commands/usbtest.c
+++ b/grub-core/commands/usbtest.c
@@ -196,7 +196,7 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
- grub_usb_poll_devices ();
+ grub_usb_poll_devices (1);
grub_printf ("USB devices:\n\n");
grub_usb_iterate (usb_iterate, NULL);
diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c
index d399d0f..c5e69eb 100644
--- a/grub-core/commands/verify.c
+++ b/grub-core/commands/verify.c
@@ -124,7 +124,10 @@ struct signature_v4_header
const char *hashes[] = {
"md5", "sha1", "ripemd160",
- [0x0a] = "sha512"
+ [0x08] = "sha256",
+ [0x09] = "sha384",
+ [0x0a] = "sha512",
+ [0x0b] = "sha224"
};
struct
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index ce755c3..f39c1ab 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -875,7 +875,10 @@ grub_cryptodisk_scan_device (const char *name,
/* Try to open disk. */
source = grub_disk_open (name);
if (!source)
- return grub_errno;
+ {
+ grub_print_error ();
+ return 0;
+ }
err = grub_cryptodisk_scan_device_real (name, source);
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index 644bbd2..2130cb1 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -349,6 +349,14 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
}
+ grub_uint32_t block_size = 0;
+ if (grub_ofdisk_get_block_size (devpath, &block_size) == 0)
+ {
+ for (disk->log_sector_size = 0;
+ (1U << disk->log_sector_size) < block_size;
+ disk->log_sector_size++);
+ }
+
/* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */
@@ -415,7 +423,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
last_devpath = disk->data;
}
- pos = sector << GRUB_DISK_SECTOR_BITS;
+ pos = sector << disk->log_sector_size;
grub_ieee1275_seek (last_ihandle, pos, &status);
if (status < 0)
@@ -434,9 +442,9 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
err = grub_ofdisk_prepare (disk, sector);
if (err)
return err;
- grub_ieee1275_read (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS,
+ grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size,
&actual);
- if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+ if (actual != (grub_ssize_t) (size << disk->log_sector_size))
return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx "
"from `%s'"),
(unsigned long long) sector,
@@ -454,9 +462,9 @@ grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
err = grub_ofdisk_prepare (disk, sector);
if (err)
return err;
- grub_ieee1275_write (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS,
+ grub_ieee1275_write (last_ihandle, buf, size << disk->log_sector_size,
&actual);
- if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+ if (actual != (grub_ssize_t) (size << disk->log_sector_size))
return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx "
"to `%s'"),
(unsigned long long) sector,
@@ -493,3 +501,44 @@ grub_ofdisk_fini (void)
grub_disk_dev_unregister (&grub_ofdisk_dev);
}
+
+grub_err_t
+grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
+{
+ struct size_args_ieee1275
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t result;
+ grub_ieee1275_cell_t size1;
+ grub_ieee1275_cell_t size2;
+ } args_ieee1275;
+
+ if (last_ihandle)
+ grub_ieee1275_close (last_ihandle);
+
+ last_ihandle = 0;
+ last_devpath = NULL;
+
+ grub_ieee1275_open (device, &last_ihandle);
+ if (! last_ihandle)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+
+ INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2);
+ args_ieee1275.method = (grub_ieee1275_cell_t) "block-size";
+ args_ieee1275.ihandle = last_ihandle;
+ args_ieee1275.result = 1;
+
+ *block_size = GRUB_DISK_SECTOR_SIZE;
+
+ if ((IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) || (args_ieee1275.result))
+ grub_dprintf ("disk", "can't get block size\n");
+ else
+ if (args_ieee1275.size1
+ && !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
+ && args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
+ *block_size = args_ieee1275.size1;
+
+ return 0;
+}
diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
index 50f0caf..da01be3 100644
--- a/grub-core/disk/usbms.c
+++ b/grub-core/disk/usbms.c
@@ -151,6 +151,8 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
unsigned curnum;
grub_usb_err_t err = GRUB_ERR_NONE;
+ grub_boot_time ("Attaching USB mass storage");
+
if (first_available_slot == ARRAY_SIZE (grub_usbms_devices))
return 0;
@@ -246,6 +248,8 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
usbdev->config[configno].interf[interfno].detach_hook = grub_usbms_detach;
+ grub_boot_time ("Attached USB mass storage");
+
#if 0 /* All this part should be probably deleted.
* This make trouble on some devices if they are not in
* Phase Error state - and there they should be not in such state...
@@ -273,7 +277,7 @@ grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data,
if (pull != GRUB_DISK_PULL_NONE)
return 0;
- grub_usb_poll_devices ();
+ grub_usb_poll_devices (1);
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (grub_usbms_devices[i])
@@ -326,7 +330,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
/* Write the request.
* XXX: Error recovery is maybe still not fully correct. */
- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr,
+ err = grub_usb_bulk_write (dev->dev, dev->out,
sizeof (cbw), (char *) &cbw);
if (err)
{
@@ -341,7 +345,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
/* Read/write the data, (maybe) according to specification. */
if (size && (read_write == 0))
{
- err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf);
+ err = grub_usb_bulk_read (dev->dev, dev->in, size, buf);
grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
if (err)
{
@@ -362,7 +366,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
}
else if (size)
{
- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf);
+ err = grub_usb_bulk_write (dev->dev, dev->out, size, buf);
grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
grub_dprintf ("usb", "First 16 bytes of sent data:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
buf[ 0], buf[ 1], buf[ 2], buf[ 3],
@@ -388,12 +392,12 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
/* Read the status - (maybe) according to specification. */
CheckCSW:
- errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
+ errCSW = grub_usb_bulk_read (dev->dev, dev->in,
sizeof (status), (char *) &status);
if (errCSW)
{
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
- errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
+ errCSW = grub_usb_bulk_read (dev->dev, dev->in,
sizeof (status), (char *) &status);
if (errCSW)
{ /* Bulk-only reset device. */
@@ -476,7 +480,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
else if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI)
{
/* Try to get status from interrupt pipe */
- err = grub_usb_bulk_read (dev->dev, dev->intrpt->endp_addr,
+ err = grub_usb_bulk_read (dev->dev, dev->intrpt,
2, (char*)&status);
grub_dprintf ("usb", "CBI cmdcb setup status: err=%d, status=0x%x\n", err, status);
}
@@ -487,7 +491,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
/* Read/write the data, (maybe) according to specification. */
if (size && (read_write == 0))
{
- err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf);
+ err = grub_usb_bulk_read (dev->dev, dev->in, size, buf);
grub_dprintf ("usb", "read: %d\n", err);
if (err)
{
@@ -498,7 +502,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
}
else if (size)
{
- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf);
+ err = grub_usb_bulk_write (dev->dev, dev->out, size, buf);
grub_dprintf ("usb", "write: %d\n", err);
if (err)
{
@@ -517,7 +521,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
* (we do not it yet) - ? */
if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI)
{ /* Check status in interrupt pipe */
- err = grub_usb_bulk_read (dev->dev, dev->intrpt->endp_addr,
+ err = grub_usb_bulk_read (dev->dev, dev->intrpt,
2, (char*)&status);
grub_dprintf ("usb", "read status: %d\n", err);
if (err)
@@ -607,7 +611,8 @@ grub_usbms_open (int id, int devnum, struct grub_scsi *scsi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"not USB Mass Storage device");
- grub_usb_poll_devices ();
+ if (!grub_usbms_devices[devnum])
+ grub_usb_poll_devices (1);
if (!grub_usbms_devices[devnum])
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c
index 7e557c3..11a1259 100644
--- a/grub-core/fs/fshelp.c
+++ b/grub-core/fs/fshelp.c
@@ -147,6 +147,7 @@ find_file (const char *currpath, grub_fshelp_node_t currroot,
free_node (ctx->currnode, ctx);
free_node (ctx->oldnode, ctx);
ctx->currnode = 0;
+ ctx->oldnode = 0;
return grub_error (GRUB_ERR_SYMLINK_LOOP,
N_("too deep nesting of symlinks"));
}
@@ -158,6 +159,7 @@ find_file (const char *currpath, grub_fshelp_node_t currroot,
if (!symlink)
{
free_node (ctx->oldnode, ctx);
+ ctx->oldnode = 0;
return grub_errno;
}
@@ -177,12 +179,16 @@ find_file (const char *currpath, grub_fshelp_node_t currroot,
if (grub_errno)
{
free_node (ctx->oldnode, ctx);
+ ctx->oldnode = 0;
return grub_errno;
}
}
if (ctx->oldnode != ctx->currnode)
- free_node (ctx->oldnode, ctx);
+ {
+ free_node (ctx->oldnode, ctx);
+ ctx->oldnode = 0;
+ }
/* Found the node! */
if (! next || *next == '\0')
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 49d2a89..aee1582 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -295,9 +295,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
keys = &node->inode.data.btree.keys[0];
if (node->inode.fork_offset)
- recoffset = (node->inode.fork_offset
- - ((char *) &node->inode.data.btree.keys - (char *) &node->inode))
- / (2 * sizeof (grub_uint64_t));
+ recoffset = (node->inode.fork_offset - 1) / 2;
else
recoffset = ((1 << node->data->sblock.log2_inode)
- ((char *) &node->inode.data.btree.keys
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index 5b0aa65..d06b6ae 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -648,7 +648,10 @@ grub_dl_load_core (void *addr, grub_size_t size)
grub_dprintf ("modules", "module name: %s\n", mod->name);
grub_dprintf ("modules", "init function: %p\n", mod->init);
+
+ grub_boot_time ("Initing module %s", mod->name);
grub_dl_call_init (mod);
+ grub_boot_time ("Module %s inited", mod->name);
if (grub_dl_add (mod))
{
diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c
new file mode 100644
index 0000000..b35e235
--- /dev/null
+++ b/grub-core/kern/elfXX.c
@@ -0,0 +1,144 @@
+int
+grub_elf_is_elfXX (grub_elf_t elf)
+{
+ return elf->ehdr.ehdrXX.e_ident[EI_CLASS] == ELFCLASSXX;
+}
+
+grub_err_t
+grub_elfXX_load_phdrs (grub_elf_t elf)
+{
+ grub_ssize_t phdrs_size;
+
+ if (elf->phdrs)
+ return GRUB_ERR_NONE;
+
+ phdrs_size = elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize;
+
+ grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
+ (unsigned long long) elf->ehdr.ehdrXX.e_phoff,
+ (unsigned long) phdrs_size);
+
+ elf->phdrs = grub_malloc (phdrs_size);
+ if (! elf->phdrs)
+ return grub_errno;
+
+ if ((grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_phoff) == (grub_off_t) -1)
+ || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ elf->filename);
+ return grub_errno;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/* Calculate the amount of memory spanned by the segments. */
+grub_size_t
+grub_elfXX_size (grub_elf_t elf,
+ ElfXX_Addr *base, grub_uintXX_t *max_align)
+{
+ ElfXX_Addr segments_start = (ElfXX_Addr) -1;
+ ElfXX_Addr segments_end = 0;
+ int nr_phdrs = 0;
+ grub_uint32_t curr_align = 1;
+ ElfXX_Phdr *phdr;
+
+ /* Run through the program headers to calculate the total memory size we
+ * should claim. */
+ FOR_ELFXX_PHDRS (elf, phdr)
+ {
+ /* Only consider loadable segments. */
+ if (phdr->p_type != PT_LOAD)
+ continue;
+ nr_phdrs++;
+ if (phdr->p_paddr < segments_start)
+ segments_start = phdr->p_paddr;
+ if (phdr->p_paddr + phdr->p_memsz > segments_end)
+ segments_end = phdr->p_paddr + phdr->p_memsz;
+ if (curr_align < phdr->p_align)
+ curr_align = phdr->p_align;
+ }
+
+ if (base)
+ *base = 0;
+
+ if (nr_phdrs == 0)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "no program headers present");
+ return 0;
+ }
+
+ if (segments_end < segments_start)
+ {
+ /* Very bad addresses. */
+ grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
+ return 0;
+ }
+
+ if (base)
+ *base = segments_start;
+ if (max_align)
+ *max_align = curr_align;
+ return segments_end - segments_start;
+}
+
+grub_err_t
+grub_elfXX_load (grub_elf_t elf, const char *filename,
+ void *load_offset, enum grub_elf_load_flags load_flags,
+ grub_addr_t *base, grub_size_t *size)
+{
+ grub_addr_t load_base = (grub_addr_t) -1ULL;
+ grub_size_t load_size = 0;
+ ElfXX_Phdr *phdr;
+
+ FOR_ELFXX_PHDRS(elf, phdr)
+ {
+ grub_addr_t load_addr;
+
+ if (phdr->p_type != PT_LOAD && !((load_flags & GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC) && phdr->p_type == PT_DYNAMIC))
+ continue;
+
+ load_addr = (grub_addr_t) phdr->p_paddr;
+ if (load_flags & GRUB_ELF_LOAD_FLAGS_28BITS)
+ load_addr &= 0xFFFFFFF;
+ load_addr += (grub_addr_t) load_offset;
+
+ if (load_addr < load_base)
+ load_base = load_addr;
+
+ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+ (unsigned long long) load_addr,
+ (unsigned long long) phdr->p_memsz);
+
+ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+ return grub_errno;
+
+ if (phdr->p_filesz)
+ {
+ grub_ssize_t read;
+ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+ if (read != (grub_ssize_t) phdr->p_filesz)
+ {
+ if (!grub_errno)
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+ filename);
+ return grub_errno;
+ }
+ }
+
+ if (phdr->p_filesz < phdr->p_memsz)
+ grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+ 0, phdr->p_memsz - phdr->p_filesz);
+
+ load_size += phdr->p_memsz;
+ }
+
+ if (base)
+ *base = load_base;
+ if (size)
+ *size = load_size;
+
+ return grub_errno;
+}
diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c
index ae4af08..a062a59 100644
--- a/grub-core/kern/i386/coreboot/mmap.c
+++ b/grub-core/kern/i386/coreboot/mmap.c
@@ -32,7 +32,7 @@ check_signature (grub_linuxbios_table_header_t tbl_header)
return 0;
}
-static grub_err_t
+grub_err_t
grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t,
void *),
void *hook_data)
diff --git a/grub-core/kern/i386/pit.c b/grub-core/kern/i386/pit.c
deleted file mode 100644
index 092481a..0000000
--- a/grub-core/kern/i386/pit.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2008 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/i386/io.h>
-#include <grub/i386/pit.h>
-
-void
-grub_pit_wait (grub_uint16_t tics)
-{
- /* Disable timer2 gate and speaker. */
- grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
- & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
- GRUB_PIT_SPEAKER_PORT);
-
- /* Set tics. */
- grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD,
- GRUB_PIT_CTRL);
- grub_outb (tics & 0xff, GRUB_PIT_COUNTER_2);
- grub_outb (tics >> 8, GRUB_PIT_COUNTER_2);
-
- /* Enable timer2 gate, keep speaker disabled. */
- grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA)
- | GRUB_PIT_SPK_TMR2,
- GRUB_PIT_SPEAKER_PORT);
-
- /* Wait. */
- while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00);
-
- /* Disable timer2 gate and speaker. */
- grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
- & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
- GRUB_PIT_SPEAKER_PORT);
-}
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 99477c7..19dc988 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -30,10 +30,10 @@
#include <grub/reader.h>
#include <grub/parser.h>
-/* This is actualy platform-independant but used only on some platforms. */
-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || \
- defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) || \
- defined (GRUB_MACHINE_ARM)
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/memory.h>
+#endif
+
grub_addr_t
grub_modules_get_end (void)
{
@@ -47,7 +47,6 @@ grub_modules_get_end (void)
return grub_modbase + modinfo->size;
}
-#endif
/* Load all modules in core. */
static void
@@ -69,6 +68,8 @@ grub_load_modules (void)
}
}
+static char *load_config;
+
static void
grub_load_config (void)
{
@@ -78,9 +79,17 @@ grub_load_config (void)
/* Not an embedded config, skip. */
if (header->type != OBJ_TYPE_CONFIG)
continue;
-
- grub_parser_execute ((char *) header +
- sizeof (struct grub_module_header));
+
+ load_config = grub_malloc (header->size - sizeof (struct grub_module_header) + 1);
+ if (!load_config)
+ {
+ grub_print_error ();
+ break;
+ }
+ grub_memcpy (load_config, (char *) header +
+ sizeof (struct grub_module_header),
+ header->size - sizeof (struct grub_module_header));
+ load_config[header->size - sizeof (struct grub_module_header)] = 0;
break;
}
}
@@ -170,7 +179,16 @@ grub_set_prefix_and_root (void)
else
grub_free (fwdevice);
if (fwpath && !path)
- path = fwpath;
+ {
+ grub_size_t len = grub_strlen (fwpath);
+ while (len > 1 && fwpath[len - 1] == '/')
+ fwpath[--len] = 0;
+ if (len >= sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1
+ && grub_memcmp (fwpath + len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1), GRUB_TARGET_CPU "-" GRUB_PLATFORM,
+ sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1) == 0)
+ fwpath[len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1)] = 0;
+ path = fwpath;
+ }
else
grub_free (fwpath);
if (device)
@@ -205,6 +223,30 @@ grub_load_normal_mode (void)
grub_command_execute ("normal", 0, 0);
}
+static void
+reclaim_module_space (void)
+{
+ grub_addr_t modstart, modend;
+
+ if (!grub_modbase)
+ return;
+
+#ifdef GRUB_MACHINE_PCBIOS
+ modstart = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR;
+#else
+ modstart = grub_modbase;
+#endif
+ modend = grub_modules_get_end ();
+ grub_modbase = 0;
+
+#if GRUB_KERNEL_PRELOAD_SPACE_REUSABLE
+ grub_mm_init_region ((void *) modstart, modend - modstart);
+#else
+ (void) modstart;
+ (void) modend;
+#endif
+}
+
/* The main routine. */
void __attribute__ ((noreturn))
grub_main (void)
@@ -212,11 +254,17 @@ grub_main (void)
/* First of all, initialize the machine. */
grub_machine_init ();
+ grub_boot_time ("After machine init.");
+
/* Hello. */
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("Welcome to GRUB!\n\n");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+ grub_load_config ();
+
+ grub_boot_time ("Before loading embedded modules.");
+
/* Load pre-loaded modules and free the space. */
grub_register_exported_symbols ();
#ifdef GRUB_LINKER_HAVE_INIT
@@ -224,15 +272,28 @@ grub_main (void)
#endif
grub_load_modules ();
+ grub_boot_time ("After loading embedded modules.");
+
/* It is better to set the root device as soon as possible,
for convenience. */
grub_set_prefix_and_root ();
grub_env_export ("root");
grub_env_export ("prefix");
+ /* Reclaim space used for modules. */
+ reclaim_module_space ();
+
+ grub_boot_time ("After reclaiming module space.");
+
grub_register_core_commands ();
- grub_load_config ();
+ grub_boot_time ("Before execution of embedded config.");
+
+ if (load_config)
+ grub_parser_execute (load_config);
+
+ grub_boot_time ("After execution of embedded config. Attempt to go to normal mode");
+
grub_load_normal_mode ();
grub_rescue_run ();
}
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index c3203a0..143b52c 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -1138,3 +1138,42 @@ void __deregister_frame_info (void)
}
#endif
+#if BOOT_TIME_STATS
+
+#include <grub/time.h>
+
+struct grub_boot_time *grub_boot_time_head;
+static struct grub_boot_time **boot_time_last = &grub_boot_time_head;
+
+void
+grub_real_boot_time (const char *file,
+ const int line,
+ const char *fmt, ...)
+{
+ struct grub_boot_time *n;
+ va_list args;
+
+ grub_error_push ();
+ n = grub_malloc (sizeof (*n));
+ if (!n)
+ {
+ grub_errno = 0;
+ grub_error_pop ();
+ return;
+ }
+ n->file = file;
+ n->line = line;
+ n->tp = grub_get_time_ms ();
+ n->next = 0;
+
+ va_start (args, fmt);
+ n->msg = grub_xvasprintf (fmt, args);
+ va_end (args);
+
+ *boot_time_last = n;
+ boot_time_last = &n->next;
+
+ grub_errno = 0;
+ grub_error_pop ();
+}
+#endif
diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c
index 34096bc..ad79566 100644
--- a/grub-core/kern/term.c
+++ b/grub-core/kern/term.c
@@ -32,7 +32,7 @@ struct grub_term_input *grub_term_inputs;
grub_uint8_t grub_term_normal_color;
grub_uint8_t grub_term_highlight_color;
-void (*grub_term_poll_usb) (void) = NULL;
+void (*grub_term_poll_usb) (int wait_for_completion) = NULL;
void (*grub_net_poll_cards_idle) (void) = NULL;
/* Put a Unicode character. */
@@ -90,7 +90,7 @@ grub_getkey_noblock (void)
grub_term_input_t term;
if (grub_term_poll_usb)
- grub_term_poll_usb ();
+ grub_term_poll_usb (0);
if (grub_net_poll_cards_idle)
grub_net_poll_cards_idle ();
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 07f337d..9aaa3b2 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -296,6 +296,8 @@ grub_normal_execute (const char *config, int nested, int batch)
grub_register_variable_hook ("prefix", NULL, read_lists_hook);
}
+ grub_boot_time ("Executing config file");
+
if (config)
{
menu = read_config_file (config);
@@ -304,10 +306,14 @@ grub_normal_execute (const char *config, int nested, int batch)
grub_errno = GRUB_ERR_NONE;
}
+ grub_boot_time ("Executed config file");
+
if (! batch)
{
if (menu && menu->size)
{
+
+ grub_boot_time ("Entering menu");
grub_show_menu (menu, nested, 0);
if (nested)
grub_normal_free_menu (menu);
@@ -319,12 +325,15 @@ grub_normal_execute (const char *config, int nested, int batch)
void
grub_enter_normal_mode (const char *config)
{
+ grub_boot_time ("Entering normal mode");
nested_level++;
grub_normal_execute (config, 0, 0);
+ grub_boot_time ("Entering shell");
grub_cmdline_run (0);
nested_level--;
if (grub_normal_exit_level)
grub_normal_exit_level--;
+ grub_boot_time ("Exiting normal mode");
}
/* Enter normal mode from rescue mode. */
@@ -504,6 +513,8 @@ GRUB_MOD_INIT(normal)
{
unsigned i;
+ grub_boot_time ("Preparing normal module");
+
/* Previously many modules depended on gzio. Be nice to user and load it. */
grub_dl_load ("gzio");
grub_errno = 0;
@@ -556,6 +567,8 @@ GRUB_MOD_INIT(normal)
grub_env_export ("grub_cpu");
grub_env_set ("grub_platform", GRUB_PLATFORM);
grub_env_export ("grub_platform");
+
+ grub_boot_time ("Normal module prepared");
}
GRUB_MOD_FINI(normal)
diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
index dc03268..507f996 100644
--- a/grub-core/normal/term.c
+++ b/grub-core/normal/term.c
@@ -979,20 +979,21 @@ grub_ucs4_count_lines (const grub_uint32_t * str,
}
void
-grub_xputs_normal (const char *str)
+grub_xnputs (const char *str, grub_size_t msg_len)
{
grub_uint32_t *unicode_str = NULL, *unicode_last_position;
int backlog = 0;
grub_term_output_t term;
grub_error_push ();
- grub_utf8_to_ucs4_alloc (str, &unicode_str,
- &unicode_last_position);
+
+ unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t));
+
grub_error_pop ();
if (!unicode_str)
{
- for (; *str; str++)
+ for (; msg_len--; str++, msg_len++)
{
struct grub_unicode_glyph c =
{
@@ -1021,6 +1022,10 @@ grub_xputs_normal (const char *str)
return;
}
+ msg_len = grub_utf8_to_ucs4 (unicode_str, msg_len,
+ (grub_uint8_t *) str, -1, 0);
+ unicode_last_position = unicode_str + msg_len;
+
FOR_ACTIVE_TERM_OUTPUTS(term)
{
int cur;
@@ -1045,6 +1050,12 @@ grub_xputs_normal (const char *str)
}
void
+grub_xputs_normal (const char *str)
+{
+ grub_xnputs (str, grub_strlen (str));
+}
+
+void
grub_cls (void)
{
struct grub_term_output *term;
diff --git a/grub-core/term/i386/coreboot/cbmemc.c b/grub-core/term/i386/coreboot/cbmemc.c
new file mode 100644
index 0000000..c58d671
--- /dev/null
+++ b/grub-core/term/i386/coreboot/cbmemc.c
@@ -0,0 +1,127 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/terminfo.h>
+#include <grub/dl.h>
+#include <grub/machine/lbio.h>
+#include <grub/command.h>
+#include <grub/normal.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+struct grub_linuxbios_cbmemc
+{
+ grub_uint32_t size;
+ grub_uint32_t pointer;
+ char data[0];
+};
+
+static struct grub_linuxbios_cbmemc *cbmemc;
+
+static void
+put (struct grub_term_output *term __attribute__ ((unused)), const int c)
+{
+ if (!cbmemc)
+ return;
+ if (cbmemc->pointer < cbmemc->size)
+ cbmemc->data[cbmemc->pointer] = c;
+ cbmemc->pointer++;
+}
+
+struct grub_terminfo_output_state grub_cbmemc_terminfo_output =
+ {
+ .put = put,
+ .width = 80,
+ .height = 24
+ };
+
+static struct grub_term_output grub_cbmemc_term_output =
+ {
+ .name = "cbmemc",
+ .init = grub_terminfo_output_init,
+ .fini = 0,
+ .putchar = grub_terminfo_putchar,
+ .getxy = grub_terminfo_getxy,
+ .getwh = grub_terminfo_getwh,
+ .gotoxy = grub_terminfo_gotoxy,
+ .cls = grub_terminfo_cls,
+ .setcolorstate = grub_terminfo_setcolorstate,
+ .setcursor = grub_terminfo_setcursor,
+ .flags = GRUB_TERM_CODE_TYPE_ASCII,
+ .data = &grub_cbmemc_terminfo_output,
+ };
+
+static int
+iterate_linuxbios_table (grub_linuxbios_table_item_t table_item,
+ void *data __attribute__ ((unused)))
+{
+ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_CBMEMC)
+ return 0;
+ cbmemc = (struct grub_linuxbios_cbmemc *) (grub_addr_t)
+ *(grub_uint64_t *) (table_item + 1);
+ return 1;
+}
+
+static grub_err_t
+grub_cmd_cbmemc (struct grub_command *cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char *argv[] __attribute__ ((unused)))
+{
+ grub_size_t len;
+ char *str;
+ struct grub_linuxbios_cbmemc *cbmemc_saved;
+
+ if (!cbmemc)
+ return grub_error (GRUB_ERR_IO, "no CBMEM console found");
+
+ len = cbmemc->pointer;
+ if (len > cbmemc->size)
+ len = cbmemc->size;
+ str = cbmemc->data;
+ cbmemc_saved = cbmemc;
+ cbmemc = 0;
+ grub_xnputs (str, len);
+ cbmemc = cbmemc_saved;
+ return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT (cbmemc)
+{
+ grub_linuxbios_table_iterate (iterate_linuxbios_table, 0);
+
+ if (cbmemc)
+ grub_term_register_output ("cbmemc", &grub_cbmemc_term_output);
+
+ cmd =
+ grub_register_command ("cbmemc", grub_cmd_cbmemc,
+ 0, N_("Show CBMEM console content."));
+}
+
+
+GRUB_MOD_FINI (cbmemc)
+{
+ grub_term_unregister_output (&grub_cbmemc_term_output);
+ grub_unregister_command (cmd);
+}
diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c
index ae00936..3b74846 100644
--- a/grub-core/term/usb_keyboard.c
+++ b/grub-core/term/usb_keyboard.c
@@ -244,7 +244,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno)
#endif
data->transfer = grub_usb_bulk_read_background (usbdev,
- data->endp->endp_addr,
+ data->endp,
sizeof (data->report),
(char *) data->report);
if (!data->transfer)
@@ -394,7 +394,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term)
sizeof (termdata->report));
termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev,
- termdata->endp->endp_addr,
+ termdata->endp,
sizeof (termdata->report),
(char *) termdata->report);
if (!termdata->transfer)
diff --git a/include/grub/acpi.h b/include/grub/acpi.h
index ee0a108..52d190c 100644
--- a/include/grub/acpi.h
+++ b/include/grub/acpi.h
@@ -88,12 +88,32 @@ struct grub_acpi_madt
enum
{
+ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC = 0,
+ GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC = 1,
GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2,
+ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4,
GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6,
GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7,
GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8
};
+struct grub_acpi_madt_entry_lapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t acpiid;
+ grub_uint8_t apicid;
+ grub_uint32_t flags;
+};
+
+struct grub_acpi_madt_entry_ioapic
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t id;
+ grub_uint8_t pad;
+ grub_uint32_t address;
+ grub_uint32_t global_sys_interrupt;
+};
+
struct grub_acpi_madt_entry_interrupt_override
{
struct grub_acpi_madt_entry_header hdr;
@@ -101,7 +121,16 @@ struct grub_acpi_madt_entry_interrupt_override
grub_uint8_t source;
grub_uint32_t global_sys_interrupt;
grub_uint16_t flags;
-};
+} __attribute__ ((packed));
+
+
+struct grub_acpi_madt_entry_lapic_nmi
+{
+ struct grub_acpi_madt_entry_header hdr;
+ grub_uint8_t acpiid;
+ grub_uint16_t flags;
+ grub_uint8_t lint;
+} __attribute__ ((packed));
struct grub_acpi_madt_entry_sapic
{
diff --git a/include/grub/boottime.h b/include/grub/boottime.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/grub/boottime.h
diff --git a/include/grub/i386/coreboot/lbio.h b/include/grub/i386/coreboot/lbio.h
index aa18539..b84e812 100644
--- a/include/grub/i386/coreboot/lbio.h
+++ b/include/grub/i386/coreboot/lbio.h
@@ -27,11 +27,36 @@ struct grub_linuxbios_table_header
};
typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t;
+struct grub_linuxbios_timestamp_entry
+{
+ grub_uint32_t id;
+ grub_uint64_t tsc;
+} __attribute__((packed));
+
+struct grub_linuxbios_timestamp_table
+{
+ grub_uint64_t base_tsc;
+ grub_uint32_t capacity;
+ grub_uint32_t used;
+ struct grub_linuxbios_timestamp_entry entries[0];
+} __attribute__((packed));
+
+struct grub_linuxbios_mainboard
+{
+ grub_uint8_t vendor;
+ grub_uint8_t part_number;
+ char strings[0];
+};
+
struct grub_linuxbios_table_item
{
#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00
#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01
+#define GRUB_LINUXBIOS_MEMBER_MAINBOARD 0x03
+#define GRUB_LINUXBIOS_MEMBER_CONSOLE 0x10
#define GRUB_LINUXBIOS_MEMBER_LINK 0x11
+#define GRUB_LINUXBIOS_MEMBER_TIMESTAMPS 0x16
+#define GRUB_LINUXBIOS_MEMBER_CBMEMC 0x17
grub_uint32_t tag;
grub_uint32_t size;
};
@@ -46,4 +71,9 @@ struct grub_linuxbios_mem_region
};
typedef struct grub_linuxbios_mem_region *mem_region_t;
+grub_err_t
+EXPORT_FUNC(grub_linuxbios_table_iterate) (int (*hook) (grub_linuxbios_table_item_t,
+ void *),
+ void *hook_data);
+
#endif
diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h
index 2f69e3f..3f58317 100644
--- a/include/grub/ieee1275/ofdisk.h
+++ b/include/grub/ieee1275/ofdisk.h
@@ -22,4 +22,7 @@
extern void grub_ofdisk_init (void);
extern void grub_ofdisk_fini (void);
+extern grub_err_t grub_ofdisk_get_block_size (const char *device,
+ grub_uint32_t *block_size);
+
#endif /* ! GRUB_INIT_HEADER */
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index 23e4f02..5b7ddda 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -64,6 +64,29 @@ struct grub_module_info64
grub_uint64_t size;
};
+#ifndef GRUB_UTIL
+/* Space isn't reusable on some platforms. */
+/* On Qemu the preload space is readonly. */
+/* On emu there is no preload space. */
+/* On ieee1275 our code assumes that heap is p=v which isn't guaranteed for module space. */
+#if defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_EMU) \
+ || defined (GRUB_MACHINE_EFI) \
+ || (defined (GRUB_MACHINE_IEEE1275) && !defined (__sparc__))
+#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 0
+#endif
+
+#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \
+ || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \
+ || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \
+ || defined (__sparc__) || defined (GRUB_MACHINE_ARM)
+/* FIXME: stack is between 2 heap regions. Move it. */
+#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1
+#endif
+
+#ifndef GRUB_KERNEL_PRELOAD_SPACE_REUSABLE
+#error "Please check if preload space is reusable on this platform!"
+#endif
+
#if GRUB_TARGET_SIZEOF_VOID_P == 8
#define grub_module_info grub_module_info64
#else
@@ -82,6 +105,8 @@ extern grub_addr_t EXPORT_VAR (grub_modbase);
grub_addr_t grub_modules_get_end (void);
+#endif
+
/* The start point of the C code. */
void grub_main (void) __attribute__ ((noreturn));
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 33e6b73..82276ad 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -462,4 +462,24 @@ grub_error_load (const struct grub_error_saved *save)
grub_errno = save->grub_errno;
}
+#if BOOT_TIME_STATS
+struct grub_boot_time
+{
+ struct grub_boot_time *next;
+ grub_uint64_t tp;
+ const char *file;
+ int line;
+ char *msg;
+};
+
+extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head);
+
+void EXPORT_FUNC(grub_real_boot_time) (const char *file,
+ const int line,
+ const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
+#define grub_boot_time(fmt, args...) grub_real_boot_time(GRUB_FILE, __LINE__, fmt, ## args)
+#else
+#define grub_boot_time(fmt, args...)
+#endif
+
#endif /* ! GRUB_MISC_HEADER */
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 416faa4..4fcc3da 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -141,6 +141,9 @@ void grub_normal_free_menu (grub_menu_t menu);
void grub_normal_auth_init (void);
void grub_normal_auth_fini (void);
+void
+grub_xnputs (const char *str, grub_size_t msg_len);
+
grub_command_t
grub_dyncmd_get_cmd (grub_command_t cmd);
diff --git a/include/grub/term.h b/include/grub/term.h
index 84f5766..655a5e3 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -467,7 +467,7 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces)
grub_putcode (' ', term);
}
-extern void (*EXPORT_VAR (grub_term_poll_usb)) (void);
+extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion);
#define GRUB_TERM_REPEAT_PRE_INTERVAL 400
#define GRUB_TERM_REPEAT_INTERVAL 50
diff --git a/include/grub/usb.h b/include/grub/usb.h
index cefa8b6..718ed33 100644
--- a/include/grub/usb.h
+++ b/include/grub/usb.h
@@ -63,9 +63,6 @@ grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
grub_uint8_t type, grub_uint8_t index,
grub_size_t size, char *data);
-struct grub_usb_desc_endp *
-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr);
-
grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint);
@@ -87,10 +84,12 @@ grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype
grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
- int endpoint, grub_size_t size, char *data);
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data);
grub_usb_err_t
grub_usb_bulk_write (grub_usb_device_t dev,
- int endpoint, grub_size_t size, char *data);
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data);
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller);
@@ -164,6 +163,18 @@ struct grub_usb_configuration
struct grub_usb_interface interf[32];
};
+struct grub_usb_hub_port
+{
+ grub_uint64_t soft_limit_time;
+ grub_uint64_t hard_limit_time;
+ enum {
+ PORT_STATE_NORMAL = 0,
+ PORT_STATE_WAITING_FOR_STABLE_POWER = 1,
+ PORT_STATE_FAILED_DEVICE = 2,
+ PORT_STATE_STABLE_POWER = 3,
+ } state;
+};
+
struct grub_usb_device
{
/* The device descriptor of this device. */
@@ -198,6 +209,8 @@ struct grub_usb_device
/* Number of hub ports. */
unsigned nports;
+ struct grub_usb_hub_port *ports;
+
grub_usb_transfer_t hub_transfer;
grub_uint32_t statuschange;
@@ -285,16 +298,18 @@ struct grub_usb_attach_desc
void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc);
void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc);
-void grub_usb_poll_devices (void);
+void grub_usb_poll_devices (int wait_for_completion);
void grub_usb_device_attach (grub_usb_device_t dev);
grub_usb_err_t
grub_usb_bulk_read_extended (grub_usb_device_t dev,
- int endpoint, grub_size_t size, char *data,
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, char *data,
int timeout, grub_size_t *actual);
grub_usb_transfer_t
grub_usb_bulk_read_background (grub_usb_device_t dev,
- int endpoint, grub_size_t size, void *data);
+ struct grub_usb_desc_endp *endpoint,
+ grub_size_t size, void *data);
grub_usb_err_t
grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual);
void
diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
index 84b723a..7d14152 100644
--- a/include/grub/usbdesc.h
+++ b/include/grub/usbdesc.h
@@ -28,6 +28,7 @@ typedef enum {
GRUB_USB_DESCRIPTOR_STRING,
GRUB_USB_DESCRIPTOR_INTERFACE,
GRUB_USB_DESCRIPTOR_ENDPOINT,
+ GRUB_USB_DESCRIPTOR_DEBUG = 10,
GRUB_USB_DESCRIPTOR_HUB = 0x29
} grub_usb_descriptor_t;
@@ -111,6 +112,14 @@ struct grub_usb_desc_str
grub_uint16_t str[0];
} __attribute__ ((packed));
+struct grub_usb_desc_debug
+{
+ grub_uint8_t length;
+ grub_uint8_t type;
+ grub_uint8_t in_endp;
+ grub_uint8_t out_endp;
+} __attribute__ ((packed));
+
struct grub_usb_usb_hubdesc
{
grub_uint8_t length;
diff --git a/include/grub/usbserial.h b/include/grub/usbserial.h
index 7420125..f81f97a 100644
--- a/include/grub/usbserial.h
+++ b/include/grub/usbserial.h
@@ -27,7 +27,12 @@ void grub_usbserial_detach (grub_usb_device_t usbdev, int configno,
int
grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
- struct grub_serial_driver *driver);
+ struct grub_serial_driver *driver, int in_endp,
+ int out_endp);
+enum
+ {
+ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING = -1
+ };
int
grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 01cc53c..f2368fd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -327,7 +327,6 @@
./grub-core/kern/i386/multiboot_mmap.c
./grub-core/kern/i386/pc/init.c
./grub-core/kern/i386/pc/mmap.c
-./grub-core/kern/i386/pit.c
./grub-core/kern/i386/qemu/mmap.c
./grub-core/kern/i386/tsc.c
./grub-core/kern/ia64/dl.c