merge with mainline

This commit is contained in:
BVK Chaitanya 2010-07-18 21:23:58 +05:30
commit f745095a37
351 changed files with 46449 additions and 19735 deletions

View file

@ -2,7 +2,10 @@
10_*
30_os-prober
40_custom
41_custom
aclocal.m4
ascii.bitmaps
ascii.h
autom4te.cache
build_env.mk
.bzrignore
@ -48,6 +51,8 @@ grub_script_check_init.c
grub_script_check_init.h
grub_script.tab.c
grub_script.tab.h
grub_script.yy.c
grub_script.yy.h
grub-set-default
grub-setup
grub_setup_init.c
@ -71,3 +76,4 @@ stamp-h.in
symlist.c
trigtables.c
update-grub_lib
unidata.c

2495
ChangeLog

File diff suppressed because it is too large Load diff

16
INSTALL
View file

@ -16,8 +16,24 @@ configuring the GRUB.
* GNU Bison 2.3 or later
* GNU gettext 0.17 or later
* GNU binutils 2.9.1.0.23 or later
* Flex 2.5.35 or later
* Other standard GNU/Unix tools
On GNU/Linux, you also need:
* libdevmapper (recommended)
To build grub-emu, you need:
* ncurses
* libusb (recommended)
* SDL (recommended)
To build GRUB's graphical terminal (gfxterm), you need:
* FreeType 2 or later
* GNU Unifont
If you use a development snapshot or want to hack on GRUB you may
need the following.

View file

@ -53,9 +53,13 @@ XGETTEXT = @XGETTEXT@
MSGMERGE = @MSGMERGE@
MSGFMT = @MSGFMT@
ifeq (@USE_NLS@,yes)
LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \
if test -e $$i ; then echo $$i ; fi ; \
done | sed -e "s,.*/po/\(.*\)\.po$$,\1,")
else
LINGUAS =
endif
PACKAGE = @PACKAGE@
PACKAGE_NAME = @PACKAGE_NAME@
@ -90,7 +94,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS)
ASFLAGS = @ASFLAGS@
LDFLAGS = @LDFLAGS@ $(LIBS)
CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \
-DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\"
-DGRUB_PKGLIBROOTDIR=\"$(libdir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`\" -DLOCALEDIR=\"$(localedir)\"
TARGET_CC = @TARGET_CC@
TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@
TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@
@ -99,12 +103,12 @@ TARGET_APPLE_CC = @TARGET_APPLE_CC@
OBJCONV = @OBJCONV@
TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \
-Wall -W
TARGET_LDFLAGS = -nostdlib @TARGET_LDFLAGS@
TARGET_LDFLAGS = -nostdlib -static-libgcc @TARGET_LDFLAGS@
TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@
TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@
TARGET_OBJ2ELF = @TARGET_OBJ2ELF@
kernel_img_LDFLAGS = -static-libgcc -lgcc
kernel_img_LDFLAGS = -lgcc
EXEEXT = @EXEEXT@
OBJCOPY = @OBJCOPY@
STRIP = @STRIP@
@ -164,7 +168,9 @@ DISTCLEANFILES = config.status config.cache config.log config.h \
MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \
$(MKFILES) $(srcdir)/config.guess \
$(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \
$(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS)
$(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in \
$(srcdir)/unidata.c \
$(INFOS)
# The default target.
all: all-local
@ -247,10 +253,9 @@ docs/stamp-vti: docs/grub.texi configure.ac
-@rm -f vti.tmp
@cp $(builddir)/docs/version.texi $@
# Use --force until such time as the documentation is cleaned up.
docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi
$(MKDIR_P) docs
-$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@
$(MAKEINFO) -P $(builddir)/docs --no-split $< -o $@
ifeq (, $(FONT_SOURCE))
else
@ -276,7 +281,13 @@ ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
ascii.h: ascii.bitmaps grub-bin2h
$(builddir)/grub-bin2h ascii_bitmaps < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1
widthspec.bin: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont --width-spec -o $@ $(FONT_SOURCE)
widthspec.h: widthspec.bin grub-bin2h
$(builddir)/grub-bin2h widthspec < $< > $@
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1
endif
endif
@ -323,26 +334,26 @@ install-local: all
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
$(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \
done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
@list='$(sbin_UTILITIES)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
$(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \
done
@list='$(bin_SCRIPTS)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
$(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
PATH="$(builddir):$$PATH" $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $$file; \
done
@list='$(sbin_SCRIPTS)'; for file in $$list; do \
if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
$(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
$(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
PATH="$(builddir):$$PATH" $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$file.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $$file; \
done
$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d
@list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \
@ -513,8 +524,8 @@ check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS)
$(builddir)/$$file; \
done
.SUFFIX:
.SUFFIX: .c .o .S .d
.SUFFIXES:
.SUFFIXES: .c .o .S .d
# Regenerate configure and Makefile automatically.
$(srcdir)/aclocal.m4: configure.ac acinclude.m4

12
README
View file

@ -10,5 +10,13 @@ GRUB 2 data and program files.
Please visit the official web page of GRUB 2, for more information.
The URL is <http://www.gnu.org/software/grub/grub.html>.
For now, there is not much documentation yet. Please look at the GRUB
Wiki <http://grub.enbug.org> for testing procedures.
More extensive documentation is available in the Info manual,
accessible using 'info grub' after building and installing GRUB 2.
Please look at the GRUB Wiki <http://grub.enbug.org> for testing
procedures.
There are a number of important user-visible differences from the
first version of GRUB, now known as GRUB Legacy. For a summary, please
see:
info grub Introduction 'Changes from GRUB Legacy'

View file

@ -13,6 +13,8 @@ echo timestamp > stamp-h.in
python util/import_gcry.py lib/libgcrypt/ .
python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt unidata.c
for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
if test -e $rmk ; then
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`

View file

@ -31,14 +31,11 @@ _start:
jmp 1f
. = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR
. = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
VARIABLE(grub_core_entry_addr)
.long 0
1:
/* Process VGA rom. */
call $0xc000, $0x3
/* Set up %ds, %ss, and %es. */
xorw %ax, %ax
movw %ax, %ds
@ -63,5 +60,8 @@ VARIABLE(grub_core_entry_addr)
*right here* and this is why we need this kludge. */
. = GRUB_BOOT_MACHINE_SIZE - 16
.code16
jmp _start
. = GRUB_BOOT_MACHINE_SIZE

View file

@ -0,0 +1,630 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/mips/yeeloong/serial.h>
#include <grub/mips/yeeloong/pci.h>
#include <grub/mips/loongson.h>
#include <grub/pci.h>
#include <grub/serial.h>
#include <grub/cs5536.h>
#include <grub/smbus.h>
.set noreorder
.set noat
.set nomacro
.global start,_start,__start
start:
_start:
__start:
bal serial_hw_init
nop
/* Find CS5536 controller. */
/* $t4 chooses device in priority encoding. */
/* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG.
This way we don't need to sacrifice a register for it. */
/* We have only one bus (0). Function is 0. */
lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE)
lui $t3, %hi(GRUB_CS5536_PCIID)
addiu $t3, $t3, %lo(GRUB_CS5536_PCIID)
ori $t4, $zero, 1
lui $a0, %hi(no_cs5536)
1:
andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES) - 1)
beql $t4, $zero, fatal
addiu $a0, $a0, %lo(no_cs5536)
sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) ($t0)
lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_PCI_REG_PCI_ID) ($t1)
bnel $t2, $t3, 1b
sll $t4, $t4, 1
bal message
addiu $a0, $a0, %lo(cs5536_found)
bal printhex
move $a0, $t4
/* Initialise SMBus controller. */
/* Set GPIO LBAR. */
lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR)
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR)
ori $a1, $zero, GRUB_CS5536_LBAR_GPIO
/* Set mask to 0xf and enabled bit to 1. */
bal wrmsr
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
| GRUB_CS5536_LBAR_ENABLE) >> 32)
/* Set SMBUS LBAR. */
lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR)
addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR)
ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS
/* Set mask to 0xf and enabled bit to 1. */
bal wrmsr
ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \
| GRUB_CS5536_LBAR_ENABLE) >> 32)
lui $a0, %hi(smbus_enabled)
bal message
addiu $a0, $a0, %lo(smbus_enabled)
/* Enable SMBus controller pins. */
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO)
ori $t1, $zero, GRUB_GPIO_SMBUS_PINS
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_EN) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_OUT_AUX1) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_EN) ($t0)
sw $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_GPIO + GRUB_GPIO_REG_IN_AUX1) ($t0)
lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS)
/* Disable SMB. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
/* Disable interrupts. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0)
/* Set as master. */
sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0)
/* Launch SMBus controller at slowest speed possible. */
ori $t1, $zero, 0xff
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0)
sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0)
/* Yeeloong has only one memory slot. */
/* Output first byte on serial for debugging. */
ori $a1, $zero, GRUB_SMB_RAM_START_ADDR
bal read_spd
move $a0, $zero
bal printhex
move $a0, $v0
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR
ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2
lui $a0, %hi(unimplemented_memory_type)
bne $t0, $v0, fatal
addiu $a0, $a0, %hi(unimplemented_memory_type)
/* And here is our goal: DDR2 controller initialisation. */
lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG)
ld $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0)
/* Use addiu for sign-extension. */
addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU)
and $t1, $t1, $t2
sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
b continue
. = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
tlb_refill:
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
move $s3, $ra
lui $a0, %hi(epc)
bal message
addiu $a0, $a0, %lo(epc)
bal printhex
move $a0, $s1
lui $a0, %hi(badvaddr)
bal message
addiu $a0, $a0, %lo(badvaddr)
bal printhex
move $a0, $s2
lui $a0, %hi(return_msg)
bal message
addiu $a0, $a0, %lo(return_msg)
bal printhex
move $a0, $s3
lui $a0, %hi(newline)
bal message
addiu $a0, $a0, %lo(newline)
lui $a0, %hi(unhandled_tlb_refill)
b fatal
addiu $a0, $a0, %lo(unhandled_tlb_refill)
. = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
cache_error:
lui $a0, %hi(unhandled_cache_error)
b fatal
addiu $a0, $a0, %lo(unhandled_cache_error)
. = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
other_exception:
mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
lui $a0, %hi(cause)
bal message
addiu $a0, $a0, %lo(cause)
bal printhex
move $a0, $s0
lui $a0, %hi(epc)
bal message
addiu $a0, $a0, %lo(epc)
bal printhex
move $a0, $s1
lui $a0, %hi(badvaddr)
bal message
addiu $a0, $a0, %lo(badvaddr)
bal printhex
move $a0, $s2
lui $a0, %hi(newline)
bal message
addiu $a0, $a0, %lo(newline)
lui $a0, %hi(unhandled_exception)
b fatal
addiu $a0, $a0, %lo(unhandled_exception)
/* Same as similarly named C function but in asm since
we need it early. */
/* In: none. Out: none. Clobbered: $t0, $t1, $a0. */
serial_hw_init:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
/* Turn off the interrupt. */
sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0)
/* Set DLAB. */
ori $t1, $zero, UART_DLAB
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
/* Set the baud rate 115200. */
ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0)
sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0)
/* Set the line status. */
ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT)
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
/* Enable the FIFO. */
ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0)
/* Turn on DTR and RTS. */
ori $t1, $zero, UART_ENABLE_DTRRTS
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0)
/* Let message return to original caller. */
lui $a0, %hi(notification_string)
addiu $a0, $a0, %lo(notification_string)
/* Print message on serial console. */
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
message:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
1:
lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
andi $t1, $t1, UART_EMPTY_TRANSMITTER
beq $t1, $zero, 1b
nop
lb $t1, 0($a0)
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
bne $t1, $zero, 1b
addiu $a0, $a0, 1
jr $ra
nop
/* Print 32-bit hexadecimal on serial.
In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2
*/
printhex:
lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT)
ori $t2, $zero, 8
1:
lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
andi $t1, $t1, UART_EMPTY_TRANSMITTER
beq $t1, $zero, 1b
nop
srl $t1, $a0, 28
addiu $t1, $t1, -10
blt $t1, $zero, 2f
sll $a0, $a0, 4
addiu $t1, $t1, 'A'-10-'0'
2: addiu $t1, $t1, '0'+10
sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0)
addiu $t2, $t2, -1
bne $t2, $zero, 1b
nop
jr $ra
nop
fatal:
bal message
nop
self:
b self
nop
/* Write CS5536 MSR.
In: $a0 address, $a1 lower word, $a2 upper word.
Out: None
Clobbered: $t0
*/
wrmsr:
lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE)
sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0)
sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0)
jr $ra
sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0)
/* Wait for SMBus data or empty transmitter. */
/* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1 */
smbus_wait:
1:
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE)
lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE) ($t0)
andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST
bne $t1, $zero, return
nop
andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK)
beq $t1, $zero, 1b
nop
jr $a0
nop
return:
jr $ra
nop
/* Read SPD byte. In: $a0 byte, $a1 device. Out: $v0 read byte (0x100 on failure).
Clobbered: $t0, $t1, $t2, $t3, $a0. */
read_spd:
move $t2, $a0
move $t3, $ra
lui $a0, %hi(read_spd_fail)
addiu $a0, $a0, %hi(read_spd_fail)
/* Send START. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send device address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
sll $t1, $a1, 1
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send ACK. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send byte address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
bal smbus_wait
sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send START. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send device address. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
sll $t1, $a1, 1
ori $t1, $t1, 1
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
/* Send STOP. */
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE)
lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP
bal smbus_wait
sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE) ($t0)
lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE)
lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE) ($t0)
jr $t3
andi $v0, $v0, 0xff
read_spd_fail:
jr $t3
ori $v0, $v0, 0x100
notification_string: .asciz "GRUB "
no_cs5536: .asciz "No CS5536 found.\n\r"
cs5536_found: .asciz "CS5536 at "
sm_failed: .asciz "SM transaction failed.\n\r"
unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r"
unhandled_cache_error: .asciz "Unhandled cache error.\n\r"
unhandled_exception: .asciz "Unhandled exception.\n\r"
smbus_enabled: .asciz "SMBus controller enabled.\n\r"
unimplemented_memory_type: .asciz "non-DDR2 memory isn't supported.\n\r"
no_cas_latency: .asciz "Couldn't determine CAS latency.\n\r"
cause: .asciz "Cause: "
epc: .asciz "\n\rEPC: "
badvaddr: .asciz "\n\rBadVaddr: "
newline: .asciz "\n\r"
return_msg: .asciz "\n\rReturn address: "
caches_enabled: .asciz "Caches enabled\n\r"
.p2align 3
regdump:
.quad 0x0100010000000101 /* 0 */
.quad 0x0100010100000000 /* 2 */
.quad 0x0101000001000000 /* 3 */
.quad 0x0100020200010101 /* 4 */
.quad 0x0a04030603050203 /* 6 */
.quad 0x0f0e040000010a0b /* 7 */
.quad 0x0000010200000102 /* 8 */
.quad 0x0000060c00000000 /* 9 */
.quad 0x2323233f3f1f0200 /* a */
.quad 0x5f7f232323232323 /* b */
.quad 0x002a3c0615000000 /* c */
.quad 0x002a002a002a002a /* d */
.quad 0x002a002a002a002a /* e */
.quad 0x00b40020006d0004 /* f */
.quad 0x070007ff00000087 /* 10 */
.quad 0x000000000016101f /* 11 */
.quad 0x001c000000000000 /* 12 */
.quad 0x28e1000200c8006b /* 13 */
.quad 0x0000204200c8002f /* 14 */
.quad 0x0000000000030d40 /* 15 */
.quad 0 /* 16 */
.quad 0 /* 17 */
.quad 0 /* 18 */
.quad 0 /* 19 */
.quad 0 /* 1a */
.quad 0 /* 1b */
.quad 0 /* 1c */
.p2align
write_dumpreg:
ld $t2, 0($t6)
sd $t2, 0($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
jr $ra
addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
continue:
lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
addiu $t4, $t4, %lo(GRUB_CPU_LOONGSON_DDR2_BASE)
lui $t6, %hi(regdump)
/* 0 */
bal write_dumpreg
addiu $t6, $t6, %lo(regdump)
/* 1 */
ori $a1, $a1, GRUB_SMB_RAM_START_ADDR
move $t8, $zero
lui $t5, 0x0001
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR
ori $t7, $zero, 8
bne $v0, $t7, 1f
ori $t5, $t5, 0x0001
ori $t8, $t8, GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS
1:
dsll $t8, $t8, 32
or $t5, $t5, $t8
sd $t5, 0 ($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
/* 2 */
bal write_dumpreg
nop
/* 3 */
bal write_dumpreg
nop
/* 4 */
bal write_dumpreg
nop
/* 5 */
/* FIXME: figure termination resistance. */
ori $t5, $zero, 0x2
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR
/* $v0 = 15 - $v0. */
xori $v0, $v0, 0xf
andi $v0, $v0, 0x7
sll $v0, $v0, 8
or $t5, $t5, $v0
/* Find the fastest supported CAS latency. */
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR
ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE
ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE)
2:
and $t2, $t1, $v0
bne $t2, $zero, 1f
ori $t3, $zero, 8
lui $a0, %hi(no_cas_latency)
beq $t0, $t3, fatal
addiu $a0, $a0, %lo(no_cas_latency)
addiu $t0, $t0, 1
b 2b
sll $t1, $t1, 1
1:
sll $t0, $t0, 16
or $t5, $t5, $t0
bal read_spd
ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR
/* $v0 = 15 - ($v0 + 1) = 14 - $v0. */
addiu $v0, $v0, 1
xori $v0, $v0, 0xf
andi $v0, $v0, 0x7
sll $v0, 24
or $t5, $t5, $v0
sd $t5, 0 ($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
ori $t7, $zero, 0x16
1:
ld $t2, 0($t6)
sd $t2, 0($t4)
addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP
addiu $t7, $t7, -1
bne $t7, $zero, 1b
addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE
lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE)
ld $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
ori $t0, $zero, 1
dsll $t0, $t0, 40
or $t5, $t5, $t0
sd $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
/* Desactivate DDR2 registers. */
lui $t0, %hi (GRUB_CPU_LOONGSON_CORECFG)
ld $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
ori $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE
sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0)
/* Enable cache. */
mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
and $t0, $t1, $t1
/* Set line size to 32 bytes and disabled cache. */
ori $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \
| GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \
| GRUB_CPU_LOONGSON_CACHE_ACCELERATED)
mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
/* Invalidate all I-cache entries. */
srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT
andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS))
sll $t1, $t2, $t1
lui $t2, 0x8000
1:
cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET)
/* Invalidate all D-cache entries. */
srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT
andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS))
sll $t1, $t2, $t1
lui $t2, 0x8000
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
1:
/* All four ways. */
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2)
cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
/* Invalidate all S-cache entries. */
ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \
- GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
- GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS))
lui $t2, 0x8000
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
1:
/* All four ways. */
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2)
cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2)
addiu $t1, $t1, -1
bne $t1, $zero, 1b
addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
/* Finally enable cache. */
mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
and $t0, $t1, $t1
ori $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED
mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
lui $a0, %hi(caches_enabled)
bal message
addiu $a0, $a0, %lo(caches_enabled)
/* Set ROM delay cycles to 1. */
lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG)
lw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \
<< GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
and $t1, $t1, $t2
ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET)
sw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0)
addiu $a0, $zero, -1
addiu $a1, $zero, -1
/* Take advantage of cache. */
lui $t0, %hi(cached_continue - 0x20000000)
addiu $t0, $t0, %lo(cached_continue - 0x20000000)
jr $t0
addiu $a2, $zero, -1
cached_continue:

View file

@ -19,6 +19,7 @@
#include <grub/boot.h>
#include <grub/machine/boot.h>
#include <grub/offsets.h>
.text
.align 4
@ -87,8 +88,8 @@ after_info_block:
call console_write
mov NOTIFICATION_STRING_LEN, %o3
GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2)
set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3
bootloop:
lduw [%l2 + 0x08], %o0
brz %o0, bootit
@ -115,7 +116,7 @@ bootloop:
mov NOTIFICATION_STEP_LEN, %o3
ba bootloop
sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2
bootit:
GET_ABS(prom_close_name, %o0)
@ -127,8 +128,8 @@ bootit:
GET_ABS(notification_done, %o2)
call console_write
mov NOTIFICATION_DONE_LEN, %o3
sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2
jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7
mov CIF_REG, %o4
1: ba,a 1b
@ -136,7 +137,7 @@ lastlist:
.word 0
.word 0
. = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
. = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE)
blocklist_default_start:
.word 0
.word 2

380
bus/cs5536.c Normal file
View file

@ -0,0 +1,380 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/cs5536.h>
#include <grub/pci.h>
#include <grub/time.h>
#include <grub/ata.h>
int
grub_cs5536_find (grub_pci_device_t *devp)
{
int found = 0;
auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
grub_pci_id_t pciid);
int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
grub_pci_id_t pciid)
{
if (pciid == GRUB_CS5536_PCIID)
{
*devp = dev;
found = 1;
return 1;
}
return 0;
}
grub_pci_iterate (hook);
return found;
}
grub_uint64_t
grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr)
{
grub_uint64_t ret = 0;
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR),
addr);
ret = (grub_uint64_t)
grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0));
ret |= (((grub_uint64_t)
grub_pci_read (grub_pci_make_address (dev,
GRUB_CS5536_MSR_MAILBOX_DATA1)))
<< 32);
return ret;
}
void
grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr,
grub_uint64_t val)
{
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR),
addr);
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0),
val & 0xffffffff);
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1),
val >> 32);
}
grub_err_t
grub_cs5536_smbus_wait (grub_port_t smbbase)
{
grub_uint64_t start = grub_get_time_ms ();
while (1)
{
grub_uint8_t status;
status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS);
if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST)
return GRUB_ERR_NONE;
if (status & GRUB_CS5536_SMB_REG_STATUS_BER)
return grub_error (GRUB_ERR_IO, "SM bus error");
if (status & GRUB_CS5536_SMB_REG_STATUS_NACK)
return grub_error (GRUB_ERR_IO, "NACK received");
if (grub_get_time_ms () > start + 40)
return grub_error (GRUB_ERR_IO, "SM stalled");
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev,
grub_uint8_t addr, grub_uint8_t *res)
{
grub_err_t err;
/* Send START. */
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_START,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send device address. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send ACK. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_ACK,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send byte address. */
grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send START. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_START,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send device address. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send STOP. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_STOP,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
*res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA);
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor,
grub_port_t *smbbase)
{
grub_uint64_t smbbar;
smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR);
/* FIXME */
if (!(smbbar & GRUB_CS5536_LBAR_ENABLE))
return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n");
*smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE;
if (divisor < 8)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor");
/* Disable SMB. */
grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2);
/* Disable interrupts. */
grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Set as master. */
grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER,
*smbbase + GRUB_CS5536_SMB_REG_ADDR);
/* Launch. */
grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3);
grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE,
*smbbase + GRUB_CS5536_SMB_REG_CTRL2);
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev,
struct grub_smbus_spd *res)
{
grub_err_t err;
grub_size_t size;
grub_uint8_t b;
grub_size_t ptr;
err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b);
if (err)
return err;
if (b == 0)
return grub_error (GRUB_ERR_IO, "no SPD found");
size = b;
((grub_uint8_t *) res)[0] = b;
for (ptr = 1; ptr < size; ptr++)
{
err = grub_cs5536_read_spd_byte (smbbase, dev, ptr,
&((grub_uint8_t *) res)[ptr]);
if (err)
return err;
}
return GRUB_ERR_NONE;
}
/* Dump of GPIO connections. FIXME: Remove useless and macroify. */
static grub_uint32_t gpiodump[] = {
0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000,
0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000,
0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000,
0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000,
0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000,
0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000,
0xefff1000, 0xefff1000, 0xffff0000, 0x00000000,
0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x50000000, 0x00000000, 0x00000000,
};
static inline void
set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start,
grub_uint16_t len)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num,
((((grub_uint64_t) start + len - 4)
<< GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT)
& GRUB_CS5536_MSR_GL_REGION_TOP_MASK)
| (((grub_uint64_t) start
<< GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT)
& GRUB_CS5536_MSR_GL_REGION_BASE_MASK)
| GRUB_CS5536_MSR_GL_REGION_IO
| GRUB_CS5536_MSR_GL_REGION_ENABLE);
}
static inline void
set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num,
((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT)
| (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK)
<< GRUB_CS5536_IOD_BASE_SHIFT)
| ((mask & GRUB_CS5536_IOD_ADDR_MASK)
<< GRUB_CS5536_IOD_MASK_SHIFT));
}
static inline void
set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start)
{
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num,
(((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT)
| ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN)
<< GRUB_CS5536_P2D_BASE_SHIFT)
| (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1)
<< GRUB_CS5536_P2D_MASK_SHIFT));
}
void
grub_cs5536_init_geode (grub_pci_device_t dev)
{
int i;
/* Make sure GPIO is where we expect it to be. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GPIO_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_GPIO);
/* Setup GPIO. */
for (i = 0; i < (int) ARRAY_SIZE (gpiodump); i++)
((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_IO_BASE
+ GRUB_CS5536_LBAR_GPIO)) [i] = gpiodump[i];
/* Enable more BARs. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR,
GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM);
/* Setup DIVIL. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO,
GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
| GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
| GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK,
(~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK,
GRUB_CS5536_DIVIL_LPC_INTERRUPTS);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL,
GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE);
/* Initialise USB controller. */
/* FIXME: assign adresses dynamically. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE
| 0x05024000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE
| (0x20ULL << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT)
| 0x05023000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE,
GRUB_CS5536_MSR_USB_BASE_BUS_MASTER
| GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE,
GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000);
set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000);
set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000);
set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000);
set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000);
{
volatile grub_uint32_t *oc;
oc = grub_pci_device_map_range (dev, 0x05022000,
GRUB_CS5536_USB_OPTION_REGS_SIZE);
oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] =
(oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX]
& ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK)
| GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC;
grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE);
}
/* Setup IDE controller. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR,
GRUB_CS5536_LBAR_IDE
| GRUB_CS5536_MSR_IDE_IO_BAR_UNITS);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG,
GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE);
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING,
(GRUB_CS5536_MSR_IDE_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT)
| (GRUB_CS5536_MSR_IDE_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT));
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING,
(GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT)
| (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT)
| (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0
<< GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT));
/* Setup Geodelink PCI. */
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL,
(4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT)
| (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT)
| (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT)
| GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE
| GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE);
/* Setup windows. */
set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, GRUB_CS5536_SMBUS_REGS_SIZE);
set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE);
set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, GRUB_CS5536_MFGPT_REGS_SIZE);
set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, GRUB_CS5536_IRQ_MAP_REGS_SIZE);
set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE);
set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE);
set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, 0xffff8);
set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, 0xfff80);
set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, 0xffff0);
}

View file

@ -19,6 +19,50 @@
#include <grub/dl.h>
#include <grub/pci.h>
#include <grub/mm.h>
/* FIXME: correctly support 64-bit architectures. */
/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */
struct grub_pci_dma_chunk *
grub_memalign_dma32 (grub_size_t align, grub_size_t size)
{
return grub_memalign (align, size);
}
void
grub_dma_free (struct grub_pci_dma_chunk *ch)
{
grub_free (ch);
}
/* #endif */
#ifdef GRUB_MACHINE_MIPS_YEELOONG
volatile void *
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
{
return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000);
}
grub_uint32_t
grub_dma_get_phys (struct grub_pci_dma_chunk *ch)
{
return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000;
}
#else
volatile void *
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
{
return (void *) ch;
}
grub_uint32_t
grub_dma_get_phys (struct grub_pci_dma_chunk *ch)
{
return (grub_uint32_t) (grub_addr_t) ch;
}
#endif
grub_pci_address_t
grub_pci_make_address (grub_pci_device_t dev, int reg)
@ -48,6 +92,16 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
if (id >> 16 == 0xFFFF)
continue;
#ifdef GRUB_MACHINE_MIPS_YEELOONG
/* Skip ghosts. */
if (id == GRUB_YEELOONG_OHCI_PCIID
&& dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION)
continue;
if (id == GRUB_YEELOONG_EHCI_PCIID
&& dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION)
continue;
#endif
if (hook (dev, id))
return;

View file

@ -105,14 +105,14 @@ grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
grub_usb_err_t
grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
grub_uint8_t request, grub_uint16_t value,
grub_uint16_t index, grub_size_t size, char *data)
grub_uint16_t idx, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_control_msg (devh, reqtype, request,
value, index, data, size, 20) < 0)
value, idx, data, size, 20) < 0)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;

File diff suppressed because it is too large Load diff

View file

@ -174,14 +174,15 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
return 1;
u->iobase = base & GRUB_UHCI_IOMASK;
grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
class, subclass, interf, u->iobase);
/* Reserve a page for the frame list. */
u->framelist = grub_memalign (4096, 4096);
if (! u->framelist)
goto fail;
grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n",
class, subclass, interf, u->iobase, u->framelist);
/* The framelist pointer of UHCI is only 32 bits, make sure this
code works on on 64 bits architectures. */
#if GRUB_CPU_SIZEOF_VOID_P == 8
@ -221,6 +222,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
}
#endif
grub_dprintf ("uhci", "QH=%p, TD=%p\n",
u->qh, u->td);
/* Link all Transfer Descriptors in a list of available Transfer
Descriptors. */
for (i = 0; i < 256; i++)
@ -328,13 +332,20 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
}
static void
grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td)
grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td,
grub_usb_transfer_t transfer)
{
/* Free the TDs in this queue. */
while (td)
int i; /* Index of TD in transfer */
/* Free the TDs in this queue and set last_trans. */
for (i=0; td; i++)
{
grub_uhci_td_t tdprev;
/* Check state of TD and possibly set last_trans */
if (transfer && (td->linkptr & 1))
transfer->last_trans = i;
/* Unlink the queue. */
tdprev = td;
td = (grub_uhci_td_t) td->linkptr2;
@ -380,7 +391,7 @@ static grub_uhci_td_t
grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
grub_transfer_type_t type, unsigned int addr,
unsigned int toggle, grub_size_t size,
char *data)
grub_uint32_t data)
{
grub_uhci_td_t td;
static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
@ -398,7 +409,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
}
grub_dprintf ("uhci",
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n",
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n",
endp, type, addr, toggle, size, data, td);
/* Don't point to any TD, just terminate. */
@ -418,7 +429,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
td->token = ((size << 21) | (toggle << 19) | (endp << 15)
| (addr << 8) | tf[type]);
td->buffer = (grub_uint32_t) data;
td->buffer = data;
return td;
}
@ -441,6 +452,8 @@ grub_uhci_transfer (grub_usb_controller_t dev,
if (! qh)
return grub_errno;
grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase);
for (i = 0; i < transfer->transcnt; i++)
{
grub_usb_transaction_t tr = &transfer->transactions[i];
@ -455,7 +468,7 @@ grub_uhci_transfer (grub_usb_controller_t dev,
td_prev->linkptr = 1;
if (td_first)
grub_free_queue (u, td_first);
grub_free_queue (u, td_first, NULL);
return GRUB_USB_ERR_INTERNAL;
}
@ -548,12 +561,13 @@ grub_uhci_transfer (grub_usb_controller_t dev,
fail:
grub_dprintf ("uhci", "transaction failed\n");
if (err != GRUB_USB_ERR_NONE)
grub_dprintf ("uhci", "transaction failed\n");
/* Place the QH back in the free list and deallocate the associated
TDs. */
qh->elinkptr = 1;
grub_free_queue (u, td_first);
grub_free_queue (u, td_first, transfer);
return err;
}
@ -583,6 +597,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
unsigned int status;
grub_uint64_t endtime;
grub_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase);
grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
if (port == 0)
@ -596,27 +612,46 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
status = grub_uhci_readreg16 (u, reg);
grub_dprintf ("uhci", "detect=0x%02x\n", status);
if (!enable) /* We don't need reset port */
{
/* Disable the port. */
grub_uhci_writereg16 (u, reg, 0 << 2);
grub_dprintf ("uhci", "waiting for the port to be disabled\n");
endtime = grub_get_time_ms () + 1000;
while ((grub_uhci_readreg16 (u, reg) & (1 << 2)))
if (grub_get_time_ms () > endtime)
return grub_error (GRUB_ERR_IO, "UHCI Timed out");
status = grub_uhci_readreg16 (u, reg);
grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
return GRUB_ERR_NONE;
}
/* Reset the port. */
grub_uhci_writereg16 (u, reg, enable << 9);
grub_uhci_writereg16 (u, reg, 1 << 9);
/* Wait for the reset to complete. XXX: How long exactly? */
grub_millisleep (10);
grub_millisleep (50); /* For root hub should be nominaly 50ms */
status = grub_uhci_readreg16 (u, reg);
grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
grub_dprintf ("uhci", "reset completed\n");
grub_millisleep (10);
/* Enable the port. */
grub_uhci_writereg16 (u, reg, enable << 2);
grub_uhci_writereg16 (u, reg, 1 << 2);
grub_millisleep (10);
grub_dprintf ("uhci", "waiting for the port to be enabled\n");
endtime = grub_get_time_ms () + 1000;
while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)))
while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2)))
if (grub_get_time_ms () > endtime)
return grub_error (GRUB_ERR_IO, "UHCI Timed out");
/* Reset bit Connect Status Change */
grub_uhci_writereg16 (u, reg, status | (1 << 1));
/* Read final port status */
status = grub_uhci_readreg16 (u, reg);
grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
@ -625,12 +660,14 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
}
static grub_usb_speed_t
grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
{
struct grub_uhci *u = (struct grub_uhci *) dev->data;
int reg;
unsigned int status;
grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase);
if (port == 0)
reg = GRUB_UHCI_REG_PORTSC1;
else if (port == 1)
@ -643,6 +680,9 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
/* Connect Status Change bit - it detects change of connection */
*changed = ((status & (1 << 1)) != 0);
if (! (status & 1))
return GRUB_USB_SPEED_NONE;
else if (status & (1 << 8))

View file

@ -21,8 +21,10 @@
#include <grub/mm.h>
#include <grub/usb.h>
#include <grub/misc.h>
#include <grub/list.h>
static grub_usb_controller_dev_t grub_usb_list;
struct grub_usb_attach_desc *attach_hooks;
void
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
@ -105,10 +107,7 @@ grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
grub_usb_err_t
grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
{
int i;
for (i = 0; i < 16; i++)
dev->toggle[i] = 0;
grub_memset (dev->toggle, 0, sizeof (dev->toggle));
return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_STANDARD
@ -163,6 +162,16 @@ grub_usb_device_initialize (grub_usb_device_t dev)
grub_usb_err_t err;
int i;
/* First we have to read first 8 bytes only and determine
* max. size of packet */
dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */
err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
0, 8, (char *) &dev->descdev);
if (err)
return err;
/* Now we have valid value in dev->descdev.maxsize0,
* so we can read whole device descriptor */
err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
0, sizeof (struct grub_usb_desc_device),
(char *) &dev->descdev);
@ -225,3 +234,75 @@ grub_usb_device_initialize (grub_usb_device_t dev)
return err;
}
void grub_usb_device_attach (grub_usb_device_t dev)
{
int i;
/* XXX: Just check configuration 0 for now. */
for (i = 0; i < dev->config[0].descconf->numif; i++)
{
struct grub_usb_desc_if *interf;
struct grub_usb_attach_desc *desc;
interf = dev->config[0].interf[i].descif;
grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
i, interf->class, interf->subclass, interf->protocol);
if (dev->config[0].interf[i].attached)
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;
}
}
void
grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
{
auto int usb_iterate (grub_usb_device_t dev);
int usb_iterate (grub_usb_device_t usbdev)
{
struct grub_usb_desc_device *descdev = &usbdev->descdev;
int i;
if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0
|| descdev->configcnt == 0)
return 0;
/* XXX: Just check configuration 0 for now. */
for (i = 0; i < usbdev->config[0].descconf->numif; i++)
{
struct grub_usb_desc_if *interf;
interf = usbdev->config[0].interf[i].descif;
grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
i, interf->class, interf->subclass, interf->protocol);
if (usbdev->config[0].interf[i].attached)
continue;
if (interf->class != desc->class)
continue;
if (desc->hook (usbdev, 0, i))
usbdev->config[0].interf[i].attached = 1;
}
return 0;
}
desc->next = attach_hooks;
attach_hooks = desc;
grub_usb_iterate (usb_iterate);
}
void
grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc)
{
grub_list_remove (GRUB_AS_LIST_P (&attach_hooks), GRUB_AS_LIST (desc));
}

View file

@ -21,9 +21,23 @@
#include <grub/mm.h>
#include <grub/usb.h>
#include <grub/misc.h>
#include <grub/time.h>
#define GRUB_USBHUB_MAX_DEVICES 128
/* USB Supports 127 devices, with device 0 as special case. */
static struct grub_usb_device *grub_usb_devs[128];
static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
struct grub_usb_hub
{
struct grub_usb_hub *next;
grub_usb_controller_t controller;
int nports;
grub_usb_speed_t *speed;
grub_usb_device_t dev;
};
struct grub_usb_hub *hubs;
/* Add a device that currently has device number 0 and resides on
CONTROLLER, the Hub reported that the device speed is SPEED. */
@ -32,6 +46,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
{
grub_usb_device_t dev;
int i;
grub_usb_err_t err;
dev = grub_zalloc (sizeof (struct grub_usb_device));
if (! dev)
@ -40,31 +55,51 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
dev->controller = *controller;
dev->speed = speed;
grub_usb_device_initialize (dev);
err = grub_usb_device_initialize (dev);
if (err)
{
grub_free (dev);
return NULL;
}
/* Assign a new address to the device. */
for (i = 1; i < 128; i++)
for (i = 1; i < GRUB_USBHUB_MAX_DEVICES; i++)
{
if (! grub_usb_devs[i])
break;
}
if (i == 128)
if (i == GRUB_USBHUB_MAX_DEVICES)
{
grub_error (GRUB_ERR_IO, "can't assign address to USB device");
for (i = 0; i < 8; i++)
grub_free (dev->config[i].descconf);
grub_free (dev);
return NULL;
}
grub_usb_control_msg (dev,
(GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_STANDARD
| GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_SET_ADDRESS,
i, 0, 0, NULL);
err = grub_usb_control_msg (dev,
(GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_STANDARD
| GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_SET_ADDRESS,
i, 0, 0, NULL);
if (err)
{
for (i = 0; i < 8; i++)
grub_free (dev->config[i].descconf);
grub_free (dev);
return NULL;
}
dev->addr = i;
dev->initialized = 1;
grub_usb_devs[i] = dev;
/* Wait "recovery interval", spec. says 2ms */
grub_millisleep (2);
grub_usb_device_attach (dev);
return dev;
}
@ -75,13 +110,46 @@ grub_usb_add_hub (grub_usb_device_t dev)
struct grub_usb_usb_hubdesc hubdesc;
grub_err_t err;
int i;
grub_uint64_t timeout;
grub_usb_device_t next_dev;
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_GET_DESCRIPTOR,
(GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
0, sizeof (hubdesc), (char *) &hubdesc);
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_GET_DESCRIPTOR,
(GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
0, sizeof (hubdesc), (char *) &hubdesc);
if (err)
return err;
grub_dprintf ("usb", "Hub descriptor:\n\t\t len:%d, typ:0x%02x, cnt:%d, char:0x%02x, pwg:%d, curr:%d\n",
hubdesc.length, hubdesc.type, hubdesc.portcnt,
hubdesc.characteristics, hubdesc.pwdgood,
hubdesc.current);
/* Activate the first configuration. Hubs should have only one conf. */
grub_dprintf ("usb", "Hub set configuration\n");
grub_usb_set_configuration (dev, 1);
/* Power on all Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++)
{
grub_dprintf ("usb", "Power on - port %d\n", i);
/* Power on the port and wait for possible device connect */
err = 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_POWER,
i, 0, NULL);
/* Just ignore the device if some error happened */
if (err)
continue;
}
/* Wait for port power-on */
if (hubdesc.pwdgood >= 50)
grub_millisleep (hubdesc.pwdgood * 2);
else
grub_millisleep (100);
/* Iterate over the Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++)
@ -92,13 +160,13 @@ grub_usb_add_hub (grub_usb_device_t dev)
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_HUB_GET_PORT_STATUS,
GRUB_USB_REQ_GET_STATUS,
0, i, sizeof (status), (char *) &status);
/* Just ignore the device if the Hub does not report the
status. */
if (err)
continue;
grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status);
/* If connected, reset and enable the port. */
if (status & GRUB_USB_HUB_STATUS_CONNECTED)
@ -116,70 +184,298 @@ grub_usb_add_hub (grub_usb_device_t dev)
speed = GRUB_USB_SPEED_FULL;
}
/* A device is actually connected to this port, not enable
the port. XXX: Why 0x03? According to some docs it
should be 0x0. Check the specification! */
/* A device is actually connected to this port.
* Now do reset of port. */
grub_dprintf ("usb", "Reset hub port - port %d\n", i);
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
0x3, 0x4, i, 0, 0);
GRUB_USB_REQ_SET_FEATURE,
GRUB_USB_HUB_FEATURE_PORT_RESET,
i, 0, 0);
/* If the Hub does not cooperate for this port, just skip
the port. */
if (err)
continue;
/* Wait for reset procedure done */
timeout = grub_get_time_ms () + 1000;
do
{
/* 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 (status), (char *) &status);
}
while (!err &&
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
(grub_get_time_ms() < timeout) );
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
continue;
/* Wait a recovery time after reset, spec. says 10ms */
grub_millisleep (10);
/* Do reset of connection change bit */
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_CLEAR_FEATURE,
GRUB_USB_HUB_FEATURE_C_CONNECTED,
i, 0, 0);
/* Just ignore the device if the Hub reports some error */
if (err)
continue;
grub_dprintf ("usb", "Hub port - cleared connection change\n");
/* Add the device and assign a device address to it. */
grub_usb_hub_add_dev (&dev->controller, speed);
grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i);
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
if (! next_dev)
continue;
/* If the device is a Hub, scan it for more devices. */
if (next_dev->descdev.class == 0x09)
grub_usb_add_hub (next_dev);
}
}
return GRUB_ERR_NONE;
}
static void
attach_root_port (grub_usb_controller_t controller, int portno,
grub_usb_speed_t speed)
{
grub_usb_device_t dev;
grub_err_t err;
/* Disable the port. XXX: Why? */
err = controller->dev->portstatus (controller, portno, 0);
if (err)
return;
/* Enable the port. */
err = controller->dev->portstatus (controller, portno, 1);
if (err)
return;
/* Enable the port and create a device. */
dev = grub_usb_hub_add_dev (controller, speed);
if (! dev)
return;
/* If the device is a Hub, scan it for more devices. */
if (dev->descdev.class == 0x09)
grub_usb_add_hub (dev);
}
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller)
{
grub_err_t err;
int ports;
int i;
struct grub_usb_hub *hub;
int changed=0;
hub = grub_malloc (sizeof (*hub));
if (!hub)
return GRUB_USB_ERR_INTERNAL;
hub->next = hubs;
hubs = hub;
hub->controller = grub_malloc (sizeof (*controller));
if (!hub->controller)
{
grub_free (hub);
return GRUB_USB_ERR_INTERNAL;
}
grub_memcpy (hub->controller, controller, sizeof (*controller));
hub->dev = 0;
/* Query the number of ports the root Hub has. */
ports = controller->dev->hubports (controller);
for (i = 0; i < ports; i++)
hub->nports = controller->dev->hubports (controller);
hub->speed = grub_malloc (sizeof (hub->speed[0]) * hub->nports);
if (!hub->speed)
{
grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
grub_free (hub->controller);
grub_free (hub);
return GRUB_USB_ERR_INTERNAL;
}
if (speed != GRUB_USB_SPEED_NONE)
{
grub_usb_device_t dev;
for (i = 0; i < hub->nports; i++)
{
hub->speed[i] = controller->dev->detect_dev (hub->controller, i,
&changed);
/* Enable the port. */
err = controller->dev->portstatus (controller, i, 1);
if (err)
continue;
/* Enable the port and create a device. */
dev = grub_usb_hub_add_dev (controller, speed);
if (! dev)
continue;
/* If the device is a Hub, scan it for more devices. */
if (dev->descdev.class == 0x09)
grub_usb_add_hub (dev);
}
if (hub->speed[i] != GRUB_USB_SPEED_NONE)
attach_root_port (hub->controller, i, hub->speed[i]);
}
return GRUB_USB_ERR_NONE;
}
static void
poll_nonroot_hub (grub_usb_device_t dev)
{
struct grub_usb_usb_hubdesc hubdesc;
grub_err_t err;
int i;
grub_uint64_t timeout;
grub_usb_device_t next_dev;
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_DEV),
GRUB_USB_REQ_GET_DESCRIPTOR,
(GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
0, sizeof (hubdesc), (char *) &hubdesc);
if (err)
return;
/* Iterate over the Hub ports. */
for (i = 1; i <= hubdesc.portcnt; i++)
{
grub_uint32_t status;
/* 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 (status), (char *) &status);
/* Just ignore the device if the Hub does not report the
status. */
if (err)
continue;
/* Connected and status of connection changed ? */
if ((status & GRUB_USB_HUB_STATUS_CONNECTED)
&& (status & GRUB_USB_HUB_STATUS_C_CONNECTED))
{
grub_usb_speed_t speed;
/* Determine the device speed. */
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
speed = GRUB_USB_SPEED_LOW;
else
{
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
speed = GRUB_USB_SPEED_HIGH;
else
speed = GRUB_USB_SPEED_FULL;
}
/* A device is actually connected to this port.
* Now do reset of port. */
err = 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);
/* If the Hub does not cooperate for this port, just skip
the port. */
if (err)
continue;
/* Wait for reset procedure done */
timeout = grub_get_time_ms () + 1000;
do
{
/* 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 (status), (char *) &status);
}
while (!err &&
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
(grub_get_time_ms() < timeout) );
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
continue;
/* Wait a recovery time after reset, spec. says 10ms */
grub_millisleep (10);
/* Do reset of connection change bit */
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_CLASS
| GRUB_USB_REQTYPE_TARGET_OTHER),
GRUB_USB_REQ_CLEAR_FEATURE,
GRUB_USB_HUB_FEATURE_C_CONNECTED,
i, 0, 0);
/* Just ignore the device if the Hub reports some error */
if (err)
continue;
/* Add the device and assign a device address to it. */
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
if (! next_dev)
continue;
/* If the device is a Hub, scan it for more devices. */
if (next_dev->descdev.class == 0x09)
grub_usb_add_hub (next_dev);
}
}
return;
}
void
grub_usb_poll_devices (void)
{
struct grub_usb_hub *hub;
int i;
for (hub = hubs; hub; hub = hub->next)
{
int changed=0;
/* Do we have to recheck number of ports? */
/* No, it should be never changed, it should be constant. */
for (i = 0; i < hub->nports; i++)
{
grub_usb_speed_t speed;
speed = hub->controller->dev->detect_dev (hub->controller, i,
&changed);
if (speed != GRUB_USB_SPEED_NONE)
{
if (changed)
attach_root_port (hub->controller, i, speed);
}
/* XXX: There should be also handling
* of disconnected devices. */
hub->speed[i] = speed;
}
}
/* We should check changes of non-root hubs too. */
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
{
grub_usb_device_t dev = grub_usb_devs[i];
if (dev && dev->descdev.class == 0x09)
{
poll_nonroot_hub (dev);
}
}
}
int
grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
{
int i;
for (i = 0; i < 128; i++)
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
{
if (grub_usb_devs[i])
{

View file

@ -18,6 +18,7 @@
*/
#include <grub/dl.h>
#include <grub/pci.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/usb.h>
@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev,
grub_uint8_t request,
grub_uint16_t value,
grub_uint16_t index,
grub_size_t size, char *data)
grub_size_t size0, char *data_in)
{
int i;
grub_usb_transfer_t transfer;
int datablocks;
struct grub_usb_packet_setup setupdata;
volatile struct grub_usb_packet_setup *setupdata;
grub_uint32_t setupdata_addr;
grub_usb_err_t err;
unsigned int max;
struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk;
volatile char *data;
grub_uint32_t data_addr;
grub_size_t size = size0;
/* FIXME: avoid allocation any kind of buffer in a first place. */
data_chunk = grub_memalign_dma32 (128, size ? : 16);
if (!data_chunk)
return GRUB_USB_ERR_INTERNAL;
data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk);
grub_memcpy ((char *) data, data_in, size);
grub_dprintf ("usb",
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
reqtype, request, value, index, size);
/* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer));
transfer = grub_malloc (sizeof (*transfer));
if (! transfer)
return grub_errno;
{
grub_dma_free (data_chunk);
return grub_errno;
}
setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata));
if (! setupdata_chunk)
{
grub_free (transfer);
grub_dma_free (data_chunk);
return grub_errno;
}
setupdata = grub_dma_get_virt (setupdata_chunk);
setupdata_addr = grub_dma_get_phys (setupdata_chunk);
/* Determine the maximum packet size. */
if (dev->initialized)
if (dev->descdev.maxsize0)
max = dev->descdev.maxsize0;
else
max = 64;
grub_dprintf ("usb", "control: transfer = %p, dev = %p\n", transfer, dev);
datablocks = (size + max - 1) / max;
/* XXX: Discriminate between different types of control
@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev,
if (! transfer->transactions)
{
grub_free (transfer);
grub_dma_free (setupdata_chunk);
grub_dma_free (data_chunk);
return grub_errno;
}
/* Build a Setup packet. XXX: Endianness. */
setupdata.reqtype = reqtype;
setupdata.request = request;
setupdata.value = value;
setupdata.index = index;
setupdata.length = size;
transfer->transactions[0].size = sizeof (setupdata);
setupdata->reqtype = reqtype;
setupdata->request = request;
setupdata->value = value;
setupdata->index = index;
setupdata->length = size;
transfer->transactions[0].size = sizeof (*setupdata);
transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
transfer->transactions[0].data = (char *) &setupdata;
transfer->transactions[0].data = setupdata_addr;
transfer->transactions[0].toggle = 0;
/* Now the data... XXX: Is this the right way to transfer control
@ -99,14 +131,14 @@ grub_usb_control_msg (grub_usb_device_t dev,
tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
else
tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
tr->data = &data[i * max];
tr->data = data_addr + i * max;
size -= max;
}
/* End with an empty OUT transaction. */
transfer->transactions[datablocks + 1].size = 0;
transfer->transactions[datablocks + 1].data = NULL;
if (reqtype & 128)
transfer->transactions[datablocks + 1].data = 0;
if ((reqtype & 128) && datablocks)
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
else
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
@ -114,16 +146,22 @@ grub_usb_control_msg (grub_usb_device_t dev,
transfer->transactions[datablocks + 1].toggle = 1;
err = dev->controller.dev->transfer (&dev->controller, transfer);
grub_dprintf ("usb", "control: err=%d\n", err);
grub_free (transfer->transactions);
grub_free (transfer);
grub_dma_free (data_chunk);
grub_dma_free (setupdata_chunk);
grub_memcpy (data_in, (char *) data, size0);
return err;
}
static grub_usb_err_t
grub_usb_bulk_readwrite (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data,
int endpoint, grub_size_t size0, char *data_in,
grub_transfer_type_t type)
{
int i;
@ -132,6 +170,21 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
unsigned int max;
grub_usb_err_t err;
int toggle = dev->toggle[endpoint];
volatile char *data;
grub_uint32_t data_addr;
struct grub_pci_dma_chunk *data_chunk;
grub_size_t size = size0;
grub_dprintf ("usb", "bulk: size=0x%02x type=%d\n", size, type);
/* FIXME: avoid allocation any kind of buffer in a first place. */
data_chunk = grub_memalign_dma32 (128, size);
if (!data_chunk)
return GRUB_USB_ERR_INTERNAL;
data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
grub_memcpy ((char *) data, data_in, size);
/* Use the maximum packet size given in the endpoint descriptor. */
if (dev->initialized)
@ -150,16 +203,20 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
/* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer));
if (! transfer)
return grub_errno;
{
grub_dma_free (data_chunk);
return grub_errno;
}
datablocks = ((size + max - 1) / max);
transfer->transcnt = datablocks;
transfer->size = size - 1;
transfer->endpoint = endpoint;
transfer->endpoint = endpoint & 15;
transfer->devaddr = dev->addr;
transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
transfer->max = max;
transfer->dev = dev;
transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */
/* Allocate an array of transfer data structures. */
transfer->transactions = grub_malloc (transfer->transcnt
@ -167,6 +224,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
if (! transfer->transactions)
{
grub_free (transfer);
grub_dma_free (data_chunk);
return grub_errno;
}
@ -181,16 +239,27 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
tr->toggle = toggle;
toggle = toggle ? 0 : 1;
tr->pid = type;
tr->data = &data[i * max];
tr->data = data_addr + i * max;
size -= tr->size;
}
err = dev->controller.dev->transfer (&dev->controller, transfer);
grub_dprintf ("usb", "toggle=%d\n", toggle);
/* We must remember proper toggle value even if some transactions
* were not processed - correct value should be inversion of last
* processed transaction (TD). */
if (transfer->last_trans >= 0)
toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1;
else
toggle = dev->toggle[endpoint]; /* Nothing done, take original */
grub_dprintf ("usb", "bulk: err=%d, toggle=%d\n", err, toggle);
dev->toggle[endpoint] = toggle;
grub_free (transfer->transactions);
grub_free (transfer);
grub_dma_free (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_IN)
grub_memcpy (data_in, (char *) data, size0);
return err;
}

View file

@ -23,19 +23,28 @@
#include <grub/term.h>
#include <grub/misc.h>
#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
static grub_err_t
grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
static const struct grub_arg_option options[] =
{
{"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
{
struct grub_arg_list *state = cmd->state;
int dos = 0;
grub_file_t file;
char buf[GRUB_DISK_SECTOR_SIZE];
grub_ssize_t size;
int key = 0;
if (state[0].set)
dos = 1;
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
@ -53,7 +62,12 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c);
grub_printf ("%c", c);
else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n')
{
grub_printf ("\n");
i++;
}
else
{
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
@ -67,22 +81,23 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
;
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
grub_file_close (file);
return 0;
}
static grub_command_t cmd;
static grub_extcmd_t cmd;
GRUB_MOD_INIT(cat)
{
cmd = grub_register_command_p1 ("cat", grub_cmd_cat,
N_("FILE"), N_("Show the contents of a file."));
cmd = grub_register_extcmd ("cat", grub_cmd_cat, GRUB_COMMAND_FLAG_BOTH,
N_("FILE"), N_("Show the contents of a file."),
options);
}
GRUB_MOD_FINI(cat)
{
grub_unregister_command (cmd);
grub_unregister_extcmd (cmd);
}

View file

@ -138,8 +138,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
{
grub_device_close (dev);
return grub_error (GRUB_ERR_OUT_OF_RANGE,
"only partitions resding in the first 2TB "
"can be presen in hybrid MBR");
"only partitions residing in the first 2TB "
"can be present in hybrid MBR");
}
@ -243,8 +243,8 @@ GRUB_MOD_INIT(gptsync)
cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
N_("DEVICE [PARTITION[+/-[TYPE]]] ..."),
N_("Fill hybrid MBR of GPT drive DEVICE. "
"specified partitions will be a part "
"of hybrid mbr. Up to 3 partitions are "
"Specified partitions will be a part "
"of hybrid MBR. Up to 3 partitions are "
"allowed. TYPE is an MBR type. "
"+ means that partition is active. "
"Only one partition can be active."));

View file

@ -1,101 +0,0 @@
/* handler.c - commands to list or select handlers */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/handler.h>
#include <grub/command.h>
#include <grub/i18n.h>
static grub_err_t
grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
void *curr_item = 0;
grub_handler_class_t head;
auto int list_item (grub_named_list_t item);
int list_item (grub_named_list_t item)
{
if (item == curr_item)
grub_putchar ('*');
grub_printf ("%s\n", item->name);
return 0;
}
head = grub_handler_class_list;
if (argc == 0)
{
grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
}
else
{
char *class_name;
grub_handler_class_t class;
class_name = args[0];
argc--;
args++;
class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
if (! class)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
if (argc == 0)
{
curr_item = class->cur_handler;
grub_list_iterate (GRUB_AS_LIST (class->handler_list),
(grub_list_hook_t) list_item);
}
else
{
grub_handler_t handler;
handler =
grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
args[0]);
if (! handler)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
grub_handler_set_current (class, handler);
}
}
return 0;
}
static grub_command_t cmd_handler;
GRUB_MOD_INIT(handler)
{
cmd_handler =
grub_register_command ("handler", grub_cmd_handler,
N_("[class [handler]]"),
N_("List or select a handler."));
}
GRUB_MOD_FINI(handler)
{
grub_unregister_command (cmd_handler);
}

View file

@ -24,13 +24,14 @@
#include <grub/misc.h>
#include <grub/crypto.h>
#include <grub/normal.h>
#include <grub/i18n.h>
static const struct grub_arg_option options[] = {
{"hash", 'h', 0, "Specify hash to use.", "HASH", ARG_TYPE_STRING},
{"check", 'c', 0, "Check hash list file.", "FILE", ARG_TYPE_STRING},
{"prefix", 'p', 0, "Base directory for hash list.", "DIRECTORY",
{"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
{"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING},
{"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"),
ARG_TYPE_STRING},
{"keep-going", 'k', 0, "Don't stop after first error.", 0, 0},
{"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
{0, 0, 0, 0, 0, 0}
};
@ -249,21 +250,21 @@ GRUB_MOD_INIT(hashsum)
options);
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum,
GRUB_COMMAND_FLAG_BOTH,
"md5sum [-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]",
"Compute or check hash checksum.",
N_("[-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]"),
N_("Compute or check hash checksum."),
options);
cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum,
GRUB_COMMAND_FLAG_BOTH,
"sha256sum [-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]",
N_("[-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]"),
"Compute or check hash checksum.",
options);
cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum,
GRUB_COMMAND_FLAG_BOTH,
"sha512sum [-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]",
"Compute or check hash checksum.",
N_("[-c FILE [-p PREFIX]] "
"[FILE1 [FILE2 ...]]"),
N_("Compute or check hash checksum."),
options);
}

View file

@ -33,94 +33,93 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
int cnt = 0;
char *currarg;
auto int print_command_info (grub_command_t cmd);
auto int print_command_help (grub_command_t cmd);
int print_command_info (grub_command_t cmd)
{
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
{
struct grub_term_output *term;
const char *summary_translated = _(cmd->summary);
char *command_help;
grub_uint32_t *unicode_command_help;
grub_uint32_t *unicode_last_position;
command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
if (!command_help)
return 1;
grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
&unicode_last_position);
FOR_ACTIVE_TERM_OUTPUTS(term)
{
unsigned stringwidth;
grub_uint32_t *unicode_last_screen_position;
unicode_last_screen_position = unicode_command_help;
stringwidth = 0;
while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((grub_term_width (term) / 2) - 2))
{
stringwidth
+= grub_term_getcharwidth (term,
*unicode_last_screen_position);
unicode_last_screen_position++;
}
grub_print_ucs4 (unicode_command_help,
unicode_last_screen_position, term);
if (!(cnt % 2))
grub_print_spaces (term, grub_term_width (term) / 2
- stringwidth);
}
if (cnt % 2)
grub_printf ("\n");
cnt++;
grub_free (command_help);
grub_free (unicode_command_help);
}
return 0;
}
int print_command_help (grub_command_t cmd)
{
if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
{
if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
{
if (cnt++ > 0)
grub_printf ("\n\n");
if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
grub_arg_show_help ((grub_extcmd_t) cmd->data);
else
grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary),
_(cmd->description));
}
}
return 0;
}
if (argc == 0)
{
grub_command_iterate (print_command_info);
grub_command_t cmd;
FOR_COMMANDS(cmd)
{
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
{
struct grub_term_output *term;
const char *summary_translated = _(cmd->summary);
char *command_help;
grub_uint32_t *unicode_command_help;
grub_uint32_t *unicode_last_position;
command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
if (!command_help)
break;
grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
&unicode_last_position);
FOR_ACTIVE_TERM_OUTPUTS(term)
{
unsigned stringwidth;
grub_uint32_t *unicode_last_screen_position;
unicode_last_screen_position = unicode_command_help;
stringwidth = 0;
while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((grub_term_width (term) / 2) - 2))
{
struct grub_unicode_glyph glyph;
unicode_last_screen_position
+= grub_unicode_aglomerate_comb (unicode_last_screen_position,
unicode_last_position
- unicode_last_screen_position,
&glyph);
stringwidth
+= grub_term_getcharwidth (term, &glyph);
}
grub_print_ucs4 (unicode_command_help,
unicode_last_screen_position, 0, 0, term);
if (!(cnt % 2))
grub_print_spaces (term, grub_term_width (term) / 2
- stringwidth);
}
if (cnt % 2)
grub_printf ("\n");
cnt++;
grub_free (command_help);
grub_free (unicode_command_help);
}
}
if (!(cnt % 2))
grub_printf ("\n");
}
else
{
int i;
grub_command_t cmd;
for (i = 0; i < argc; i++)
{
currarg = args[i];
grub_command_iterate (print_command_help);
FOR_COMMANDS(cmd)
{
if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
{
if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
{
if (cnt++ > 0)
grub_printf ("\n\n");
if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
grub_arg_show_help ((grub_extcmd_t) cmd->data);
else
grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary),
_(cmd->description));
}
}
}
}
}

59
commands/i386/cmostest.c Normal file
View file

@ -0,0 +1,59 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/cmos.h>
static grub_err_t
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int byte, bit;
char *rest;
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
byte = grub_strtoul (argv[0], &rest, 0);
if (*rest != ':')
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
bit = grub_strtoul (rest + 1, 0, 0);
if (grub_cmos_read (byte) & (1 << bit))
return GRUB_ERR_NONE;
return grub_error (GRUB_ERR_TEST_FAILURE, "false");
}
static grub_command_t cmd;
GRUB_MOD_INIT(cmostest)
{
cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
"cmostest BYTE:BIT",
"Test bit at BYTE:BIT in CMOS.");
}
GRUB_MOD_FINI(cmostest)
{
grub_unregister_command (cmd);
}

View file

@ -402,11 +402,10 @@ GRUB_MOD_INIT (drivemap)
grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
GRUB_COMMAND_FLAG_BOTH,
"drivemap"
N_("-l | -r | [-s] grubdev osdisk."),
N_("Manage the BIOS drive mappings."),
options);
GRUB_COMMAND_FLAG_BOTH,
N_("-l | -r | [-s] grubdev osdisk."),
N_("Manage the BIOS drive mappings."),
options);
drivemap_hook =
grub_loader_register_preboot_hook (&install_int13_handler,
&uninstall_int13_handler,

View file

@ -177,16 +177,20 @@ static grub_err_t
grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_file_t file;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required");
file = grub_file_open (args[0]);
if (file)
if (argc == 1)
{
struct note buf;
grub_uint32_t tempo;
grub_file_t file;
file = grub_file_open (args[0]);
if (! file)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo))
{

150
commands/iorw.c Normal file
View file

@ -0,0 +1,150 @@
/* memrw.c - command to read / write physical memory */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/env.h>
#include <grub/cpu/io.h>
#include <grub/i18n.h>
static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword;
static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
static const struct grub_arg_option options[] =
{
{0, 'v', 0, N_("Save read value into variable VARNAME."),
N_("VARNAME"), ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
{
grub_target_addr_t addr;
grub_uint32_t value = 0;
char buf[sizeof ("XXXXXXXX")];
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
addr = grub_strtoul (argv[0], 0, 0);
switch (cmd->cmd->name[sizeof ("in") - 1])
{
case 'l':
value = grub_inl (addr);
break;
case 'w':
value = grub_inw (addr);
break;
case 'b':
value = grub_inb (addr);
break;
}
if (cmd->state[0].set)
{
grub_snprintf (buf, sizeof (buf), "%x", value);
grub_env_set (cmd->state[0].arg, buf);
}
else
grub_printf ("0x%x\n", value);
return 0;
}
static grub_err_t
grub_cmd_write (grub_command_t cmd, int argc, char **argv)
{
grub_target_addr_t addr;
grub_uint32_t value;
grub_uint32_t mask = 0xffffffff;
if (argc != 2 && argc != 3)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
addr = grub_strtoul (argv[0], 0, 0);
value = grub_strtoul (argv[1], 0, 0);
if (argc == 3)
mask = grub_strtoul (argv[2], 0, 0);
value &= mask;
switch (cmd->name[sizeof ("out") - 1])
{
case 'l':
if (mask != 0xffffffff)
grub_outl ((grub_inl (addr) & ~mask) | value, addr);
else
grub_outl (value, addr);
break;
case 'w':
if ((mask & 0xffff) != 0xffff)
grub_outw ((grub_inw (addr) & ~mask) | value, addr);
else
grub_outw (value, addr);
break;
case 'b':
if ((mask & 0xff) != 0xff)
grub_outb ((grub_inb (addr) & ~mask) | value, addr);
else
grub_outb (value, addr);
break;
}
return 0;
}
GRUB_MOD_INIT(memrw)
{
cmd_read_byte =
grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
N_("PORT"), N_("Read byte from PORT."), options);
cmd_read_word =
grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
N_("PORT"), N_("Read word from PORT."), options);
cmd_read_dword =
grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
N_("PORT"), N_("Read dword from PORT."), options);
cmd_write_byte =
grub_register_command ("outb", grub_cmd_write,
N_("PORT VALUE [MASK]"),
N_("Write byte VALUE to PORT."));
cmd_write_word =
grub_register_command ("outw", grub_cmd_write,
N_("PORT VALUE [MASK]"),
N_("Write word VALUE to PORT."));
cmd_write_dword =
grub_register_command ("outl", grub_cmd_write,
N_("ADDR VALUE [MASK]"),
N_("Write dword VALUE to PORT."));
}
GRUB_MOD_FINI(memrw)
{
grub_unregister_extcmd (cmd_read_byte);
grub_unregister_extcmd (cmd_read_word);
grub_unregister_extcmd (cmd_read_dword);
grub_unregister_command (cmd_write_byte);
grub_unregister_command (cmd_write_word);
grub_unregister_command (cmd_write_dword);
}

View file

@ -57,7 +57,7 @@ grub_ls_list_devices (int longlist)
}
grub_device_iterate (grub_ls_print_devices);
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
return 0;
@ -233,7 +233,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
}
if (grub_errno == GRUB_ERR_NONE)
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
}

View file

@ -54,7 +54,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
unsigned char c = buf[i];
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c);
grub_printf ("%c", c);
else
{
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
@ -64,7 +64,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
}
}
grub_putchar ('\n');
grub_xputs ("\n");
grub_refresh ();
grub_file_close (file);
@ -301,27 +301,23 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
auto int print_module (grub_dl_t mod);
int print_module (grub_dl_t mod)
{
grub_dl_dep_t dep;
grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
for (dep = mod->dep; dep; dep = dep->next)
{
if (dep != mod->dep)
grub_putchar (',');
grub_printf ("%s", dep->mod->name);
}
grub_putchar ('\n');
return 0;
}
grub_dl_t mod;
grub_printf ("Name\tRef Count\tDependencies\n");
grub_dl_iterate (print_module);
FOR_DL_MODULES (mod)
{
grub_dl_dep_t dep;
grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
for (dep = mod->dep; dep; dep = dep->next)
{
if (dep != mod->dep)
grub_xputs (",");
grub_printf ("%s", dep->mod->name);
}
grub_xputs ("\n");
}
return 0;
}
@ -336,19 +332,8 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
return 0;
}
/* clear */
static grub_err_t
grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
grub_cls ();
return 0;
}
static grub_command_t cmd_cat, cmd_help, cmd_root;
static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
static grub_command_t cmd_clear;
GRUB_MOD_INIT(minicmd)
{
@ -373,9 +358,6 @@ GRUB_MOD_INIT(minicmd)
cmd_exit =
grub_register_command ("exit", grub_mini_cmd_exit,
0, N_("Exit from GRUB."));
cmd_clear =
grub_register_command ("clear", grub_mini_cmd_clear,
0, N_("Clear the screen."));
}
GRUB_MOD_FINI(minicmd)
@ -387,5 +369,4 @@ GRUB_MOD_FINI(minicmd)
grub_unregister_command (cmd_rmmod);
grub_unregister_command (cmd_lsmod);
grub_unregister_command (cmd_exit);
grub_unregister_command (cmd_clear);
}

View file

@ -0,0 +1,92 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/cs5536.h>
static grub_err_t
grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_pci_device_t dev;
grub_port_t smbbase;
int i;
grub_err_t err;
if (!grub_cs5536_find (&dev))
{
grub_printf ("No CS5536 found\n");
return GRUB_ERR_NONE;
}
grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev),
grub_pci_get_device (dev), grub_pci_get_function (dev));
err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase);
if (err)
return err;
grub_printf ("SMB base = 0x%x\n", smbbase);
for (i = GRUB_SMB_RAM_START_ADDR;
i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++)
{
struct grub_smbus_spd spd;
grub_memset (&spd, 0, sizeof (spd));
grub_printf ("Device %d\n", i);
err = grub_cs5536_read_spd (smbbase, i, &spd);
if (err)
{
grub_print_error ();
continue;
}
grub_printf ("Written SPD bytes: %d B.\n", spd.written_size);
grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size);
if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2)
{
char str[sizeof (spd.ddr2.part_number) + 1];
grub_printf ("Memory type: DDR2.\n");
grub_memcpy (str, spd.ddr2.part_number,
sizeof (spd.ddr2.part_number));
str[sizeof (spd.ddr2.part_number)] = 0;
grub_printf ("Part no: %s.\n", str);
}
else
grub_printf ("Memory type: Unknown.\n");
}
return GRUB_ERR_NONE;
}
static grub_command_t cmd;
GRUB_MOD_INIT(lsspd)
{
cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0,
"Print Memory information.");
}
GRUB_MOD_FINI(lsspd)
{
grub_unregister_command (cmd);
}

View file

@ -175,7 +175,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
}
/* Load modules. */
#if GRUB_NO_MODULES
#if !GRUB_NO_MODULES
{
const char *prefix;
prefix = grub_env_get ("prefix");

View file

@ -24,6 +24,7 @@
#include <grub/env.h>
#include <grub/normal.h>
#include <grub/dl.h>
#include <grub/i18n.h>
static grub_dl_t my_mod;
@ -186,8 +187,8 @@ GRUB_MOD_INIT(password_pbkdf2)
{
my_mod = mod;
cmd = grub_register_command ("password_pbkdf2", grub_cmd_password,
"password_pbkdf2 USER PBKDF2_PASSWORD",
"Set user password (PBKDF2). ");
N_("USER PBKDF2_PASSWORD"),
N_("Set user password (PBKDF2). "));
}
GRUB_MOD_FINI(password_pbkdf2)

View file

@ -47,7 +47,7 @@ grub_getline (void)
line[i] = c;
if (grub_isprint (c))
grub_putchar (c);
grub_printf ("%c", c);
i++;
tmp = grub_realloc (line, 1 + i + sizeof('\0'));
if (! tmp)

View file

@ -21,6 +21,7 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <regex.h>
static grub_err_t
@ -69,8 +70,8 @@ static grub_command_t cmd;
GRUB_MOD_INIT(regexp)
{
cmd = grub_register_command ("regexp", grub_cmd_regexp,
"REGEXP STRING",
"Test if REGEXP matches STRING.");
N_("REGEXP STRING"),
N_("Test if REGEXP matches STRING."));
}
GRUB_MOD_FINI(regexp)

View file

@ -23,6 +23,7 @@
#include <grub/extcmd.h>
#include <grub/env.h>
#include <grub/mm.h>
#include <grub/i18n.h>
struct pci_register
{
@ -95,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
if (check_device && grub_pci_get_device (dev) != device)
return 0;
if (check_function && grub_pci_get_function (dev) != device)
if (check_function && grub_pci_get_function (dev) != function)
return 0;
addr = grub_pci_make_address (dev, regaddr);
@ -329,9 +330,9 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(setpci)
{
cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH,
"setpci [-s POSITION] [-d DEVICE] [-v VAR] "
"[REGISTER][=VALUE[:MASK]]",
"Manipulate PCI devices.", options);
N_("[-s POSITION] [-d DEVICE] [-v VAR] "
"[REGISTER][=VALUE[:MASK]]"),
N_("Manipulate PCI devices."), options);
}
GRUB_MOD_FINI(setpci)

View file

@ -26,37 +26,48 @@
struct grub_term_autoload *grub_term_input_autoload = NULL;
struct grub_term_autoload *grub_term_output_autoload = NULL;
struct abstract_terminal
{
struct abstract_terminal *next;
const char *name;
grub_err_t (*init) (struct abstract_terminal *term);
grub_err_t (*fini) (struct abstract_terminal *term);
};
static grub_err_t
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
handle_command (int argc, char **args, struct abstract_terminal **enabled,
struct abstract_terminal **disabled,
struct grub_term_autoload *autoloads,
const char *active_str,
const char *available_str)
{
int i;
grub_term_input_t term;
struct abstract_terminal *term;
struct grub_term_autoload *aut;
if (argc == 0)
{
grub_puts_ (N_ ("Active input terminals:"));
FOR_ACTIVE_TERM_INPUTS(term)
grub_printf ("%s ", term->name);
grub_puts_ (active_str);
for (term = *enabled; term; term = term->next)
grub_printf ("%s ", term->name);
grub_printf ("\n");
grub_puts_ (N_ ("Available input terminals:"));
FOR_DISABLED_TERM_INPUTS(term)
grub_printf ("%s ", term->name);
grub_puts_ (available_str);
for (term = *disabled; term; term = term->next)
grub_printf ("%s ", term->name);
/* This is quadratic but we don't expect mode than 30 terminal
modules ever. */
for (aut = grub_term_input_autoload; aut; aut = aut->next)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
grub_printf ("%s ", aut->name);
}
modules ever. */
for (aut = autoloads; aut; aut = aut->next)
{
for (term = *disabled; term; term = term->next)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
for (term = *enabled; term; term = term->next)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
grub_printf ("%s ", aut->name);
}
grub_printf ("\n");
return GRUB_ERR_NONE;
}
@ -73,112 +84,108 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
{
int again = 0;
while (1)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
break;
if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
for (aut = grub_term_input_autoload; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0)
{
grub_dl_t mod;
mod = grub_dl_load (aut->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
break;
}
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
again = 1;
}
{
for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
for (term = *enabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
break;
if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
for (aut = autoloads; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0)
{
grub_dl_t mod;
mod = grub_dl_load (aut->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
break;
}
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
again = 1;
}
}
if (grub_strcmp (args[0], "--append") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
{
for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
GRUB_AS_LIST (term));
}
}
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
if (grub_strcmp (args[0], "--remove") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (!term->next && term == grub_term_inputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
}
{
for (term = *enabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (!term->next && term == *enabled)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini)
term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
for (i = 0; i < argc; i++)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
for (term = *disabled; term; term = term->next)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
return grub_errno;
{
if (term->init && term->init (term) != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
GRUB_AS_LIST (term));
}
grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
}
}
FOR_ACTIVE_TERM_INPUTS(term)
{
for (i = 0; i < argc; i++)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (i == argc)
struct abstract_terminal *next;
for (term = *enabled; term; term = next)
{
if (!term->next && term == grub_term_inputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
next = term->next;
for (i = 0; i < argc; i++)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (i == argc)
{
if (!term->next && term == *enabled)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
if (term->fini)
term->fini (term);
grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
}
}
}
@ -186,163 +193,34 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
}
static grub_err_t
grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_output_t term;
struct grub_term_autoload *aut;
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
return handle_command (argc, args,
(struct abstract_terminal **) &grub_term_inputs,
(struct abstract_terminal **) &grub_term_inputs_disabled,
grub_term_input_autoload,
N_ ("Active input terminals:"),
N_ ("Available input terminals:"));
}
if (argc == 0)
{
grub_puts_ (N_ ("Active output terminals:"));
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_printf ("%s ", term->name);
grub_printf ("\n");
grub_puts_ (N_ ("Available output terminals:"));
FOR_DISABLED_TERM_OUTPUTS(term)
grub_printf ("%s ", term->name);
/* This is quadratic but we don't expect mode than 30 terminal
modules ever. */
for (aut = grub_term_output_autoload; aut; aut = aut->next)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
grub_printf ("%s ", aut->name);
}
grub_printf ("\n");
return GRUB_ERR_NONE;
}
i = 0;
if (grub_strcmp (args[0], "--append") == 0
|| grub_strcmp (args[0], "--remove") == 0)
i++;
if (i == argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
for (; i < argc; i++)
{
int again = 0;
while (1)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
break;
if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
for (aut = grub_term_output_autoload; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0)
{
grub_dl_t mod;
mod = grub_dl_load (aut->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
break;
}
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
again = 1;
}
}
if (grub_strcmp (args[0], "--append") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
if (grub_strcmp (args[0], "--remove") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (!term->next && term == grub_term_outputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
for (i = 0; i < argc; i++)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (term->init && term->init () != GRUB_ERR_NONE)
return grub_errno;
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
}
FOR_ACTIVE_TERM_OUTPUTS(term)
{
for (i = 0; i < argc; i++)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (i == argc)
{
if (!term->next && term == grub_term_outputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
static grub_err_t
grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
(struct abstract_terminal **) &grub_term_outputs_disabled,
grub_term_output_autoload,
N_ ("Active output terminals:"),
N_ ("Available output terminals:"));
}
static grub_command_t cmd_terminal_input, cmd_terminal_output;
@ -351,14 +229,14 @@ GRUB_MOD_INIT(terminal)
{
cmd_terminal_input =
grub_register_command ("terminal_input", grub_cmd_terminal_input,
"[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ...",
"List or select an input terminal.");
N_("[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ..."),
N_("List or select an input terminal."));
cmd_terminal_output =
grub_register_command ("terminal_output", grub_cmd_terminal_output,
"[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ...",
"List or select an output terminal.");
N_("[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ..."),
N_("List or select an output terminal."));
}
GRUB_MOD_FINI(terminal)

View file

@ -83,15 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
0x06, (3 << 8) | index,
langid, descstr.length, (char *) descstrp);
*string = grub_malloc (descstr.length / 2);
if (descstrp->length == 0)
{
grub_free (descstrp);
*string = grub_strdup ("");
if (! *string)
return GRUB_USB_ERR_INTERNAL;
return GRUB_USB_ERR_NONE;
}
*string = grub_malloc (descstr.length * 2 + 1);
if (! *string)
{
grub_free (descstrp);
return GRUB_USB_ERR_INTERNAL;
}
grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1);
(*string)[descstr.length / 2 - 1] = '\0';
*grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
descstrp->length / 2 - 1) = 0;
grub_free (descstrp);
return GRUB_USB_ERR_NONE;
@ -185,6 +194,8 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_usb_poll_devices ();
grub_printf ("USB devices:\n\n");
grub_usb_iterate (usb_iterate);

View file

@ -25,6 +25,7 @@
#include <grub/term.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/gfxmenu_view.h>
static grub_err_t
grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
@ -38,15 +39,8 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
unsigned int width;
unsigned int height;
int i;
grub_font_t sansbig;
grub_font_t sans;
grub_font_t sanssmall;
grub_font_t fixed;
struct grub_font_glyph *glyph;
struct grub_video_render_target *text_layer;
grub_video_color_t palette[16];
const char *str;
int texty;
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
if (err)
@ -54,102 +48,115 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
grub_video_get_viewport (&x, &y, &width, &height);
grub_video_create_render_target (&text_layer, width, height,
GRUB_VIDEO_MODE_TYPE_RGB
| GRUB_VIDEO_MODE_TYPE_ALPHA);
{
const char *str;
int texty;
grub_font_t sansbig;
grub_font_t sans;
grub_font_t sanssmall;
grub_font_t fixed;
struct grub_font_glyph *glyph;
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
grub_video_create_render_target (&text_layer, width, height,
GRUB_VIDEO_MODE_TYPE_RGB
| GRUB_VIDEO_MODE_TYPE_ALPHA);
color = grub_video_map_rgb (0, 0, 0);
grub_video_fill_rect (color, 0, 0, width, height);
grub_video_set_active_render_target (text_layer);
color = grub_video_map_rgb (255, 0, 0);
grub_video_fill_rect (color, 0, 0, 100, 100);
color = grub_video_map_rgb (0, 255, 255);
sansbig = grub_font_get ("Unknown Regular 16");
sans = grub_font_get ("Unknown Regular 16");
sanssmall = grub_font_get ("Unknown Regular 16");
fixed = grub_font_get ("Fixed 20");
if (! sansbig || ! sans || ! sanssmall || ! fixed)
return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
color = grub_video_map_rgb (0, 255, 255);
grub_video_fill_rect (color, 100, 100, 100, 100);
glyph = grub_font_get_glyph (fixed, '*');
grub_font_draw_glyph (glyph, color, 200 ,0);
sansbig = grub_font_get ("Unknown Regular 16");
sans = grub_font_get ("Unknown Regular 16");
sanssmall = grub_font_get ("Unknown Regular 16");
fixed = grub_font_get ("Fixed 20");
if (! sansbig || ! sans || ! sanssmall || ! fixed)
return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
color = grub_video_map_rgb (255, 255, 255);
glyph = grub_font_get_glyph (fixed, '*');
grub_font_draw_glyph (glyph, color, 200 ,0);
texty = 32;
grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
sans, color, 16, texty);
texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
grub_video_set_viewport (x + 150, y + 150,
width - 150 * 2, height - 150 * 2);
color = grub_video_map_rgb (77, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height);
texty += grub_font_get_ascent (fixed);
grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
fixed, color, 16, texty);
texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
grub_video_set_active_render_target (text_layer);
color = grub_video_map_rgb (255, 255, 255);
texty = 32;
grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
sans, color, 16, texty);
texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
texty += grub_font_get_ascent (fixed);
grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
fixed, color, 16, texty);
texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
/* To convert Unicode characters into UTF-8 for this test, the following
command is useful:
/* To convert Unicode characters into UTF-8 for this test, the following
command is useful:
echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1
This converts the Unicode character U+263A to UTF-8. */
This converts the Unicode character U+263A to UTF-8. */
/* Characters used:
Code point Description UTF-8 encoding
----------- ------------------------------ --------------
U+263A unfilled smiley face E2 98 BA
U+00A1 inverted exclamation point C2 A1
U+00A3 British pound currency symbol C2 A3
U+03C4 Greek tau CF 84
U+00E4 lowercase letter a with umlaut C3 A4
U+2124 set 'Z' symbol (integers) E2 84 A4
U+2287 subset symbol E2 8A 87
U+211D set 'R' symbol (real numbers) E2 84 9D */
/* Characters used:
Code point Description UTF-8 encoding
----------- ------------------------------ --------------
U+263A unfilled smiley face E2 98 BA
U+00A1 inverted exclamation point C2 A1
U+00A3 British pound currency symbol C2 A3
U+03C4 Greek tau CF 84
U+00E4 lowercase letter a with umlaut C3 A4
U+2124 set 'Z' symbol (integers) E2 84 A4
U+2287 subset symbol E2 8A 87
U+211D set 'R' symbol (real numbers) E2 84 9D */
str =
"Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
" \xC2\xA1\xCF\x84\xC3\xA4u! "
" \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
color = grub_video_map_rgb (128, 128, 255);
str =
"Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
" \xC2\xA1\xCF\x84\xC3\xA4u! "
" \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
color = grub_video_map_rgb (128, 128, 255);
/* All characters in the string exist in the 'Fixed 20' (10x20) font. */
texty += grub_font_get_ascent(fixed);
grub_font_draw_string (str, fixed, color, 16, texty);
texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
/* All characters in the string exist in the 'Fixed 20' (10x20) font. */
texty += grub_font_get_ascent(fixed);
grub_font_draw_string (str, fixed, color, 16, texty);
texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
texty += grub_font_get_ascent(sansbig);
grub_font_draw_string (str, sansbig, color, 16, texty);
texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
texty += grub_font_get_ascent(sansbig);
grub_font_draw_string (str, sansbig, color, 16, texty);
texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
texty += grub_font_get_ascent(sans);
grub_font_draw_string (str, sans, color, 16, texty);
texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
texty += grub_font_get_ascent(sans);
grub_font_draw_string (str, sans, color, 16, texty);
texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
texty += grub_font_get_ascent(sanssmall);
grub_font_draw_string (str, sanssmall, color, 16, texty);
texty += (grub_font_get_descent (sanssmall)
+ grub_font_get_leading (sanssmall));
texty += grub_font_get_ascent(sanssmall);
grub_font_draw_string (str, sanssmall, color, 16, texty);
texty += (grub_font_get_descent (sanssmall)
+ grub_font_get_leading (sanssmall));
glyph = grub_font_get_glyph (fixed, '*');
glyph = grub_font_get_glyph (fixed, '*');
for (i = 0; i < 16; i++)
{
color = grub_video_map_color (i);
palette[i] = color;
grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
}
for (i = 0; i < 16; i++)
{
color = grub_video_map_color (i);
palette[i] = color;
grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
}
}
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
for (i = 0; i < 2; i++)
{
color = grub_video_map_rgb (0, 0, 0);
grub_video_fill_rect (color, 0, 0, width, height);
color = grub_video_map_rgb (255, 0, 0);
grub_video_fill_rect (color, 0, 0, 100, 100);
color = grub_video_map_rgb (0, 255, 255);
grub_video_fill_rect (color, 100, 100, 100, 100);
grub_video_set_viewport (x + 150, y + 150,
width - 150 * 2, height - 150 * 2);
color = grub_video_map_rgb (77, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height);
grub_video_swap_buffers ();
}
for (i = 0; i < 5; i++)
{
color = grub_video_map_rgb (i, 33, 77);

View file

@ -1,34 +1,33 @@
# -*- makefile -*-
COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)
kernel_img_RELOCATABLE = yes
pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \
kern/err.c kern/list.c kern/handler.c kern/command.c \
kern/err.c kern/list.c kern/command.c \
kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \
kern/parser.c kern/partition.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
\
util/console.c util/grub-emu.c util/misc.c \
util/hostdisk.c util/getroot.c util/mm.c util/time.c \
\
gnulib/progname.c util/hostfs.c disk/host.c
kernel_img_HEADERS += datetime.h util/misc.h
kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib
\
kern/emu/main.c kern/emu/mm.c kern/emu/misc.c \
kern/emu/getroot.c kern/emu/time.c kern/emu/hostdisk.c \
kern/emu/hostfs.c kern/emu/console.c \
\
gnulib/progname.c disk/host.c
kernel_img_HEADERS += datetime.h emu/misc.h
kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-char-subscripts -Wno-unused -Wno-deprecated-declarations -Wno-undef -I$(srcdir)/gnulib
kernel_img_LDFLAGS = $(COMMON_LDFLAGS)
TARGET_NO_STRIP = yes
ifneq ($(TARGET_NO_MODULES), yes)
kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c
else
kernel_img_SOURCES += grub_emu_init.c
endif
ifneq ($(target_cpu), i386)
ifneq ($(target_cpu), x86_64)
kernel_img_SOURCES += kern/$(target_cpu)/cache.S
endif
endif
else
kernel_img_SOURCES += grub_emu_init.c
endif
# For halt.mod.
pkglib_MODULES += halt.mod
@ -49,7 +48,7 @@ ifeq ($(enable_grub_emu_usb), yes)
kernel_img_HEADERS += libusb.h
pkglib_MODULES += libusb.mod
libusb_mod_SOURCES = util/usb.c
libusb_mod_SOURCES = bus/usb/emu/usb.c
libusb_mod_CFLAGS =
libusb_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -76,7 +75,7 @@ endif
ifeq ($(enable_grub_emu_sdl), yes)
pkglib_MODULES += sdl.mod
sdl_mod_SOURCES = util/sdl.c
sdl_mod_SOURCES = video/emu/sdl.c
sdl_mod_CFLAGS =
sdl_mod_LDFLAGS = $(COMMON_LDFLAGS)
grub_emu_LDFLAGS += $(LIBSDL)
@ -85,7 +84,7 @@ endif
ifeq ($(enable_grub_emu_pci), yes)
pkglib_MODULES += pci.mod
pci_mod_SOURCES = util/pci.c commands/lspci.c
pci_mod_SOURCES = bus/emu/pci.c commands/lspci.c
pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
grub_emu_LDFLAGS += $(LIBPCIACCESS)
kernel_img_HEADERS += libpciaccess.h
@ -104,10 +103,10 @@ DISTCLEANFILES += grub_emu_init.c
CLEANFILES += grub-emu
ifneq ($(TARGET_NO_MODULES), yes)
grub-emu: $(pkglib_PROGRAMS)
$(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
$(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS)
else
grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS)
$(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
$(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS)
endif
GRUB_EMU=grub-emu

View file

@ -1,12 +1,13 @@
# -*- makefile -*-
# Used by various components. These rules need to precede them.
script/lexer.c_DEPENDENCIES = grub_script.tab.h
script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h
sbin_UTILITIES += grub-mkdevicemap
grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \
util/deviceiter.c \
util/misc.c
util/misc.c kern/emu/misc.c \
kern/env.c kern/err.c kern/list.c kern/misc.c kern/emu/mm.c
ifeq ($(target_cpu)-$(platform), sparc64-ieee1275)
grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c
@ -14,54 +15,40 @@ else
grub_mkdevicemap_SOURCES += util/devicemap.c
endif
# For grub-mkelfimage.
bin_UTILITIES += grub-mkelfimage
grub_mkelfimage_SOURCES = gnulib/progname.c \
util/elf/grub-mkimage.c util/misc.c \
util/resolve.c
util/elf/grub-mkimage.c_DEPENDENCIES = Makefile
# For grub-mkimage.
bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \
util/resolve.c kern/emu/misc.c lib/LzmaEnc.c lib/LzFind.c
util/grub-mkimage.c_DEPENDENCIES = Makefile
# For grub-probe.
sbin_UTILITIES += grub-probe
util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \
util/hostdisk.c util/misc.c util/getroot.c util/mm.c \
kern/emu/hostdisk.c util/misc.c kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c \
kern/device.c kern/disk.c kern/err.c kern/misc.c \
kern/parser.c kern/partition.c kern/file.c kern/list.c \
kern/partition.c kern/file.c kern/list.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
fs/befs.c fs/befs_be.c fs/tar.c \
fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \
fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \
fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \
\
partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
partmap/sun.c partmap/sunpc.c partmap/gpt.c \
kern/fs.c kern/env.c fs/fshelp.c \
disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
ifeq ($(enable_grub_fstest), yes)
bin_UTILITIES += grub-fstest
endif
bin_UTILITIES += grub-mkisofs
grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \
util/mkisofs/hash.c util/mkisofs/joliet.c \
util/mkisofs/match.c util/mkisofs/mkisofs.c \
util/mkisofs/multi.c util/mkisofs/name.c \
util/mkisofs/rock.c util/mkisofs/tree.c \
util/mkisofs/write.c \
\
gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \
gnulib/error.c gnulib/progname.c
grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \
-I$(srcdir)/util/mkisofs/include \
-Wno-all -Werror $(GNULIB_UTIL_CFLAGS)
# For grub-fstest.
util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
util/misc.c util/mm.c \
grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \
util/misc.c kern/emu/misc.c kern/emu/mm.c \
kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \
disk/host.c disk/loopback.c kern/list.c kern/command.c \
lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c \
@ -69,7 +56,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \
fs/befs_be.c fs/tar.c \
\
@ -83,14 +70,15 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
# For grub-mkfont.
ifeq ($(enable_grub_mkfont), yes)
bin_UTILITIES += grub-mkfont
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c
grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c \
unidata.c kern/emu/misc.c
grub_mkfont_CFLAGS = $(freetype_cflags)
grub_mkfont_LDFLAGS = $(freetype_libs)
endif
# For grub-mkrelpath.
bin_UTILITIES += grub-mkrelpath
grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c
grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c
bin_UTILITIES += grub-bin2h
grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c
@ -102,24 +90,24 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h
# For grub-script-check.
bin_UTILITIES += grub-script-check
util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h
grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \
util/grub-script-check.c util/misc.c util/mm.c \
util/grub-script-check.c util/misc.c kern/emu/misc.c kern/emu/mm.c \
script/main.c script/script.c script/function.c script/lexer.c \
kern/handler.c kern/err.c kern/parser.c kern/list.c \
kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \
kern/err.c kern/list.c \
kern/misc.c kern/env.c grub_script.tab.c \
grub_script.yy.c
grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
grub_script_check_DEPENDENCIES = grub_script.tab.h
MOSTLYCLEANFILES += symlist.c kernel_syms.lst
DEFSYMFILES += kernel_syms.lst
kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
list.h handler.h command.h i18n.h env_private.h libgcc.h
list.h command.h i18n.h env_private.h libgcc.h
ifneq ($(platform), emu)
kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h
kernel_img_HEADERS += machine/memory.h machine/loader.h
endif
symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
@ -133,19 +121,6 @@ grub_script.tab.c grub_script.tab.h: script/parser.y
$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
# For grub-script-check.
grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES))
rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
DISTCLEANFILES += grub_script_check_init.lst
grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh
rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
DISTCLEANFILES += grub_script_check_init.h
grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh
rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
DISTCLEANFILES += grub_script_check_init.c
# For grub-probe.
grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES))
rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
@ -187,7 +162,7 @@ DISTCLEANFILES += grub_fstest_init.c
# for grub-editenv
bin_UTILITIES += grub-editenv
grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c
grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c
CLEANFILES += grub-editenv
# Needed for genmk.rb to work
@ -195,7 +170,7 @@ ifeq (0,1)
bin_UTILITIES += grub-macho2img grub-pe2elf
endif
grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c
grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c kern/emu/misc.c
CLEANFILES += grub-pe2elf
grub_macho2img_SOURCES = util/grub-macho2img.c
@ -229,10 +204,13 @@ CLEANFILES += grub-gettext_lib
%: util/grub.d/%.in config.status
./config.status --file=$@:$<
chmod +x $@
grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom
grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom 41_custom
ifneq (, $(host_kernel))
grub-mkconfig_SCRIPTS += 10_$(host_kernel)
endif
ifeq (linux, $(host_kernel))
grub-mkconfig_SCRIPTS += 20_linux_xen
endif
CLEANFILES += $(grub-mkconfig_SCRIPTS)
@ -298,6 +276,12 @@ minix_mod_SOURCES = fs/minix.c
minix_mod_CFLAGS = $(COMMON_CFLAGS)
minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For nilfs2.mod.
pkglib_MODULES += nilfs2.mod
nilfs2_mod_SOURCES = fs/nilfs2.c
nilfs2_mod_CFLAGS = $(COMMON_CFLAGS)
nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For hfs.mod.
hfs_mod_SOURCES = fs/hfs.c
hfs_mod_CFLAGS = $(COMMON_CFLAGS)
@ -456,12 +440,12 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS)
scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Commands.
pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \
pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \
ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \
configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
msdospart.mod memrw.mod normal.mod sh.mod \
msdospart.mod memrw.mod normal.mod \
gptsync.mod true.mod probe.mod password.mod \
keystatus.mod
@ -508,7 +492,8 @@ gfxmenu_mod_SOURCES = \
gfxmenu/gui_progress_bar.c \
gfxmenu/gui_util.c \
gfxmenu/gui_string_util.c \
gfxmenu/named_colors.c
gfxmenu/named_colors.c \
gfxmenu/font.c
gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -522,11 +507,6 @@ msdospart_mod_SOURCES = parttool/msdospart.c
msdospart_mod_CFLAGS = $(COMMON_CFLAGS)
msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For handler.mod.
handler_mod_SOURCES = commands/handler.c
handler_mod_CFLAGS = $(COMMON_CFLAGS)
handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
ls_mod_CFLAGS = $(COMMON_CFLAGS)
@ -589,10 +569,13 @@ configfile_mod_SOURCES = commands/configfile.c
configfile_mod_CFLAGS = $(COMMON_CFLAGS)
configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifneq ($(platform), ieee1275)
# For terminfo.mod.
pkglib_MODULES += terminfo.mod
terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For blocklist.mod.
blocklist_mod_SOURCES = commands/blocklist.c
@ -645,19 +628,18 @@ keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For normal.mod.
ifneq (, $(FONT_SOURCE))
normal/charset.c_DEPENDENCIES = widthspec.h
endif
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c normal/handler.c \
normal/auth.c normal/autofs.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c \
normal/misc.c normal/crypto.c normal/term.c normal/context.c
normal_mod_CFLAGS = $(COMMON_CFLAGS)
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For sh.mod.
sh_mod_SOURCES = script/main.c script/script.c script/execute.c \
normal/menu_entry.c normal/menu_text.c normal/charset.c \
normal/misc.c normal/crypto.c normal/term.c normal/context.c \
script/main.c script/script.c script/execute.c unidata.c \
script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifneq (, $(FONT_SOURCE))
font/font.c_DEPENDENCIES = ascii.h
@ -728,7 +710,6 @@ png_mod_SOURCES = video/readers/png.c
png_mod_CFLAGS = $(COMMON_CFLAGS)
png_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Misc.
pkglib_MODULES += gzio.mod elf.mod
@ -782,11 +763,6 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += charset.mod
charset_mod_SOURCES = lib/charset.c
charset_mod_CFLAGS = $(COMMON_CFLAGS)
charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += regexp.mod
regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)
@ -855,7 +831,7 @@ boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
bin_UTILITIES += grub-mkpasswd-pbkdf2
grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c
grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c
grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1
include $(srcdir)/conf/gcry.mk

View file

@ -4,19 +4,17 @@ COMMON_CFLAGS = -mrtd -mregparm=3
# Images.
GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
pkglib_PROGRAMS += kernel.img
kernel_img_SOURCES = kern/i386/coreboot/startup.S \
kern/i386/misc.S \
kern/i386/coreboot/init.c \
kern/i386/multiboot_mmap.c \
kern/i386/coreboot/mmap.c \
kern/i386/halt.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/time.c kern/list.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
@ -26,7 +24,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \
symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in
@ -70,5 +68,11 @@ datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For cmostest.mod
pkglib_MODULES += cmostest.mod
cmostest_mod_SOURCES = commands/i386/cmostest.c
cmostest_mod_CFLAGS = $(COMMON_CFLAGS)
cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS)
include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk

View file

@ -18,13 +18,14 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
kern/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/env.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/time.c kern/list.c kern/command.c kern/corecmd.c \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
symlist.c
kernel_img_HEADERS += ieee1275/ieee1275.h
kernel_img_HEADERS += ieee1275/ieee1275.h terminfo.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic

74
conf/i386-multiboot.rmk Normal file
View file

@ -0,0 +1,74 @@
# -*- makefile -*-
COMMON_CFLAGS = -mrtd -mregparm=3
# Images.
GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
pkglib_PROGRAMS += kernel.img
kernel_img_SOURCES = kern/i386/coreboot/startup.S \
kern/i386/misc.S \
kern/i386/coreboot/init.c \
kern/i386/multiboot_mmap.c \
kern/i386/halt.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c \
kern/env.c \
term/i386/pc/vga_text.c term/i386/vga_common.c \
symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in
bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/grub-mkrescue.in
# Modules.
pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
# For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
mmap_mod_CFLAGS = $(COMMON_CFLAGS)
mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For linux.mod.
linux_mod_SOURCES = loader/i386/linux.c
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For halt.mod.
halt_mod_SOURCES = commands/halt.c
halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For aout.mod.
aout_mod_SOURCES = loader/aout.c
aout_mod_CFLAGS = $(COMMON_CFLAGS)
aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For bsd.mod
pkglib_MODULES += bsd.mod
bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
bsd_mod_CFLAGS = $(COMMON_CFLAGS)
bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For datetime.mod
datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk

View file

@ -1,12 +1,9 @@
# -*- makefile -*-
GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
COMMON_CFLAGS = -mrtd -mregparm=3
# Images.
pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
pxeboot.img
pkglib_IMAGES = boot.img cdboot.img diskboot.img lnxboot.img pxeboot.img
# For boot.img.
boot_img_SOURCES = boot/i386/pc/boot.S
@ -39,13 +36,14 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
cdboot_img_FORMAT = binary
# For kernel.img.
pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/i386/pc/startup.S \
kern/i386/misc.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/time.c kern/list.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
@ -55,42 +53,34 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
term/i386/pc/console.c term/i386/vga_common.c \
symlist.c
kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \
machine/pxe.h i386/pit.h
machine/pxe.h i386/pit.h machine/kernel.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
kernel_img_FORMAT = binary
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS)
# Utilities.
bin_UTILITIES = grub-mkimage
sbin_UTILITIES = grub-setup
# For grub-mkimage.
grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
util/grub-mkrawimage.c_DEPENDENCIES = Makefile
# For grub-setup.
util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = gnulib/progname.c \
util/i386/pc/grub-setup.c util/hostdisk.c \
util/misc.c util/getroot.c kern/device.c kern/disk.c \
kern/err.c kern/misc.c kern/parser.c kern/partition.c \
kern/file.c kern/fs.c kern/env.c kern/list.c \
fs/fshelp.c \
\
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
fs/befs.c fs/befs_be.c fs/tar.c \
\
partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \
partmap/gpt.c \
\
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
util/raid.c util/lvm.c util/mm.c \
grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \
util/misc.c kern/emu/misc.c kern/emu/getroot.c \
kern/emu/hostdisk.c kern/device.c kern/disk.c kern/err.c \
kern/misc.c kern/partition.c kern/file.c \
kern/emu/mm.c kern/fs.c kern/env.c kern/list.c fs/fshelp.c \
\
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \
fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \
fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \
\
partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \
partmap/gpt.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c \
util/raid.c util/lvm.c \
grub_setup_init.c
sbin_SCRIPTS += grub-install
@ -158,7 +148,7 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += xnu.mod
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -185,7 +175,7 @@ vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For vga.mod.
vga_mod_SOURCES = term/i386/pc/vga.c
vga_mod_SOURCES = video/i386/pc/vga.c
vga_mod_CFLAGS = $(COMMON_CFLAGS)
vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -255,6 +245,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For cmostest.mod
pkglib_MODULES += cmostest.mod
cmostest_mod_SOURCES = commands/i386/cmostest.c
cmostest_mod_CFLAGS = $(COMMON_CFLAGS)
cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifeq ($(enable_efiemu), yes)
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)

View file

@ -13,30 +13,28 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
boot_img_FORMAT = binary
bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
util/resolve.c gnulib/progname.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
util/grub-mkrawimage.c_DEPENDENCIES = Makefile
kern/i386/qemu/init.c_DEPENDENCIES = ascii.h
pkglib_IMAGES += kernel.img
pkglib_PROGRAMS += kernel.img
kernel_img_SOURCES = kern/i386/qemu/startup.S \
kern/i386/misc.S \
kern/i386/coreboot/init.c \
kern/i386/qemu/init.c \
kern/i386/qemu/mmap.c \
kern/i386/halt.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/time.c kern/list.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c \
kern/env.c \
term/i386/pc/vga_text.c term/i386/vga_common.c \
term/i386/pc/vga_text.c term/i386/vga_common.c bus/pci.c \
symlist.c
kernel_img_HEADERS += pci.h
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)

View file

@ -15,6 +15,16 @@ vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += video_cirrus.mod
video_cirrus_mod_SOURCES = video/cirrus.c
video_cirrus_mod_CFLAGS = $(COMMON_CFLAGS)
video_cirrus_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += video_bochs.mod
video_bochs_mod_SOURCES = video/bochs.c
video_bochs_mod_CFLAGS = $(COMMON_CFLAGS)
video_bochs_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
relocator_mod_CFLAGS = $(COMMON_CFLAGS)
@ -50,11 +60,20 @@ serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
# On qemu it's compiled in
ifneq ($(platform), qemu)
# For pci.mod
pkglib_MODULES += pci.mod
pci_mod_SOURCES = bus/pci.c
pci_mod_CFLAGS = $(COMMON_CFLAGS)
pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For cs5536.mod
pkglib_MODULES += cs5536.mod
cs5536_mod_SOURCES = bus/cs5536.c
cs5536_mod_CFLAGS = $(COMMON_CFLAGS)
cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lspci.mod
pkglib_MODULES += lspci.mod
@ -68,3 +87,8 @@ play_mod_SOURCES = commands/i386/pc/play.c
play_mod_CFLAGS = $(COMMON_CFLAGS)
play_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For iorw.mod.
pkglib_MODULES += iorw.mod
iorw_mod_SOURCES = commands/iorw.c
iorw_mod_CFLAGS = $(COMMON_CFLAGS)
iorw_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -5,14 +5,14 @@ COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3
include $(srcdir)/conf/mips.mk
pkglib_IMAGES = kernel.img
pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
kern/main.c kern/device.c kern/$(target_cpu)/init.c \
kern/$(target_cpu)/$(target_machine)/init.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S
@ -20,3 +20,9 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary
# For serial.mod.
pkglib_MODULES += serial.mod
serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -4,18 +4,19 @@ target_machine=yeeloong
COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3
kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h
kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \
bitmap_scale.h bufio.h cs5536.h machine/pci.h
include $(srcdir)/conf/mips.mk
pkglib_IMAGES = kernel.img
pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
kern/main.c kern/device.c kern/$(target_cpu)/init.c \
kern/$(target_cpu)/$(target_machine)/init.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \
kern/$(target_cpu)/cache.S \
@ -26,12 +27,21 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \
term/gfxterm.c commands/extcmd.c lib/arg.c \
bus/cs5536.c term/serial.c term/terminfo.c term/tparm.c \
symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
kernel_img_FORMAT = binary
pkglib_IMAGES += fwstart.img
fwstart_img_SOURCES = boot/$(target_cpu)/$(target_machine)/fwstart.S
fwstart_img_CFLAGS = $(COMMON_CFLAGS)
fwstart_img_ASFLAGS = $(COMMON_ASFLAGS)
fwstart_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic
fwstart_img_FORMAT = binary
# For ata.mod.
pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c
@ -63,11 +73,53 @@ datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lsspd.mod
pkglib_MODULES += lsspd.mod
lsspd_mod_SOURCES = commands/mips/yeeloong/lsspd.c
lsspd_mod_CFLAGS = $(COMMON_CFLAGS)
lsspd_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += linux.mod
linux_mod_SOURCES = loader/$(target_cpu)/linux.c
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For halt.mod.
pkglib_MODULES += halt.mod
halt_mod_SOURCES = commands/halt.c
halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usb.mod
pkglib_MODULES += usb.mod
usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
usb_mod_CFLAGS = $(COMMON_CFLAGS)
usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usbtest.mod
pkglib_MODULES += usbtest.mod
usbtest_mod_SOURCES = commands/usbtest.c
usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ohci.mod
pkglib_MODULES += ohci.mod
ohci_mod_SOURCES = bus/usb/ohci.c
ohci_mod_CFLAGS = $(COMMON_CFLAGS)
ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usbms.mod
pkglib_MODULES += usbms.mod
usbms_mod_SOURCES = disk/usbms.c
usbms_mod_CFLAGS = $(COMMON_CFLAGS)
usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usb_keyboard.mod
pkglib_MODULES += usb_keyboard.mod
usb_keyboard_mod_SOURCES = term/usb_keyboard.c
usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in

View file

@ -10,19 +10,6 @@ kernel_img_HEADERS += cpu/cache.h
sbin_SCRIPTS =
bin_SCRIPTS =
# For grub-mkimage.
bin_UTILITIES += grub-mkimage
grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE)
util/grub-mkrawimage.c_DEPENDENCIES = Makefile
# For serial.mod.
pkglib_MODULES += serial.mod
serial_mod_SOURCES = term/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For relocator.mod.
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S

View file

@ -13,10 +13,10 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/ieee1275/init.c \
kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \
term/ieee1275/ofconsole.c term/terminfo.c term/tparm.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \

View file

@ -5,7 +5,8 @@ COMMON_CFLAGS = -mno-app-regs
COMMON_LDFLAGS = -melf64_sparc -mno-relax
# Images.
pkglib_IMAGES = boot.img diskboot.img kernel.img
pkglib_IMAGES = boot.img diskboot.img
pkglib_PROGRAMS = kernel.img
# For boot.img.
boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
@ -25,12 +26,13 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/list.c kern/command.c kern/corecmd.c \
kern/sparc64/ieee1275/ieee1275.c \
kern/sparc64/ieee1275/init.c \
kern/ieee1275/mmap.c \
term/ieee1275/ofconsole.c \
kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/ieee1275/openfw.c term/terminfo.c term/tparm.c \
disk/ieee1275/ofdisk.c \
kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \
kern/generic/millisleep.c kern/time.c \
symlist.c kern/$(target_cpu)/cache.S
@ -40,38 +42,34 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc
kernel_img_FORMAT = binary
# Utilities.
bin_UTILITIES = grub-mkimage
sbin_UTILITIES = grub-setup grub-ofpathname
# For grub-mkimage.
grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
util/resolve.c gnulib/progname.c
# For grub-setup.
util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \
util/ieee1275/ofpath.c \
util/misc.c util/getroot.c kern/device.c kern/disk.c \
kern/err.c kern/misc.c kern/parser.c kern/partition.c \
kern/file.c kern/fs.c kern/env.c kern/list.c \
fs/fshelp.c \
\
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
fs/befs.c fs/befs_be.c fs/tar.c \
\
partmap/amiga.c partmap/apple.c partmap/msdos.c \
partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \
\
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
util/raid.c util/lvm.c util/mm.c gnulib/progname.c \
grub_setup_init.c
grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \
util/ieee1275/ofpath.c util/misc.c kern/emu/hostdisk.c \
kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c kern/device.c \
kern/disk.c kern/err.c kern/misc.c \
kern/partition.c kern/file.c kern/fs.c kern/env.c kern/list.c \
fs/fshelp.c \
\
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \
fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \
fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \
\
partmap/amiga.c partmap/apple.c partmap/msdos.c \
partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/lvm.c util/raid.c \
util/lvm.c gnulib/progname.c grub_setup_init.c
# For grub-ofpathname.
grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \
util/ieee1275/ofpath.c util/misc.c gnulib/progname.c
grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \
util/ieee1275/ofpath.c util/misc.c kern/emu/misc.c \
gnulib/progname.c
# Scripts.
sbin_SCRIPTS = grub-install

View file

@ -68,6 +68,9 @@ grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in
check_SCRIPTS += grub_script_dollar
grub_script_dollar_SOURCES = tests/grub_script_dollar.in
check_SCRIPTS += grub_script_comments
grub_script_comments_SOURCES = tests/grub_script_comments.in
# List of tests to execute on "make check"
# SCRIPTED_TESTS = example_scripted_test
# SCRIPTED_TESTS += example_grub_script_test
@ -83,6 +86,7 @@ SCRIPTED_TESTS += grub_script_if
SCRIPTED_TESTS += grub_script_blanklines
SCRIPTED_TESTS += grub_script_final_semicolon
SCRIPTED_TESTS += grub_script_dollar
SCRIPTED_TESTS += grub_script_comments
# dependencies between tests and testing-tools
$(SCRIPTED_TESTS): grub-shell grub-shell-tester

View file

@ -1,19 +1,14 @@
# -*- makefile -*-
# Utilities.
bin_UTILITIES = grub-mkimage
# For grub-mkimage.
grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \
util/misc.c util/resolve.c
util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile
# Scripts.
sbin_SCRIPTS = grub-install
# For grub-install.
grub_install_SOURCES = util/i386/efi/grub-install.in
bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/grub-mkrescue.in
# Modules.
pkglib_PROGRAMS = kernel.img
pkglib_MODULES = chain.mod appleldr.mod \
@ -30,7 +25,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c
kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/time.c kern/list.c kern/command.c kern/corecmd.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
@ -64,13 +59,17 @@ appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For linux.mod.
linux_mod_SOURCES = loader/i386/efi/linux.c
ifeq ($(target_cpu), x86_64)
linux_mod_SOURCES += loader/i386/linux_trampoline.S
endif
linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
else
linux_mod_SOURCES = loader/i386/efi/linux.c
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
endif
# For halt.mod.
halt_mod_SOURCES = commands/halt.c
@ -103,7 +102,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += xnu.mod
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \
xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -102,6 +102,7 @@ case "$target_cpu"-"$platform" in
i386-efi) ;;
x86_64-efi) ;;
i386-pc) ;;
i386-multiboot) ;;
i386-coreboot) ;;
i386-linuxbios) platform=coreboot ;;
i386-ieee1275) ;;
@ -136,6 +137,7 @@ esac
case "$platform" in
coreboot) machine_CFLAGS="-DGRUB_MACHINE_COREBOOT=1" ;;
multiboot) machine_CFLAGS="-DGRUB_MACHINE_MULTIBOOT=1" ;;
efi) machine_CFLAGS="-DGRUB_MACHINE_EFI=1" ;;
ieee1275) machine_CFLAGS="-DGRUB_MACHINE_IEEE1275=1" ;;
qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;;
@ -148,6 +150,7 @@ case "$target_cpu" in
mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;;
sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
esac
machine_CFLAGS="$machine_CFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
CFLAGS="$CFLAGS $machine_CFLAGS"
TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS"
@ -176,20 +179,30 @@ if test "x$YACC" = x; then
AC_MSG_ERROR([bison is not found])
fi
for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do
if test -e $file ; then
AC_SUBST([FONT_SOURCE], [$file])
break
fi
FONT_SOURCE=
for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do
if test -f "$dir/unifont.$ext"; then
FONT_SOURCE="$dir/unifont.$ext"
break 2
fi
done
done
if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xyeeloong ); then
AC_MSG_ERROR([qemu and yeeloong ports need unifont])
fi
AC_SUBST([FONT_SOURCE])
AC_PROG_INSTALL
AC_PROG_AWK
AC_PROG_LEX
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
if test "x$LEX" = x; then
if test "x$LEX" = "x:"; then
AC_MSG_ERROR([flex is not found])
else
version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`
@ -511,11 +524,11 @@ grub_PROG_OBJCOPY_ABSOLUTE
fi
grub_PROG_LD_BUILD_ID_NONE
if test "x$target_cpu" = xi386; then
if test ! -z "$TARGET_IMG_LDSCRIPT"; then
# Check symbols provided by linker script.
CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100"
fi
if test "x$TARGET_APPLE_CC" != x1 ; then
if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then
if test ! -z "$TARGET_IMG_LDSCRIPT"; then
# Check symbols provided by linker script.
CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100"
fi
grub_CHECK_BSS_START_SYMBOL
grub_CHECK_END_SYMBOL
fi
@ -635,6 +648,12 @@ else
fi
AC_SUBST(TARGET_NO_MODULES)
if test "$TARGET_NO_MODULES" = yes ; then
# Do not convert modules, otherwise linkage may fail (Cygwin only).
# FIXME: Should be checked above before TARGET_OBJ2ELF is set first.
TARGET_OBJ2ELF=
fi
if test x"$enable_grub_emu_usb" = xno ; then
grub_emu_usb_excuse="explicitly disabled"
fi
@ -771,6 +790,22 @@ AC_SUBST([enable_grub_mkfont])
AC_SUBST([freetype_cflags])
AC_SUBST([freetype_libs])
AC_ARG_ENABLE([device-mapper],
[AS_HELP_STRING([--enable-device-mapper],
[enable Linux device-mapper support (default=guessed)])])
if test x"$enable_device_mapper" = xno ; then
device_mapper_excuse="explicitly disabled"
fi
if test x"$device_mapper_excuse" = x ; then
# Check for device-mapper library.
AC_CHECK_LIB([devmapper], [dm_task_create],
[LDFLAGS="$LDFLAGS -ldevmapper"
AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
[Define to 1 if you have the devmapper library.])],
[device_mapper_excuse="need devmapper library"])
fi
AC_SUBST(ASFLAGS)
# Output files.

View file

@ -24,10 +24,13 @@
#include <grub/time.h>
#include <grub/pci.h>
#include <grub/scsi.h>
#include <grub/cs5536.h>
/* At the moment, only two IDE ports are supported. */
static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 };
static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1,
GRUB_ATA_CH1_PORT1 };
static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2,
GRUB_ATA_CH1_PORT2 };
static struct grub_ata_device *grub_ata_devices;
@ -331,11 +334,38 @@ grub_ata_identify (struct grub_ata_device *dev)
return 0;
}
static grub_err_t
check_device (struct grub_ata_device *dev)
{
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
grub_ata_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected");
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
return grub_ata_identify (dev);
}
static grub_err_t
grub_ata_device_initialize (int port, int device, int addr, int addr2)
{
struct grub_ata_device *dev;
struct grub_ata_device **devp;
grub_err_t err;
grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
port, device, addr, addr2);
@ -351,39 +381,14 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
dev->next = NULL;
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
grub_ata_wait ();
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
if (sec != 0x5A)
{
grub_free(dev);
return 0;
}
/* The above test may detect a second (slave) device
connected to a SATA controller which supports only one
(master) device. It is not safe to use the status register
READY bit to check for controller channel existence. Some
ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
/* Use the IDENTIFY DEVICE command to query the device. */
if (grub_ata_identify (dev))
{
grub_free (dev);
return 0;
}
/* Register the device. */
for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
*devp = dev;
err = check_device (dev);
if (err)
grub_print_error ();
return 0;
}
@ -408,7 +413,7 @@ grub_ata_pciinit (grub_pci_device_t dev,
class = grub_pci_read (addr);
/* AMD CS5536 Southbridge. */
if (pciid == 0x208f1022)
if (pciid == GRUB_CS5536_PCIID)
{
cs5536 = 1;
nports = 1;
@ -666,6 +671,14 @@ grub_ata_iterate (int (*hook) (const char *name))
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_err_t err;
err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (dev->atapi)
continue;
@ -684,6 +697,7 @@ static grub_err_t
grub_ata_open (const char *name, grub_disk_t disk)
{
struct grub_ata_device *dev;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
@ -700,6 +714,11 @@ grub_ata_open (const char *name, grub_disk_t disk)
if (dev->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
err = check_device (dev);
if (err)
return err;
disk->total_sectors = dev->size;
disk->id = (unsigned long) dev;
@ -749,20 +768,25 @@ static struct grub_disk_dev grub_atadisk_dev =
/* ATAPI code. */
static int
grub_atapi_iterate (int (*hook) (const char *name, int luns))
grub_atapi_iterate (int (*hook) (int bus, int luns))
{
struct grub_ata_device *dev;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device);
grub_err_t err;
err = check_device (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
if (! dev->atapi)
continue;
if (hook (devname, 1))
if (hook (dev->port * 2 + dev->device, 1))
return 1;
}
@ -822,46 +846,45 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
}
static grub_err_t
grub_atapi_open (const char *name, struct grub_scsi *scsi)
grub_atapi_open (int devnum, struct grub_scsi *scsi)
{
struct grub_ata_device *dev;
struct grub_ata_device *devfnd = 0;
grub_err_t err;
for (dev = grub_ata_devices; dev; dev = dev->next)
{
char devname[10];
grub_snprintf (devname, sizeof (devname),
"ata%d", dev->port * 2 + dev->device);
if (!grub_strcmp (devname, name))
if (dev->port * 2 + dev->device == devnum)
{
devfnd = dev;
break;
}
}
grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
grub_dprintf ("ata", "opening ATAPI dev `ata%d'\n", devnum);
if (! devfnd)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
err = check_device (devfnd);
if (err)
return err;
if (! devfnd->atapi)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
scsi->data = devfnd;
return GRUB_ERR_NONE;
}
static void
grub_atapi_close (struct grub_scsi *scsi)
{
grub_free (scsi->name);
}
static struct grub_scsi_dev grub_atapi_dev =
{
.name = "ATAPI",
.name = "ata",
.id = GRUB_SCSI_SUBSYSTEM_ATAPI,
.iterate = grub_atapi_iterate,
.open = grub_atapi_open,
.close = grub_atapi_close,
.read = grub_atapi_read,
.write = grub_atapi_write
};

View file

@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
{
data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
data->sectors = 32;
total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */
/* TODO: get the correct size. */
total_sectors = GRUB_DISK_SIZE_UNKNOWN;
}
else if (drive & 0x80)
{

View file

@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
/* 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. */
disk->total_sectors = 0xFFFFFFFFUL;
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
disk->id = (unsigned long) op;

View file

@ -25,7 +25,7 @@
#include <grub/lvm.h>
#ifdef GRUB_UTIL
#include <grub/util/misc.h>
#include <grub/emu/misc.h>
#endif
static struct grub_lvm_vg *vg_list;
@ -45,6 +45,52 @@ grub_lvm_getvalue (char **p, char *str)
return grub_strtoul (*p, NULL, 10);
}
static int
grub_lvm_checkvalue (char **p, char *str, char *tmpl)
{
int tmpllen = grub_strlen (tmpl);
*p = grub_strstr (*p, str);
if (! *p)
return 0;
*p += grub_strlen (str);
if (**p != '"')
return 0;
return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"');
}
static int
grub_lvm_check_flag (char *p, char *str, char *flag)
{
int len_str = grub_strlen (str), len_flag = grub_strlen (flag);
while (1)
{
char *q;
p = grub_strstr (p, str);
if (! p)
return 0;
p += len_str;
if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0)
continue;
q = p + sizeof (" = [") - 1;
while (1)
{
while (grub_isspace (*q))
q++;
if (*q != '"')
return 0;
q++;
if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"')
return 1;
while (*q != '"')
q++;
q++;
if (*q == ']')
return 0;
q++;
}
}
}
static int
grub_lvm_iterate (int (*hook) (const char *name))
{
@ -421,6 +467,7 @@ grub_lvm_scan_device (const char *name)
while (1)
{
int s;
int skip_lv = 0;
struct grub_lvm_lv *lv;
struct grub_lvm_segment *seg;
@ -445,6 +492,12 @@ grub_lvm_scan_device (const char *name)
lv->size = 0;
if (!grub_lvm_check_flag (p, "status", "VISIBLE"))
{
skip_lv = 1;
goto lv_parsed;
}
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
if (p == NULL)
goto lvs_fail;
@ -465,6 +518,14 @@ grub_lvm_scan_device (const char *name)
seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
if (p == NULL)
goto lvs_segment_fail;
if (grub_lvm_checkvalue (&p, "type = ", "snapshot"))
{
/* Found a snapshot, give up and move on. */
skip_lv = 1;
break;
}
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
if (p == NULL)
goto lvs_segment_fail;
@ -531,12 +592,20 @@ grub_lvm_scan_device (const char *name)
goto fail4;
}
lv_parsed:
if (p != NULL)
p = grub_strchr (p, '}');
if (p == NULL)
goto lvs_fail;
p += 3;
if (skip_lv)
{
grub_free (lv->name);
grub_free (lv);
continue;
}
lv->number = lv_count++;
lv->vg = vg;
lv->next = vg->lvs;

View file

@ -25,6 +25,7 @@
#include <grub/types.h>
#include <grub/scsi.h>
#include <grub/scsicmd.h>
#include <grub/time.h>
static grub_scsi_dev_t grub_scsi_dev_list;
@ -50,7 +51,62 @@ grub_scsi_dev_unregister (grub_scsi_dev_t dev)
}
/* Determine the the device is removable and the type of the device
/* Check result of previous operation. */
static grub_err_t
grub_scsi_request_sense (grub_scsi_t scsi)
{
struct grub_scsi_request_sense rs;
struct grub_scsi_request_sense_data rsd;
grub_err_t err;
rs.opcode = grub_scsi_cmd_request_sense;
rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
rs.reserved1 = 0;
rs.reserved2 = 0;
rs.alloc_length = 0x12; /* XXX: Hardcoded for now */
rs.control = 0;
grub_memset (rs.pad, 0, sizeof(rs.pad));
err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs,
sizeof (rsd), (char *) &rsd);
if (err)
return err;
return GRUB_ERR_NONE;
}
/* Self commenting... */
static grub_err_t
grub_scsi_test_unit_ready (grub_scsi_t scsi)
{
struct grub_scsi_test_unit_ready tur;
grub_err_t err;
grub_err_t err_sense;
tur.opcode = grub_scsi_cmd_test_unit_ready;
tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
tur.reserved1 = 0;
tur.reserved2 = 0;
tur.reserved3 = 0;
tur.control = 0;
grub_memset (tur.pad, 0, sizeof(tur.pad));
err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur,
0, NULL);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err)
return err;
return GRUB_ERR_NONE;
}
/* Determine if the device is removable and the type of the device
SCSI. */
static grub_err_t
grub_scsi_inquiry (grub_scsi_t scsi)
@ -58,15 +114,26 @@ grub_scsi_inquiry (grub_scsi_t scsi)
struct grub_scsi_inquiry iq;
struct grub_scsi_inquiry_data iqd;
grub_err_t err;
grub_err_t err_sense;
iq.opcode = grub_scsi_cmd_inquiry;
iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
iq.page = 0;
iq.reserved = 0;
iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
iq.reserved2 = 0;
iq.control = 0;
grub_memset (iq.pad, 0, sizeof(iq.pad));
err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
sizeof (iqd), (char *) &iqd);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err)
return err;
@ -83,13 +150,27 @@ grub_scsi_read_capacity (grub_scsi_t scsi)
struct grub_scsi_read_capacity rc;
struct grub_scsi_read_capacity_data rcd;
grub_err_t err;
grub_err_t err_sense;
rc.opcode = grub_scsi_cmd_read_capacity;
rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
grub_memset (rc.reserved, 0, sizeof (rc.reserved));
rc.logical_block_addr = 0;
rc.reserved1 = 0;
rc.reserved2 = 0;
rc.PMI = 0;
rc.control = 0;
rc.pad = 0;
err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
sizeof (rcd), (char *) &rcd);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err)
return err;
@ -107,6 +188,8 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
{
grub_scsi_t scsi;
struct grub_scsi_read10 rd;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data;
@ -118,7 +201,16 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
rd.reserved2 = 0;
rd.pad = 0;
return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
}
/* Send a SCSI request for DISK: read SIZE sectors starting with
@ -129,6 +221,8 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
{
grub_scsi_t scsi;
struct grub_scsi_read12 rd;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data;
@ -139,7 +233,16 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
rd.reserved = 0;
rd.control = 0;
return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
}
#if 0
@ -151,6 +254,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
{
grub_scsi_t scsi;
struct grub_scsi_write10 wr;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data;
@ -162,7 +267,16 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
wr.reserved2 = 0;
wr.pad = 0;
return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
}
/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
@ -172,7 +286,9 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
grub_scsi_t scsi;
struct grub_scsi_write10 wr;
struct grub_scsi_write12 wr;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data;
@ -181,9 +297,18 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
wr.lba = grub_cpu_to_be32 (sector);
wr.size = grub_cpu_to_be32 (size);
wr.reserved = 0;
wr.pad = 0;
wr.control = 0;
return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
}
#endif
@ -193,15 +318,24 @@ grub_scsi_iterate (int (*hook) (const char *name))
{
grub_scsi_dev_t p;
auto int scsi_iterate (const char *name, int luns);
auto int scsi_iterate (int bus, int luns);
int scsi_iterate (const char *name, int luns)
int scsi_iterate (int bus, int luns)
{
int i;
/* In case of a single LUN, just return `usbX'. */
if (luns == 1)
return hook (name);
{
char *sname;
int ret;
sname = grub_xasprintf ("%s%d", p->name, bus);
if (!sname)
return 1;
ret = hook (sname);
grub_free (sname);
return ret;
}
/* In case of multiple LUNs, every LUN will get a prefix to
distinguish it. */
@ -209,7 +343,7 @@ grub_scsi_iterate (int (*hook) (const char *name))
{
char *sname;
int ret;
sname = grub_xasprintf ("%s%c", name, 'a' + i);
sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i);
if (!sname)
return 1;
ret = hook (sname);
@ -233,36 +367,46 @@ grub_scsi_open (const char *name, grub_disk_t disk)
grub_scsi_dev_t p;
grub_scsi_t scsi;
grub_err_t err;
int len;
int lun;
int lun, bus;
grub_uint64_t maxtime;
const char *nameend;
nameend = name + grub_strlen (name) - 1;
/* Try to detect a LUN ('a'-'z'), otherwise just use the first
LUN. */
if (nameend >= name && *nameend >= 'a' && *nameend <= 'z')
{
lun = *nameend - 'a';
nameend--;
}
else
lun = 0;
while (nameend >= name && grub_isdigit (*nameend))
nameend--;
if (!nameend[1] || !grub_isdigit (nameend[1]))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
bus = grub_strtoul (nameend + 1, 0, 0);
scsi = grub_malloc (sizeof (*scsi));
if (! scsi)
return grub_errno;
len = grub_strlen (name);
lun = name[len - 1] - 'a';
/* Try to detect a LUN ('a'-'z'), otherwise just use the first
LUN. */
if (lun < 0 || lun > 26)
lun = 0;
for (p = grub_scsi_dev_list; p; p = p->next)
{
if (p->open (name, scsi))
if (grub_strncmp (p->name, name, nameend - name) != 0)
continue;
disk->id = (unsigned long) "scsi"; /* XXX */
if (p->open (bus, scsi))
continue;
disk->id = grub_make_scsi_id (p->id, bus, lun);
disk->data = scsi;
scsi->dev = p;
scsi->lun = lun;
scsi->name = grub_strdup (name);
if (! scsi->name)
{
grub_free (scsi);
return grub_errno;
}
scsi->bus = bus;
grub_dprintf ("scsi", "dev opened\n");
@ -292,6 +436,31 @@ grub_scsi_open (const char *name, grub_disk_t disk)
else
disk->has_partitions = 1;
/* According to USB MS tests specification, issue Test Unit Ready
* until OK */
maxtime = grub_get_time_ms () + 5000; /* It is safer value */
do
{
/* Timeout is necessary - for example in case when we have
* universal card reader with more LUNs and we have only
* one card inserted (or none), so only one LUN (or none)
* will be ready - and we want not to hang... */
if (grub_get_time_ms () > maxtime)
{
err = GRUB_ERR_READ_ERROR;
grub_free (scsi);
grub_dprintf ("scsi", "LUN is not ready - timeout\n");
return err;
}
err = grub_scsi_test_unit_ready (scsi);
}
while (err == GRUB_ERR_READ_ERROR);
/* Reset grub_errno !
* It is set to some error code in loop before... */
grub_errno = GRUB_ERR_NONE;
/* Read capacity of media */
err = grub_scsi_read_capacity (scsi);
if (err)
{
@ -302,12 +471,14 @@ grub_scsi_open (const char *name, grub_disk_t disk)
/* SCSI blocks can be something else than 512, although GRUB
wants 512 byte blocks. */
disk->total_sectors = ((scsi->size * scsi->blocksize)
<< GRUB_DISK_SECTOR_BITS);
disk->total_sectors = ((grub_uint64_t)scsi->size
* (grub_uint64_t)scsi->blocksize)
>> GRUB_DISK_SECTOR_BITS;
grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n",
(unsigned long long) disk->total_sectors,
scsi->blocksize);
grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n",
scsi->size, scsi->blocksize);
grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n",
(unsigned long long) disk->total_sectors);
return GRUB_ERR_NONE;
}
@ -323,7 +494,8 @@ grub_scsi_close (grub_disk_t disk)
grub_scsi_t scsi;
scsi = disk->data;
scsi->dev->close (scsi);
if (scsi->dev->close)
scsi->dev->close (scsi);
grub_free (scsi);
}
@ -366,6 +538,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
/* XXX: Never reached. */
return GRUB_ERR_NONE;
#if 0 /* Workaround - it works - but very slowly, from some reason
* unknown to me (specially on OHCI). Do not use it. */
/* Split transfer requests to device sector size because */
/* some devices are not able to transfer more than 512-1024 bytes */
grub_err_t err = GRUB_ERR_NONE;
for ( ; size; size--)
{
/* Depending on the type, select a read function. */
switch (scsi->devtype)
{
case grub_scsi_devtype_direct:
err = grub_scsi_read10 (disk, sector, 1, buf);
break;
case grub_scsi_devtype_cdrom:
err = grub_scsi_read12 (disk, sector, 1, buf);
break;
default: /* This should not happen */
return GRUB_ERR_READ_ERROR;
}
if (err)
return err;
sector++;
buf += scsi->blocksize;
}
return err;
#endif
}
static grub_err_t

View file

@ -52,20 +52,19 @@ struct grub_usbms_dev
int luns;
int config;
int interface;
struct grub_usb_desc_endp *in;
struct grub_usb_desc_endp *out;
int in_maxsz;
int out_maxsz;
struct grub_usbms_dev *next;
};
typedef struct grub_usbms_dev *grub_usbms_dev_t;
static grub_usbms_dev_t grub_usbms_dev_list;
static int devcnt;
/* FIXME: remove limit. */
#define MAX_USBMS_DEVICES 128
static grub_usbms_dev_t grub_usbms_devices[MAX_USBMS_DEVICES];
static grub_err_t
grub_usbms_reset (grub_usb_device_t dev, int interface)
@ -74,143 +73,150 @@ grub_usbms_reset (grub_usb_device_t dev, int interface)
}
static void
grub_usbms_finddevs (void)
grub_usbms_detach (grub_usb_device_t usbdev, int config, int interface)
{
auto int usb_iterate (grub_usb_device_t dev);
unsigned i;
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (grub_usbms_devices[i] && grub_usbms_devices[i]->dev == usbdev
&& grub_usbms_devices[i]->interface == interface
&& grub_usbms_devices[i]->config == config)
{
grub_free (grub_usbms_devices[i]);
grub_usbms_devices[i] = 0;
}
}
int usb_iterate (grub_usb_device_t usbdev)
static int
grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
{
struct grub_usb_desc_if *interf
= usbdev->config[configno].interf[interfno].descif;
int j;
grub_uint8_t luns = 0;
unsigned curnum;
grub_usb_err_t err;
for (curnum = 0; curnum < ARRAY_SIZE (grub_usbms_devices); curnum++)
if (!grub_usbms_devices[curnum])
break;
if (curnum == ARRAY_SIZE (grub_usbms_devices))
return 0;
interf = usbdev->config[configno].interf[interfno].descif;
if ((interf->subclass != GRUB_USBMS_SUBCLASS_BULK
/* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */
&& interf->subclass != GRUB_USBMS_SUBCLASS_RBC
&& interf->subclass != GRUB_USBMS_SUBCLASS_MMC2
&& interf->subclass != GRUB_USBMS_SUBCLASS_UFI
&& interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 )
|| interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
return 0;
grub_usbms_devices[curnum] = grub_zalloc (sizeof (struct grub_usbms_dev));
if (! grub_usbms_devices[curnum])
return 0;
grub_usbms_devices[curnum]->dev = usbdev;
grub_usbms_devices[curnum]->interface = interfno;
grub_dprintf ("usbms", "alive\n");
/* Iterate over all endpoints of this interface, at least a
IN and OUT bulk endpoint are required. */
for (j = 0; j < interf->endpointcnt; j++)
{
grub_usb_err_t err;
struct grub_usb_desc_device *descdev = &usbdev->descdev;
int i;
struct grub_usb_desc_endp *endp;
endp = &usbdev->config[0].interf[interfno].descendp[j];
if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0)
return 0;
/* XXX: Just check configuration 0 for now. */
for (i = 0; i < usbdev->config[0].descconf->numif; i++)
if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{
struct grub_usbms_dev *usbms;
struct grub_usb_desc_if *interf;
int j;
grub_uint8_t luns;
interf = usbdev->config[0].interf[i].descif;
/* If this is not a USB Mass Storage device with a supported
protocol, just skip it. */
if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
|| interf->subclass != GRUB_USBMS_SUBCLASS_BULK
|| interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
{
continue;
}
devcnt++;
usbms = grub_zalloc (sizeof (struct grub_usbms_dev));
if (! usbms)
return 1;
usbms->dev = usbdev;
usbms->interface = i;
/* Iterate over all endpoints of this interface, at least a
IN and OUT bulk endpoint are required. */
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 & 128) && (endp->attrib & 3) == 2)
{
/* Bulk IN endpoint. */
usbms->in = endp;
grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
usbms->in_maxsz = endp->maxpacket;
}
else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{
/* Bulk OUT endpoint. */
usbms->out = endp;
grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
usbms->out_maxsz = endp->maxpacket;
}
}
if (!usbms->in || !usbms->out)
{
grub_free (usbms);
return 0;
}
/* Query the amount of LUNs. */
err = grub_usb_control_msg (usbdev, 0xA1, 254,
0, i, 1, (char *) &luns);
if (err)
{
/* In case of a stall, clear the stall. */
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3);
grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3);
}
/* Just set the amount of LUNs to one. */
grub_errno = GRUB_ERR_NONE;
usbms->luns = 1;
}
else
usbms->luns = luns;
/* XXX: Check the magic values, does this really make
sense? */
grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
0, i, 0, 0);
/* XXX: To make Qemu work? */
if (usbms->luns == 0)
usbms->luns = 1;
usbms->next = grub_usbms_dev_list;
grub_usbms_dev_list = usbms;
/* XXX: Activate the first configuration. */
grub_usb_set_configuration (usbdev, 1);
/* Bulk-Only Mass Storage Reset, after the reset commands
will be accepted. */
grub_usbms_reset (usbdev, i);
return 0;
/* Bulk IN endpoint. */
grub_usbms_devices[curnum]->in = endp;
/* Clear Halt is not possible yet! */
/* grub_usb_clear_halt (usbdev, endp->endp_addr); */
grub_usbms_devices[curnum]->in_maxsz = endp->maxpacket;
}
else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{
/* Bulk OUT endpoint. */
grub_usbms_devices[curnum]->out = endp;
/* Clear Halt is not possible yet! */
/* grub_usb_clear_halt (usbdev, endp->endp_addr); */
grub_usbms_devices[curnum]->out_maxsz = endp->maxpacket;
}
}
if (!grub_usbms_devices[curnum]->in || !grub_usbms_devices[curnum]->out)
{
grub_free (grub_usbms_devices[curnum]);
grub_usbms_devices[curnum] = 0;
return 0;
}
grub_usb_iterate (usb_iterate);
grub_dprintf ("usbms", "alive\n");
/* XXX: Activate the first configuration. */
grub_usb_set_configuration (usbdev, 1);
/* Query the amount of LUNs. */
err = grub_usb_control_msg (usbdev, 0xA1, 254, 0, interfno, 1, (char *) &luns);
if (err)
{
/* In case of a stall, clear the stall. */
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->in->endp_addr);
grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->out->endp_addr);
}
/* Just set the amount of LUNs to one. */
grub_errno = GRUB_ERR_NONE;
grub_usbms_devices[curnum]->luns = 1;
}
else
/* luns = 0 means one LUN with ID 0 present ! */
/* We get from device not number of LUNs but highest
* LUN number. LUNs are numbered from 0,
* i.e. number of LUNs is luns+1 ! */
grub_usbms_devices[curnum]->luns = luns + 1;
grub_dprintf ("usbms", "alive\n");
usbdev->config[configno].interf[interfno].detach_hook = grub_usbms_detach;
#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...
* Bulk only mass storage reset procedure should be used only
* on place and in time when it is really necessary. */
/* Reset recovery procedure */
/* Bulk-Only Mass Storage Reset, after the reset commands
will be accepted. */
grub_usbms_reset (usbdev, i);
grub_usb_clear_halt (usbdev, usbms->in->endp_addr);
grub_usb_clear_halt (usbdev, usbms->out->endp_addr);
#endif
return 1;
}
static int
grub_usbms_iterate (int (*hook) (const char *name, int luns))
grub_usbms_iterate (int (*hook) (int bus, int luns))
{
grub_usbms_dev_t p;
int cnt = 0;
unsigned i;
for (p = grub_usbms_dev_list; p; p = p->next)
{
char *devname;
devname = grub_xasprintf ("usb%d", cnt);
grub_usb_poll_devices ();
if (hook (devname, p->luns))
{
grub_free (devname);
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
if (grub_usbms_devices[i])
{
if (hook (i, grub_usbms_devices[i]->luns))
return 1;
}
grub_free (devname);
cnt++;
}
}
return 0;
}
@ -224,6 +230,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
struct grub_usbms_csw status;
static grub_uint32_t tag = 0;
grub_usb_err_t err = GRUB_USB_ERR_NONE;
grub_usb_err_t errCSW = GRUB_USB_ERR_NONE;
int retrycnt = 3 + 1;
retry:
@ -237,73 +244,112 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
cbw.tag = tag++;
cbw.transfer_length = grub_cpu_to_le32 (size);
cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
cbw.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */
cbw.length = cmdsize;
grub_memcpy (cbw.cbwcb, cmd, cmdsize);
/* Write the request. */
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15,
/* Debug print of CBW content. */
grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n",
cbw.signature, cbw.tag, cbw.transfer_length);
grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n",
cbw.flags, cbw.lun, cbw.length);
grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3],
cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7],
cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11],
cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]);
/* Write the request.
* XXX: Error recovery is maybe still not fully correct. */
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr,
sizeof (cbw), (char *) &cbw);
if (err)
{
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto retry;
goto CheckCSW;
}
return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
}
/* Read/write the data. */
if (read_write == 0)
/* Read/write the data, (maybe) according to specification. */
if (size && (read_write == 0))
{
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf);
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf);
grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
if (err)
{
if (err == GRUB_USB_ERR_STALL)
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
goto CheckCSW;
}
/* Debug print of received data. */
grub_dprintf ("usb", "buf:\n");
if (size <= 64)
{
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
goto retry;
}
return grub_error (GRUB_ERR_READ_ERROR,
"can't read from USB Mass Storage device");
unsigned i;
for (i = 0; i < size; i++)
grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]);
}
else
grub_dprintf ("usb", "Too much data for debug print...\n");
}
else
else if (size)
{
err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, 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],
buf[ 4], buf[ 5], buf[ 6], buf[ 7],
buf[ 8], buf[ 9], buf[10], buf[11],
buf[12], buf[13], buf[14], buf[15]);
if (err)
{
if (err == GRUB_USB_ERR_STALL)
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto CheckCSW;
}
/* Debug print of sent data. */
if (size <= 256)
{
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto retry;
}
return grub_error (GRUB_ERR_WRITE_ERROR,
"can't write to USB Mass Storage device");
unsigned i;
for (i=0; i<size; i++)
grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]);
}
else
grub_dprintf ("usb", "Too much data for debug print...\n");
}
/* Read the status. */
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15,
sizeof (status), (char *) &status);
if (err)
/* Read the status - (maybe) according to specification. */
CheckCSW:
errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
sizeof (status), (char *) &status);
if (errCSW)
{
if (err == GRUB_USB_ERR_STALL)
{
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
sizeof (status), (char *) &status);
if (errCSW)
{ /* Bulk-only reset device. */
grub_dprintf ("usb", "Bulk-only reset device - errCSW\n");
grub_usbms_reset (dev->dev, dev->interface);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto retry;
}
return grub_error (GRUB_ERR_READ_ERROR,
"can't read status from USB Mass Storage device");
}
}
/* XXX: Magic and check this code. */
if (status.status == 2)
{
/* XXX: Phase error, reset device. */
/* Debug print of CSW content. */
grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n",
status.signature, status.tag, status.residue);
grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status);
/* If phase error or not valid signature, do bulk-only reset device. */
if ((status.status == 2) ||
(status.signature != grub_cpu_to_le32(0x53425355)))
{ /* Bulk-only reset device. */
grub_dprintf ("usb", "Bulk-only reset device - bad status\n");
grub_usbms_reset (dev->dev, dev->interface);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
@ -311,9 +357,13 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
goto retry;
}
if (status.status)
/* If "command failed" status or data transfer failed -> error */
if ((status.status || err) && !read_write)
return grub_error (GRUB_ERR_READ_ERROR,
"error communication with USB Mass Storage device");
else if ((status.status || err) && read_write)
return grub_error (GRUB_ERR_WRITE_ERROR,
"error communication with USB Mass Storage device");
return GRUB_ERR_NONE;
}
@ -334,61 +384,52 @@ grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
}
static grub_err_t
grub_usbms_open (const char *name, struct grub_scsi *scsi)
grub_usbms_open (int devnum, struct grub_scsi *scsi)
{
grub_usbms_dev_t p;
int devnum;
int i = 0;
grub_usb_poll_devices ();
if (grub_strncmp (name, "usb", 3))
if (!grub_usbms_devices[devnum])
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"not a USB Mass Storage device");
"unknown USB Mass Storage device");
devnum = grub_strtoul (name + 3, NULL, 10);
for (p = grub_usbms_dev_list; p; p = p->next)
{
/* Check if this is the devnumth device. */
if (devnum == i)
{
scsi->data = p;
scsi->name = grub_strdup (name);
scsi->luns = p->luns;
if (! scsi->name)
return grub_errno;
scsi->data = grub_usbms_devices[devnum];
scsi->luns = grub_usbms_devices[devnum]->luns;
return GRUB_ERR_NONE;
}
i++;
}
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"not a USB Mass Storage device");
}
static void
grub_usbms_close (struct grub_scsi *scsi)
{
grub_free (scsi->name);
return GRUB_ERR_NONE;
}
static struct grub_scsi_dev grub_usbms_dev =
{
.name = "usb",
.id = GRUB_SCSI_SUBSYSTEM_USBMS,
.iterate = grub_usbms_iterate,
.open = grub_usbms_open,
.close = grub_usbms_close,
.read = grub_usbms_read,
.write = grub_usbms_write
};
struct grub_usb_attach_desc attach_hook =
{
.class = GRUB_USB_CLASS_MASS_STORAGE,
.hook = grub_usbms_attach
};
GRUB_MOD_INIT(usbms)
{
grub_usbms_finddevs ();
grub_usb_register_attach_hook_class (&attach_hook);
grub_scsi_dev_register (&grub_usbms_dev);
}
GRUB_MOD_FINI(usbms)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
{
grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config]
.interf[grub_usbms_devices[i]->interface].detach_hook = 0;
grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config]
.interf[grub_usbms_devices[i]->interface].attached = 0;
}
grub_usb_unregister_attach_hook_class (&attach_hook);
grub_scsi_dev_unregister (&grub_usbms_dev);
}

File diff suppressed because it is too large Load diff

2
docs/man/grub-bin2h.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-bin2h \- convert a binary file to a C header

View file

@ -0,0 +1,2 @@
[NAME]
grub-editenv \- edit GRUB environment block

2
docs/man/grub-emu.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-emu \- GRUB emulator

2
docs/man/grub-fstest.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-fstest \- debug tool for GRUB filesystem drivers

View file

@ -0,0 +1,2 @@
[NAME]
grub-install \- install GRUB to a device

View file

@ -0,0 +1,2 @@
[NAME]
grub-macho2img \- convert Mach-O to raw image

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkconfig \- generate a GRUB configuration file

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkdevicemap \- generate a GRUB device map file automatically

2
docs/man/grub-mkfont.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-mkfont \- make GRUB font files

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkimage \- make a bootable image of GRUB

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkrelpath \- make a system path relative to its root

View file

@ -0,0 +1,2 @@
[NAME]
grub-mkrescue \- make a GRUB rescue image

View file

@ -0,0 +1,2 @@
[NAME]
grub-ofpathname \- find OpenBOOT path for a device

2
docs/man/grub-pe2elf.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-pe2elf \- convert PE image to ELF

2
docs/man/grub-probe.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-probe \- probe device information for GRUB

2
docs/man/grub-reboot.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-reboot \- set the default boot entry for GRUB, for the next boot only

View file

@ -0,0 +1,2 @@
[NAME]
grub-script-check \- check grub.cfg for syntax errors

View file

@ -0,0 +1,2 @@
[NAME]
grub-set-default \- set the default boot entry for GRUB

2
docs/man/grub-setup.h2m Normal file
View file

@ -0,0 +1,2 @@
[NAME]
grub-setup \- set up a device to boot using GRUB

View file

@ -31,6 +31,7 @@
#include <grub/efiemu/efiemu.h>
#include <grub/machine/efiemu.h>
#include <grub/command.h>
#include <grub/i18n.h>
/* System table. Two version depending on mode */
grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
@ -327,15 +328,15 @@ GRUB_MOD_INIT(efiemu)
{
cmd_loadcore = grub_register_command ("efiemu_loadcore",
grub_cmd_efiemu_load,
"FILE",
"Load and initialize EFI emulator.");
N_("FILE"),
N_("Load and initialize EFI emulator."));
cmd_prepare = grub_register_command ("efiemu_prepare",
grub_cmd_efiemu_prepare,
0,
"Finalize loading of EFI emulator.");
N_("Finalize loading of EFI emulator."));
cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
0,
"Unload EFI emulator.");
N_("Unload EFI emulator."));
}
GRUB_MOD_FINI(efiemu)

View file

@ -26,6 +26,8 @@
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
#ifdef USE_ASCII_FAILBACK
@ -92,7 +94,7 @@ struct font_file_section
/* Replace unknown glyphs with a rounded question mark. */
static grub_uint8_t unknown_glyph_bitmap[] = {
/* 76543210 */
/* 76543210 */
0x7C, /* ooooo */
0x82, /* o o */
0xBA, /* o ooo o */
@ -133,7 +135,7 @@ ascii_glyph_lookup (grub_uint32_t code)
static int ascii_failback_initialized = 0;
if (code >= 0x80)
return unknown_glyph;
return NULL;
if (ascii_failback_initialized == 0)
{
@ -148,9 +150,10 @@ ascii_glyph_lookup (grub_uint32_t code)
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
ascii_font_glyph[current]->font = NULL;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE);
}
@ -160,7 +163,7 @@ ascii_glyph_lookup (grub_uint32_t code)
return ascii_font_glyph[code];
#else
(void) code;
return unknown_glyph;
return NULL;
#endif
}
@ -900,6 +903,13 @@ grub_font_get_descent (grub_font_t font)
return font->descent;
}
/* FIXME: not correct for all fonts. */
int
grub_font_get_xheight (grub_font_t font)
{
return font->ascent / 2;
}
/* Get the *standard leading* of the font in pixel, which is the spacing
between two lines of text. Specifically, it is the space between the
descent of one line and the ascent of the next line. This is included
@ -917,27 +927,6 @@ grub_font_get_height (grub_font_t font)
return font->ascent + font->descent + font->leading;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, width = 0;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
width += glyph->device_width;
}
return width;
}
/* Get the glyph for FONT corresponding to the Unicode code point CODE.
Returns the ASCII glyph for the code if no other fonts are available.
The glyphs are cached once loaded. */
@ -1029,6 +1018,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
next = node->next;
glyph = grub_font_get_glyph_internal (curfont, code);
if (glyph && !font)
return glyph;
if (glyph)
{
int d;
@ -1042,13 +1033,457 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
}
}
if (best_glyph)
return best_glyph;
else
/* Glyph not available in any font. Return ASCII failback. */
return ascii_glyph_lookup (code);
return best_glyph;
}
static struct grub_font_glyph *
grub_font_dup_glyph (struct grub_font_glyph *glyph)
{
static struct grub_font_glyph *ret;
ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
if (!ret)
return NULL;
grub_memcpy (ret, glyph, sizeof (*ret)
+ (glyph->width * glyph->height + 7) / 8);
return ret;
}
/* FIXME: suboptimal. */
static void
grub_font_blit_glyph (struct grub_font_glyph *target,
struct grub_font_glyph *src, unsigned dx, unsigned dy)
{
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i) % 8;
src_byte = (src->width * i) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit++;
tgt_bit++;
if (src_bit == 8)
{
src_byte++;
src_bit = 0;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
struct grub_font_glyph *src,
unsigned dx, unsigned dy)
{
unsigned tgt_bit, src_byte, tgt_byte;
signed src_bit;
unsigned i, j;
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i + src->width - 1) % 8;
src_byte = (src->width * i + src->width - 1) / 8;
tgt_bit = (target->width * (dy + i) + dx) % 8;
tgt_byte = (target->width * (dy + i) + dx) / 8;
for (j = 0; j < src->width; j++)
{
target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
& 0x80) >> tgt_bit;
src_bit--;
tgt_bit++;
if (src_bit == -1)
{
src_byte--;
src_bit = 7;
}
if (tgt_bit == 8)
{
tgt_byte++;
tgt_bit = 0;
}
}
}
}
static void
blit_comb (const struct grub_unicode_glyph *glyph_id,
struct grub_font_glyph *glyph,
struct grub_video_signed_rect *bounds_out,
struct grub_font_glyph *main_glyph,
struct grub_font_glyph **combining_glyphs, int *device_width)
{
struct grub_video_signed_rect bounds;
unsigned i;
signed above_rightx, above_righty;
signed above_leftx, above_lefty;
signed below_rightx, below_righty;
signed min_devwidth = 0;
auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy);
void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
signed dx, signed dy)
{
if (glyph)
grub_font_blit_glyph (glyph, src, dx - glyph->offset_x,
(glyph->height + glyph->offset_y) + dy);
if (dx < bounds.x)
{
bounds.width += bounds.x - dx;
bounds.x = dx;
}
if (bounds.y > -src->height - dy)
{
bounds.height += bounds.y - (-src->height - dy);
bounds.y = (-src->height - dy);
}
if (dx + src->width - bounds.x >= (signed) bounds.width)
bounds.width = dx + src->width - bounds.x + 1;
if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y)
bounds.height = src->height + (-src->height - dy) - bounds.y;
}
auto void add_device_width (int val);
void add_device_width (int val)
{
if (glyph)
glyph->device_width += val;
if (device_width)
*device_width += val;
}
if (glyph)
glyph->device_width = main_glyph->device_width;
if (device_width)
*device_width = main_glyph->device_width;
bounds.x = main_glyph->offset_x;
bounds.y = main_glyph->offset_y;
bounds.width = main_glyph->width;
bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
above_righty = bounds.y + bounds.height;
above_leftx = main_glyph->offset_x;
above_lefty = bounds.y + bounds.height;
below_rightx = bounds.x + bounds.width;
below_righty = bounds.y;
for (i = 0; i < glyph_id->ncomb; i++)
{
grub_int16_t space = 0;
/* Center by default. */
grub_int16_t targetx;
if (!combining_glyphs[i])
continue;
targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
continue;
switch (glyph_id->combining[i].type)
{
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
(bounds.height - combining_glyphs[i]->height) / 2
- (bounds.height + bounds.y));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx, -above_righty);
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_RIGHT:
do_blit (combining_glyphs[i], above_rightx,
-(above_righty + combining_glyphs[i]->height));
above_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_ABOVE_LEFT:
above_leftx -= combining_glyphs[i]->width;
do_blit (combining_glyphs[i], above_leftx,
-(above_lefty + combining_glyphs[i]->height));
break;
case GRUB_UNICODE_COMB_BELOW_RIGHT:
do_blit (combining_glyphs[i], below_rightx, below_righty);
below_rightx += combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_HOLAM:
if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW)
targetx =
main_glyph->offset_x - combining_glyphs[i]->width -
(combining_glyphs[i]->width + 3) / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SIN_DOT:
targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4;
goto above_on_main;
case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT:
targetx =
main_glyph->width + main_glyph->offset_x -
combining_glyphs[i]->width;
above_on_main:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
do_blit (combining_glyphs[i], targetx,
-(main_glyph->height + main_glyph->offset_y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
/* TODO: Put dammah, fathah and alif nearer to shadda. */
case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH:
case GRUB_UNICODE_COMB_ARABIC_DAMMAH:
case GRUB_UNICODE_COMB_ARABIC_DAMMATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHATAN:
case GRUB_UNICODE_COMB_ARABIC_FATHAH:
case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF:
case GRUB_UNICODE_COMB_ARABIC_SUKUN:
case GRUB_UNICODE_COMB_ARABIC_SHADDA:
case GRUB_UNICODE_COMB_HEBREW_RAFE:
case GRUB_UNICODE_STACK_ABOVE:
stacked_above:
space = combining_glyphs[i]->offset_y
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
-(bounds.height + bounds.y + space
+ combining_glyphs[i]->height));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_HEBREW_SHEVA:
case GRUB_UNICODE_COMB_HEBREW_HIRIQ:
case GRUB_UNICODE_COMB_HEBREW_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_TSERE:
case GRUB_UNICODE_COMB_HEBREW_SEGOL:
/* TODO: placement in final kaf and under reish. */
case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL:
case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH:
case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS:
case GRUB_UNICODE_COMB_HEBREW_PATAH:
case GRUB_UNICODE_COMB_HEBREW_QUBUTS:
case GRUB_UNICODE_COMB_HEBREW_METEG:
/* TODO: Put kasra and kasratan under shadda. */
case GRUB_UNICODE_COMB_ARABIC_KASRA:
case GRUB_UNICODE_COMB_ARABIC_KASRATAN:
/* I don't know how ypogegrammeni differs from subscript. */
case GRUB_UNICODE_COMB_YPOGEGRAMMENI:
case GRUB_UNICODE_STACK_BELOW:
stacked_below:
space = -(combining_glyphs[i]->offset_y
+ combining_glyphs[i]->height);
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
case GRUB_UNICODE_STACK_ATTACHED_BELOW:
do_blit (combining_glyphs[i], targetx, -(bounds.y - space));
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_COMB_MN:
switch (glyph_id->combining[i].code)
{
case GRUB_UNICODE_THAANA_ABAFILI:
case GRUB_UNICODE_THAANA_AABAAFILI:
case GRUB_UNICODE_THAANA_UBUFILI:
case GRUB_UNICODE_THAANA_OOBOOFILI:
case GRUB_UNICODE_THAANA_EBEFILI:
case GRUB_UNICODE_THAANA_EYBEYFILI:
case GRUB_UNICODE_THAANA_OBOFILI:
case GRUB_UNICODE_THAANA_OABOAFILI:
case GRUB_UNICODE_THAANA_SUKUN:
goto stacked_above;
case GRUB_UNICODE_THAANA_IBIFILI:
case GRUB_UNICODE_THAANA_EEBEEFILI:
goto stacked_below;
}
/* Fall through. */
default:
{
/* Default handling. Just draw combining character on top
of base character.
FIXME: support more unicode types correctly.
*/
do_blit (combining_glyphs[i],
main_glyph->device_width
+ combining_glyphs[i]->offset_x,
-(combining_glyphs[i]->height
+ combining_glyphs[i]->offset_y));
add_device_width (combining_glyphs[i]->device_width);
}
}
}
add_device_width ((above_rightx >
below_rightx ? above_rightx : below_rightx) -
(main_glyph->offset_x + main_glyph->width));
add_device_width (above_leftx - main_glyph->offset_x);
if (glyph && glyph->device_width < min_devwidth)
glyph->device_width = min_devwidth;
if (device_width && *device_width < min_devwidth)
*device_width = min_devwidth;
if (bounds_out)
*bounds_out = bounds;
}
static struct grub_font_glyph *
grub_font_construct_dry_run (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id,
struct grub_video_signed_rect *bounds,
struct grub_font_glyph ***combining_glyphs_out,
int *device_width)
{
struct grub_font_glyph *main_glyph = NULL;
struct grub_font_glyph **combining_glyphs;
grub_uint32_t desired_attributes = 0;
if (combining_glyphs_out)
*combining_glyphs_out = NULL;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base
| desired_attributes);
if (!main_glyph)
main_glyph = grub_font_get_glyph_with_fallback (hinted_font,
glyph_id->base);
/* Glyph not available in any font. Use ASCII fallback. */
if (!main_glyph)
main_glyph = ascii_glyph_lookup (glyph_id->base);
/* Glyph not available in any font. Return unknown glyph. */
if (!main_glyph)
return NULL;
if (device_width)
*device_width = main_glyph->device_width;
if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph;
combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
* glyph_id->ncomb);
if (glyph_id->ncomb && !combining_glyphs)
{
grub_errno = GRUB_ERR_NONE;
return main_glyph;
}
{
unsigned i;
for (i = 0; i < glyph_id->ncomb; i++)
combining_glyphs[i]
= grub_font_get_glyph_with_fallback (main_glyph->font,
glyph_id->combining[i].code);
}
blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
device_width);
if (combining_glyphs_out)
*combining_glyphs_out = combining_glyphs;
else
grub_free (combining_glyphs);
return main_glyph;
}
int
grub_font_get_constructed_device_width (grub_font_t hinted_font,
const struct grub_unicode_glyph
*glyph_id)
{
int ret;
struct grub_font_glyph *main_glyph;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
NULL, &ret);
if (!main_glyph)
return unknown_glyph->device_width;
return ret;
}
struct grub_font_glyph *
grub_font_construct_glyph (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id)
{
struct grub_font_glyph *main_glyph;
struct grub_video_signed_rect bounds;
struct grub_font_glyph *glyph;
struct grub_font_glyph **combining_glyphs;
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
&bounds, &combining_glyphs, NULL);
if (!main_glyph)
return grub_font_dup_glyph (unknown_glyph);
if (!combining_glyphs)
return grub_font_dup_glyph (main_glyph);
glyph =
grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
if (!glyph)
{
grub_errno = GRUB_ERR_NONE;
return grub_font_dup_glyph (main_glyph);
}
glyph->font = main_glyph->font;
glyph->width = bounds.width;
glyph->height = bounds.height;
glyph->offset_x = bounds.x;
glyph->offset_y = bounds.y;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
grub_font_blit_glyph_mirror (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height +
main_glyph->offset_y));
else
grub_font_blit_glyph (glyph, main_glyph,
main_glyph->offset_x - glyph->offset_x,
(glyph->height + glyph->offset_y)
- (main_glyph->height + main_glyph->offset_y));
blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL);
return glyph;
}
/* Draw the specified glyph at (x, y). The y coordinate designates the
baseline of the character, while the x coordinate designates the left
@ -1065,8 +1500,8 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
glyph_bitmap.mode_info.width = glyph->width;
glyph_bitmap.mode_info.height = glyph->height;
glyph_bitmap.mode_info.mode_type =
(1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.mode_type
= (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
glyph_bitmap.mode_info.bpp = 1;
@ -1096,29 +1531,3 @@ grub_font_draw_glyph (struct grub_font_glyph * glyph,
bitmap_left, bitmap_top,
0, 0, glyph->width, glyph->height);
}
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color, int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, x = left_x;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
{
glyph = grub_font_get_glyph_with_fallback (font, code);
if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
return grub_errno;
x += glyph->device_width;
}
return GRUB_ERR_NONE;
}

View file

@ -21,6 +21,7 @@
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
static grub_err_t
loadfont_command (grub_command_t cmd __attribute__ ((unused)),
@ -62,11 +63,11 @@ GRUB_MOD_INIT(font)
cmd_loadfont =
grub_register_command ("loadfont", loadfont_command,
"FILE...",
"Specify one or more font files to load.");
N_("FILE..."),
N_("Specify one or more font files to load."));
cmd_lsfonts =
grub_register_command ("lsfonts", lsfonts_command,
0, "List the loaded fonts.");
0, N_("List the loaded fonts."));
}
GRUB_MOD_FINI(font)

View file

@ -114,7 +114,7 @@ grub_pxe_open (const char *name, grub_disk_t disk)
return err;
if (*ptr == ':')
{
err = parse_ip (ptr + 1, &(data->server_ip), 0);
err = parse_ip (ptr + 1, &(data->gateway_ip), 0);
if (err)
return err;
}

1178
fs/nilfs2.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -929,7 +929,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
"Warning : %s has no stat block !\n",
entry_name);
grub_free (entry_item);
continue;
goto next;
}
}
if (hook (entry_name, entry_type, entry_item))
@ -940,6 +940,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
goto found;
}
next:
*entry_name = 0; /* Make sure next entry name (which is just
before this one in disk order) stops before
the current one. */

View file

@ -228,7 +228,7 @@ VIDEOFILES += #{video}
#{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh
@ -238,7 +238,7 @@ VIDEOFILES += #{video}
#{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
@ -253,7 +253,7 @@ VIDEOFILES += #{video}
#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} -DGRUB_LST_GENERATOR $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
"

View file

@ -309,14 +309,10 @@ grub_gettext_init_ext (const char *lang)
static void
grub_gettext_delete_list (void)
{
struct grub_gettext_msg *item;
while ((item =
grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0)
while (grub_gettext_msg_list)
{
char *original = (char *) ((struct grub_gettext_msg *) item)->name;
grub_free (original);
grub_free ((char *) grub_gettext_msg_list->name);
grub_gettext_msg_list = grub_gettext_msg_list->next;
/* Don't delete the translated message because could be in use. */
}
}

109
gfxmenu/font.c Normal file
View file

@ -0,0 +1,109 @@
/* font.c - Font API and font file loader. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/bufio.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/font.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
#include <grub/gfxmenu_view.h>
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
0, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width;
grub_free (glyph);
if (err)
return err;
}
grub_free (visual);
return GRUB_ERR_NONE;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width = 0;
grub_uint32_t *ptr;
grub_ssize_t logical_len;
grub_uint32_t *logical;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
for (ptr = logical; ptr < logical + logical_len;)
{
struct grub_unicode_glyph glyph;
ptr += grub_unicode_aglomerate_comb (ptr,
logical_len - (ptr - logical),
&glyph);
width += grub_font_get_constructed_device_width (font, &glyph);
grub_free (glyph.combining);
}
return width;
}

View file

@ -110,6 +110,13 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
view->nested = nested;
view->first_timeout = -1;
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
if (view->double_repaint)
{
grub_video_swap_buffers ();
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
}
grub_gfxmenu_view_draw (view);
instance->data = view;

View file

@ -54,6 +54,7 @@ static void
circprog_destroy (void *vself)
{
circular_progress_t self = vself;
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self);
}
@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds)
*bounds = self->bounds;
}
static void
circprog_set_state (void *vself, int visible, int start,
int current, int end)
{
circular_progress_t self = vself;
self->visible = visible;
self->start = start;
self->value = current;
self->end = end;
}
static grub_err_t
circprog_set_property (void *vself, const char *name, const char *value)
{
@ -247,26 +259,20 @@ circprog_set_property (void *vself, const char *name, const char *value)
}
else if (grub_strcmp (name, "id") == 0)
{
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self->id);
if (value)
self->id = grub_strdup (value);
else
self->id = 0;
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
== 0)
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
circprog_set_state);
}
return grub_errno;
}
static void
circprog_set_state (void *vself, int visible, int start,
int current, int end)
{
circular_progress_t self = vself;
self->visible = visible;
self->start = start;
self->value = current;
self->end = end;
}
static struct grub_gui_component_ops circprog_ops =
{
.destroy = circprog_destroy,

View file

@ -46,8 +46,10 @@ struct grub_gui_label
char *id;
int visible;
char *text;
char *template;
grub_font_t font;
grub_gui_color_t color;
int value;
enum align_mode align;
};
@ -57,7 +59,9 @@ static void
label_destroy (void *vself)
{
grub_gui_label_t self = vself;
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self->text);
grub_free (self->template);
grub_free (self);
}
@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
+ grub_font_get_descent (self->font));
}
static void
label_set_state (void *vself, int visible, int start __attribute__ ((unused)),
int current, int end __attribute__ ((unused)))
{
grub_gui_label_t self = vself;
self->value = -current;
self->visible = visible;
grub_free (self->text);
self->text = grub_xasprintf (self->template ? : "%d", self->value);
}
static grub_err_t
label_set_property (void *vself, const char *name, const char *value)
{
@ -153,9 +168,17 @@ label_set_property (void *vself, const char *name, const char *value)
if (grub_strcmp (name, "text") == 0)
{
grub_free (self->text);
grub_free (self->template);
if (! value)
value = "";
self->text = grub_strdup (value);
{
self->template = NULL;
self->text = grub_strdup ("");
}
else
{
self->template = grub_strdup (value);
self->text = grub_xasprintf (value, self->value);
}
}
else if (grub_strcmp (name, "font") == 0)
{
@ -183,11 +206,16 @@ label_set_property (void *vself, const char *name, const char *value)
}
else if (grub_strcmp (name, "id") == 0)
{
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self->id);
if (value)
self->id = grub_strdup (value);
else
self->id = 0;
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
== 0)
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
label_set_state);
}
return GRUB_ERR_NONE;
}

View file

@ -210,8 +210,7 @@ draw_scrollbar (list_impl_t self,
/* Draw the list of items. */
static void
draw_menu (list_impl_t self, int width, int drawing_scrollbar,
int num_shown_items)
draw_menu (list_impl_t self, int num_shown_items)
{
if (! self->menu_box || ! self->selected_item_box)
return;
@ -226,14 +225,20 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar,
make_selected_item_visible (self);
int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_leftpad = selbox->get_left_pad (selbox);
int item_top = boxpad;
int item_left = boxpad + sel_leftpad;
int sel_toppad = selbox->get_top_pad (selbox);
int item_top = sel_toppad;
int menu_index;
int visible_index;
struct grub_video_rect oviewport;
grub_video_get_viewport (&oviewport.x, &oviewport.y,
&oviewport.width, &oviewport.height);
grub_video_set_viewport (oviewport.x + boxpad,
oviewport.y + boxpad,
oviewport.width - 2 * boxpad,
oviewport.height - 2 * boxpad);
for (visible_index = 0, menu_index = self->first_shown_index;
visible_index < num_shown_items && menu_index < self->view->menu->size;
@ -243,20 +248,16 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar,
if (is_selected)
{
int sel_toppad = selbox->get_top_pad (selbox);
selbox->set_content_size (selbox,
(width - 2 * boxpad
- scrollbar_h_space),
item_height);
selbox->draw (selbox,
item_left - sel_leftpad,
selbox->set_content_size (selbox, oviewport.width - 2 * boxpad - 2,
item_height - 1);
selbox->draw (selbox, 0,
item_top - sel_toppad);
}
struct grub_video_bitmap *icon;
if ((icon = get_item_icon (self, menu_index)) != 0)
grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
item_left,
sel_leftpad,
item_top + (item_height - self->icon_height) / 2,
0, 0, self->icon_width, self->icon_height);
@ -273,12 +274,16 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar,
grub_font_draw_string (item_title,
font,
grub_gui_map_color (text_color),
item_left + self->icon_width + icon_text_space,
sel_leftpad + self->icon_width + icon_text_space,
(item_top + (item_height - (ascent + descent))
/ 2 + ascent));
item_top += item_height + item_vspace;
}
grub_video_set_viewport (oviewport.x,
oviewport.y,
oviewport.width,
oviewport.height);
}
static void
@ -320,7 +325,7 @@ list_paint (void *vself, const grub_video_rect_t *region)
box->draw (box, 0, 0);
grub_gui_set_viewport (&content_rect, &vpsave2);
draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items);
draw_menu (self, num_shown_items);
grub_gui_restore_viewport (&vpsave2);
if (drawing_scrollbar)
@ -329,7 +334,7 @@ list_paint (void *vself, const grub_video_rect_t *region)
0, self->view->menu->size,
self->bounds.width - box_right_pad
+ self->scrollbar_width,
box_top_pad + self->item_padding,
box_top_pad,
self->bounds.height - box_top_pad - box_bottom_pad);
}
@ -383,6 +388,9 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
int box_bottom_pad = box->get_bottom_pad (box);
unsigned width_s;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_toppad = selbox->get_top_pad (selbox);
*width = grub_font_get_string_width (self->item_font, "Typical OS");
width_s = grub_font_get_string_width (self->selected_item_font,
"Typical OS");
@ -395,7 +403,7 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
*height = (item_height * num_items
+ item_vspace * (num_items - 1)
+ 2 * boxpad
+ box_top_pad + box_bottom_pad);
+ box_top_pad + box_bottom_pad + sel_toppad);
}
else
{

View file

@ -60,6 +60,7 @@ static void
progress_bar_destroy (void *vself)
{
grub_gui_progress_bar_t self = vself;
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self);
}
@ -333,11 +334,16 @@ progress_bar_set_property (void *vself, const char *name, const char *value)
}
else if (grub_strcmp (name, "id") == 0)
{
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self->id);
if (value)
self->id = grub_strdup (value);
else
self->id = 0;
/* if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
== 0)*/
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
progress_bar_set_state);
}
return grub_errno;
}
@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void)
self = grub_zalloc (sizeof (*self));
if (! self)
return 0;
self->progress.ops = &progress_bar_pb_ops;
self->progress.component.ops = &progress_bar_ops;
self->visible = 1;

View file

@ -37,10 +37,6 @@
#include <grub/gui_string_util.h>
#include <grub/icon_manager.h>
/* The component ID identifying GUI components to be updated as the timeout
status changes. */
#define TIMEOUT_COMPONENT_ID "__timeout__"
static void
init_terminal (grub_gfxmenu_view_t view);
static grub_video_rect_t term_rect;
@ -166,16 +162,28 @@ struct progress_value_data
int value;
};
static void
update_timeout_visit (grub_gui_component_t component,
void *userdata)
{
struct progress_value_data *pv;
pv = (struct progress_value_data *) userdata;
struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
((struct grub_gui_progress *) component)->ops
->set_state ((struct grub_gui_progress *) component,
pv->visible, pv->start, pv->value, pv->end);
static void
update_timeouts (int visible, int start, int value, int end)
{
struct grub_gfxmenu_timeout_notify *cur;
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
cur->set_state (cur->self, visible, start, value, end);
}
static void
redraw_timeouts (struct grub_gfxmenu_view *view)
{
struct grub_gfxmenu_timeout_notify *cur;
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
{
grub_video_rect_t bounds;
cur->self->ops->get_bounds (cur->self, &bounds);
grub_gfxmenu_view_redraw (view, &bounds);
}
}
void
@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data)
{
struct grub_gfxmenu_view *view = data;
struct progress_value_data pv;
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)));
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)))
{
grub_video_rect_t bounds;
component->ops->get_bounds (component, &bounds);
grub_gfxmenu_view_redraw (view, &bounds);
}
if (view->first_timeout == -1)
view->first_timeout = timeout;
pv.visible = 1;
pv.start = -(view->first_timeout + 1);
pv.end = 0;
pv.value = -timeout;
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
update_timeouts (1, -(view->first_timeout + 1), -timeout, 0);
redraw_timeouts (view);
grub_video_swap_buffers ();
if (view->double_repaint)
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
redraw_timeouts (view);
}
void
grub_gfxmenu_clear_timeout (void *data)
{
struct progress_value_data pv;
struct grub_gfxmenu_view *view = data;
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)));
auto void redraw_timeout_visit (grub_gui_component_t component,
void *userdata __attribute__ ((unused)))
{
grub_video_rect_t bounds;
component->ops->get_bounds (component, &bounds);
grub_gfxmenu_view_redraw (view, &bounds);
}
pv.visible = 0;
pv.start = 1;
pv.end = 0;
pv.value = 0;
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
update_timeouts (0, 1, 0, 0);
redraw_timeouts (view);
grub_video_swap_buffers ();
if (view->double_repaint)
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
redraw_timeouts (view);
}
static void
@ -390,11 +357,6 @@ grub_gfxmenu_draw_terminal_box (void)
term_box->draw (term_box,
term_rect.x - term_box->get_left_pad (term_box),
term_rect.y - term_box->get_top_pad (term_box));
grub_video_swap_buffers ();
if (term_view->double_repaint)
term_box->draw (term_box,
term_rect.x - term_box->get_left_pad (term_box),
term_rect.y - term_box->get_top_pad (term_box));
}
static void

View file

@ -32,6 +32,12 @@ typedef enum
GRUB_ATA_LBA48
} grub_ata_addressing_t;
#define GRUB_ATA_CH0_PORT1 0x1f0
#define GRUB_ATA_CH1_PORT1 0x170
#define GRUB_ATA_CH0_PORT2 0x3f6
#define GRUB_ATA_CH1_PORT2 0x376
#define GRUB_ATA_REG_DATA 0
#define GRUB_ATA_REG_ERROR 1
#define GRUB_ATA_REG_FEATURES 1

View file

@ -63,6 +63,8 @@
#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18
#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19
#define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2
/* The BSD partition entry. */
struct grub_partition_bsd_entry
{

View file

@ -117,5 +117,11 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position);
void
grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
grub_uint8_t *dest, grub_size_t destsize);
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend);
#endif

View file

@ -115,12 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv)
return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND;
}
static inline int
grub_command_iterate (int (*func) (grub_command_t))
{
return grub_list_iterate (GRUB_AS_LIST (grub_command_list),
(grub_list_hook_t) func);
}
#define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list)
void grub_register_core_commands (void);

Some files were not shown because too many files have changed in this diff Show more